commit 8a5223aec174a4e175351ab8fa221a791ffac010 Author: Mario Fetka Date: Thu Mar 22 15:51:09 2018 +0100 Imported Upstream version 0.048 diff --git a/Changes b/Changes new file mode 100644 index 0000000..2b15929 --- /dev/null +++ b/Changes @@ -0,0 +1,249 @@ +Changes for CryptX + +TODO: + - add support for PKCS#8 encrypted RSA+ECC private keys "-----BEGIN ENCRYPTED PRIVATE KEY-----" + - RSA|DSA|ECC: verify_key($level) (basic check + extented primality test) + - better primality testing: http://questhub.io/realm/perl/quest/519032ee1088c76505000035 (idea: mp_prime_lucas) + - DSA: generate_key($p, $q, $g), generate_key(\$dsa_params_der), generate_key($dsa_params_file) + - XS croaks should report the "real caller" (Crypt::Mac::*, Crypt::Mode::*, ...) + - maybe: add CCM interface for new-add-add-done mode + - maybe: add encode_b32/decode_b32 + +0.048 2017/05/31 + - NEW: Crypt::Digest::SHA3_224 + - NEW: Crypt::Digest::SHA3_256 + - NEW: Crypt::Digest::SHA3_384 + - NEW: Crypt::Digest::SHA3_512 + - NEW: Crypt::Digest::SHAKE + - NEW: Crypt::Digest::BLAKE2b_160 + - NEW: Crypt::Digest::BLAKE2b_256 + - NEW: Crypt::Digest::BLAKE2b_384 + - NEW: Crypt::Digest::BLAKE2b_512 + - NEW: Crypt::Digest::BLAKE2s_128 + - NEW: Crypt::Digest::BLAKE2s_160 + - NEW: Crypt::Digest::BLAKE2s_224 + - NEW: Crypt::Digest::BLAKE2s_256 + - NEW: Crypt::AuthEnc::ChaCha20Poly1305 + - NEW: Crypt::Mac::Poly1305 + - NEW: Crypt::Mac::BLAKE2s + - NEW: Crypt::Mac::BLAKE2b + - NEW: Crypt::PRNG::ChaCha20 + - NEW: Crypt::Stream::ChaCha + - NEW: Crypt::Stream::RC4 + - NEW: Crypt::Stream::Sober128 + - NEW: functions in Crypt::Misc - increment_octets_be, increment_octets_le + - Crypt::PRNG now uses chacha20 prng by default + +0.047 2017/04/05 + - fix #32 Compile "ar" step fails when Perl built with -flto (better version) + - fix #33 build fails on freebsd 9.2 and 10.0 (ar: fatal: Numeric group ID too large) + +0.046 2017/04/04 + - fix #32 Compile "ar" step fails when Perl built with -flto + +0.045 2017/03/31 + - sync with libtomcrypt/develop + - fix #30 fix on SPARC+SolarisStudio + - fix #31 Fails tests without '.' in @INC + - polish compiler warnings + +0.044 2016/11/28 + - fix #27 Math::BigInt::LTM compatibility with older Math::BigInt + +0.043 2016/11/27 + - fix #26 Math::BigInt::LTM compatibility with Math::BigInt 1.999801+ + +0.042 2016/11/12 + - RSA: sign/verify functions now support 'none' padding (INSECURE!) + - RC2: min keylen 40bit, used to be 64bit (INSECURE!) + +0.041 2016/10/12 + - ECC: ltc_ecc_is_point memory leak + - DSA: properly handle FIPS 186-4 (4.6 + 4.7) + - GCM: counter incrementation isn't stopped at 2^32 blocks, which breaks GCM + - fix issue #24 Crypt::PK::ECC needs $VERSION (all *.pm have $VERSION) + +0.040 2016/09/12 + - fix file permissions + - fix compiler warnings + +0.039 2016/08/02 + - fix build troubles for MacOS / PPC + +0.038 2016/07/06 + - fix issue #20 DSA/RSA/ECC/DH key2hash - hexadecimal numbers are missing leading zero + - Math::BigInt::LTM fixed mp_invmod(a,b,c) for b == 1 + - Math::BigInt::LTM fixed _log_int() + - Math::BigInt::LTM fixed _alen() + - fix 'Please specify prototyping behavior for CryptX.xs' + - libtomcrypt (renaming *tab.c > *tab.c.inc not needed anymore) + +0.037 2016/06/16 + - fix issue #18 Minor issue with comment syntax + - fix issue #19 t/checksum.t fails on AIX-5.3 + +0.036 2016/06/07 + - fix issue #17 ability to export ecc keys in short/oid form + +0.035 2016/06/03 + - fix issue #14 Ensure Crypt::PK::ECC->key2hash()->{curve_name} is lowercase + - fix issue #15 OpenSSL interoperability broken + +0.034 2016/05/11 + - Prevent RSA import_key() from altering a JWK hash reference + +0.033 2016/05/09 + - MSVC6 related fixes (needed for older ActivePerl@MSWin32) + +0.032 2016/05/04 + - Crypt::PK::DH - accept base/prime values + - new: DH methods export_key_raw, import_key_raw, params2hash + - enhanced: DH method generate_key + - new: Crypt::Checksum, Crypt::Checksum::CRC32, Crypt::Checksum::Adler32 + +0.031 2016/05/01 + - new: RSA+ECC method export_key_jwk_thumbprint() + - new: Crypt::Misc functions random_v4uuid + is_v4uuid + - fix: RSA+ECC export_key_jwk produces canonical JSON + - fix: RSA+DSA public key export now produces PEM/DER compatible with openssl + public keys exported be previous version can still be imported + - fix: ECC import_key now accepts non-standard JWK curve names e.g. "secp112r1", "secp521r1" + +0.030 2016/04/13 + - fix: 0.029 + 0.028 by mistake installed *.inc files to perl/(lib|site|vendor) + +0.029 2016/04/13 + - NEW module: Math::BigInt::LTM + - NEW module: Crypt::Misc + +0.028 2016/03/23 + - IMPORTANT: switch from Module::Build to ExtUtils::MakeMaker + - fix for broken DSA key (ssh format) loading + +0.027 2016/01/25 + - sync with https://github.com/libtom/libtomcrypt (branch develop) + - sync with https://github.com/libtom/libtommath (branch develop) + - HP-UX related fixes + - JSON dependency is now optional (we check JSON::PP, JSON::XS, Cpanel::JSON::XS) + - skip jwk.t if no JSON::* module available + - does not require MIME::Base64 (we use base64 routines from libtomcrypt) + +0.026 2015/11/28 + - switch to JSON::MaybeXS + - Crypt::PRNG - rand/irand related cosmetics + - consistently using UNIX newlines + +0.025 2015/07/07 + - Crypt::PK::ECC+RSA export_key_jwk() allows to export a perl HASH with JWK structure + +0.024 2015/06/29 + - new Crypt::PK::ECC methods + verify_message_rfc7518() + sign_message_rfc7518() + curve2hash() + - fix for Crypt::PK::RSA - bug in loading private key in JWK format + +0.023 2015/06/10 + - support for older compilers (gcc3, vc6) + - typo in documentation (by tomhukins) + +0.022 2015/05/22 + - new: Crypt::PK::ECC+RSA export_key_jwk() - exporting JWK format + - new: Crypt::Digest::SHA512_224 + - new: Crypt::Digest::SHA512_256 + - Crypt::PK::ECC+RSA import_key() - support for: + * public/private keys in JWK format + * private keys in PKCS8 PEM/DER format (unencrypted only) + - Crypt::PK::ECC+RSA+DSA import_key() - support for: + * public keys in SSH format + * public/private keys as a hashref exported via key2hash + - libtomcrypt updated to the latest develop branch, commit aeaa6d4a51 Apr 17 08:59:35 2015 +0200 + - libtommath updated to the latest develop branch, commit 0fd5e6c17f Dec 11 14:59:35 2014 +0100 + - documentation fixes + +0.021 2014/01/23 + - fixed asm(...) related compiler failures + - dsa_encrypt_key small correction + - optimized ecc_encrypt_key + +0.020 2014/01/18 + - INCOMPATIBLE CHANGE: huge redesign of Crypt::PK::ECC + - ECC now supports curves y^2 = x^3 + a*x + b + - ECC you can use custom curves + - ECC import/export of keys in DER/PEM format now compatible with openssl + - enabling compile options ASM + ECC_TIMING_RESISTANT + - added many test vectors (RSA, DSA, EC) for interoperability with openssl + +0.019 2013/10/20 + - fixed broken CAMELLIA implementation + +0.018 2013/10/18 + - DSA: make_key + sign_hash fixes + +0.017 2013/09/24 + - lowering MIME::Base64 version requirement + - support for import/export of password protected RSA/DSA keys + - RSA: added - export_key_pem('public_x509') + - better handling of dh_free/rsa_free/dsa_free/ecc_free + - added openssl test vectors + - fixed compiler warnings (RSA/DSA/ECC/DH) + +0.016 2013/09/15 + - added missing test for key2hash, sign_hash, verify_hash + - fixed build failures on VC6 + +0.015 2013/09/12 + - only documentation fixes + +0.014 2013/09/11 + - Crypt::Digest::NNN + Crypt::Mac::NNN - can produce Base64-URL-Safe encoded digest/mac + - Crypt::PRNG + Crypt::PRNG::NNN - Base64-URL-Safe encoded random bytes (random_bytes_b64u/bytes_b64u) + - Crypt::PK::RSA/DSA/DH/ECC - sign/verify replaced by sign_message/verify_message + sign_hash/verify_hash + - Crypt::PK::RSA/DSA/DH/ECC - new method key2hash + - documentation fixes + +0.013 2013/08/28 + - DSA/RSA/ECC/DH - importing keys from string changed - now: $pk->import_key(\$buffer_with_key) + - DSA/RSA/ECC/DH - size() and is_private() now return undef if no key loaded + - improved RSA doc + +0.012 2013/06/17 + - README, LICENSE etc. to improve CPANTS score + - somehow works with perl 5.6.2 + +0.011 2013/06/15 + - fixing various compiler warnings + +0.009 2013/05/19 + - doc fixes + - requires perl 5.8.8 or higher + - INCOMPATIBILITY: all digest related 'xxx_base64' functions renamed to 'xxx_b64' + +0.008 2013/05/02 + - fixed prng test failures + - Crypt::Digest::* croaks with the "real caller" (not a nice solution) + +0.007 2013/04/23 + - Crypt::PRNG supports add_entropy() - without params + - Crypt::PRNG fork-safe & thread-safe + - random_string has default $len = 20 + - doc fixes + - cpan tester failure fix for pk_dsa.t + +0.006 2013/04/19 + - added Crypt::KeyDerivation + - Win64 compatibility + +0.005 2013/04/18 + - added Crypt::PRNG::Fortuna|RC4|Sober128|Yarrow + - added Crypt::PK::RSA|DSA|ECC|DH + +0.004 2013/04/16 + - removing illegal Crypt::Random + +0.003 2013/04/16 + - added Crypt::Mode::CBC|CFB|CTR|ECB|OFB + - added Crypt::AuthEnc::CCM|EAX|GCM|OCB + +0.002 2013/04/11 + - first release on CPAN diff --git a/CryptX.xs b/CryptX.xs new file mode 100644 index 0000000..404d0da --- /dev/null +++ b/CryptX.xs @@ -0,0 +1,580 @@ +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" + +#define NEED_sv_2pvbyte_GLOBAL +#define NEED_sv_2pv_flags_GLOBAL +#define NEED_newRV_noinc_GLOBAL +#include "ppport.h" + +#undef LTC_SOURCE +#include "tomcrypt.h" +#include "tommath.h" + +typedef adler32_state *Crypt__Checksum__Adler32; +typedef crc32_state *Crypt__Checksum__CRC32; + +typedef struct cipher_struct { /* used by Crypt::Cipher */ + symmetric_key skey; + int id; + struct ltc_cipher_descriptor *desc; +} *Crypt__Cipher; + +typedef struct digest_struct { /* used by Crypt::Digest */ + hash_state state; + int id; + struct ltc_hash_descriptor *desc; +} *Crypt__Digest; + +typedef struct digest_shake_struct { /* used by Crypt::Digest::SHAKE */ + hash_state state; + int num; +} *Crypt__Digest__SHAKE; + +typedef struct ccm_struct { /* used by Crypt::AuthEnc::CCM */ + ccm_state state; + int id; +} *Crypt__AuthEnc__CCM; + +typedef struct eax_struct { /* used by Crypt::AuthEnc::EAX */ + eax_state state; + int id; +} *Crypt__AuthEnc__EAX; + +typedef struct gcm_struct { /* used by Crypt::AuthEnc::GCM */ + gcm_state state; + int id; +} *Crypt__AuthEnc__GCM; + +typedef struct chacha20poly1305_struct {/* used by Crypt::AuthEnc::ChaCha20Poly1305 */ + chacha20poly1305_state state; + int id; +} *Crypt__AuthEnc__ChaCha20Poly1305; + +typedef struct ocb_struct { /* used by Crypt::AuthEnc::OCB */ + ocb3_state state; + int id; +} *Crypt__AuthEnc__OCB; + +typedef struct chacha_struct { /* used by Crypt::Stream::ChaCha */ + chacha_state state; + int id; +} *Crypt__Stream__ChaCha; + +typedef struct rc4_struct { /* used by Crypt::Stream::RC4 */ + rc4_state state; + int id; +} *Crypt__Stream__RC4; + +typedef struct sober128_struct { /* used by Crypt::Stream::Sober128 */ + sober128_state state; + int id; +} *Crypt__Stream__Sober128; + +typedef struct f9_struct { /* used by Crypt::Mac::F9 */ + f9_state state; + int id; +} *Crypt__Mac__F9; + +typedef struct hmac_struct { /* used by Crypt::Mac::HMAC */ + hmac_state state; + int id; +} *Crypt__Mac__HMAC; + +typedef struct omac_struct { /* used by Crypt::Mac::OMAC */ + omac_state state; + int id; +} *Crypt__Mac__OMAC; + +typedef struct pelican_struct { /* used by Crypt::Mac::Pelican */ + pelican_state state; + int id; +} *Crypt__Mac__Pelican; + +typedef struct pmac_struct { /* used by Crypt::Mac::PMAC */ + pmac_state state; + int id; +} *Crypt__Mac__PMAC; + +typedef struct xcbc_struct { /* used by Crypt::Mac::XCBC */ + xcbc_state state; + int id; +} *Crypt__Mac__XCBC; + +typedef struct poly1305_struct { /* used by Crypt::Mac::Poly1305 */ + poly1305_state state; + int id; +} *Crypt__Mac__Poly1305; + +typedef struct blake2s_struct { /* used by Crypt::Mac::BLAKE2s */ + blake2smac_state state; + int id; +} *Crypt__Mac__BLAKE2s; + +typedef struct blake2b_struct { /* used by Crypt::Mac::BLAKE2b */ + blake2bmac_state state; + int id; +} *Crypt__Mac__BLAKE2b; + +typedef struct cbc_struct { /* used by Crypt::Mode::CBC */ + int cipher_id, cipher_rounds; + symmetric_CBC state; + unsigned char pad[MAXBLOCKSIZE]; + int padlen; + int padding_mode; + int direction; + int id; +} *Crypt__Mode__CBC; + +typedef struct ecb_struct { /* used by Crypt::Mode::ECB */ + int cipher_id, cipher_rounds; + symmetric_ECB state; + unsigned char pad[MAXBLOCKSIZE]; + int padlen; + int padding_mode; + int direction; + int id; +} *Crypt__Mode__ECB; + +typedef struct cfb_struct { /* used by Crypt::Mode::CFB */ + int cipher_id, cipher_rounds; + symmetric_CFB state; + int direction; + int id; +} *Crypt__Mode__CFB; + +typedef struct ctr_struct { /* used by Crypt::Mode::CTR */ + int cipher_id, cipher_rounds; + int ctr_mode_param; + symmetric_CTR state; + int direction; + int id; +} *Crypt__Mode__CTR; + +typedef struct f8_struct { /* used by Crypt::Mode::F8 */ + int cipher_id, cipher_rounds; + symmetric_F8 state; + int direction; + int id; +} *Crypt__Mode__F8; + +typedef struct lrw_struct { /* used by Crypt::Mode::LRW */ + int cipher_id, cipher_rounds; + symmetric_LRW state; + int direction; + int id; +} *Crypt__Mode__LRW; + +typedef struct ofb_struct { /* used by Crypt::Mode::OFB */ + int cipher_id, cipher_rounds; + symmetric_OFB state; + int direction; + int id; +} *Crypt__Mode__OFB; + +typedef struct xts_struct { /* used by Crypt::Mode::XTS */ + int cipher_id, cipher_rounds; + symmetric_xts state; + int direction; + int id; +} *Crypt__Mode__XTS; + +typedef struct prng_struct { /* used by Crypt::PRNG */ + prng_state state; + struct ltc_prng_descriptor *desc; + IV last_pid; + int id; +} *Crypt__PRNG; + +typedef struct rsa_struct { /* used by Crypt::PK::RSA */ + prng_state pstate; + int pindex; + rsa_key key; + int id; +} *Crypt__PK__RSA; + +typedef struct dsa_struct { /* used by Crypt::PK::DSA */ + prng_state pstate; + int pindex; + dsa_key key; + int id; +} *Crypt__PK__DSA; + +typedef struct dh_struct { /* used by Crypt::PK::DH */ + prng_state pstate; + int pindex; + dh_key key; + int id; +} *Crypt__PK__DH; + +typedef struct ecc_struct { /* used by Crypt::PK::ECC */ + prng_state pstate; + int pindex; + ecc_key key; + ltc_ecc_set_type dp; + int id; +} *Crypt__PK__ECC; + +int str_add_leading_zero(char *str, int maxlen, int minlen) { + int len; + len = (int)strlen(str); + if (len > 0 && len % 2 && len < maxlen-2) { + memmove(str+1, str, len+1); /* incl. NUL byte */ + *str = '0'; /* add leading zero */ + } + len = (int)strlen(str); + if (len < minlen && minlen < maxlen-1) { + memmove(str+(minlen-len), str, len+1); /* incl. NUL byte */ + memset(str, '0', minlen-len); /* add leading zero */ + } + return MP_OKAY; +} + +int mp_tohex_with_leading_zero(mp_int * a, char *str, int maxlen, int minlen) { + int rv; + if (mp_isneg(a) == MP_YES) { + *str = '\0'; + return MP_VAL; + } + rv = mp_toradix_n(a, str, 16, maxlen); + if (rv != MP_OKAY) { + *str = '\0'; + return rv; + } + return str_add_leading_zero(str, maxlen, minlen); +} + +/* Math::BigInt::LTM related */ +typedef mp_int * Math__BigInt__LTM; +STATIC SV * sv_from_mpi(mp_int *mpi) { + SV *obj = newSV(0); + sv_setref_pv(obj, "Math::BigInt::LTM", (void*)mpi); + return obj; +} + +ltc_ecc_set_type* _ecc_set_dp_from_SV(ltc_ecc_set_type *dp, SV *curve) +{ + HV *h; + SV *param, **pref; + SV **sv_cofactor, **sv_prime, **sv_A, **sv_B, **sv_order, **sv_Gx, **sv_Gy; + int err; + char *ch_name; + STRLEN l_name; + + if (SvPOK(curve)) { + ch_name = SvPV(curve, l_name); + if ((h = get_hv("Crypt::PK::ECC::curve", 0)) == NULL) croak("FATAL: generate_key_ex: no curve register"); + if ((pref = hv_fetch(h, ch_name, (U32)l_name, 0)) == NULL) croak("FATAL: generate_key_ex: unknown curve/1 '%s'", ch_name); + if (!SvOK(*pref)) croak("FATAL: generate_key_ex: unknown curve/2 '%s'", ch_name); + param = *pref; + } + else if (SvROK(curve)) { + param = curve; + } + else { + croak("FATAL: curve has to be a string or a hashref"); + } + + if ((h = (HV*)(SvRV(param))) == NULL) croak("FATAL: ecparams: param is not valid hashref"); + + if ((sv_prime = hv_fetchs(h, "prime", 0)) == NULL) croak("FATAL: ecparams: missing param prime"); + if ((sv_A = hv_fetchs(h, "A", 0)) == NULL) croak("FATAL: ecparams: missing param A"); + if ((sv_B = hv_fetchs(h, "B", 0)) == NULL) croak("FATAL: ecparams: missing param B"); + if ((sv_order = hv_fetchs(h, "order", 0)) == NULL) croak("FATAL: ecparams: missing param order"); + if ((sv_Gx = hv_fetchs(h, "Gx", 0)) == NULL) croak("FATAL: ecparams: missing param Gx"); + if ((sv_Gy = hv_fetchs(h, "Gy", 0)) == NULL) croak("FATAL: ecparams: missing param Gy"); + if ((sv_cofactor = hv_fetchs(h, "cofactor", 0)) == NULL) croak("FATAL: ecparams: missing param cofactor"); + + if (!SvOK(*sv_prime )) croak("FATAL: ecparams: undefined param prime"); + if (!SvOK(*sv_A )) croak("FATAL: ecparams: undefined param A"); + if (!SvOK(*sv_B )) croak("FATAL: ecparams: undefined param B"); + if (!SvOK(*sv_order )) croak("FATAL: ecparams: undefined param order"); + if (!SvOK(*sv_Gx )) croak("FATAL: ecparams: undefined param Gx"); + if (!SvOK(*sv_Gy )) croak("FATAL: ecparams: undefined param Gy"); + if (!SvOK(*sv_cofactor)) croak("FATAL: ecparams: undefined param cofactor"); + + err = ecc_dp_set( dp, + SvPV_nolen(*sv_prime), + SvPV_nolen(*sv_A), + SvPV_nolen(*sv_B), + SvPV_nolen(*sv_order), + SvPV_nolen(*sv_Gx), + SvPV_nolen(*sv_Gy), + (unsigned long)SvUV(*sv_cofactor), + NULL, /* we intentionally don't allow setting custom names */ + NULL /* we intentionally don't allow setting custom OIDs */ + ); + return err == CRYPT_OK ? dp : NULL; +} + +void _ecc_free_key(ecc_key *key, ltc_ecc_set_type *dp) +{ + if(dp) { + ecc_dp_clear(dp); + } + if (key->type != -1) { + ecc_free(key); + key->type = -1; + key->dp = NULL; + } +} + +MODULE = CryptX PACKAGE = CryptX PREFIX = CryptX_ + +PROTOTYPES: DISABLE + +BOOT: + if(register_cipher(&blowfish_desc)==-1) { croak("FATAL: cannot register_cipher blowfish"); } + if(register_cipher(&rc5_desc)==-1) { croak("FATAL: cannot register_cipher rc5"); } + if(register_cipher(&rc6_desc)==-1) { croak("FATAL: cannot register_cipher rc6"); } + if(register_cipher(&rc2_desc)==-1) { croak("FATAL: cannot register_cipher rc2"); } + if(register_cipher(&saferp_desc)==-1) { croak("FATAL: cannot register_cipher saferp"); } + if(register_cipher(&safer_k64_desc)==-1) { croak("FATAL: cannot register_cipher safer_k64"); } + if(register_cipher(&safer_k128_desc)==-1) { croak("FATAL: cannot register_cipher safer_k128"); } + if(register_cipher(&safer_sk64_desc)==-1) { croak("FATAL: cannot register_cipher safer_sk64"); } + if(register_cipher(&safer_sk128_desc)==-1) { croak("FATAL: cannot register_cipher safer_sk128"); } + if(register_cipher(&aes_desc)==-1) { croak("FATAL: cannot register_cipher aes"); } + if(register_cipher(&xtea_desc)==-1) { croak("FATAL: cannot register_cipher xtea"); } + if(register_cipher(&twofish_desc)==-1) { croak("FATAL: cannot register_cipher twofish"); } + if(register_cipher(&des_desc)==-1) { croak("FATAL: cannot register_cipher des"); } + if(register_cipher(&des3_desc)==-1) { croak("FATAL: cannot register_cipher des3"); } + if(register_cipher(&cast5_desc)==-1) { croak("FATAL: cannot register_cipher cast5"); } + if(register_cipher(&noekeon_desc)==-1) { croak("FATAL: cannot register_cipher noekeon"); } + if(register_cipher(&skipjack_desc)==-1) { croak("FATAL: cannot register_cipher skipjack"); } + if(register_cipher(&khazad_desc)==-1) { croak("FATAL: cannot register_cipher khazad"); } + if(register_cipher(&anubis_desc)==-1) { croak("FATAL: cannot register_cipher anubis"); } + if(register_cipher(&kseed_desc)==-1) { croak("FATAL: cannot register_cipher kseed"); } + if(register_cipher(&kasumi_desc)==-1) { croak("FATAL: cannot register_cipher kasumi"); } + if(register_cipher(&multi2_desc)==-1) { croak("FATAL: cannot register_cipher multi2"); } + if(register_cipher(&camellia_desc)==-1) { croak("FATAL: cannot register_cipher camellia"); } + /* --- */ + if(register_hash(&chc_desc)==-1) { croak("FATAL: cannot register_hash chc_hash"); } + if(register_hash(&md2_desc)==-1) { croak("FATAL: cannot register_hash md2"); } + if(register_hash(&md4_desc)==-1) { croak("FATAL: cannot register_hash md4"); } + if(register_hash(&md5_desc)==-1) { croak("FATAL: cannot register_hash md5"); } + if(register_hash(&rmd128_desc)==-1) { croak("FATAL: cannot register_hash rmd128"); } + if(register_hash(&rmd160_desc)==-1) { croak("FATAL: cannot register_hash rmd160"); } + if(register_hash(&rmd256_desc)==-1) { croak("FATAL: cannot register_hash rmd256"); } + if(register_hash(&rmd320_desc)==-1) { croak("FATAL: cannot register_hash rmd320"); } + if(register_hash(&sha1_desc)==-1) { croak("FATAL: cannot register_hash sha1"); } + if(register_hash(&sha224_desc)==-1) { croak("FATAL: cannot register_hash sha224"); } + if(register_hash(&sha256_desc)==-1) { croak("FATAL: cannot register_hash sha256"); } + if(register_hash(&sha384_desc)==-1) { croak("FATAL: cannot register_hash sha384"); } + if(register_hash(&sha512_desc)==-1) { croak("FATAL: cannot register_hash sha512"); } + if(register_hash(&sha512_224_desc)==-1) { croak("FATAL: cannot register_hash sha512_224"); } + if(register_hash(&sha512_256_desc)==-1) { croak("FATAL: cannot register_hash sha512_256"); } + if(register_hash(&sha3_224_desc)==-1) { croak("FATAL: cannot register_hash sha3_224"); } + if(register_hash(&sha3_256_desc)==-1) { croak("FATAL: cannot register_hash sha3_256"); } + if(register_hash(&sha3_384_desc)==-1) { croak("FATAL: cannot register_hash sha3_384"); } + if(register_hash(&sha3_512_desc)==-1) { croak("FATAL: cannot register_hash sha3_512"); } + if(register_hash(&tiger_desc)==-1) { croak("FATAL: cannot register_hash tiger"); } + if(register_hash(&whirlpool_desc)==-1) { croak("FATAL: cannot register_hash whirlpool"); } + if(register_hash(&blake2b_160_desc)==-1) { croak("FATAL: cannot register_hash blake2b_160"); } + if(register_hash(&blake2b_256_desc)==-1) { croak("FATAL: cannot register_hash blake2b_256"); } + if(register_hash(&blake2b_384_desc)==-1) { croak("FATAL: cannot register_hash blake2b_384"); } + if(register_hash(&blake2b_512_desc)==-1) { croak("FATAL: cannot register_hash blake2b_512"); } + if(register_hash(&blake2s_128_desc)==-1) { croak("FATAL: cannot register_hash blake2s_128"); } + if(register_hash(&blake2s_160_desc)==-1) { croak("FATAL: cannot register_hash blake2s_160"); } + if(register_hash(&blake2s_224_desc)==-1) { croak("FATAL: cannot register_hash blake2s_224"); } + if(register_hash(&blake2s_256_desc)==-1) { croak("FATAL: cannot register_hash blake2s_256"); } + /* --- */ + if(chc_register(find_cipher("aes"))==-1) { croak("FATAL: chc_register failed"); } + /* --- */ + if(register_prng(&fortuna_desc)==-1) { croak("FATAL: cannot register_prng fortuna"); } + if(register_prng(&yarrow_desc)==-1) { croak("FATAL: cannot register_prng yarrow"); } + if(register_prng(&rc4_desc)==-1) { croak("FATAL: cannot register_prng rc4"); } + if(register_prng(&sober128_desc)==-1) { croak("FATAL: cannot register_prng sober128"); } + if(register_prng(&chacha20_prng_desc)==-1) { croak("FATAL: cannot register_prng chacha20"); } + /* --- */ +#ifdef TFM_DESC + ltc_mp = tfm_desc; +#else + ltc_mp = ltm_desc; +#endif + +SV * +CryptX__encode_base64url(SV * in) + CODE: + { + STRLEN in_len; + unsigned long out_len; + unsigned char *out_data, *in_data; + int rv; + + if (!SvPOK(in)) XSRETURN_UNDEF; + in_data = (unsigned char *) SvPVbyte(in, in_len); + out_len = (unsigned long)(4 * ((in_len + 2) / 3) + 1); + Newz(0, out_data, out_len, unsigned char); + if (!out_data) croak("FATAL: Newz failed [%ld]", out_len); + rv = base64url_encode(in_data, (unsigned long)in_len, out_data, &out_len); + RETVAL = (rv == CRYPT_OK) ? newSVpvn((char *)out_data, out_len) : newSVpvn(NULL, 0); + Safefree(out_data); + } + OUTPUT: + RETVAL + +SV * +CryptX__decode_base64url(SV * in) + CODE: + { + STRLEN in_len; + unsigned long out_len; + unsigned char *out_data, *in_data; + int rv; + + if (!SvPOK(in)) XSRETURN_UNDEF; + in_data = (unsigned char *) SvPVbyte(in, in_len); + out_len = (unsigned long)in_len; + Newz(0, out_data, out_len, unsigned char); + if (!out_data) croak("FATAL: Newz failed [%ld]", out_len); + rv = base64url_decode(in_data, (unsigned long)in_len, out_data, &out_len); + RETVAL = (rv == CRYPT_OK) ? newSVpvn((char *)out_data, out_len) : newSVpvn(NULL, 0); + Safefree(out_data); + } + OUTPUT: + RETVAL + +SV * +CryptX__encode_base64(SV * in) + CODE: + { + STRLEN in_len; + unsigned long out_len; + unsigned char *out_data, *in_data; + int rv; + + if (!SvPOK(in)) XSRETURN_UNDEF; + in_data = (unsigned char *) SvPVbyte(in, in_len); + out_len = (unsigned long)(4 * ((in_len + 2) / 3) + 1); + Newz(0, out_data, out_len, unsigned char); + if (!out_data) croak("FATAL: Newz failed [%ld]", out_len); + rv = base64_encode(in_data, (unsigned long)in_len, out_data, &out_len); + RETVAL = (rv == CRYPT_OK) ? newSVpvn((char *)out_data, out_len) : newSVpvn(NULL, 0); + Safefree(out_data); + } + OUTPUT: + RETVAL + +SV * +CryptX__decode_base64(SV * in) + CODE: + { + STRLEN in_len; + unsigned long out_len; + unsigned char *out_data, *in_data; + int rv; + + if (!SvPOK(in)) XSRETURN_UNDEF; + in_data = (unsigned char *) SvPVbyte(in, in_len); + out_len = (unsigned long)in_len; + Newz(0, out_data, out_len, unsigned char); + if (!out_data) croak("FATAL: Newz failed [%ld]", out_len); + rv = base64_decode(in_data, (unsigned long)in_len, out_data, &out_len); + RETVAL = (rv == CRYPT_OK) ? newSVpvn((char *)out_data, out_len) : newSVpvn(NULL, 0); + Safefree(out_data); + } + OUTPUT: + RETVAL + +SV * +CryptX__increment_octets_le(SV * in) + CODE: + { + STRLEN len, i = 0; + unsigned char *out_data, *in_data; + int rv; + + if (!SvPOK(in)) XSRETURN_UNDEF; + in_data = (unsigned char *) SvPVbyte(in, len); + if (len == 0) XSRETURN_UNDEF; + + RETVAL = NEWSV(0, len); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, len); + out_data = (unsigned char *)SvPV_nolen(RETVAL); + Copy(in_data, out_data, len, unsigned char); + while (i < len) { + out_data[i]++; + if (0 != out_data[i]) break; + i++; + } + if (i == len) croak("FATAL: increment_octets_le overflow"); + } + OUTPUT: + RETVAL + +SV * +CryptX__increment_octets_be(SV * in) + CODE: + { + STRLEN len, i = 0; + unsigned char *out_data, *in_data; + int rv; + + if (!SvPOK(in)) XSRETURN_UNDEF; + in_data = (unsigned char *) SvPVbyte(in, len); + if (len == 0) XSRETURN_UNDEF; + + RETVAL = NEWSV(0, len); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, len); + out_data = (unsigned char *)SvPV_nolen(RETVAL); + Copy(in_data, out_data, len, unsigned char); + while (i < len) { + out_data[len - 1 - i]++; + if (0 != out_data[len - 1 - i]) break; + i++; + } + if (i == len) croak("FATAL: increment_octets_le overflow"); + } + OUTPUT: + RETVAL + +############################################################################### + +INCLUDE: inc/CryptX_Digest.xs.inc +INCLUDE: inc/CryptX_Digest_SHAKE.xs.inc +INCLUDE: inc/CryptX_Cipher.xs.inc + +INCLUDE: inc/CryptX_Checksum_Adler32.xs.inc +INCLUDE: inc/CryptX_Checksum_CRC32.xs.inc + +INCLUDE: inc/CryptX_AuthEnc_EAX.xs.inc +INCLUDE: inc/CryptX_AuthEnc_GCM.xs.inc +INCLUDE: inc/CryptX_AuthEnc_OCB.xs.inc +INCLUDE: inc/CryptX_AuthEnc_CCM.xs.inc +INCLUDE: inc/CryptX_AuthEnc_ChaCha20Poly1305.xs.inc + +INCLUDE: inc/CryptX_Stream_ChaCha.xs.inc +INCLUDE: inc/CryptX_Stream_RC4.xs.inc +INCLUDE: inc/CryptX_Stream_Sober128.xs.inc + +INCLUDE: inc/CryptX_Mac_F9.xs.inc +INCLUDE: inc/CryptX_Mac_HMAC.xs.inc +INCLUDE: inc/CryptX_Mac_OMAC.xs.inc +INCLUDE: inc/CryptX_Mac_Pelican.xs.inc +INCLUDE: inc/CryptX_Mac_PMAC.xs.inc +INCLUDE: inc/CryptX_Mac_XCBC.xs.inc +INCLUDE: inc/CryptX_Mac_Poly1305.xs.inc +INCLUDE: inc/CryptX_Mac_BLAKE2s.xs.inc +INCLUDE: inc/CryptX_Mac_BLAKE2b.xs.inc + +INCLUDE: inc/CryptX_Mode_CBC.xs.inc +INCLUDE: inc/CryptX_Mode_ECB.xs.inc +INCLUDE: inc/CryptX_Mode_CFB.xs.inc +INCLUDE: inc/CryptX_Mode_OFB.xs.inc +INCLUDE: inc/CryptX_Mode_CTR.xs.inc +#INCLUDE: inc/CryptX_Mode_F8.xs.inc +#INCLUDE: inc/CryptX_Mode_LRW.xs.inc +#INCLUDE: inc/CryptX_Mode_XTS.xs.inc + +INCLUDE: inc/CryptX_PRNG.xs.inc + +INCLUDE: inc/CryptX_PK_RSA.xs.inc +INCLUDE: inc/CryptX_PK_DSA.xs.inc +INCLUDE: inc/CryptX_PK_DH.xs.inc +INCLUDE: inc/CryptX_PK_ECC.xs.inc + +INCLUDE: inc/CryptX_KeyDerivation.xs.inc + +INCLUDE: inc/CryptX_BigInt_LTM.xs.inc diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a46bd29 --- /dev/null +++ b/LICENSE @@ -0,0 +1 @@ +This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. \ No newline at end of file diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..1cf5a5e --- /dev/null +++ b/MANIFEST @@ -0,0 +1,929 @@ +Changes +CryptX.xs +inc/CryptX_AuthEnc_CCM.xs.inc +inc/CryptX_AuthEnc_ChaCha20Poly1305.xs.inc +inc/CryptX_AuthEnc_EAX.xs.inc +inc/CryptX_AuthEnc_GCM.xs.inc +inc/CryptX_AuthEnc_OCB.xs.inc +inc/CryptX_BigInt_LTM.xs.inc +inc/CryptX_Checksum_Adler32.xs.inc +inc/CryptX_Checksum_CRC32.xs.inc +inc/CryptX_Cipher.xs.inc +inc/CryptX_Digest.xs.inc +inc/CryptX_Digest_SHAKE.xs.inc +inc/CryptX_KeyDerivation.xs.inc +inc/CryptX_Mac_BLAKE2b.xs.inc +inc/CryptX_Mac_BLAKE2s.xs.inc +inc/CryptX_Mac_F9.xs.inc +inc/CryptX_Mac_HMAC.xs.inc +inc/CryptX_Mac_OMAC.xs.inc +inc/CryptX_Mac_Pelican.xs.inc +inc/CryptX_Mac_PMAC.xs.inc +inc/CryptX_Mac_Poly1305.xs.inc +inc/CryptX_Mac_XCBC.xs.inc +inc/CryptX_Mode_CBC.xs.inc +inc/CryptX_Mode_CFB.xs.inc +inc/CryptX_Mode_CTR.xs.inc +inc/CryptX_Mode_ECB.xs.inc +inc/CryptX_Mode_OFB.xs.inc +inc/CryptX_PK_DH.xs.inc +inc/CryptX_PK_DSA.xs.inc +inc/CryptX_PK_ECC.xs.inc +inc/CryptX_PK_RSA.xs.inc +inc/CryptX_PRNG.xs.inc +inc/CryptX_Stream_ChaCha.xs.inc +inc/CryptX_Stream_RC4.xs.inc +inc/CryptX_Stream_Sober128.xs.inc +lib/Crypt/AuthEnc.pm +lib/Crypt/AuthEnc/CCM.pm +lib/Crypt/AuthEnc/ChaCha20Poly1305.pm +lib/Crypt/AuthEnc/EAX.pm +lib/Crypt/AuthEnc/GCM.pm +lib/Crypt/AuthEnc/OCB.pm +lib/Crypt/Checksum.pm +lib/Crypt/Checksum/Adler32.pm +lib/Crypt/Checksum/CRC32.pm +lib/Crypt/Cipher.pm +lib/Crypt/Cipher/AES.pm +lib/Crypt/Cipher/Anubis.pm +lib/Crypt/Cipher/Blowfish.pm +lib/Crypt/Cipher/Camellia.pm +lib/Crypt/Cipher/CAST5.pm +lib/Crypt/Cipher/DES.pm +lib/Crypt/Cipher/DES_EDE.pm +lib/Crypt/Cipher/KASUMI.pm +lib/Crypt/Cipher/Khazad.pm +lib/Crypt/Cipher/MULTI2.pm +lib/Crypt/Cipher/Noekeon.pm +lib/Crypt/Cipher/RC2.pm +lib/Crypt/Cipher/RC5.pm +lib/Crypt/Cipher/RC6.pm +lib/Crypt/Cipher/SAFER_K128.pm +lib/Crypt/Cipher/SAFER_K64.pm +lib/Crypt/Cipher/SAFER_SK128.pm +lib/Crypt/Cipher/SAFER_SK64.pm +lib/Crypt/Cipher/SAFERP.pm +lib/Crypt/Cipher/SEED.pm +lib/Crypt/Cipher/Skipjack.pm +lib/Crypt/Cipher/Twofish.pm +lib/Crypt/Cipher/XTEA.pm +lib/Crypt/Digest.pm +lib/Crypt/Digest/BLAKE2b_160.pm +lib/Crypt/Digest/BLAKE2b_256.pm +lib/Crypt/Digest/BLAKE2b_384.pm +lib/Crypt/Digest/BLAKE2b_512.pm +lib/Crypt/Digest/BLAKE2s_128.pm +lib/Crypt/Digest/BLAKE2s_160.pm +lib/Crypt/Digest/BLAKE2s_224.pm +lib/Crypt/Digest/BLAKE2s_256.pm +lib/Crypt/Digest/CHAES.pm +lib/Crypt/Digest/MD2.pm +lib/Crypt/Digest/MD4.pm +lib/Crypt/Digest/MD5.pm +lib/Crypt/Digest/RIPEMD128.pm +lib/Crypt/Digest/RIPEMD160.pm +lib/Crypt/Digest/RIPEMD256.pm +lib/Crypt/Digest/RIPEMD320.pm +lib/Crypt/Digest/SHA1.pm +lib/Crypt/Digest/SHA224.pm +lib/Crypt/Digest/SHA256.pm +lib/Crypt/Digest/SHA384.pm +lib/Crypt/Digest/SHA3_224.pm +lib/Crypt/Digest/SHA3_256.pm +lib/Crypt/Digest/SHA3_384.pm +lib/Crypt/Digest/SHA3_512.pm +lib/Crypt/Digest/SHA512.pm +lib/Crypt/Digest/SHA512_224.pm +lib/Crypt/Digest/SHA512_256.pm +lib/Crypt/Digest/SHAKE.pm +lib/Crypt/Digest/Tiger192.pm +lib/Crypt/Digest/Whirlpool.pm +lib/Crypt/KeyDerivation.pm +lib/Crypt/Mac.pm +lib/Crypt/Mac/BLAKE2b.pm +lib/Crypt/Mac/BLAKE2s.pm +lib/Crypt/Mac/F9.pm +lib/Crypt/Mac/HMAC.pm +lib/Crypt/Mac/OMAC.pm +lib/Crypt/Mac/Pelican.pm +lib/Crypt/Mac/PMAC.pm +lib/Crypt/Mac/Poly1305.pm +lib/Crypt/Mac/XCBC.pm +lib/Crypt/Misc.pm +lib/Crypt/Mode.pm +lib/Crypt/Mode/CBC.pm +lib/Crypt/Mode/CFB.pm +lib/Crypt/Mode/CTR.pm +lib/Crypt/Mode/ECB.pm +lib/Crypt/Mode/OFB.pm +lib/Crypt/PK.pm +lib/Crypt/PK/DH.pm +lib/Crypt/PK/DSA.pm +lib/Crypt/PK/ECC.pm +lib/Crypt/PK/RSA.pm +lib/Crypt/PRNG.pm +lib/Crypt/PRNG/ChaCha20.pm +lib/Crypt/PRNG/Fortuna.pm +lib/Crypt/PRNG/RC4.pm +lib/Crypt/PRNG/Sober128.pm +lib/Crypt/PRNG/Yarrow.pm +lib/Crypt/Stream/ChaCha.pm +lib/Crypt/Stream/RC4.pm +lib/Crypt/Stream/Sober128.pm +lib/CryptX.pm +lib/Math/BigInt/LTM.pm +LICENSE +Makefile.PL +MANIFEST This list of files +META.json +META.yml +ppport.h +README +src/ltc/ciphers/aes/aes.c +src/ltc/ciphers/aes/aes_tab.c +src/ltc/ciphers/anubis.c +src/ltc/ciphers/blowfish.c +src/ltc/ciphers/camellia.c +src/ltc/ciphers/cast5.c +src/ltc/ciphers/des.c +src/ltc/ciphers/kasumi.c +src/ltc/ciphers/khazad.c +src/ltc/ciphers/kseed.c +src/ltc/ciphers/multi2.c +src/ltc/ciphers/noekeon.c +src/ltc/ciphers/rc2.c +src/ltc/ciphers/rc5.c +src/ltc/ciphers/rc6.c +src/ltc/ciphers/safer/safer.c +src/ltc/ciphers/safer/safer_tab.c +src/ltc/ciphers/safer/saferp.c +src/ltc/ciphers/skipjack.c +src/ltc/ciphers/twofish/twofish.c +src/ltc/ciphers/twofish/twofish_tab.c +src/ltc/ciphers/xtea.c +src/ltc/encauth/ccm/ccm_add_aad.c +src/ltc/encauth/ccm/ccm_add_nonce.c +src/ltc/encauth/ccm/ccm_done.c +src/ltc/encauth/ccm/ccm_init.c +src/ltc/encauth/ccm/ccm_memory.c +src/ltc/encauth/ccm/ccm_process.c +src/ltc/encauth/ccm/ccm_reset.c +src/ltc/encauth/chachapoly/chacha20poly1305_add_aad.c +src/ltc/encauth/chachapoly/chacha20poly1305_decrypt.c +src/ltc/encauth/chachapoly/chacha20poly1305_done.c +src/ltc/encauth/chachapoly/chacha20poly1305_encrypt.c +src/ltc/encauth/chachapoly/chacha20poly1305_init.c +src/ltc/encauth/chachapoly/chacha20poly1305_memory.c +src/ltc/encauth/chachapoly/chacha20poly1305_setiv.c +src/ltc/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.c +src/ltc/encauth/eax/eax_addheader.c +src/ltc/encauth/eax/eax_decrypt.c +src/ltc/encauth/eax/eax_decrypt_verify_memory.c +src/ltc/encauth/eax/eax_done.c +src/ltc/encauth/eax/eax_encrypt.c +src/ltc/encauth/eax/eax_encrypt_authenticate_memory.c +src/ltc/encauth/eax/eax_init.c +src/ltc/encauth/gcm/gcm_add_aad.c +src/ltc/encauth/gcm/gcm_add_iv.c +src/ltc/encauth/gcm/gcm_done.c +src/ltc/encauth/gcm/gcm_gf_mult.c +src/ltc/encauth/gcm/gcm_init.c +src/ltc/encauth/gcm/gcm_memory.c +src/ltc/encauth/gcm/gcm_mult_h.c +src/ltc/encauth/gcm/gcm_process.c +src/ltc/encauth/gcm/gcm_reset.c +src/ltc/encauth/ocb3/ocb3_add_aad.c +src/ltc/encauth/ocb3/ocb3_decrypt.c +src/ltc/encauth/ocb3/ocb3_decrypt_last.c +src/ltc/encauth/ocb3/ocb3_decrypt_verify_memory.c +src/ltc/encauth/ocb3/ocb3_done.c +src/ltc/encauth/ocb3/ocb3_encrypt.c +src/ltc/encauth/ocb3/ocb3_encrypt_authenticate_memory.c +src/ltc/encauth/ocb3/ocb3_encrypt_last.c +src/ltc/encauth/ocb3/ocb3_init.c +src/ltc/encauth/ocb3/ocb3_int_aad_add_block.c +src/ltc/encauth/ocb3/ocb3_int_calc_offset_zero.c +src/ltc/encauth/ocb3/ocb3_int_ntz.c +src/ltc/encauth/ocb3/ocb3_int_xor_blocks.c +src/ltc/hashes/blake2b.c +src/ltc/hashes/blake2s.c +src/ltc/hashes/chc/chc.c +src/ltc/hashes/helper/hash_file.c +src/ltc/hashes/helper/hash_filehandle.c +src/ltc/hashes/helper/hash_memory.c +src/ltc/hashes/helper/hash_memory_multi.c +src/ltc/hashes/md2.c +src/ltc/hashes/md4.c +src/ltc/hashes/md5.c +src/ltc/hashes/rmd128.c +src/ltc/hashes/rmd160.c +src/ltc/hashes/rmd256.c +src/ltc/hashes/rmd320.c +src/ltc/hashes/sha1.c +src/ltc/hashes/sha2/sha224.c +src/ltc/hashes/sha2/sha256.c +src/ltc/hashes/sha2/sha384.c +src/ltc/hashes/sha2/sha512.c +src/ltc/hashes/sha2/sha512_224.c +src/ltc/hashes/sha2/sha512_256.c +src/ltc/hashes/sha3.c +src/ltc/hashes/sha3_test.c +src/ltc/hashes/tiger.c +src/ltc/hashes/whirl/whirl.c +src/ltc/hashes/whirl/whirltab.c +src/ltc/headers/tomcrypt.h +src/ltc/headers/tomcrypt_argchk.h +src/ltc/headers/tomcrypt_cfg.h +src/ltc/headers/tomcrypt_cipher.h +src/ltc/headers/tomcrypt_custom.h +src/ltc/headers/tomcrypt_hash.h +src/ltc/headers/tomcrypt_mac.h +src/ltc/headers/tomcrypt_macros.h +src/ltc/headers/tomcrypt_math.h +src/ltc/headers/tomcrypt_misc.h +src/ltc/headers/tomcrypt_pk.h +src/ltc/headers/tomcrypt_pkcs.h +src/ltc/headers/tomcrypt_prng.h +src/ltc/mac/blake2/blake2bmac.c +src/ltc/mac/blake2/blake2bmac_file.c +src/ltc/mac/blake2/blake2bmac_memory.c +src/ltc/mac/blake2/blake2bmac_memory_multi.c +src/ltc/mac/blake2/blake2smac.c +src/ltc/mac/blake2/blake2smac_file.c +src/ltc/mac/blake2/blake2smac_memory.c +src/ltc/mac/blake2/blake2smac_memory_multi.c +src/ltc/mac/f9/f9_done.c +src/ltc/mac/f9/f9_file.c +src/ltc/mac/f9/f9_init.c +src/ltc/mac/f9/f9_memory.c +src/ltc/mac/f9/f9_memory_multi.c +src/ltc/mac/f9/f9_process.c +src/ltc/mac/hmac/hmac_done.c +src/ltc/mac/hmac/hmac_file.c +src/ltc/mac/hmac/hmac_init.c +src/ltc/mac/hmac/hmac_memory.c +src/ltc/mac/hmac/hmac_memory_multi.c +src/ltc/mac/hmac/hmac_process.c +src/ltc/mac/omac/omac_done.c +src/ltc/mac/omac/omac_file.c +src/ltc/mac/omac/omac_init.c +src/ltc/mac/omac/omac_memory.c +src/ltc/mac/omac/omac_memory_multi.c +src/ltc/mac/omac/omac_process.c +src/ltc/mac/pelican/pelican.c +src/ltc/mac/pelican/pelican_memory.c +src/ltc/mac/pmac/pmac_done.c +src/ltc/mac/pmac/pmac_file.c +src/ltc/mac/pmac/pmac_init.c +src/ltc/mac/pmac/pmac_memory.c +src/ltc/mac/pmac/pmac_memory_multi.c +src/ltc/mac/pmac/pmac_ntz.c +src/ltc/mac/pmac/pmac_process.c +src/ltc/mac/pmac/pmac_shift_xor.c +src/ltc/mac/poly1305/poly1305.c +src/ltc/mac/poly1305/poly1305_file.c +src/ltc/mac/poly1305/poly1305_memory.c +src/ltc/mac/poly1305/poly1305_memory_multi.c +src/ltc/mac/xcbc/xcbc_done.c +src/ltc/mac/xcbc/xcbc_file.c +src/ltc/mac/xcbc/xcbc_init.c +src/ltc/mac/xcbc/xcbc_memory.c +src/ltc/mac/xcbc/xcbc_memory_multi.c +src/ltc/mac/xcbc/xcbc_process.c +src/ltc/math/fp/ltc_ecc_fp_mulmod.c +src/ltc/math/ltm_desc.c +src/ltc/math/multi.c +src/ltc/math/rand_bn.c +src/ltc/math/rand_prime.c +src/ltc/math/tfm_desc.c +src/ltc/misc/adler32.c +src/ltc/misc/base64/base64_decode.c +src/ltc/misc/base64/base64_encode.c +src/ltc/misc/burn_stack.c +src/ltc/misc/crc32.c +src/ltc/misc/crypt/crypt.c +src/ltc/misc/crypt/crypt_argchk.c +src/ltc/misc/crypt/crypt_cipher_descriptor.c +src/ltc/misc/crypt/crypt_cipher_is_valid.c +src/ltc/misc/crypt/crypt_find_cipher.c +src/ltc/misc/crypt/crypt_find_cipher_any.c +src/ltc/misc/crypt/crypt_find_cipher_id.c +src/ltc/misc/crypt/crypt_find_hash.c +src/ltc/misc/crypt/crypt_find_hash_any.c +src/ltc/misc/crypt/crypt_find_hash_id.c +src/ltc/misc/crypt/crypt_find_hash_oid.c +src/ltc/misc/crypt/crypt_find_prng.c +src/ltc/misc/crypt/crypt_fsa.c +src/ltc/misc/crypt/crypt_hash_descriptor.c +src/ltc/misc/crypt/crypt_hash_is_valid.c +src/ltc/misc/crypt/crypt_inits.c +src/ltc/misc/crypt/crypt_ltc_mp_descriptor.c +src/ltc/misc/crypt/crypt_prng_descriptor.c +src/ltc/misc/crypt/crypt_prng_is_valid.c +src/ltc/misc/crypt/crypt_register_cipher.c +src/ltc/misc/crypt/crypt_register_hash.c +src/ltc/misc/crypt/crypt_register_prng.c +src/ltc/misc/crypt/crypt_unregister_cipher.c +src/ltc/misc/crypt/crypt_unregister_hash.c +src/ltc/misc/crypt/crypt_unregister_prng.c +src/ltc/misc/error_to_string.c +src/ltc/misc/hkdf/hkdf.c +src/ltc/misc/mem_neq.c +src/ltc/misc/pk_get_oid.c +src/ltc/misc/pkcs5/pkcs_5_1.c +src/ltc/misc/pkcs5/pkcs_5_2.c +src/ltc/misc/zeromem.c +src/ltc/modes/cbc/cbc_decrypt.c +src/ltc/modes/cbc/cbc_done.c +src/ltc/modes/cbc/cbc_encrypt.c +src/ltc/modes/cbc/cbc_getiv.c +src/ltc/modes/cbc/cbc_setiv.c +src/ltc/modes/cbc/cbc_start.c +src/ltc/modes/cfb/cfb_decrypt.c +src/ltc/modes/cfb/cfb_done.c +src/ltc/modes/cfb/cfb_encrypt.c +src/ltc/modes/cfb/cfb_getiv.c +src/ltc/modes/cfb/cfb_setiv.c +src/ltc/modes/cfb/cfb_start.c +src/ltc/modes/ctr/ctr_decrypt.c +src/ltc/modes/ctr/ctr_done.c +src/ltc/modes/ctr/ctr_encrypt.c +src/ltc/modes/ctr/ctr_getiv.c +src/ltc/modes/ctr/ctr_setiv.c +src/ltc/modes/ctr/ctr_start.c +src/ltc/modes/ecb/ecb_decrypt.c +src/ltc/modes/ecb/ecb_done.c +src/ltc/modes/ecb/ecb_encrypt.c +src/ltc/modes/ecb/ecb_start.c +src/ltc/modes/ofb/ofb_decrypt.c +src/ltc/modes/ofb/ofb_done.c +src/ltc/modes/ofb/ofb_encrypt.c +src/ltc/modes/ofb/ofb_getiv.c +src/ltc/modes/ofb/ofb_setiv.c +src/ltc/modes/ofb/ofb_start.c +src/ltc/pk/asn1/der/bit/der_decode_bit_string.c +src/ltc/pk/asn1/der/bit/der_decode_raw_bit_string.c +src/ltc/pk/asn1/der/bit/der_encode_bit_string.c +src/ltc/pk/asn1/der/bit/der_encode_raw_bit_string.c +src/ltc/pk/asn1/der/bit/der_length_bit_string.c +src/ltc/pk/asn1/der/boolean/der_decode_boolean.c +src/ltc/pk/asn1/der/boolean/der_encode_boolean.c +src/ltc/pk/asn1/der/boolean/der_length_boolean.c +src/ltc/pk/asn1/der/choice/der_decode_choice.c +src/ltc/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c +src/ltc/pk/asn1/der/generalizedtime/der_encode_generalizedtime.c +src/ltc/pk/asn1/der/generalizedtime/der_length_generalizedtime.c +src/ltc/pk/asn1/der/ia5/der_decode_ia5_string.c +src/ltc/pk/asn1/der/ia5/der_encode_ia5_string.c +src/ltc/pk/asn1/der/ia5/der_length_ia5_string.c +src/ltc/pk/asn1/der/integer/der_decode_integer.c +src/ltc/pk/asn1/der/integer/der_encode_integer.c +src/ltc/pk/asn1/der/integer/der_length_integer.c +src/ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.c +src/ltc/pk/asn1/der/object_identifier/der_encode_object_identifier.c +src/ltc/pk/asn1/der/object_identifier/der_length_object_identifier.c +src/ltc/pk/asn1/der/octet/der_decode_octet_string.c +src/ltc/pk/asn1/der/octet/der_encode_octet_string.c +src/ltc/pk/asn1/der/octet/der_length_octet_string.c +src/ltc/pk/asn1/der/printable_string/der_decode_printable_string.c +src/ltc/pk/asn1/der/printable_string/der_encode_printable_string.c +src/ltc/pk/asn1/der/printable_string/der_length_printable_string.c +src/ltc/pk/asn1/der/sequence/der_decode_sequence_ex.c +src/ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.c +src/ltc/pk/asn1/der/sequence/der_decode_sequence_multi.c +src/ltc/pk/asn1/der/sequence/der_decode_subject_public_key_info.c +src/ltc/pk/asn1/der/sequence/der_encode_sequence_ex.c +src/ltc/pk/asn1/der/sequence/der_encode_sequence_multi.c +src/ltc/pk/asn1/der/sequence/der_encode_subject_public_key_info.c +src/ltc/pk/asn1/der/sequence/der_length_sequence.c +src/ltc/pk/asn1/der/sequence/der_sequence_free.c +src/ltc/pk/asn1/der/set/der_encode_set.c +src/ltc/pk/asn1/der/set/der_encode_setof.c +src/ltc/pk/asn1/der/short_integer/der_decode_short_integer.c +src/ltc/pk/asn1/der/short_integer/der_encode_short_integer.c +src/ltc/pk/asn1/der/short_integer/der_length_short_integer.c +src/ltc/pk/asn1/der/teletex_string/der_decode_teletex_string.c +src/ltc/pk/asn1/der/teletex_string/der_length_teletex_string.c +src/ltc/pk/asn1/der/utctime/der_decode_utctime.c +src/ltc/pk/asn1/der/utctime/der_encode_utctime.c +src/ltc/pk/asn1/der/utctime/der_length_utctime.c +src/ltc/pk/asn1/der/utf8/der_decode_utf8_string.c +src/ltc/pk/asn1/der/utf8/der_encode_utf8_string.c +src/ltc/pk/asn1/der/utf8/der_length_utf8_string.c +src/ltc/pk/dh/dh.c +src/ltc/pk/dh/dh_static.c +src/ltc/pk/dh/dh_static.h +src/ltc/pk/dh/dh_sys.c +src/ltc/pk/dsa/dsa_decrypt_key.c +src/ltc/pk/dsa/dsa_encrypt_key.c +src/ltc/pk/dsa/dsa_export.c +src/ltc/pk/dsa/dsa_free.c +src/ltc/pk/dsa/dsa_import.c +src/ltc/pk/dsa/dsa_import_radix.c +src/ltc/pk/dsa/dsa_make_key.c +src/ltc/pk/dsa/dsa_shared_secret.c +src/ltc/pk/dsa/dsa_sign_hash.c +src/ltc/pk/dsa/dsa_verify_hash.c +src/ltc/pk/dsa/dsa_verify_key.c +src/ltc/pk/ecc/ecc.c +src/ltc/pk/ecc/ecc_ansi_x963_export.c +src/ltc/pk/ecc/ecc_ansi_x963_import.c +src/ltc/pk/ecc/ecc_decrypt_key.c +src/ltc/pk/ecc/ecc_dp_clear.c +src/ltc/pk/ecc/ecc_dp_fill_from_sets.c +src/ltc/pk/ecc/ecc_dp_from_oid.c +src/ltc/pk/ecc/ecc_dp_from_params.c +src/ltc/pk/ecc/ecc_dp_init.c +src/ltc/pk/ecc/ecc_dp_set.c +src/ltc/pk/ecc/ecc_encrypt_key.c +src/ltc/pk/ecc/ecc_export.c +src/ltc/pk/ecc/ecc_export_full.c +src/ltc/pk/ecc/ecc_export_raw.c +src/ltc/pk/ecc/ecc_free.c +src/ltc/pk/ecc/ecc_get_size.c +src/ltc/pk/ecc/ecc_import.c +src/ltc/pk/ecc/ecc_import_full.c +src/ltc/pk/ecc/ecc_import_pkcs8.c +src/ltc/pk/ecc/ecc_import_raw.c +src/ltc/pk/ecc/ecc_make_key.c +src/ltc/pk/ecc/ecc_shared_secret.c +src/ltc/pk/ecc/ecc_sign_hash.c +src/ltc/pk/ecc/ecc_sizes.c +src/ltc/pk/ecc/ecc_verify_hash.c +src/ltc/pk/ecc/ecc_verify_key.c +src/ltc/pk/ecc/ltc_ecc_export_point.c +src/ltc/pk/ecc/ltc_ecc_import_point.c +src/ltc/pk/ecc/ltc_ecc_is_point.c +src/ltc/pk/ecc/ltc_ecc_is_point_at_infinity.c +src/ltc/pk/ecc/ltc_ecc_is_valid_idx.c +src/ltc/pk/ecc/ltc_ecc_map.c +src/ltc/pk/ecc/ltc_ecc_mul2add.c +src/ltc/pk/ecc/ltc_ecc_mulmod.c +src/ltc/pk/ecc/ltc_ecc_mulmod_timing.c +src/ltc/pk/ecc/ltc_ecc_points.c +src/ltc/pk/ecc/ltc_ecc_projective_add_point.c +src/ltc/pk/ecc/ltc_ecc_projective_dbl_point.c +src/ltc/pk/pkcs1/pkcs_1_i2osp.c +src/ltc/pk/pkcs1/pkcs_1_mgf1.c +src/ltc/pk/pkcs1/pkcs_1_oaep_decode.c +src/ltc/pk/pkcs1/pkcs_1_oaep_encode.c +src/ltc/pk/pkcs1/pkcs_1_os2ip.c +src/ltc/pk/pkcs1/pkcs_1_pss_decode.c +src/ltc/pk/pkcs1/pkcs_1_pss_encode.c +src/ltc/pk/pkcs1/pkcs_1_v1_5_decode.c +src/ltc/pk/pkcs1/pkcs_1_v1_5_encode.c +src/ltc/pk/rsa/rsa_decrypt_key.c +src/ltc/pk/rsa/rsa_encrypt_key.c +src/ltc/pk/rsa/rsa_export.c +src/ltc/pk/rsa/rsa_exptmod.c +src/ltc/pk/rsa/rsa_free.c +src/ltc/pk/rsa/rsa_get_size.c +src/ltc/pk/rsa/rsa_import.c +src/ltc/pk/rsa/rsa_import_pkcs8.c +src/ltc/pk/rsa/rsa_import_radix.c +src/ltc/pk/rsa/rsa_import_x509.c +src/ltc/pk/rsa/rsa_make_key.c +src/ltc/pk/rsa/rsa_sign_hash.c +src/ltc/pk/rsa/rsa_sign_saltlen_get.c +src/ltc/pk/rsa/rsa_verify_hash.c +src/ltc/prngs/chacha20.c +src/ltc/prngs/fortuna.c +src/ltc/prngs/rc4.c +src/ltc/prngs/rng_get_bytes.c +src/ltc/prngs/rng_make_prng.c +src/ltc/prngs/sober128.c +src/ltc/prngs/sprng.c +src/ltc/prngs/yarrow.c +src/ltc/stream/chacha/chacha_crypt.c +src/ltc/stream/chacha/chacha_done.c +src/ltc/stream/chacha/chacha_ivctr32.c +src/ltc/stream/chacha/chacha_ivctr64.c +src/ltc/stream/chacha/chacha_keystream.c +src/ltc/stream/chacha/chacha_setup.c +src/ltc/stream/rc4/rc4.c +src/ltc/stream/sober128/sober128.c +src/ltc/stream/sober128/sober128tab.c +src/ltm/bn_error.c +src/ltm/bn_fast_mp_invmod.c +src/ltm/bn_fast_mp_montgomery_reduce.c +src/ltm/bn_fast_s_mp_mul_digs.c +src/ltm/bn_fast_s_mp_mul_high_digs.c +src/ltm/bn_fast_s_mp_sqr.c +src/ltm/bn_mp_2expt.c +src/ltm/bn_mp_abs.c +src/ltm/bn_mp_add.c +src/ltm/bn_mp_add_d.c +src/ltm/bn_mp_addmod.c +src/ltm/bn_mp_and.c +src/ltm/bn_mp_clamp.c +src/ltm/bn_mp_clear.c +src/ltm/bn_mp_clear_multi.c +src/ltm/bn_mp_cmp.c +src/ltm/bn_mp_cmp_d.c +src/ltm/bn_mp_cmp_mag.c +src/ltm/bn_mp_cnt_lsb.c +src/ltm/bn_mp_copy.c +src/ltm/bn_mp_count_bits.c +src/ltm/bn_mp_div.c +src/ltm/bn_mp_div_2.c +src/ltm/bn_mp_div_2d.c +src/ltm/bn_mp_div_3.c +src/ltm/bn_mp_div_d.c +src/ltm/bn_mp_dr_is_modulus.c +src/ltm/bn_mp_dr_reduce.c +src/ltm/bn_mp_dr_setup.c +src/ltm/bn_mp_exch.c +src/ltm/bn_mp_export.c +src/ltm/bn_mp_expt_d.c +src/ltm/bn_mp_expt_d_ex.c +src/ltm/bn_mp_exptmod.c +src/ltm/bn_mp_exptmod_fast.c +src/ltm/bn_mp_exteuclid.c +src/ltm/bn_mp_fread.c +src/ltm/bn_mp_fwrite.c +src/ltm/bn_mp_gcd.c +src/ltm/bn_mp_get_int.c +src/ltm/bn_mp_get_long.c +src/ltm/bn_mp_get_long_long.c +src/ltm/bn_mp_grow.c +src/ltm/bn_mp_import.c +src/ltm/bn_mp_init.c +src/ltm/bn_mp_init_copy.c +src/ltm/bn_mp_init_multi.c +src/ltm/bn_mp_init_set.c +src/ltm/bn_mp_init_set_int.c +src/ltm/bn_mp_init_size.c +src/ltm/bn_mp_invmod.c +src/ltm/bn_mp_invmod_slow.c +src/ltm/bn_mp_is_square.c +src/ltm/bn_mp_jacobi.c +src/ltm/bn_mp_karatsuba_mul.c +src/ltm/bn_mp_karatsuba_sqr.c +src/ltm/bn_mp_lcm.c +src/ltm/bn_mp_lshd.c +src/ltm/bn_mp_mod.c +src/ltm/bn_mp_mod_2d.c +src/ltm/bn_mp_mod_d.c +src/ltm/bn_mp_montgomery_calc_normalization.c +src/ltm/bn_mp_montgomery_reduce.c +src/ltm/bn_mp_montgomery_setup.c +src/ltm/bn_mp_mul.c +src/ltm/bn_mp_mul_2.c +src/ltm/bn_mp_mul_2d.c +src/ltm/bn_mp_mul_d.c +src/ltm/bn_mp_mulmod.c +src/ltm/bn_mp_n_root.c +src/ltm/bn_mp_n_root_ex.c +src/ltm/bn_mp_neg.c +src/ltm/bn_mp_or.c +src/ltm/bn_mp_prime_fermat.c +src/ltm/bn_mp_prime_is_divisible.c +src/ltm/bn_mp_prime_is_prime.c +src/ltm/bn_mp_prime_miller_rabin.c +src/ltm/bn_mp_prime_next_prime.c +src/ltm/bn_mp_prime_rabin_miller_trials.c +src/ltm/bn_mp_prime_random_ex.c +src/ltm/bn_mp_radix_size.c +src/ltm/bn_mp_radix_smap.c +src/ltm/bn_mp_rand.c +src/ltm/bn_mp_read_radix.c +src/ltm/bn_mp_read_signed_bin.c +src/ltm/bn_mp_read_unsigned_bin.c +src/ltm/bn_mp_reduce.c +src/ltm/bn_mp_reduce_2k.c +src/ltm/bn_mp_reduce_2k_l.c +src/ltm/bn_mp_reduce_2k_setup.c +src/ltm/bn_mp_reduce_2k_setup_l.c +src/ltm/bn_mp_reduce_is_2k.c +src/ltm/bn_mp_reduce_is_2k_l.c +src/ltm/bn_mp_reduce_setup.c +src/ltm/bn_mp_rshd.c +src/ltm/bn_mp_set.c +src/ltm/bn_mp_set_int.c +src/ltm/bn_mp_set_long.c +src/ltm/bn_mp_set_long_long.c +src/ltm/bn_mp_shrink.c +src/ltm/bn_mp_signed_bin_size.c +src/ltm/bn_mp_sqr.c +src/ltm/bn_mp_sqrmod.c +src/ltm/bn_mp_sqrt.c +src/ltm/bn_mp_sqrtmod_prime.c +src/ltm/bn_mp_sub.c +src/ltm/bn_mp_sub_d.c +src/ltm/bn_mp_submod.c +src/ltm/bn_mp_to_signed_bin.c +src/ltm/bn_mp_to_signed_bin_n.c +src/ltm/bn_mp_to_unsigned_bin.c +src/ltm/bn_mp_to_unsigned_bin_n.c +src/ltm/bn_mp_toom_mul.c +src/ltm/bn_mp_toom_sqr.c +src/ltm/bn_mp_toradix.c +src/ltm/bn_mp_toradix_n.c +src/ltm/bn_mp_unsigned_bin_size.c +src/ltm/bn_mp_xor.c +src/ltm/bn_mp_zero.c +src/ltm/bn_prime_tab.c +src/ltm/bn_reverse.c +src/ltm/bn_s_mp_add.c +src/ltm/bn_s_mp_exptmod.c +src/ltm/bn_s_mp_mul_digs.c +src/ltm/bn_s_mp_mul_high_digs.c +src/ltm/bn_s_mp_sqr.c +src/ltm/bn_s_mp_sub.c +src/ltm/bncore.c +src/ltm/tommath.h +src/ltm/tommath_class.h +src/ltm/tommath_private.h +src/ltm/tommath_superclass.h +src/Makefile +src/Makefile.nmake +t/001_compile.t +t/002_all_pm.t +t/003_all_pm_pod.t +t/auth_enc_ccm.t +t/auth_enc_ccm_test_vector_ltc.t +t/auth_enc_chacha20poly1305.t +t/auth_enc_eax.t +t/auth_enc_eax_test_vector_ltc.t +t/auth_enc_gcm.t +t/auth_enc_gcm_test_vector_ltc.t +t/auth_enc_ocb.t +t/auth_enc_ocb_test_vectors_ietf.t +t/checksum.t +t/cipher_aes.t +t/cipher_aes_test_vectors_bc.t +t/cipher_anubis.t +t/cipher_blowfish.t +t/cipher_camellia.t +t/cipher_cast5.t +t/cipher_des.t +t/cipher_des_ede.t +t/cipher_kasumi.t +t/cipher_khazad.t +t/cipher_multi2.t +t/cipher_multi2_rounds.t +t/cipher_noekeon.t +t/cipher_rc2.t +t/cipher_rc5.t +t/cipher_rc6.t +t/cipher_safer_k128.t +t/cipher_safer_k64.t +t/cipher_safer_sk128.t +t/cipher_safer_sk64.t +t/cipher_saferp.t +t/cipher_seed.t +t/cipher_seed_test_vectors_bc.t +t/cipher_skipjack.t +t/cipher_stream.t +t/cipher_test_vectors_ltc.t +t/cipher_test_vectors_openssl.t +t/cipher_twofish.t +t/cipher_twofish_test_vectors_bc.t +t/cipher_xtea.t +t/cipher_xtea_test_vectors_bc.t +t/crypt-misc.t +t/data/binary-test.file +t/data/cryptx_priv_dh1.bin +t/data/cryptx_priv_dh2.bin +t/data/cryptx_priv_dh_pg1.bin +t/data/cryptx_priv_dh_pg2.bin +t/data/cryptx_priv_dsa1.der +t/data/cryptx_priv_dsa1.pem +t/data/cryptx_priv_dsa2.der +t/data/cryptx_priv_dsa2.pem +t/data/cryptx_priv_ecc1.der +t/data/cryptx_priv_ecc1.pem +t/data/cryptx_priv_ecc1_OLD.der +t/data/cryptx_priv_ecc1_OLD.pem +t/data/cryptx_priv_ecc2.der +t/data/cryptx_priv_ecc2.pem +t/data/cryptx_priv_ecc2_OLD.der +t/data/cryptx_priv_ecc2_OLD.pem +t/data/cryptx_priv_rsa1.der +t/data/cryptx_priv_rsa1.pem +t/data/cryptx_priv_rsa2.der +t/data/cryptx_priv_rsa2.pem +t/data/cryptx_pub_dh1.bin +t/data/cryptx_pub_dh2.bin +t/data/cryptx_pub_dh_pg1.bin +t/data/cryptx_pub_dh_pg2.bin +t/data/cryptx_pub_dsa1.der +t/data/cryptx_pub_dsa1.pem +t/data/cryptx_pub_dsa2.der +t/data/cryptx_pub_dsa2.pem +t/data/cryptx_pub_ecc1.der +t/data/cryptx_pub_ecc1.pem +t/data/cryptx_pub_ecc1_OLD.der +t/data/cryptx_pub_ecc1_OLD.pem +t/data/cryptx_pub_ecc2.der +t/data/cryptx_pub_ecc2.pem +t/data/cryptx_pub_ecc2_OLD.der +t/data/cryptx_pub_ecc2_OLD.pem +t/data/cryptx_pub_rsa1.der +t/data/cryptx_pub_rsa1.pem +t/data/cryptx_pub_rsa2.der +t/data/cryptx_pub_rsa2.pem +t/data/dsa-aes128.pem +t/data/dsa-aes192.pem +t/data/dsa-aes256.pem +t/data/dsa-camellia128.pem +t/data/dsa-camellia192.pem +t/data/dsa-camellia256.pem +t/data/dsa-des.pem +t/data/dsa-des3.pem +t/data/dsa-param.pem +t/data/dsa-seed.pem +t/data/ec-aes128.pem +t/data/ec-aes192.pem +t/data/ec-aes256.pem +t/data/ec-camellia128.pem +t/data/ec-camellia192.pem +t/data/ec-camellia256.pem +t/data/ec-des.pem +t/data/ec-des3.pem +t/data/ec-seed.pem +t/data/jwk_ec-priv1.json +t/data/jwk_ec-pub.json +t/data/jwk_ec-pub1.json +t/data/jwk_rsa-priv.json +t/data/jwk_rsa-priv1.json +t/data/jwk_rsa-pub1.json +t/data/openssl_dsa1.der +t/data/openssl_dsa1.pem +t/data/openssl_dsa2.der +t/data/openssl_dsa2.pem +t/data/openssl_ec-short.der +t/data/openssl_ec-short.pem +t/data/openssl_ec-short.pub.der +t/data/openssl_ec-short.pub.pem +t/data/openssl_ec1.key.pem +t/data/openssl_ec1.pri.der +t/data/openssl_ec1.pri.pem +t/data/openssl_ec1.pric.der +t/data/openssl_ec1.pric.pem +t/data/openssl_ec1.pub.der +t/data/openssl_ec1.pub.pem +t/data/openssl_ec1.pubc.der +t/data/openssl_ec1.pubc.pem +t/data/openssl_rsa1.der +t/data/openssl_rsa1.pem +t/data/openssl_rsa1.pubonly.der +t/data/openssl_rsa1.pubonly.pem +t/data/openssl_rsa2.der +t/data/openssl_rsa2.pem +t/data/openssl_rsa2.pubonly.der +t/data/openssl_rsa2.pubonly.pem +t/data/pkcs8.ec-priv-nopass.der +t/data/pkcs8.ec-priv-nopass.pem +t/data/pkcs8.ec-priv-pass.der +t/data/pkcs8.ec-priv-pass.pem +t/data/pkcs8.ec-short-priv-nopass.der +t/data/pkcs8.ec-short-priv-nopass.pem +t/data/pkcs8.ec-short-priv-pass.der +t/data/pkcs8.ec-short-priv-pass.pem +t/data/pkcs8.rsa-priv-nopass.der +t/data/pkcs8.rsa-priv-nopass.pem +t/data/pkcs8.rsa-priv-pass.der +t/data/pkcs8.rsa-priv-pass.pem +t/data/rsa-aes128.pem +t/data/rsa-aes192.pem +t/data/rsa-aes256.pem +t/data/rsa-camellia128.pem +t/data/rsa-camellia192.pem +t/data/rsa-camellia256.pem +t/data/rsa-des.pem +t/data/rsa-des3.pem +t/data/rsa-seed.pem +t/data/ssh/ssh_dsa_1024 +t/data/ssh/ssh_dsa_1024.pub +t/data/ssh/ssh_dsa_1024.pub.pkcs8 +t/data/ssh/ssh_dsa_1024.pub.rfc4716 +t/data/ssh/ssh_ecdsa_256 +t/data/ssh/ssh_ecdsa_256.pub +t/data/ssh/ssh_ecdsa_256.pub.pkcs8 +t/data/ssh/ssh_ecdsa_256.pub.rfc4716 +t/data/ssh/ssh_ecdsa_384 +t/data/ssh/ssh_ecdsa_384.pub +t/data/ssh/ssh_ecdsa_384.pub.pkcs8 +t/data/ssh/ssh_ecdsa_384.pub.rfc4716 +t/data/ssh/ssh_ecdsa_521 +t/data/ssh/ssh_ecdsa_521.pub +t/data/ssh/ssh_ecdsa_521.pub.pkcs8 +t/data/ssh/ssh_ecdsa_521.pub.rfc4716 +t/data/ssh/ssh_rsa_1024 +t/data/ssh/ssh_rsa_1024.pub +t/data/ssh/ssh_rsa_1024.pub.pem +t/data/ssh/ssh_rsa_1024.pub.pkcs8 +t/data/ssh/ssh_rsa_1024.pub.rfc4716 +t/data/ssh/ssh_rsa_1024_passwd +t/data/ssh/ssh_rsa_1536 +t/data/ssh/ssh_rsa_1536.pub +t/data/ssh/ssh_rsa_1536.pub.pem +t/data/ssh/ssh_rsa_1536.pub.pkcs8 +t/data/ssh/ssh_rsa_1536.pub.rfc4716 +t/data/ssh/ssh_rsa_1536_passwd +t/data/ssh/ssh_rsa_2048 +t/data/ssh/ssh_rsa_2048.pub +t/data/ssh/ssh_rsa_2048.pub.pem +t/data/ssh/ssh_rsa_2048.pub.pkcs8 +t/data/ssh/ssh_rsa_2048.pub.rfc4716 +t/data/ssh/ssh_rsa_2048_passwd +t/data/ssh/ssh_rsa_4096 +t/data/ssh/ssh_rsa_4096.pub +t/data/ssh/ssh_rsa_4096.pub.pem +t/data/ssh/ssh_rsa_4096.pub.pkcs8 +t/data/ssh/ssh_rsa_4096.pub.rfc4716 +t/data/ssh/ssh_rsa_4096_passwd +t/data/ssh/ssh_rsa_768 +t/data/ssh/ssh_rsa_768.pub +t/data/ssh/ssh_rsa_768.pub.pem +t/data/ssh/ssh_rsa_768.pub.pkcs8 +t/data/ssh/ssh_rsa_768.pub.rfc4716 +t/data/ssh/ssh_rsa_768_passwd +t/data/ssh/ssh_rsa_8192 +t/data/ssh/ssh_rsa_8192.pub +t/data/ssh/ssh_rsa_8192.pub.pem +t/data/ssh/ssh_rsa_8192.pub.pkcs8 +t/data/ssh/ssh_rsa_8192.pub.rfc4716 +t/data/ssh/ssh_rsa_8192_passwd +t/data/text-CR.file +t/data/text-CRLF.file +t/data/text-LF.file +t/digest_blake2b_160.t +t/digest_blake2b_256.t +t/digest_blake2b_384.t +t/digest_blake2b_512.t +t/digest_blake2s_128.t +t/digest_blake2s_160.t +t/digest_blake2s_224.t +t/digest_blake2s_256.t +t/digest_chaes.t +t/digest_md2.t +t/digest_md4.t +t/digest_md5.t +t/digest_ripemd128.t +t/digest_ripemd160.t +t/digest_ripemd256.t +t/digest_ripemd320.t +t/digest_sha1.t +t/digest_sha224.t +t/digest_sha256.t +t/digest_sha384.t +t/digest_sha3_224.t +t/digest_sha3_256.t +t/digest_sha3_384.t +t/digest_sha3_512.t +t/digest_sha512.t +t/digest_sha512_224.t +t/digest_sha512_256.t +t/digest_shake.t +t/digest_test_vectors_ltc.t +t/digest_tiger192.t +t/digest_whirlpool.t +t/jwk.t +t/key_derivation.t +t/mac_blake2b.t +t/mac_blake2s.t +t/mac_f9.t +t/mac_hmac.t +t/mac_hmac_test_vectors_ltc.t +t/mac_omac.t +t/mac_omac_test_vectors_ltc.t +t/mac_pelican.t +t/mac_pmac.t +t/mac_pmac_test_vectors_ltc.t +t/mac_poly1305.t +t/mac_xcbc.t +t/mbi_ltm/bigfltpm.inc +t/mbi_ltm/bigintpm.inc +t/mbi_ltm_01load.t +t/mbi_ltm_bigfltpm.t +t/mbi_ltm_bigintg.t +t/mbi_ltm_bigintpm.t +t/mbi_ltm_biglog.t +t/mbi_ltm_bigroot.t +t/mbi_ltm_bugs.t +t/mbi_ltm_mbi-from-big-scalar.t +t/mbi_ltm_storable.t +t/mode_cbc.t +t/mode_cfb.t +t/mode_ctr.t +t/mode_ecb.t +t/mode_ofb.t +t/pk_dh.t +t/pk_dsa.t +t/pk_dsa_test_vectors_openssl.t +t/pk_ecc.t +t/pk_ecc_test_vectors_openssl.t +t/pk_enc_pem.t +t/pk_rsa.t +t/pk_rsa_test_vectors_openssl.t +t/pkcs8.t +t/prng.t +t/prng_chacha20.t +t/prng_fortuna.t +t/prng_rc4.t +t/prng_sober128.t +t/prng_yarrow.t +t/sshkey.t +typemap diff --git a/META.json b/META.json new file mode 100644 index 0000000..9813b1f --- /dev/null +++ b/META.json @@ -0,0 +1,50 @@ +{ + "abstract" : "Crypto toolkit", + "author" : [ + "Karel Miko" + ], + "dynamic_config" : 1, + "generated_by" : "ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150010", + "license" : [ + "perl_5" + ], + "meta-spec" : { + "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", + "version" : "2" + }, + "name" : "CryptX", + "no_index" : { + "directory" : [ + "t", + "inc" + ] + }, + "prereqs" : { + "build" : { + "requires" : { + "ExtUtils::MakeMaker" : "0" + } + }, + "configure" : { + "requires" : { + "ExtUtils::MakeMaker" : "0" + } + }, + "runtime" : { + "requires" : { + "perl" : "5.006" + } + } + }, + "release_status" : "stable", + "resources" : { + "bugtracker" : { + "web" : "https://github.com/DCIT/perl-CryptX/issues" + }, + "repository" : { + "url" : "https://github.com/DCIT/perl-CryptX" + } + }, + "version" : "0.048", + "x_serialization_backend" : "JSON::PP version 2.27400" +} diff --git a/META.yml b/META.yml new file mode 100644 index 0000000..e904536 --- /dev/null +++ b/META.yml @@ -0,0 +1,26 @@ +--- +abstract: 'Crypto toolkit' +author: + - 'Karel Miko' +build_requires: + ExtUtils::MakeMaker: '0' +configure_requires: + ExtUtils::MakeMaker: '0' +dynamic_config: 1 +generated_by: 'ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150010' +license: perl +meta-spec: + url: http://module-build.sourceforge.net/META-spec-v1.4.html + version: '1.4' +name: CryptX +no_index: + directory: + - t + - inc +requires: + perl: '5.006' +resources: + bugtracker: https://github.com/DCIT/perl-CryptX/issues + repository: https://github.com/DCIT/perl-CryptX +version: '0.048' +x_serialization_backend: 'CPAN::Meta::YAML version 0.018' diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..bbe42fb --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,87 @@ +use strict; +use warnings; +use ExtUtils::MakeMaker; +use Config; + +my @myobjs = map { s|.c$|$Config{obj_ext}|; $_ } grep { $_ !~ m|^src/ltc/\.*tab\.c$| } ( + glob('src/ltm/*.c'), + glob('src/ltc/*/*.c'), + glob('src/ltc/*/*/*.c'), + glob('src/ltc/*/*/*/*.c'), + glob('src/ltc/*/*/*/*/*.c'), +); +my $myextlib = "src/liballinone$Config{lib_ext}"; +my $mycflags = "$Config{cccdlflags} $Config{ccflags} $Config{optimize} -Iltm -Iltc/headers -DLTC_SOURCE -DLTC_NO_TEST -DLTC_NO_PROTOTYPES -DLTM_DESC"; + +#FIX: gcc with -flto is a trouble maker see https://github.com/DCIT/perl-CryptX/issues/32 +$mycflags =~ s/-flto\b//g; + +#FIX: avoid "ar: fatal: Numeric group ID too large" see https://github.com/DCIT/perl-CryptX/issues/33 +my $myarflags = '$(AR_STATIC_ARGS)'; +if ($^O ne 'MSWin32' && $Config{ar}) { + # for ar's "deterministic mode" we need GNU binutils 2.20+ (2009-10-16) + my $arver = `$Config{ar} --version`; + my ($maj, $min) = $arver =~ /^GNU ar [^\d]*(\d)\.(\d+)\.\d+/s; + $myarflags = 'rcD' if ($maj && $min && $maj >= 2 && $min >= 20) || $arver=~ /^BSD ar /; +} + +my %eumm_args = ( + NAME => 'CryptX', + VERSION_FROM => 'lib/CryptX.pm', + AUTHOR => 'Karel Miko', + ABSTRACT => 'Crypto toolkit', + MIN_PERL_VERSION => '5.006', + LICENSE => 'perl_5', + META_MERGE => { resources => { repository => 'https://github.com/DCIT/perl-CryptX', bugtracker => 'https://github.com/DCIT/perl-CryptX/issues' } }, + DEFINE => '-DLTC_SOURCE -DLTC_NO_TEST -DLTC_NO_PROTOTYPES -DLTM_DESC', + INC => '-Isrc/ltc/headers -Isrc/ltm', + LIBS => [''], + MYEXTLIB => $myextlib, + clean => { 'FILES' => join(' ', @myobjs, $myextlib) }, +); + +my $eumm_ver = eval $ExtUtils::MakeMaker::VERSION; +delete $eumm_args{MIN_PERL_VERSION} if $eumm_ver < 6.48; +delete $eumm_args{META_ADD} if $eumm_ver < 6.46; +delete $eumm_args{META_MERGE} if $eumm_ver < 6.46; +delete $eumm_args{LICENSE} if $eumm_ver < 6.31; + +WriteMakefile(%eumm_args); + +# ARFLAGS=\$(AR_STATIC_ARGS) RANLIB=\$(RANLIB) AR=\$(AR) + +sub MY::postamble { + my $myextlib = qq{ +\$(MYEXTLIB): src/Makefile + cd src && \$(MAKE) ARFLAGS="$myarflags" RANLIB="\$(RANLIB)" AR="\$(AR)" CC="\$(CC)" LIB_EXT=\$(LIB_EXT) OBJ_EXT=\$(OBJ_EXT) CFLAGS="$mycflags" +}; + + $myextlib = qq{ +\$(MYEXTLIB): src/Makefile + cd src && \$(MAKE) -f Makefile.nmake CFLAGS="$mycflags" +} if $^O eq 'MSWin32' && $Config{make} =~ /nmake/ && $Config{cc} =~ /cl/; + + $myextlib = qq{ +\$(MYEXTLIB): src/Makefile + cd src && \$(MAKE) CC="$Config{cc}" CFLAGS="$mycflags" +} if $^O eq 'MSWin32' && $Config{cc} =~ /gcc/; + + my $version_patch = q{ +versionsync: + $(NOECHO) perl _generators/version_patch.pl sync + +versioninc: + $(NOECHO) perl _generators/version_patch.pl inc + +versionincdev: + $(NOECHO) perl _generators/version_patch.pl incdev + +versiondec: + $(NOECHO) perl _generators/version_patch.pl dec + +versiondecdev: + $(NOECHO) perl _generators/version_patch.pl decdev +}; + + return "$myextlib\n$version_patch"; +} diff --git a/README b/README new file mode 100644 index 0000000..63f661b --- /dev/null +++ b/README @@ -0,0 +1,68 @@ +NAME + CryptX - Crypto toolkit (self-contained no external libraries needed) + +DESCRIPTION + Cryptography in CryptX is based on + + + Currently available modules: + + * Ciphers - see Crypt::Cipher and related modules + + Crypt::Cipher::AES, Crypt::Cipher::Anubis, Crypt::Cipher::Blowfish, + Crypt::Cipher::Camellia, Crypt::Cipher::CAST5, Crypt::Cipher::DES, + Crypt::Cipher::DES_EDE, Crypt::Cipher::KASUMI, + Crypt::Cipher::Khazad, Crypt::Cipher::MULTI2, + Crypt::Cipher::Noekeon, Crypt::Cipher::RC2, Crypt::Cipher::RC5, + Crypt::Cipher::RC6, Crypt::Cipher::SAFERP, + Crypt::Cipher::SAFER_K128, Crypt::Cipher::SAFER_K64, + Crypt::Cipher::SAFER_SK128, Crypt::Cipher::SAFER_SK64, + Crypt::Cipher::SEED, Crypt::Cipher::Skipjack, + Crypt::Cipher::Twofish, Crypt::Cipher::XTEA + + * Block cipher modes + + Crypt::Mode::CBC, Crypt::Mode::CFB, Crypt::Mode::CTR, + Crypt::Mode::ECB, Crypt::Mode::OFB + + * Authenticated encryption modes + + Crypt::AuthEnc::CCM, Crypt::AuthEnc::EAX, Crypt::AuthEnc::GCM, + Crypt::AuthEnc::OCB + + * Hash Functions - see Crypt::Digest and related modules + + Crypt::Digest::CHAES, Crypt::Digest::MD2, Crypt::Digest::MD4, + Crypt::Digest::MD5, Crypt::Digest::RIPEMD128, + Crypt::Digest::RIPEMD160, Crypt::Digest::RIPEMD256, + Crypt::Digest::RIPEMD320, Crypt::Digest::SHA1, + Crypt::Digest::SHA224, Crypt::Digest::SHA256, Crypt::Digest::SHA384, + Crypt::Digest::SHA512, Crypt::Digest::SHA512_224, + Crypt::Digest::SHA512_256, Crypt::Digest::Tiger192, + Crypt::Digest::Whirlpool + + * Message Authentication Codes + + Crypt::Mac::F9, Crypt::Mac::HMAC, Crypt::Mac::OMAC, + Crypt::Mac::Pelican, Crypt::Mac::PMAC, Crypt::Mac::XCBC + + * Public key cryptography + + Crypt::PK::RSA, Crypt::PK::DSA, Crypt::PK::ECC, Crypt::PK::DH + + * Cryptographically secure random number generators + + Crypt::PRNG, Crypt::PRNG::Fortuna, Crypt::PRNG::Yarrow, + Crypt::PRNG::RC4, Crypt::PRNG::Sober128 + + * Key derivation functions - PBKDF1, PBKFD2 and HKDF + + Crypt::KeyDerivation + +LICENSE + This program is free software; you can redistribute it and/or modify it + under the same terms as Perl itself. + +COPYRIGHT + Copyright (c) 2013-2015 DCIT, a.s. / Karel Miko + diff --git a/inc/CryptX_AuthEnc_CCM.xs.inc b/inc/CryptX_AuthEnc_CCM.xs.inc new file mode 100644 index 0000000..13171b2 --- /dev/null +++ b/inc/CryptX_AuthEnc_CCM.xs.inc @@ -0,0 +1,90 @@ +MODULE = CryptX PACKAGE = Crypt::AuthEnc::CCM + +void +_memory_encrypt(char *cipher_name, SV *key, SV *nonce, SV *header, unsigned long tag_len, SV *plaintext) + PPCODE: + { + STRLEN k_len, n_len, h_len, pt_len; + unsigned char *k, *n, *h, *pt; + int rv, id; + unsigned char tag[MAXBLOCKSIZE]; + SV *ct; + + if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); + if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar"); + if (!SvPOK(header)) croak("FATAL: header must be string/buffer scalar"); + if (!SvPOK(plaintext)) croak("FATAL: plaintext must be string/buffer scalar"); + k = (unsigned char *) SvPVbyte(key, k_len); + n = (unsigned char *) SvPVbyte(nonce, n_len); + h = (unsigned char *) SvPVbyte(header, h_len); + pt = (unsigned char *) SvPVbyte(plaintext, pt_len); + + id = find_cipher(cipher_name); + if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); + + ct = NEWSV(0, pt_len); + SvPOK_only(ct); + SvCUR_set(ct, pt_len); + + if(tag_len<4 || tag_len>16) tag_len = 16; + + rv = ccm_memory(id, k, (unsigned long)k_len, NULL, n, (unsigned long)n_len, h, (unsigned long)h_len, + pt, (unsigned long)pt_len, (unsigned char *)SvPV_nolen(ct), tag, &tag_len, CCM_ENCRYPT); + if (rv != CRYPT_OK) croak("FATAL: ccm_memory failed: %s", error_to_string(rv)); + + XPUSHs(sv_2mortal(ct)); + XPUSHs(sv_2mortal(newSVpvn((char*)tag,tag_len))); + + /* int ccm_memory( int cipher, + const unsigned char *key, unsigned long keylen, + symmetric_key *uskey, + 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); */ + + } + +void +_memory_decrypt(char *cipher_name, SV *key, SV *nonce, SV *header, SV *ciphertext, SV *tag) + PPCODE: + { + STRLEN k_len, n_len, h_len, ct_len, t_len; + unsigned char *k, *n, *h, *ct, *t; + int rv, id; + unsigned char xtag[MAXBLOCKSIZE]; + unsigned long xtag_len; + SV *pt; + + if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); + if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar"); + if (!SvPOK(header)) croak("FATAL: header must be string/buffer scalar"); + if (!SvPOK(ciphertext)) croak("FATAL: ciphertext must be string/buffer scalar"); + if (!SvPOK(tag)) croak("FATAL: tag must be string/buffer scalar"); + k = (unsigned char *) SvPVbyte(key, k_len); + n = (unsigned char *) SvPVbyte(nonce, n_len); + h = (unsigned char *) SvPVbyte(header, h_len); + ct = (unsigned char *) SvPVbyte(ciphertext, ct_len); + t = (unsigned char *) SvPVbyte(tag, t_len); + + id = find_cipher(cipher_name); + if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); + + pt = NEWSV(0, ct_len); + SvPOK_only(pt); + SvCUR_set(pt, ct_len); + + xtag_len = (unsigned long)t_len; + Copy(t, xtag, t_len, unsigned char); + + rv = ccm_memory(id, k, (unsigned long)k_len, NULL, n, (unsigned long)n_len, h, (unsigned long)h_len, + (unsigned char *)SvPV_nolen(pt), (unsigned long)ct_len, ct, xtag, &xtag_len, CCM_DECRYPT); + if (rv != CRYPT_OK) { + XPUSHs(sv_2mortal(newSVpvn(NULL,0))); /* undef */ + } + else { + XPUSHs(sv_2mortal(pt)); + } + } diff --git a/inc/CryptX_AuthEnc_ChaCha20Poly1305.xs.inc b/inc/CryptX_AuthEnc_ChaCha20Poly1305.xs.inc new file mode 100644 index 0000000..3e8ed07 --- /dev/null +++ b/inc/CryptX_AuthEnc_ChaCha20Poly1305.xs.inc @@ -0,0 +1,185 @@ +MODULE = CryptX PACKAGE = Crypt::AuthEnc::ChaCha20Poly1305 + +Crypt::AuthEnc::ChaCha20Poly1305 +_new(SV * key, SV * nonce = NULL) + CODE: + { + int rv; + STRLEN iv_len=0, k_len=0; + unsigned char *iv=NULL, *k=NULL; + + if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); + k = (unsigned char *) SvPVbyte(key, k_len); + if (nonce) { + if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar"); + iv = (unsigned char *) SvPVbyte(nonce, iv_len); + } + + Newz(0, RETVAL, 1, struct chacha20poly1305_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + + rv = chacha20poly1305_init(&RETVAL->state, k, (unsigned long)k_len); + if (rv != CRYPT_OK) croak("FATAL: chacha20poly1305_init failed: %s", error_to_string(rv)); + + if (iv && iv_len > 0) { + rv = chacha20poly1305_setiv(&RETVAL->state, iv, (unsigned long)iv_len); + if (rv != CRYPT_OK) croak("FATAL: chacha20poly1305_setiv failed: %s", error_to_string(rv)); + } + } + OUTPUT: + RETVAL + +void +DESTROY(Crypt::AuthEnc::ChaCha20Poly1305 self) + CODE: + Safefree(self); + +Crypt::AuthEnc::ChaCha20Poly1305 +clone(Crypt::AuthEnc::ChaCha20Poly1305 self) + CODE: + Newz(0, RETVAL, 1, struct chacha20poly1305_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + Copy(&self->state, &RETVAL->state, 1, struct chacha20poly1305_struct); + OUTPUT: + RETVAL + +int +set_iv(Crypt::AuthEnc::ChaCha20Poly1305 self, SV * nonce) + CODE: + { + int rv; + STRLEN iv_len=0; + unsigned char *iv=NULL; + + if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar"); + iv = (unsigned char *) SvPVbyte(nonce, iv_len); + rv = chacha20poly1305_setiv(&self->state, iv, (unsigned long)iv_len); + if (rv != CRYPT_OK) croak("FATAL: chacha20poly1305_setiv failed: %s", error_to_string(rv)); + RETVAL = rv; + } + OUTPUT: + RETVAL + +int +set_iv_rfc7905(Crypt::AuthEnc::ChaCha20Poly1305 self, SV * nonce, UV seqnum) + CODE: + { + int rv; + STRLEN iv_len=0; + unsigned char *iv=NULL; + + if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar"); + iv = (unsigned char *) SvPVbyte(nonce, iv_len); + rv = chacha20poly1305_setiv_rfc7905(&self->state, iv, (unsigned long)iv_len, (ulong64)seqnum); + if (rv != CRYPT_OK) croak("FATAL: chacha20poly1305_setiv_rfc7905 failed: %s", error_to_string(rv)); + RETVAL = rv; + } + OUTPUT: + RETVAL + +int +adata_add(Crypt::AuthEnc::ChaCha20Poly1305 self, SV * data) + CODE: + { + int rv; + STRLEN in_data_len; + unsigned char *in_data; + + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + rv = chacha20poly1305_add_aad(&self->state, in_data, (unsigned long)in_data_len); + if (rv != CRYPT_OK) croak("FATAL: chacha20poly1305_add_aad failed: %s", error_to_string(rv)); + RETVAL = rv; + } + OUTPUT: + RETVAL + +SV * +decrypt_add(Crypt::AuthEnc::ChaCha20Poly1305 self, SV * data) + CODE: + { + int rv; + STRLEN in_data_len; + unsigned char *in_data, *out_data; + + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + if (in_data_len==0) { + RETVAL = newSVpvn("", 0); + } + else { + RETVAL = NEWSV(0, in_data_len); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, in_data_len); + out_data = (unsigned char *)SvPV_nolen(RETVAL); + rv = chacha20poly1305_decrypt(&self->state, in_data, (unsigned long)in_data_len, out_data); + if (rv != CRYPT_OK) croak("FATAL: chacha20poly1305_decrypt failed: %s", error_to_string(rv)); + } + } + OUTPUT: + RETVAL + +SV * +encrypt_add(Crypt::AuthEnc::ChaCha20Poly1305 self, SV * data) + CODE: + { + int rv; + STRLEN in_data_len; + unsigned char *in_data, *out_data; + + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + if (in_data_len==0) { + RETVAL = newSVpvn("", 0); + } + else { + RETVAL = NEWSV(0, in_data_len); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, in_data_len); + out_data = (unsigned char *)SvPV_nolen(RETVAL); + rv = chacha20poly1305_encrypt(&self->state, in_data, (unsigned long)in_data_len, out_data); + if (rv != CRYPT_OK) croak("FATAL: chacha20poly1305_encrypt failed: %s", error_to_string(rv)); + } + } + OUTPUT: + RETVAL + +void +encrypt_done(Crypt::AuthEnc::ChaCha20Poly1305 self) + PPCODE: + { + int rv; + unsigned char tag[MAXBLOCKSIZE]; + unsigned long tag_len = sizeof(tag); + + rv = chacha20poly1305_done(&self->state, tag, &tag_len); + if (rv != CRYPT_OK) croak("FATAL: chacha20poly1305_done failed: %s", error_to_string(rv)); + XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); + } + +void +decrypt_done(Crypt::AuthEnc::ChaCha20Poly1305 self, ...) + PPCODE: + { + int rv; + unsigned char tag[MAXBLOCKSIZE]; + unsigned long tag_len = sizeof(tag); + STRLEN expected_tag_len; + unsigned char *expected_tag; + + rv = chacha20poly1305_done(&self->state, tag, &tag_len); + if (rv != CRYPT_OK) croak("FATAL: chacha20poly1305_done failed: %s", error_to_string(rv)); + if (items == 1) { + XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); + } + else { + if(!SvPOK(ST(1))) croak("FATAL: expected_tag must be string/buffer scalar"); + expected_tag = (unsigned char *) SvPVbyte(ST(1), expected_tag_len); + if (expected_tag_len!=tag_len) { + XPUSHs(sv_2mortal(newSViv(0))); /* false */ + } + else if (memNE(expected_tag, tag, tag_len)) { + XPUSHs(sv_2mortal(newSViv(0))); /* false */ + } + else { + XPUSHs(sv_2mortal(newSViv(1))); /* true */ + } + } + } diff --git a/inc/CryptX_AuthEnc_EAX.xs.inc b/inc/CryptX_AuthEnc_EAX.xs.inc new file mode 100644 index 0000000..6a80c08 --- /dev/null +++ b/inc/CryptX_AuthEnc_EAX.xs.inc @@ -0,0 +1,152 @@ +MODULE = CryptX PACKAGE = Crypt::AuthEnc::EAX + +Crypt::AuthEnc::EAX +_new(char * cipher_name, SV * key, SV * nonce, SV * adata=&PL_sv_undef) + CODE: + { + STRLEN k_len=0; + unsigned char *k=NULL; + unsigned char *n=NULL; + STRLEN n_len=0; + unsigned char *h=NULL; + STRLEN h_len=0; + int id; + + if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); + k = (unsigned char *) SvPVbyte(key, k_len); + if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar"); + n = (unsigned char *) SvPVbyte(nonce, n_len); + if(SvOK(adata)) { /* adata is optional param */ + if(!SvPOK(adata)) croak("FATAL: adata must be string/buffer scalar"); + h = (unsigned char *) SvPVbyte(adata, h_len); + } + + id = find_cipher(cipher_name); + if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); + + Newz(0, RETVAL, 1, struct eax_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + + if (eax_init(&RETVAL->state, id, k, (unsigned long)k_len, n, (unsigned long)n_len, h, (unsigned long)h_len) != CRYPT_OK) { + croak("FATAL: eax setup failed"); + } + } + OUTPUT: + RETVAL + +void +DESTROY(Crypt::AuthEnc::EAX self) + CODE: + Safefree(self); + +Crypt::AuthEnc::EAX +clone(Crypt::AuthEnc::EAX self) + CODE: + Newz(0, RETVAL, 1, struct eax_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + Copy(&self->state, &RETVAL->state, 1, struct eax_struct); + OUTPUT: + RETVAL + +SV * +encrypt_add(Crypt::AuthEnc::EAX self, SV * data) + CODE: + { + int rv; + STRLEN in_data_len; + unsigned char *in_data, *out_data; + + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + if (in_data_len==0) { + RETVAL = newSVpvn("", 0); + } + else { + RETVAL = NEWSV(0, in_data_len); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, in_data_len); + out_data = (unsigned char *)SvPV_nolen(RETVAL); + rv = eax_encrypt(&self->state, in_data, out_data, (unsigned long)in_data_len); + if (rv != CRYPT_OK) croak("FATAL: eax_encrypt failed: %s", error_to_string(rv)); + } + } + OUTPUT: + RETVAL + +SV * +decrypt_add(Crypt::AuthEnc::EAX self, SV * data) + CODE: + { + int rv; + STRLEN in_data_len; + unsigned char *in_data, *out_data; + + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + if (in_data_len==0) { + RETVAL = newSVpvn("", 0); + } + else { + RETVAL = NEWSV(0, in_data_len); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, in_data_len); + out_data = (unsigned char *)SvPV_nolen(RETVAL); + rv = eax_decrypt(&self->state, in_data, out_data, (unsigned long)in_data_len); + if (rv != CRYPT_OK) croak("FATAL: eax_decrypt failed: %s", error_to_string(rv)); + } + } + OUTPUT: + RETVAL + +void +encrypt_done(Crypt::AuthEnc::EAX self) + PPCODE: + { + int rv; + unsigned char tag[MAXBLOCKSIZE]; + unsigned long tag_len = sizeof(tag); + + rv = eax_done(&self->state, tag, &tag_len); + if (rv != CRYPT_OK) croak("FATAL: eax_done failed: %s", error_to_string(rv)); + XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); + } + +void +decrypt_done(Crypt::AuthEnc::EAX self, ...) + PPCODE: + { + int rv; + unsigned char tag[MAXBLOCKSIZE]; + unsigned long tag_len = sizeof(tag); + STRLEN expected_tag_len; + unsigned char *expected_tag; + + rv = eax_done(&self->state, tag, &tag_len); + if (rv != CRYPT_OK) croak("FATAL: eax_done failed: %s", error_to_string(rv)); + if (items == 1) { + XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); + } + else { + if(!SvPOK(ST(1))) croak("FATAL: expected_tag must be string/buffer scalar"); + expected_tag = (unsigned char *) SvPVbyte(ST(1), expected_tag_len); + if (expected_tag_len!=tag_len) { + XPUSHs(sv_2mortal(newSViv(0))); /* false */ + } + else if (memNE(expected_tag, tag, tag_len)) { + XPUSHs(sv_2mortal(newSViv(0))); /* false */ + } + else { + XPUSHs(sv_2mortal(newSViv(1))); /* true */ + } + } + } + +int +aad_add(Crypt::AuthEnc::EAX self, SV * adata) + CODE: + { + STRLEN h_len; + unsigned char *h; + h = (unsigned char *)SvPVbyte(adata, h_len); + RETVAL = eax_addheader(&self->state, h, (unsigned long)h_len); + } + OUTPUT: + RETVAL diff --git a/inc/CryptX_AuthEnc_GCM.xs.inc b/inc/CryptX_AuthEnc_GCM.xs.inc new file mode 100644 index 0000000..232f973 --- /dev/null +++ b/inc/CryptX_AuthEnc_GCM.xs.inc @@ -0,0 +1,184 @@ +MODULE = CryptX PACKAGE = Crypt::AuthEnc::GCM + +Crypt::AuthEnc::GCM +_new(char * cipher_name, SV * key, SV * nonce = NULL) + CODE: + { + STRLEN k_len = 0, iv_len = 0; + unsigned char *k = NULL, *iv = NULL; + int id, rv; + + if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); + k = (unsigned char *) SvPVbyte(key, k_len); + if (nonce) { + if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar"); + iv = (unsigned char *)SvPVbyte(nonce, iv_len); + } + + id = find_cipher(cipher_name); + if (id == -1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); + + Newz(0, RETVAL, 1, struct gcm_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + + rv = gcm_init(&RETVAL->state, id, k, (unsigned long)k_len); + if (rv != CRYPT_OK) croak("FATAL: gcm_init failed: %s", error_to_string(rv)); + + if (iv && iv_len > 0) { + rv = gcm_add_iv(&RETVAL->state, iv, (unsigned long)iv_len); + if (rv != CRYPT_OK) croak("FATAL: gcm_add_iv failed: %s", error_to_string(rv)); + } + } + OUTPUT: + RETVAL + +void +DESTROY(Crypt::AuthEnc::GCM self) + CODE: + Safefree(self); + +Crypt::AuthEnc::GCM +clone(Crypt::AuthEnc::GCM self) + CODE: + Newz(0, RETVAL, 1, struct gcm_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + Copy(&self->state, &RETVAL->state, 1, struct gcm_struct); + OUTPUT: + RETVAL + +int +reset(Crypt::AuthEnc::GCM self) + CODE: + { + int rv; + rv = gcm_reset(&self->state); + if (rv != CRYPT_OK) croak("FATAL: gcm_reset failed: %s", error_to_string(rv)); + RETVAL = rv; + } + OUTPUT: + RETVAL + +SV * +encrypt_add(Crypt::AuthEnc::GCM self, SV * data) + CODE: + { + int rv; + STRLEN in_data_len; + unsigned char *in_data, *out_data; + + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + if (in_data_len==0) { + RETVAL = newSVpvn("", 0); + } + else + { + RETVAL = NEWSV(0, in_data_len); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, in_data_len); + out_data = (unsigned char *)SvPV_nolen(RETVAL); + rv = gcm_process(&self->state, in_data, (unsigned long)in_data_len, out_data, GCM_ENCRYPT); + if (rv != CRYPT_OK) croak("FATAL: encrypt_add/gcm_process failed: %s", error_to_string(rv)); + } + } + OUTPUT: + RETVAL + +int +iv_add(Crypt::AuthEnc::GCM self, SV * data) + CODE: + { + int rv; + STRLEN in_data_len; + unsigned char *in_data; + + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + rv = gcm_add_iv(&self->state, in_data, (unsigned long)in_data_len); + if (rv != CRYPT_OK) croak("FATAL: gcm_add_iv failed: %s", error_to_string(rv)); + RETVAL = rv; + } + OUTPUT: + RETVAL + +int +adata_add(Crypt::AuthEnc::GCM self, SV * data) + CODE: + { + int rv; + STRLEN in_data_len; + unsigned char *in_data; + + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + rv = gcm_add_aad(&self->state, in_data, (unsigned long)in_data_len); + if (rv != CRYPT_OK) croak("FATAL: gcm_add_aad failed: %s", error_to_string(rv)); + RETVAL = rv; + } + OUTPUT: + RETVAL + +SV * +decrypt_add(Crypt::AuthEnc::GCM self, SV * data) + CODE: + { + int rv; + STRLEN in_data_len; + unsigned char *in_data, *out_data; + + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + if (in_data_len==0) { + RETVAL = newSVpvn("", 0); + } + else { + RETVAL = NEWSV(0, in_data_len); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, in_data_len); + out_data = (unsigned char *)SvPV_nolen(RETVAL); + rv = gcm_process(&self->state, out_data, (unsigned long)in_data_len, in_data, GCM_DECRYPT); + if (rv != CRYPT_OK) croak("FATAL: encrypt_add/gcm_process failed: %s", error_to_string(rv)); + } + } + OUTPUT: + RETVAL + + +void +encrypt_done(Crypt::AuthEnc::GCM self) + PPCODE: + { + int rv; + unsigned char tag[MAXBLOCKSIZE]; + unsigned long tag_len = sizeof(tag); + + rv = gcm_done(&self->state, tag, &tag_len); + if (rv != CRYPT_OK) croak("FATAL: gcm_done failed: %s", error_to_string(rv)); + XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); + } + +void +decrypt_done(Crypt::AuthEnc::GCM self, ...) + PPCODE: + { + int rv; + unsigned char tag[MAXBLOCKSIZE]; + unsigned long tag_len = sizeof(tag); + STRLEN expected_tag_len; + unsigned char *expected_tag; + + rv = gcm_done(&self->state, tag, &tag_len); + if (rv != CRYPT_OK) croak("FATAL: gcm_done failed: %s", error_to_string(rv)); + if (items == 1) { + XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); + } + else { + if(!SvPOK(ST(1))) croak("FATAL: expected_tag must be string/buffer scalar"); + expected_tag = (unsigned char *) SvPVbyte(ST(1), expected_tag_len); + if (expected_tag_len!=tag_len) { + XPUSHs(sv_2mortal(newSViv(0))); /* false */ + } + else if (memNE(expected_tag, tag, tag_len)) { + XPUSHs(sv_2mortal(newSViv(0))); /* false */ + } + else { + XPUSHs(sv_2mortal(newSViv(1))); /* true */ + } + } + } diff --git a/inc/CryptX_AuthEnc_OCB.xs.inc b/inc/CryptX_AuthEnc_OCB.xs.inc new file mode 100644 index 0000000..4e6ba09 --- /dev/null +++ b/inc/CryptX_AuthEnc_OCB.xs.inc @@ -0,0 +1,218 @@ +MODULE = CryptX PACKAGE = Crypt::AuthEnc::OCB + +Crypt::AuthEnc::OCB +_new(char * cipher_name, SV * key, SV * nonce) + CODE: + { + STRLEN k_len=0; + unsigned char *k=NULL; + unsigned char *n=NULL; + STRLEN n_len=0; + int id; + + if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); + k = (unsigned char *) SvPVbyte(key, k_len); + if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar"); + n = (unsigned char *) SvPVbyte(nonce, n_len); + + id = find_cipher(cipher_name); + if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); + + Newz(0, RETVAL, 1, struct ocb_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + + if (ocb3_init(&RETVAL->state, id, k, (unsigned long)k_len, n, (unsigned long)n_len) != CRYPT_OK) { + croak("FATAL: ocb setup failed"); + } + } + OUTPUT: + RETVAL + +void +DESTROY(Crypt::AuthEnc::OCB self) + CODE: + Safefree(self); + +Crypt::AuthEnc::OCB +clone(Crypt::AuthEnc::OCB self) + CODE: + Newz(0, RETVAL, 1, struct ocb_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + Copy(&self->state, &RETVAL->state, 1, struct ocb_struct); + OUTPUT: + RETVAL + +void +aad_add(Crypt::AuthEnc::OCB self, SV * data) + CODE: + { + int rv; + STRLEN in_data_len; + unsigned char *in_data; + + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + + if (in_data_len>0) { + rv = ocb3_add_aad(&self->state, in_data, (unsigned long)in_data_len); + if (rv != CRYPT_OK) croak("FATAL: ocb3_add_aad failed: %s", error_to_string(rv)); + } + } + +SV * +encrypt_add(Crypt::AuthEnc::OCB self, SV * data) + CODE: + { + int rv; + STRLEN in_data_len; + unsigned char *in_data, *out_data; + + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + if (in_data_len==0) { + RETVAL = newSVpvn("", 0); + } + else { + RETVAL = NEWSV(0, in_data_len); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, in_data_len); + out_data = (unsigned char *)SvPV_nolen(RETVAL); + + if (in_data_len % (&self->state)->block_len) + croak ("FATAL: sizeof(data) should be multiple of blocksize (%d)", (&self->state)->block_len); + + rv = ocb3_encrypt(&self->state, in_data, (unsigned long)in_data_len, out_data); + if (rv != CRYPT_OK) croak("FATAL: ocb3_encrypt failed: %s", error_to_string(rv)); + } + } + OUTPUT: + RETVAL + +SV * +encrypt_last(Crypt::AuthEnc::OCB self, SV * data) + CODE: + { + int rv; + STRLEN in_data_len; + unsigned char *in_data, *out_data; + + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + if (in_data_len>0) { + RETVAL = NEWSV(0, in_data_len); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, in_data_len); + out_data = (unsigned char *)SvPV_nolen(RETVAL); + } + else { + RETVAL = newSVpvn("", 0); + out_data = NULL; + } + rv = ocb3_encrypt_last(&self->state, in_data, (unsigned long)in_data_len, out_data); + if (rv != CRYPT_OK) croak("FATAL: ocb3_encrypt_last failed: %s", error_to_string(rv)); + } + OUTPUT: + RETVAL + +SV * +decrypt_add(Crypt::AuthEnc::OCB self, SV * data) + CODE: + { + int rv; + STRLEN in_data_len; + unsigned char *in_data, *out_data; + + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + if (in_data_len==0) { + RETVAL = newSVpvn("", 0); + } + else { + RETVAL = NEWSV(0, in_data_len); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, in_data_len); + out_data = (unsigned char *)SvPV_nolen(RETVAL); + + if (in_data_len % (&self->state)->block_len) + croak ("FATAL: sizeof(data) should be multiple of blocksize (%d)", (&self->state)->block_len); + + rv = ocb3_decrypt(&self->state, in_data, (unsigned long)in_data_len, out_data); + if (rv != CRYPT_OK) croak("FATAL: ocb3_decrypt failed: %s", error_to_string(rv)); + } + } + OUTPUT: + RETVAL + +SV * +decrypt_last(Crypt::AuthEnc::OCB self, SV * data) + CODE: + { + int rv; + STRLEN in_data_len; + unsigned char *in_data, *out_data; + + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + if (in_data_len>0) { + RETVAL = NEWSV(0, in_data_len); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, in_data_len); + out_data = (unsigned char *)SvPV_nolen(RETVAL); + } + else { + RETVAL = newSVpvn("", 0); + out_data = NULL; + } + rv = ocb3_decrypt_last(&self->state, in_data, (unsigned long)in_data_len, out_data); + if (rv != CRYPT_OK) croak("FATAL: ocb3_encrypt_last failed: %s", error_to_string(rv)); + } + OUTPUT: + RETVAL + +void +encrypt_done(Crypt::AuthEnc::OCB self) + PPCODE: + { + int rv; + unsigned char tag[MAXBLOCKSIZE]; + unsigned long tag_len = sizeof(tag); + + rv = ocb3_done(&self->state, tag, &tag_len); + if (rv != CRYPT_OK) croak("FATAL: ocb3_done_encrypt failed: %s", error_to_string(rv)); + + XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); + } + +void +decrypt_done(Crypt::AuthEnc::OCB self, ...) + PPCODE: + { + int rv; + unsigned char tag[MAXBLOCKSIZE]; + unsigned long tag_len = sizeof(tag); + STRLEN expected_tag_len; + unsigned char *expected_tag; + + rv = ocb3_done(&self->state, tag, &tag_len); + if (rv != CRYPT_OK) croak("FATAL: ocb3_done_decrypt failed: %s", error_to_string(rv)); + if (items == 1) { + XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); + } + else { + if(!SvPOK(ST(1))) croak("FATAL: expected_tag must be string/buffer scalar"); + expected_tag = (unsigned char *) SvPVbyte(ST(1), expected_tag_len); + if (expected_tag_len!=tag_len) { + XPUSHs(sv_2mortal(newSViv(0))); /* false */ + } + else if (memNE(expected_tag, tag, tag_len)) { + XPUSHs(sv_2mortal(newSViv(0))); /* false */ + } + else { + XPUSHs(sv_2mortal(newSViv(1))); /* true */ + } + } + } + +int +blocksize(Crypt::AuthEnc::OCB self) + CODE: + { + RETVAL = (&self->state)->block_len; + } + OUTPUT: + RETVAL diff --git a/inc/CryptX_BigInt_LTM.xs.inc b/inc/CryptX_BigInt_LTM.xs.inc new file mode 100644 index 0000000..e321c38 --- /dev/null +++ b/inc/CryptX_BigInt_LTM.xs.inc @@ -0,0 +1,658 @@ +MODULE = CryptX PACKAGE = Math::BigInt::LTM + + +############################################################################## +# _new() + +Math::BigInt::LTM +_new(Class, SV *x) + CODE: + Newz(0, RETVAL, 1, mp_int); + mp_init(RETVAL); + if ((SvUOK(x) || SvIOK(x)) && (sizeof(UV) <= sizeof(unsigned long) || SvUV(x) == (unsigned long)SvUV(x))) { + mp_set_int(RETVAL, (unsigned long)SvUV(x)); + } + else { + mp_read_radix(RETVAL, SvPV_nolen(x), 10); + } + OUTPUT: + RETVAL + +############################################################################## +# _from_bin() + +Math::BigInt::LTM +_from_bin(Class, SV *x) + PREINIT: + char *str, *start; + CODE: + Newz(0, RETVAL, 1, mp_int); + mp_init(RETVAL); + str = SvPV_nolen(x); + start = (strlen(str)>2 && str[0] == '0' && str[1] == 'b') ? str+2 : str; + mp_read_radix(RETVAL, start, 2); + OUTPUT: + RETVAL + +############################################################################## +# _from_hex() + +Math::BigInt::LTM +_from_hex(Class, SV *x) + PREINIT: + char *str, *start; + CODE: + Newz(0, RETVAL, 1, mp_int); + mp_init(RETVAL); + str = SvPV_nolen(x); + start = (strlen(str)>2 && str[0] == '0' && str[1] == 'x') ? str+2 : str; + mp_read_radix(RETVAL, start, 16); + OUTPUT: + RETVAL + +############################################################################## +# _from_oct() + +Math::BigInt::LTM +_from_oct(Class, SV *x) + CODE: + Newz(0, RETVAL, 1, mp_int); + mp_init(RETVAL); + mp_read_radix(RETVAL, SvPV_nolen(x), 8); + OUTPUT: + RETVAL + +############################################################################## +# _set() - set an already existing object to the given scalar value + +void +_set(Class, Math::BigInt::LTM n, SV *x) + CODE: + mp_set_int(n, (unsigned long)SvIV(x)); + +############################################################################## +# _zero() + +Math::BigInt::LTM +_zero(Class) + CODE: + Newz(0, RETVAL, 1, mp_int); + mp_init(RETVAL); + mp_set_int(RETVAL, 0); + OUTPUT: + RETVAL + +############################################################################## +# _one() + +Math::BigInt::LTM +_one(Class) + CODE: + Newz(0, RETVAL, 1, mp_int); + mp_init(RETVAL); + mp_set_int(RETVAL, 1); + OUTPUT: + RETVAL + +############################################################################## +# _two() + +Math::BigInt::LTM +_two(Class) + CODE: + Newz(0, RETVAL, 1, mp_int); + mp_init(RETVAL); + mp_set_int(RETVAL, 2); + OUTPUT: + RETVAL + +############################################################################## +# _ten() + +Math::BigInt::LTM +_ten(Class) + CODE: + Newz(0, RETVAL, 1, mp_int); + mp_init(RETVAL); + mp_set_int(RETVAL, 10); + OUTPUT: + RETVAL + +############################################################################## +# _1ex() + +Math::BigInt::LTM +_1ex(Class, int x) + CODE: + Newz(0, RETVAL, 1, mp_int); + mp_init(RETVAL); + mp_set_int(RETVAL, 10); + mp_expt_d(RETVAL, x, RETVAL); + OUTPUT: + RETVAL + +############################################################################## +# DESTROY() - free memory of a GMP number + +void +DESTROY(Math::BigInt::LTM n) + PPCODE: + if (n) { + mp_clear(n); + Safefree(n); + } + +############################################################################## +# _str() - return string so that atof() and atoi() can use it + +SV * +_str(Class, Math::BigInt::LTM n) + PREINIT: + int len; + char *buf; + CODE: + if (mp_iszero(n) == MP_YES) { + RETVAL = newSVpv("0", 0); + } + else { + len = mp_count_bits(n) / 3 + 3; /* decimal_size ~ (binary_size/3 + 1) +1 for sign +1 for NUL-byte */ + Newz(0, buf, len, char); + mp_toradix_n(n, buf, 10, len); + RETVAL = newSVpv(buf, 0); + Safefree(buf); + } + OUTPUT: + RETVAL + +############################################################################## +# _len() - return the length of the number in base 10 (costly) + +int +_len(Class, Math::BigInt::LTM n) + PREINIT: + int len; + char *buf; + CODE: + if (mp_iszero(n) == MP_YES) { + RETVAL = 1; + } + else { + len = mp_count_bits(n) / 3 + 3; /* decimal_size ~ (binary_size/3 + 1) +1 for sign +1 for NUL-byte */ + Newz(0, buf, len, char); + mp_toradix_n(n, buf, 10, len); + RETVAL = (int)strlen(buf); + Safefree(buf); + } + OUTPUT: + RETVAL + +############################################################################## +# _alen() - return the approx. length of the number in base 10 (fast) +# _alen() might underestimate, but never overestimate the true value +int +_alen(Class, Math::BigInt::LTM n) + PREINIT: + int bits; + CODE: + bits = mp_count_bits(n); + /* alen = round(bits * log(2) / log(10)) */ + RETVAL = (bits < 5) ? 1 : (int)(bits * 0.301029995663 + 0.499999999999); + /* less accurate approximation, but without floating-point calculations + RETVAL = (bits < 5) ? 1 : bits / 4 + bits / 32 + bits / 64 + bits / 256; + RETVAL = (bits < 5) ? 1 : bits / 4; + */ + OUTPUT: + RETVAL + +############################################################################## +# _zeros() - return number of trailing zeros (in decimal form) + +int +_zeros(Class, Math::BigInt::LTM n) + PREINIT: + int len; + char *buf; + CODE: + if (mp_iszero(n) == MP_YES) { + RETVAL = 0; /* '0' has no trailing zeros! */ + } + else { + len = mp_count_bits(n) / 3 + 3; /* decimal_size ~ (binary_size/3 + 1) +1 for sign +1 for NUL-byte */ + Newz(0, buf, len, char); + mp_toradix_n(n, buf, 10, len); + len = (int)strlen(buf); + RETVAL = 0; + while (len > 0) { + if (buf[len-1] != '0') break; + RETVAL++; + len--; + } + Safefree(buf); + } + OUTPUT: + RETVAL + +############################################################################## +# _as_hex() - return ref to hexadecimal string (prefixed with 0x) + +SV * +_as_hex(Class, Math::BigInt::LTM n) + PREINIT: + int i, len; + char *buf; + CODE: + len = mp_unsigned_bin_size(n) * 2 + 3; + RETVAL = newSV(len); + SvPOK_on(RETVAL); + buf = SvPVX(RETVAL); /* get ptr to storage */ + *buf++ = '0'; *buf++ = 'x'; /* prepend '0x' */ + mp_tohex(n, buf); + for (i=0; i0; i++) buf[i] = toLOWER(buf[i]); + SvCUR_set(RETVAL, strlen(buf)+2); /* set real length */ + OUTPUT: + RETVAL + +############################################################################## +# _as_bin() - return ref to binary string (prefixed with 0b) + +SV * +_as_bin(Class, Math::BigInt::LTM n) + PREINIT: + int len; + char *buf; + CODE: + len = mp_unsigned_bin_size(n) * 8 + 3; + RETVAL = newSV(len); + SvPOK_on(RETVAL); + buf = SvPVX(RETVAL); /* get ptr to storage */ + *buf++ = '0'; *buf++ = 'b'; /* prepend '0b' */ + mp_tobinary(n, buf); + SvCUR_set(RETVAL, strlen(buf)+2); /* set real length */ + OUTPUT: + RETVAL + +############################################################################## +# _as_oct() - return ref to octal string (prefixed with 0) + +SV * +_as_oct(Class, Math::BigInt::LTM n) + PREINIT: + int len; + char *buf; + CODE: + len = mp_unsigned_bin_size(n) * 3 + 3; + RETVAL = newSV(len); + SvPOK_on(RETVAL); + buf = SvPVX(RETVAL); + *buf++ = '0'; /* prepend '0' */ + mp_tooctal(n, buf); + SvCUR_set(RETVAL, strlen(buf)+1); /* set real length */ + OUTPUT: + RETVAL + +############################################################################## +# _modpow() - ($n ** $exp) % $mod + +Math::BigInt::LTM +_modpow(Class, Math::BigInt::LTM n, Math::BigInt::LTM exp, Math::BigInt::LTM mod) + CODE: + Newz(0, RETVAL, 1, mp_int); + mp_init(RETVAL); + if (mp_cmp_d(mod, 1) == MP_EQ) { + mp_set_int(RETVAL, 0); + } + else { + mp_exptmod(n, exp, mod, RETVAL); + } + OUTPUT: + RETVAL + +############################################################################## +# _modinv() - compute the inverse of x % y + +void +_modinv(Class, Math::BigInt::LTM x, Math::BigInt::LTM y) + PREINIT: + int rc; + SV* s; + mp_int* RETVAL; + PPCODE: + Newz(0, RETVAL, 1, mp_int); + mp_init(RETVAL); + rc = mp_invmod(x, y, RETVAL); + EXTEND(SP, 2); /* we return two values */ + if (rc != MP_OKAY) { + /* Inverse doesn't exist. Return both values undefined. */ + PUSHs(&PL_sv_undef); + PUSHs(&PL_sv_undef); + } + else { + /* Inverse exists. When the modulus to mp_invert() is positive, + * the returned value is also positive. */ + PUSHs(sv_2mortal(sv_from_mpi(RETVAL))); + s = sv_newmortal(); + sv_setpvn(s, "+", 1); + PUSHs(s); + } + +############################################################################## +# _add() - add $y to $x in place + +void +_add(Class, Math::BigInt::LTM x, Math::BigInt::LTM y) + PPCODE: + mp_add(x, y, x); + XPUSHs(ST(1)); /* x */ + +############################################################################## +# _inc() - modify x inline by doing x++ + +void +_inc(Class, Math::BigInt::LTM x) + PPCODE: + mp_add_d(x, 1, x); + XPUSHs(ST(1)); /* x */ + +############################################################################## +# _dec() - modify x inline by doing x-- + +void +_dec(Class, Math::BigInt::LTM x) + PPCODE: + mp_sub_d(x, 1, x); + XPUSHs(ST(1)); /* x */ + +############################################################################## +# _sub() - $x - $y +# $x is always larger than $y! So overflow/underflow can not happen here. + +void +_sub(Class, Math::BigInt::LTM x, Math::BigInt::LTM y, ...) + PPCODE: + if ( items == 4 && SvTRUE(ST(3)) ) { + /* y -= x */ + mp_sub(x, y, y); + XPUSHs(ST(2)); /* y */ + } + else { + /* x -= y */ + mp_sub(x, y, x); + XPUSHs(ST(1)); /* x */ + } + +############################################################################## +# _rsft() + +void +_rsft(Class, Math::BigInt::LTM x, Math::BigInt::LTM y, unsigned long base_int) + PREINIT: + mp_int* BASE; + PPCODE: + Newz(0, BASE, 1, mp_int); + mp_init_set_int(BASE, base_int); + mp_expt_d(BASE, mp_get_long(y), BASE); + mp_div(x, BASE, x, NULL); + mp_clear(BASE); + Safefree(BASE); + XPUSHs(ST(1)); /* x */ + +############################################################################## +# _lsft() + +void +_lsft(Class, Math::BigInt::LTM x, Math::BigInt::LTM y, unsigned long base_int) + PREINIT: + mp_int* BASE; + PPCODE: + Newz(0, BASE, 1, mp_int); + mp_init_set_int(BASE, base_int); + mp_expt_d(BASE, mp_get_long(y), BASE); + mp_mul(x, BASE, x); + mp_clear(BASE); + Safefree(BASE); + XPUSHs(ST(1)); /* x */ + +############################################################################## +# _mul() + +void +_mul(Class, Math::BigInt::LTM x, Math::BigInt::LTM y) + PPCODE: + mp_mul(x, y, x); + XPUSHs(ST(1)); /* x */ + +############################################################################## +# _div(): x /= y or (x,rem) = x / y + +void +_div(Class, Math::BigInt::LTM x, Math::BigInt::LTM y) + PREINIT: + mp_int * rem; + PPCODE: + if (GIMME_V == G_ARRAY) { + Newz(0, rem, 1, mp_int); + mp_init(rem); + mp_div(x, y, x, rem); + EXTEND(SP, 2); + PUSHs(ST(1)); /* x */ + PUSHs(sv_2mortal(sv_from_mpi(rem))); + } + else { + mp_div(x, y, x, NULL); + XPUSHs(ST(1)); /* x */ + } + +############################################################################## +# _mod() - x %= y + +void +_mod(Class, Math::BigInt::LTM x, Math::BigInt::LTM y) + PPCODE: + mp_mod(x, y, x); + XPUSHs(ST(1)); /* x */ + +############################################################################## +# _acmp() - cmp two numbers + +int +_acmp(Class, Math::BigInt::LTM m, Math::BigInt::LTM n) + CODE: + RETVAL = mp_cmp(m, n); + if ( RETVAL < 0) RETVAL = -1; + if ( RETVAL > 0) RETVAL = 1; + OUTPUT: + RETVAL + +############################################################################## +# _is_zero() + +int +_is_zero(Class, Math::BigInt::LTM x) + CODE: + RETVAL = (mp_iszero(x) == MP_YES) ? 1 : 0; + OUTPUT: + RETVAL + +############################################################################## +# _is_one() + +int +_is_one(Class, Math::BigInt::LTM x) + CODE: + RETVAL = (mp_cmp_d(x, 1) == MP_EQ) ? 1 : 0; + OUTPUT: + RETVAL + +############################################################################## +# _is_two() + +int +_is_two(Class, Math::BigInt::LTM x) + CODE: + RETVAL = (mp_cmp_d(x, 2) == MP_EQ) ? 1 : 0; + OUTPUT: + RETVAL + +############################################################################## +# _is_ten() + +int +_is_ten(Class, Math::BigInt::LTM x) + CODE: + RETVAL = (mp_cmp_d(x, 10) == MP_EQ) ? 1 : 0; + OUTPUT: + RETVAL + +############################################################################## +# _pow() - x **= y + +void +_pow(Class, Math::BigInt::LTM x, Math::BigInt::LTM y) + PPCODE: + mp_expt_d(x, mp_get_long(y), x); + XPUSHs(ST(1)); /* x */ + +############################################################################## +# _gcd() - gcd(m,n) + +Math::BigInt::LTM +_gcd(Class, Math::BigInt::LTM x, Math::BigInt::LTM y) + CODE: + Newz(0, RETVAL, 1, mp_int); + mp_init(RETVAL); + mp_gcd(x, y, RETVAL); + OUTPUT: + RETVAL + +############################################################################## +# _and() - m &= n + +void +_and(Class, Math::BigInt::LTM x, Math::BigInt::LTM y) + PPCODE: + mp_and(x, y, x); + XPUSHs(ST(1)); /* x */ + +############################################################################## +# _xor() - m =^ n + +void +_xor(Class, Math::BigInt::LTM x, Math::BigInt::LTM y) + PPCODE: + mp_xor(x, y, x); + XPUSHs(ST(1)); /* x */ + +############################################################################## +# _or() - m =| n + +void +_or(Class, Math::BigInt::LTM x, Math::BigInt::LTM y) + PPCODE: + mp_or(x, y, x); + XPUSHs(ST(1)); /* x */ + +############################################################################## +# _copy() + +Math::BigInt::LTM +_copy(Class, Math::BigInt::LTM m) + CODE: + Newz(0, RETVAL, 1, mp_int); + mp_init(RETVAL); + mp_copy(m, RETVAL); + OUTPUT: + RETVAL + +############################################################################## +# _is_odd() - test for number being odd + +int +_is_odd(Class, Math::BigInt::LTM n) + CODE: + RETVAL = (mp_isodd(n) == MP_YES) ? 1 : 0; + OUTPUT: + RETVAL + +############################################################################## +# _is_even() - test for number being even + +int +_is_even(Class, Math::BigInt::LTM n) + CODE: + RETVAL = (mp_iseven(n) == MP_YES || mp_iszero(n) == MP_YES) ? 1 : 0; + OUTPUT: + RETVAL + +############################################################################## +# _sqrt() - square root + +void +_sqrt(Class, Math::BigInt::LTM x) + PPCODE: + mp_sqrt(x, x); + XPUSHs(ST(1)); /* x */ + +############################################################################## +# _root() - integer roots + +void +_root(Class, Math::BigInt::LTM x, Math::BigInt::LTM y) + PPCODE: + mp_n_root(x, mp_get_long(y), x); + XPUSHs(ST(1)); /* x */ + +############################################################################## +# _lcm() - least common multiple +void +_lcm(Class, Math::BigInt::LTM x, Math::BigInt::LTM y) + PPCODE: + mp_lcm(x, y, x) ; + XPUSHs(ST(1)); /* x */ + +############################################################################## +# Storable hooks + +void +STORABLE_thaw(blank_obj, cloning, serialized, ...) + SV *blank_obj + SV *cloning = NO_INIT + SV *serialized + PREINIT: + SV *target; + mp_int *mpi; + PPCODE: + PERL_UNUSED_VAR(cloning); + if (SvROK(blank_obj) && sv_isa(blank_obj, "Math::BigInt::LTM")) { + Newz(0, mpi, 1, mp_int); + mp_init(mpi); + mp_read_radix(mpi, SvPV_nolen(serialized), 10); + target = SvRV(blank_obj); + SvIV_set(target, PTR2IV(mpi)); + SvIOK_on(target); + PUSHs(target); + XSRETURN(1); + } + else + croak("Bad object for Math::BigInt::LTM::STORABLE_thaw call"); + +SV * +STORABLE_freeze(self, cloning = NULL) + Math::BigInt::LTM self + SV *cloning = NO_INIT + PREINIT: + unsigned long len; + char *buf; + CODE: + PERL_UNUSED_VAR(cloning); + if (mp_iszero(self) == MP_YES) { + RETVAL = newSVpv("0", 0); + } + else { + len = mp_count_bits(self) / 3 + 3; /* decimal_size ~ (binary_size/3 + 1) +1 for sign +1 for NUL-byte */ + Newz(0, buf, len, char); + mp_toradix_n(self, buf, 10, len); + RETVAL = newSVpv(buf, 0); + Safefree(buf); + } +OUTPUT: + RETVAL diff --git a/inc/CryptX_Checksum_Adler32.xs.inc b/inc/CryptX_Checksum_Adler32.xs.inc new file mode 100644 index 0000000..5a95e72 --- /dev/null +++ b/inc/CryptX_Checksum_Adler32.xs.inc @@ -0,0 +1,70 @@ +MODULE = CryptX PACKAGE = Crypt::Checksum::Adler32 + +Crypt::Checksum::Adler32 +new(Class) + CODE: + Newz(0, RETVAL, 1, adler32_state); + if (!RETVAL) croak("FATAL: Newz failed"); + adler32_init(RETVAL); + OUTPUT: + RETVAL + +void +DESTROY(Crypt::Checksum::Adler32 self) + CODE: + Safefree(self); + +void +reset(Crypt::Checksum::Adler32 self) + CODE: + adler32_init(self); + +Crypt::Checksum::Adler32 +clone(Crypt::Checksum::Adler32 self) + CODE: + Newz(0, RETVAL, 1, adler32_state); + if (!RETVAL) croak("FATAL: Newz failed"); + Copy(self, RETVAL, 1, adler32_state); + OUTPUT: + RETVAL + +void +add(Crypt::Checksum::Adler32 self, ...) + PPCODE: + { + STRLEN inlen; + int i; + unsigned char *in; + for(i=1; i0) adler32_update(self, in, (unsigned long)inlen); + } + XPUSHs(ST(0)); /* return self */ + } + +SV * +digest(Crypt::Checksum::Adler32 self) + CODE: + { + unsigned char hash[4]; + adler32_finish(self, hash, 4); + RETVAL = newSVpvn((char *) hash, 4); + } + OUTPUT: + RETVAL + +SV * +hexdigest(Crypt::Checksum::Adler32 self) + CODE: + { + unsigned long i; + unsigned char hash[4]; + char hash_hex[4*2 + 1]; + adler32_finish(self, hash, 4); + hash_hex[0] = '\0'; + for(i=0; i<4; i++) sprintf(&hash_hex[2*i], "%02x", hash[i]); + RETVAL = newSVpvn(hash_hex, strlen(hash_hex)); + } + OUTPUT: + RETVAL + diff --git a/inc/CryptX_Checksum_CRC32.xs.inc b/inc/CryptX_Checksum_CRC32.xs.inc new file mode 100644 index 0000000..42e47ea --- /dev/null +++ b/inc/CryptX_Checksum_CRC32.xs.inc @@ -0,0 +1,70 @@ +MODULE = CryptX PACKAGE = Crypt::Checksum::CRC32 + +Crypt::Checksum::CRC32 +new(Class) + CODE: + Newz(0, RETVAL, 1, crc32_state); + if (!RETVAL) croak("FATAL: Newz failed"); + crc32_init(RETVAL); + OUTPUT: + RETVAL + +void +DESTROY(Crypt::Checksum::CRC32 self) + CODE: + Safefree(self); + +void +reset(Crypt::Checksum::CRC32 self) + CODE: + crc32_init(self); + +Crypt::Checksum::CRC32 +clone(Crypt::Checksum::CRC32 self) + CODE: + Newz(0, RETVAL, 1, crc32_state); + if (!RETVAL) croak("FATAL: Newz failed"); + Copy(self, RETVAL, 1, crc32_state); + OUTPUT: + RETVAL + +void +add(Crypt::Checksum::CRC32 self, ...) + PPCODE: + { + STRLEN inlen; + int i; + unsigned char *in; + for(i=1; i0) crc32_update(self, in, (unsigned long)inlen); + } + XPUSHs(ST(0)); /* return self */ + } + +SV * +digest(Crypt::Checksum::CRC32 self) + CODE: + { + unsigned char hash[4]; + crc32_finish(self, hash, 4); + RETVAL = newSVpvn((char *) hash, 4); + } + OUTPUT: + RETVAL + +SV * +hexdigest(Crypt::Checksum::CRC32 self) + CODE: + { + unsigned long i; + unsigned char hash[4]; + char hash_hex[4*2 + 1]; + crc32_finish(self, hash, 4); + hash_hex[0] = '\0'; + for(i=0; i<4; i++) sprintf(&hash_hex[2*i], "%02x", hash[i]); + RETVAL = newSVpvn(hash_hex, strlen(hash_hex)); + } + OUTPUT: + RETVAL + diff --git a/inc/CryptX_Cipher.xs.inc b/inc/CryptX_Cipher.xs.inc new file mode 100644 index 0000000..3f24acf --- /dev/null +++ b/inc/CryptX_Cipher.xs.inc @@ -0,0 +1,188 @@ +MODULE = CryptX PACKAGE = Crypt::Cipher + +Crypt::Cipher +_new(cipher_name, key, rounds=0) + char * cipher_name + SV * key + int rounds + CODE: + { + STRLEN key_len; + unsigned char *key_data=NULL; + int rv; + int id; + + if (!SvPOK (key)) croak("FATAL: key must be string scalar"); + key_data = (unsigned char *)SvPVbyte(key, key_len); + + id = find_cipher(cipher_name); + if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); + + Newz(0, RETVAL, 1, struct cipher_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + + RETVAL->id = id; + RETVAL->desc = &cipher_descriptor[id]; + rv = RETVAL->desc->setup(key_data, (int)key_len, rounds, &RETVAL->skey); + if(rv!=CRYPT_OK) croak("FATAL: cipher setup failed: %s", error_to_string(rv)); + } + OUTPUT: + RETVAL + +void +DESTROY(self) + Crypt::Cipher self + CODE: + Safefree(self); + +int +_max_keysize(self, ...) + Crypt::Cipher self + CODE: + RETVAL = self->desc->max_key_length; + OUTPUT: + RETVAL + +int +_min_keysize(self, ...) + Crypt::Cipher self + CODE: + RETVAL = self->desc->min_key_length; + OUTPUT: + RETVAL + +int +_blocksize(self, ...) + Crypt::Cipher self + CODE: + RETVAL = self->desc->block_length; + OUTPUT: + RETVAL + +int +_default_rounds(self, ...) + Crypt::Cipher self + CODE: + RETVAL = self->desc->default_rounds; + OUTPUT: + RETVAL + +SV * +encrypt(self, data) + Crypt::Cipher self + SV * data + CODE: + { + int rv; + STRLEN len; + void *plaintext = SvPVbyte(data, len); + + if (len==0) + RETVAL = newSVpvn("", 0); + else if (len % self->desc->block_length) + croak ("FATAL: sizeof(data) should be multiple of blocksize (%d)", self->desc->block_length); + else { + /* idea from Crypt::Rijndael */ + RETVAL = NEWSV(0, len); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, len); + rv = self->desc->ecb_encrypt((unsigned char *)plaintext, (unsigned char *)SvPV_nolen(RETVAL), &self->skey); + if (rv!=CRYPT_OK) croak("FATAL: encrypt failed: %s", error_to_string(rv)); + } + } + OUTPUT: + RETVAL + +SV * +decrypt(self, data) + Crypt::Cipher self + SV * data + CODE: + { + int rv; + STRLEN len; + void *ciphertext = SvPVbyte(data, len); + + if (len==0) + RETVAL = newSVpvn("", 0); + else if (len % self->desc->block_length) + croak ("FATAL: sizeof(data) should be multiple of blocksize (%d)", self->desc->block_length); + else { + /* idea from Crypt::Rijndael */ + RETVAL = NEWSV(0, len); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, len); + rv = self->desc->ecb_decrypt((unsigned char *)ciphertext, (unsigned char *)SvPV_nolen(RETVAL), &self->skey); + if (rv!=CRYPT_OK) croak("FATAL: decrypt failed: %s", error_to_string(rv)); + } + } + OUTPUT: + RETVAL + +int +_block_length_by_name(cipher_name) + char * cipher_name + CODE: + { + int rv, id; + + id = find_cipher(cipher_name); + if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); + + rv = cipher_descriptor[id].block_length; + if (!rv) XSRETURN_UNDEF; + RETVAL = rv; + } + OUTPUT: + RETVAL + +int +_min_key_length_by_name(cipher_name) + char * cipher_name + CODE: + { + int rv, id; + + id = find_cipher(cipher_name); + if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); + + rv = cipher_descriptor[id].min_key_length; + if (!rv) XSRETURN_UNDEF; + RETVAL = rv; + } + OUTPUT: + RETVAL + +int +_max_key_length_by_name(cipher_name) + char * cipher_name + CODE: + { + int rv, id; + + id = find_cipher(cipher_name); + if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); + + rv = cipher_descriptor[id].max_key_length; + if (!rv) XSRETURN_UNDEF; + RETVAL = rv; + } + OUTPUT: + RETVAL + +int +_default_rounds_by_name(cipher_name) + char * cipher_name + CODE: + { + int rv, id; + + id = find_cipher(cipher_name); + if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); + + rv = cipher_descriptor[id].default_rounds; + if (!rv) XSRETURN_UNDEF; + RETVAL = rv; + } + OUTPUT: + RETVAL diff --git a/inc/CryptX_Digest.xs.inc b/inc/CryptX_Digest.xs.inc new file mode 100644 index 0000000..26e63ce --- /dev/null +++ b/inc/CryptX_Digest.xs.inc @@ -0,0 +1,169 @@ +MODULE = CryptX PACKAGE = Crypt::Digest + +Crypt::Digest +_new(digest_name) + char * digest_name + CODE: + { + int rv; + int id; + + id = find_hash(digest_name); + if(id==-1) croak("FATAL: find_hash failed for '%s'", digest_name); + + Newz(0, RETVAL, 1, struct digest_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + + RETVAL->id = id; + RETVAL->desc = &hash_descriptor[id]; + rv = RETVAL->desc->init(&RETVAL->state); + if(rv!=CRYPT_OK) croak("FATAL: digest setup failed: %s", error_to_string(rv)); + } + OUTPUT: + RETVAL + +void +DESTROY(self) + Crypt::Digest self + CODE: + Safefree(self); + +void +reset(self) + Crypt::Digest self + CODE: + { + int rv; + rv = self->desc->init(&self->state); + if (rv != CRYPT_OK) croak("FATAL: digest init failed: %s", error_to_string(rv)); + } + +Crypt::Digest +clone(self) + Crypt::Digest self + CODE: + Newz(0, RETVAL, 1, struct digest_struct); + Copy(&self->state, &RETVAL->state, 1, struct digest_struct); + OUTPUT: + RETVAL + +void +add(Crypt::Digest self, ...) + PPCODE: + { + STRLEN inlen; + int rv, i; + unsigned char *in; + + for(i=1; i0) { + rv = self->desc->process(&self->state, in, (unsigned long)inlen); + if (rv != CRYPT_OK) croak("FATAL: digest process failed: %s", error_to_string(rv)); + } + } + XPUSHs(ST(0)); /* return self */ + } + +SV * +digest(self) + Crypt::Digest self + CODE: + { + unsigned char hash[MAXBLOCKSIZE]; + int rv; + + rv = self->desc->done(&self->state, hash); + if (rv != CRYPT_OK) croak("FATAL: digest done failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) hash, self->desc->hashsize); + } + OUTPUT: + RETVAL + +SV * +hexdigest(self) + Crypt::Digest self + CODE: + { + int rv; + unsigned long i; + unsigned char hash[MAXBLOCKSIZE]; + char hash_hex[MAXBLOCKSIZE*2 + 1]; + + rv = self->desc->done(&self->state, hash); + if (rv != CRYPT_OK) croak("FATAL: digest done failed: %s", error_to_string(rv)); + + hash_hex[0] = '\0'; + for(i=0; idesc->hashsize; i++) + sprintf(&hash_hex[2*i], "%02x", hash[i]); + RETVAL = newSVpvn(hash_hex, strlen(hash_hex)); + } + OUTPUT: + RETVAL + +SV * +b64digest(self) + Crypt::Digest self + CODE: + { + int rv; + unsigned long outlen; + unsigned char hash[MAXBLOCKSIZE]; + char hash_base64[MAXBLOCKSIZE*2 + 1]; + + rv = self->desc->done(&self->state, hash); + if (rv != CRYPT_OK) croak("FATAL: digest done failed: %s", error_to_string(rv)); + + outlen = sizeof(hash_base64); + rv = base64_encode(hash, self->desc->hashsize, (unsigned char *)hash_base64, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(hash_base64, outlen); + } + OUTPUT: + RETVAL + +SV * +b64udigest(self) + Crypt::Digest self + CODE: + { + int rv; + unsigned long outlen; + unsigned char hash[MAXBLOCKSIZE]; + char hash_base64[MAXBLOCKSIZE*2 + 1]; + + rv = self->desc->done(&self->state, hash); + if (rv != CRYPT_OK) croak("FATAL: digest done failed: %s", error_to_string(rv)); + + outlen = sizeof(hash_base64); + rv = base64url_encode(hash, self->desc->hashsize, (unsigned char *)hash_base64, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(hash_base64, outlen); + } + OUTPUT: + RETVAL + +int +_hashsize(self) + Crypt::Digest self + CODE: + RETVAL = self->desc->hashsize; + OUTPUT: + RETVAL + +int +_hashsize_by_name(digest_name) + char * digest_name + CODE: + { + int rv, id; + + id = find_hash(digest_name); + if(id==-1) croak("FATAL: find_digest failed for '%s'", digest_name); + + rv = hash_descriptor[id].hashsize; + if (!rv) croak("FATAL: invalid hashsize for '%s'", digest_name);; + RETVAL = rv; + } + OUTPUT: + RETVAL diff --git a/inc/CryptX_Digest_SHAKE.xs.inc b/inc/CryptX_Digest_SHAKE.xs.inc new file mode 100644 index 0000000..aa5335f --- /dev/null +++ b/inc/CryptX_Digest_SHAKE.xs.inc @@ -0,0 +1,74 @@ +MODULE = CryptX PACKAGE = Crypt::Digest::SHAKE + +Crypt::Digest::SHAKE +_new(int num) + CODE: + { + int rv; + + Newz(0, RETVAL, 1, struct digest_shake_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + + RETVAL->num = num; + rv = sha3_shake_init(&RETVAL->state, RETVAL->num); + if (rv != CRYPT_OK) croak("FATAL: sha3_shake_init failed: %s", error_to_string(rv)); + } + OUTPUT: + RETVAL + +void +DESTROY(Crypt::Digest::SHAKE self) + CODE: + Safefree(self); + +void +reset(Crypt::Digest::SHAKE self) + CODE: + { + int rv; + rv = sha3_shake_init(&self->state, self->num); + if (rv != CRYPT_OK) croak("FATAL: sha3_shake_init failed: %s", error_to_string(rv)); + } + +Crypt::Digest::SHAKE +clone(Crypt::Digest::SHAKE self) + CODE: + Newz(0, RETVAL, 1, struct digest_shake_struct); + Copy(&self->state, &RETVAL->state, 1, struct digest_shake_struct); + OUTPUT: + RETVAL + +void +add(Crypt::Digest::SHAKE self, ...) + PPCODE: + { + STRLEN inlen; + int rv, i; + unsigned char *in; + + for(i=1; i0) { + rv = sha3_shake_process(&self->state, in, (unsigned long)inlen); + if (rv != CRYPT_OK) croak("FATAL: sha3_shake_process failed: %s", error_to_string(rv)); + } + } + XPUSHs(ST(0)); /* return self */ + } + +SV * +done(Crypt::Digest::SHAKE self, STRLEN out_len) + CODE: + { + int rv; + unsigned char *out_data; + + RETVAL = NEWSV(0, out_len); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, out_len); + out_data = (unsigned char *)SvPV_nolen(RETVAL); + rv = sha3_shake_done(&self->state, out_data, out_len); + if (rv != CRYPT_OK) croak("FATAL: sha3_shake_done failed: %s", error_to_string(rv)); + } + OUTPUT: + RETVAL diff --git a/inc/CryptX_KeyDerivation.xs.inc b/inc/CryptX_KeyDerivation.xs.inc new file mode 100644 index 0000000..7bc4303 --- /dev/null +++ b/inc/CryptX_KeyDerivation.xs.inc @@ -0,0 +1,181 @@ +MODULE = CryptX PACKAGE = Crypt::KeyDerivation + +SV * +_pkcs_5_alg1(SV * password, SV * salt, int iteration_count, char * hash_name, int len) + CODE: + { + /* + int pkcs_5_alg1(const unsigned char *password, unsigned long password_len, + const unsigned char *salt, + int iteration_count, int hash_idx, + unsigned char *out, unsigned long *outlen) + */ + int rv, id; + unsigned long output_len; + unsigned char *output; + unsigned char *password_ptr=NULL; + STRLEN password_len=0; + unsigned char *salt_ptr=NULL; + STRLEN salt_len=0; + + id = find_hash(hash_name); + if(id==-1) croak("FATAL: find_hash failed for '%s'", hash_name); + + password_ptr = (unsigned char *)SvPVbyte(password, password_len); + salt_ptr = (unsigned char *)SvPVbyte(salt, salt_len); + if (salt_len < 8) croak("FATAL: salt_len has to be 8"); + + output_len = len; + Newz(0, output, output_len, unsigned char); + if (!output) croak("FATAL: Newz failed [%ld]", output_len); + + rv = pkcs_5_alg1(password_ptr, (unsigned long)password_len, salt_ptr, iteration_count, id, output, &output_len); + if (rv != CRYPT_OK) croak("FATAL: pkcs_5_alg1 process failed: %s", error_to_string(rv)); + + RETVAL = newSVpvn((char *)output, output_len); + Safefree(output); + } + OUTPUT: + RETVAL + +SV * +_pkcs_5_alg2(SV * password, SV * salt, int iteration_count, char * hash_name, int len) + CODE: + { + /* + int pkcs_5_alg2(const unsigned char *password, unsigned long password_len, + const unsigned char *salt, unsigned long salt_len, + int iteration_count, int hash_idx, + unsigned char *out, unsigned long *outlen) + */ + int rv, id; + unsigned long output_len; + unsigned char *output; + unsigned char *password_ptr=NULL; + STRLEN password_len=0; + unsigned char *salt_ptr=NULL; + STRLEN salt_len=0; + + id = find_hash(hash_name); + if(id==-1) croak("FATAL: find_hash failed for '%s'", hash_name); + + password_ptr = (unsigned char *)SvPVbyte(password, password_len); + salt_ptr = (unsigned char *)SvPVbyte(salt, salt_len); + + output_len = len; + Newz(0, output, output_len, unsigned char); + if (!output) croak("FATAL: Newz failed [%ld]", output_len); + + rv = pkcs_5_alg2(password_ptr, (unsigned long)password_len, salt_ptr, (unsigned long)salt_len, iteration_count, id, output, &output_len); + if (rv != CRYPT_OK) croak("FATAL: pkcs_5_alg2 process failed: %s", error_to_string(rv)); + + RETVAL = newSVpvn((char *)output, output_len); + Safefree(output); + } + OUTPUT: + RETVAL + +SV * +_hkdf_extract(char * hash_name, SV * salt, SV * in) + CODE: + { + /* + int hkdf_extract(int hash_idx, const unsigned char *salt, unsigned long saltlen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) + */ + int rv, id; + unsigned char output[MAXBLOCKSIZE]; + unsigned long output_len; + unsigned char *in_ptr=NULL; + STRLEN in_len=0; + unsigned char *salt_ptr=NULL; + STRLEN salt_len=0; + + id = find_hash(hash_name); + if(id==-1) croak("FATAL: find_hash failed for '%s'", hash_name); + + in_ptr = (unsigned char *)SvPVbyte(in, in_len); + salt_ptr = (unsigned char *)SvPVbyte(salt, salt_len); + + output_len = sizeof(output); + rv = hkdf_extract(id, salt_ptr, (unsigned long)salt_len, in_ptr, (unsigned long)in_len, output, &output_len); + if (rv != CRYPT_OK) croak("FATAL: hkdf_extract process failed: %s", error_to_string(rv)); + + RETVAL = newSVpvn((char *)output, output_len); + } + OUTPUT: + RETVAL + +SV * +_hkdf_expand(char * hash_name, SV * info, SV * in, unsigned long output_len) + CODE: + { + /* + int hkdf_expand(int hash_idx, const unsigned char *info, unsigned long infolen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long outlen) + */ + int rv, id; + unsigned char *output; + unsigned char *in_ptr=NULL; + STRLEN in_len=0; + unsigned char *info_ptr=NULL; + STRLEN info_len=0; + + id = find_hash(hash_name); + if(id==-1) croak("FATAL: find_hash failed for '%s'", hash_name); + + in_ptr = (unsigned char *)SvPVbyte(in, in_len); + info_ptr = (unsigned char *)SvPVbyte(info, info_len); + + Newz(0, output, output_len, unsigned char); + if (!output) croak("FATAL: Newz failed [%ld]", output_len); + + rv = hkdf_expand(id, info_ptr, (unsigned long)info_len, in_ptr, (unsigned long)in_len, output, output_len); + if (rv != CRYPT_OK) croak("FATAL: hkdf_expand process failed: %s", error_to_string(rv)); + + RETVAL = newSVpvn((char *)output, output_len); + Safefree(output); + } + OUTPUT: + RETVAL + +SV * +_hkdf(char * hash_name, SV * salt, SV * info, SV * in, unsigned long output_len) + CODE: + { + /* + int hkdf(int hash_idx, const unsigned char *salt, unsigned long saltlen, + const unsigned char *info, unsigned long infolen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long outlen) + */ + int rv, id; + unsigned char *output; + unsigned char *in_ptr=NULL; + STRLEN in_len=0; + unsigned char *info_ptr=NULL; + STRLEN info_len=0; + unsigned char *salt_ptr=NULL; + STRLEN salt_len=0; + + id = find_hash(hash_name); + if(id==-1) croak("FATAL: find_hash failed for '%s'", hash_name); + + in_ptr = (unsigned char *)SvPVbyte(in, in_len); + info_ptr = (unsigned char *)SvPVbyte(info, info_len); + salt_ptr = (unsigned char *)SvPVbyte(salt, salt_len); + + Newz(0, output, output_len, unsigned char); + if (!output) croak("FATAL: Newz failed [%ld]", output_len); + + rv = hkdf(id, salt_ptr, (unsigned long)salt_len, info_ptr, (unsigned long)info_len, in_ptr, (unsigned long)in_len, output, output_len); + if (rv != CRYPT_OK) croak("FATAL: hkdf_expand process failed: %s", error_to_string(rv)); + + RETVAL = newSVpvn((char *)output, output_len); + Safefree(output); + } + OUTPUT: + RETVAL + diff --git a/inc/CryptX_Mac_BLAKE2b.xs.inc b/inc/CryptX_Mac_BLAKE2b.xs.inc new file mode 100644 index 0000000..298c2a9 --- /dev/null +++ b/inc/CryptX_Mac_BLAKE2b.xs.inc @@ -0,0 +1,130 @@ +MODULE = CryptX PACKAGE = Crypt::Mac::BLAKE2b + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +Crypt::Mac::BLAKE2b +_new(int size, SV * key) + CODE: + { + STRLEN k_len=0; + unsigned char *k=NULL; + int rv; + + if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); + k = (unsigned char *) SvPVbyte(key, k_len); + + Newz(0, RETVAL, 1, struct blake2b_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + + rv = blake2bmac_init(&RETVAL->state, size, k, (unsigned long)k_len); + if (rv != CRYPT_OK) croak("FATAL: blake2b_init failed: %s", error_to_string(rv)); + } + OUTPUT: + RETVAL + +void +DESTROY(Crypt::Mac::BLAKE2b self) + CODE: + Safefree(self); + +Crypt::Mac::BLAKE2b +clone(Crypt::Mac::BLAKE2b self) + CODE: + Newz(0, RETVAL, 1, struct blake2b_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + Copy(&self->state, &RETVAL->state, 1, struct blake2b_struct); + OUTPUT: + RETVAL + +void +_add_single(Crypt::Mac::BLAKE2b self, SV * data) + CODE: + { + int rv; + STRLEN in_data_len; + unsigned char *in_data; + + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + if (in_data_len>0) { + rv = blake2bmac_process(&self->state, in_data, (unsigned long)in_data_len); + if (rv != CRYPT_OK) croak("FATAL: blake2b_process failed: %s", error_to_string(rv)); + } + } + +SV * +mac(Crypt::Mac::BLAKE2b self) + CODE: + { + char mac[MAXBLOCKSIZE]; + unsigned long mac_len; + int rv; + + mac_len = sizeof(mac); + rv = blake2bmac_done(&self->state, (unsigned char*)mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: blake2bmac_done failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(mac, mac_len); + } + OUTPUT: + RETVAL + +SV * +b64mac(Crypt::Mac::BLAKE2b self) + CODE: + { + unsigned char mac[MAXBLOCKSIZE]; + unsigned long mac_len; + int rv; + unsigned long outlen; + char mac_base64[MAXBLOCKSIZE*2 + 1]; + + mac_len = sizeof(mac); + rv = blake2bmac_done(&self->state, mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: blake2bmac_done failed: %s", error_to_string(rv)); + outlen = sizeof(mac_base64); + rv = base64_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(mac_base64, outlen); + } + OUTPUT: + RETVAL + +SV * +b64umac(Crypt::Mac::BLAKE2b self) + CODE: + { + unsigned char mac[MAXBLOCKSIZE]; + unsigned long mac_len; + int rv; + unsigned long outlen; + char mac_base64[MAXBLOCKSIZE*2 + 1]; + + mac_len = sizeof(mac); + rv = blake2bmac_done(&self->state, mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: blake2bmac_done failed: %s", error_to_string(rv)); + outlen = sizeof(mac_base64); + rv = base64url_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(mac_base64, outlen); + } + OUTPUT: + RETVAL + +SV * +hexmac(Crypt::Mac::BLAKE2b self) + CODE: + { + unsigned char mac[MAXBLOCKSIZE]; + unsigned long mac_len, i; + int rv; + char mac_hex[MAXBLOCKSIZE*2 + 1]; + + mac_len = sizeof(mac); + rv = blake2bmac_done(&self->state, mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: blake2bmac_done failed: %s", error_to_string(rv)); + mac_hex[0] = '\0'; + for(i=0; istate, size, k, (unsigned long)k_len); + if (rv != CRYPT_OK) croak("FATAL: blake2s_init failed: %s", error_to_string(rv)); + } + OUTPUT: + RETVAL + +void +DESTROY(Crypt::Mac::BLAKE2s self) + CODE: + Safefree(self); + +Crypt::Mac::BLAKE2s +clone(Crypt::Mac::BLAKE2s self) + CODE: + Newz(0, RETVAL, 1, struct blake2s_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + Copy(&self->state, &RETVAL->state, 1, struct blake2s_struct); + OUTPUT: + RETVAL + +void +_add_single(Crypt::Mac::BLAKE2s self, SV * data) + CODE: + { + int rv; + STRLEN in_data_len; + unsigned char *in_data; + + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + if (in_data_len>0) { + rv = blake2smac_process(&self->state, in_data, (unsigned long)in_data_len); + if (rv != CRYPT_OK) croak("FATAL: blake2s_process failed: %s", error_to_string(rv)); + } + } + +SV * +mac(Crypt::Mac::BLAKE2s self) + CODE: + { + char mac[MAXBLOCKSIZE]; + unsigned long mac_len; + int rv; + + mac_len = sizeof(mac); + rv = blake2smac_done(&self->state, (unsigned char*)mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: blake2smac_done failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(mac, mac_len); + } + OUTPUT: + RETVAL + +SV * +b64mac(Crypt::Mac::BLAKE2s self) + CODE: + { + unsigned char mac[MAXBLOCKSIZE]; + unsigned long mac_len; + int rv; + unsigned long outlen; + char mac_base64[MAXBLOCKSIZE*2 + 1]; + + mac_len = sizeof(mac); + rv = blake2smac_done(&self->state, mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: blake2smac_done failed: %s", error_to_string(rv)); + outlen = sizeof(mac_base64); + rv = base64_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(mac_base64, outlen); + } + OUTPUT: + RETVAL + +SV * +b64umac(Crypt::Mac::BLAKE2s self) + CODE: + { + unsigned char mac[MAXBLOCKSIZE]; + unsigned long mac_len; + int rv; + unsigned long outlen; + char mac_base64[MAXBLOCKSIZE*2 + 1]; + + mac_len = sizeof(mac); + rv = blake2smac_done(&self->state, mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: blake2smac_done failed: %s", error_to_string(rv)); + outlen = sizeof(mac_base64); + rv = base64url_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(mac_base64, outlen); + } + OUTPUT: + RETVAL + +SV * +hexmac(Crypt::Mac::BLAKE2s self) + CODE: + { + unsigned char mac[MAXBLOCKSIZE]; + unsigned long mac_len, i; + int rv; + char mac_hex[MAXBLOCKSIZE*2 + 1]; + + mac_len = sizeof(mac); + rv = blake2smac_done(&self->state, mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: blake2smac_done failed: %s", error_to_string(rv)); + mac_hex[0] = '\0'; + for(i=0; istate, id, k, (unsigned long)k_len); + if (rv != CRYPT_OK) croak("FATAL: f9_init failed: %s", error_to_string(rv)); + } + OUTPUT: + RETVAL + +void +DESTROY(Crypt::Mac::F9 self) + CODE: + Safefree(self); + +Crypt::Mac::F9 +clone(Crypt::Mac::F9 self) + CODE: + Newz(0, RETVAL, 1, struct f9_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + Copy(&self->state, &RETVAL->state, 1, struct f9_struct); + OUTPUT: + RETVAL + +void +_add_single(Crypt::Mac::F9 self, SV * data) + CODE: + { + int rv; + STRLEN in_data_len; + unsigned char *in_data; + + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + if (in_data_len>0) { + rv = f9_process(&self->state, in_data, (unsigned long)in_data_len); + if (rv != CRYPT_OK) croak("FATAL: f9_process failed: %s", error_to_string(rv)); + } + } + +SV * +mac(Crypt::Mac::F9 self) + CODE: + { + char mac[MAXBLOCKSIZE]; + unsigned long mac_len; + int rv; + + mac_len = sizeof(mac); + rv = f9_done(&self->state, (unsigned char*)mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: f9_done failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(mac, mac_len); + } + OUTPUT: + RETVAL + +SV * +b64mac(Crypt::Mac::F9 self) + CODE: + { + unsigned char mac[MAXBLOCKSIZE]; + unsigned long mac_len; + int rv; + unsigned long outlen; + char mac_base64[MAXBLOCKSIZE*2 + 1]; + + mac_len = sizeof(mac); + rv = f9_done(&self->state, mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: f9_done failed: %s", error_to_string(rv)); + outlen = sizeof(mac_base64); + rv = base64_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(mac_base64, outlen); + } + OUTPUT: + RETVAL + +SV * +b64umac(Crypt::Mac::F9 self) + CODE: + { + unsigned char mac[MAXBLOCKSIZE]; + unsigned long mac_len; + int rv; + unsigned long outlen; + char mac_base64[MAXBLOCKSIZE*2 + 1]; + + mac_len = sizeof(mac); + rv = f9_done(&self->state, mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: f9_done failed: %s", error_to_string(rv)); + outlen = sizeof(mac_base64); + rv = base64url_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(mac_base64, outlen); + } + OUTPUT: + RETVAL + +SV * +hexmac(Crypt::Mac::F9 self) + CODE: + { + unsigned char mac[MAXBLOCKSIZE]; + unsigned long mac_len, i; + int rv; + char mac_hex[MAXBLOCKSIZE*2 + 1]; + + mac_len = sizeof(mac); + rv = f9_done(&self->state, mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: f9_done failed: %s", error_to_string(rv)); + mac_hex[0] = '\0'; + for(i=0; istate, id, k, (unsigned long)k_len); + if (rv != CRYPT_OK) croak("FATAL: hmac_init failed: %s", error_to_string(rv)); + } + OUTPUT: + RETVAL + +void +DESTROY(Crypt::Mac::HMAC self) + CODE: + Safefree(self); + +Crypt::Mac::HMAC +clone(Crypt::Mac::HMAC self) + CODE: + Newz(0, RETVAL, 1, struct hmac_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + Copy(&self->state, &RETVAL->state, 1, struct hmac_struct); + OUTPUT: + RETVAL + +void +_add_single(Crypt::Mac::HMAC self, SV * data) + CODE: + { + int rv; + STRLEN in_data_len; + unsigned char *in_data; + + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + if (in_data_len>0) { + rv = hmac_process(&self->state, in_data, (unsigned long)in_data_len); + if (rv != CRYPT_OK) croak("FATAL: hmac_process failed: %s", error_to_string(rv)); + } + } + +SV * +mac(Crypt::Mac::HMAC self) + CODE: + { + char mac[MAXBLOCKSIZE]; + unsigned long mac_len; + int rv; + + mac_len = sizeof(mac); + rv = hmac_done(&self->state, (unsigned char*)mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: hmac_done failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(mac, mac_len); + } + OUTPUT: + RETVAL + +SV * +b64mac(Crypt::Mac::HMAC self) + CODE: + { + unsigned char mac[MAXBLOCKSIZE]; + unsigned long mac_len; + int rv; + unsigned long outlen; + char mac_base64[MAXBLOCKSIZE*2 + 1]; + + mac_len = sizeof(mac); + rv = hmac_done(&self->state, mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: hmac_done failed: %s", error_to_string(rv)); + outlen = sizeof(mac_base64); + rv = base64_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(mac_base64, outlen); + } + OUTPUT: + RETVAL + +SV * +b64umac(Crypt::Mac::HMAC self) + CODE: + { + unsigned char mac[MAXBLOCKSIZE]; + unsigned long mac_len; + int rv; + unsigned long outlen; + char mac_base64[MAXBLOCKSIZE*2 + 1]; + + mac_len = sizeof(mac); + rv = hmac_done(&self->state, mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: hmac_done failed: %s", error_to_string(rv)); + outlen = sizeof(mac_base64); + rv = base64url_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(mac_base64, outlen); + } + OUTPUT: + RETVAL + +SV * +hexmac(Crypt::Mac::HMAC self) + CODE: + { + unsigned char mac[MAXBLOCKSIZE]; + unsigned long mac_len, i; + int rv; + char mac_hex[MAXBLOCKSIZE*2 + 1]; + + mac_len = sizeof(mac); + rv = hmac_done(&self->state, mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: hmac_done failed: %s", error_to_string(rv)); + mac_hex[0] = '\0'; + for(i=0; istate, id, k, (unsigned long)k_len); + if (rv != CRYPT_OK) croak("FATAL: omac_init failed: %s", error_to_string(rv)); + } + OUTPUT: + RETVAL + +void +DESTROY(Crypt::Mac::OMAC self) + CODE: + Safefree(self); + +Crypt::Mac::OMAC +clone(Crypt::Mac::OMAC self) + CODE: + Newz(0, RETVAL, 1, struct omac_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + Copy(&self->state, &RETVAL->state, 1, struct omac_struct); + OUTPUT: + RETVAL + +void +_add_single(Crypt::Mac::OMAC self, SV * data) + CODE: + { + int rv; + STRLEN in_data_len; + unsigned char *in_data; + + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + if (in_data_len>0) { + rv = omac_process(&self->state, in_data, (unsigned long)in_data_len); + if (rv != CRYPT_OK) croak("FATAL: omac_process failed: %s", error_to_string(rv)); + } + } + +SV * +mac(Crypt::Mac::OMAC self) + CODE: + { + char mac[MAXBLOCKSIZE]; + unsigned long mac_len; + int rv; + + mac_len = sizeof(mac); + rv = omac_done(&self->state, (unsigned char*)mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: omac_done failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(mac, mac_len); + } + OUTPUT: + RETVAL + +SV * +b64mac(Crypt::Mac::OMAC self) + CODE: + { + unsigned char mac[MAXBLOCKSIZE]; + unsigned long mac_len; + int rv; + unsigned long outlen; + char mac_base64[MAXBLOCKSIZE*2 + 1]; + + mac_len = sizeof(mac); + rv = omac_done(&self->state, mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: omac_done failed: %s", error_to_string(rv)); + outlen = sizeof(mac_base64); + rv = base64_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(mac_base64, outlen); + } + OUTPUT: + RETVAL + +SV * +b64umac(Crypt::Mac::OMAC self) + CODE: + { + unsigned char mac[MAXBLOCKSIZE]; + unsigned long mac_len; + int rv; + unsigned long outlen; + char mac_base64[MAXBLOCKSIZE*2 + 1]; + + mac_len = sizeof(mac); + rv = omac_done(&self->state, mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: omac_done failed: %s", error_to_string(rv)); + outlen = sizeof(mac_base64); + rv = base64url_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(mac_base64, outlen); + } + OUTPUT: + RETVAL + +SV * +hexmac(Crypt::Mac::OMAC self) + CODE: + { + unsigned char mac[MAXBLOCKSIZE]; + unsigned long mac_len, i; + int rv; + char mac_hex[MAXBLOCKSIZE*2 + 1]; + + mac_len = sizeof(mac); + rv = omac_done(&self->state, mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: omac_done failed: %s", error_to_string(rv)); + mac_hex[0] = '\0'; + for(i=0; istate, id, k, (unsigned long)k_len); + if (rv != CRYPT_OK) croak("FATAL: pmac_init failed: %s", error_to_string(rv)); + } + OUTPUT: + RETVAL + +void +DESTROY(Crypt::Mac::PMAC self) + CODE: + Safefree(self); + +Crypt::Mac::PMAC +clone(Crypt::Mac::PMAC self) + CODE: + Newz(0, RETVAL, 1, struct pmac_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + Copy(&self->state, &RETVAL->state, 1, struct pmac_struct); + OUTPUT: + RETVAL + +void +_add_single(Crypt::Mac::PMAC self, SV * data) + CODE: + { + int rv; + STRLEN in_data_len; + unsigned char *in_data; + + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + if (in_data_len>0) { + rv = pmac_process(&self->state, in_data, (unsigned long)in_data_len); + if (rv != CRYPT_OK) croak("FATAL: pmac_process failed: %s", error_to_string(rv)); + } + } + +SV * +mac(Crypt::Mac::PMAC self) + CODE: + { + char mac[MAXBLOCKSIZE]; + unsigned long mac_len; + int rv; + + mac_len = sizeof(mac); + rv = pmac_done(&self->state, (unsigned char*)mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: pmac_done failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(mac, mac_len); + } + OUTPUT: + RETVAL + +SV * +b64mac(Crypt::Mac::PMAC self) + CODE: + { + unsigned char mac[MAXBLOCKSIZE]; + unsigned long mac_len; + int rv; + unsigned long outlen; + char mac_base64[MAXBLOCKSIZE*2 + 1]; + + mac_len = sizeof(mac); + rv = pmac_done(&self->state, mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: pmac_done failed: %s", error_to_string(rv)); + outlen = sizeof(mac_base64); + rv = base64_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(mac_base64, outlen); + } + OUTPUT: + RETVAL + +SV * +b64umac(Crypt::Mac::PMAC self) + CODE: + { + unsigned char mac[MAXBLOCKSIZE]; + unsigned long mac_len; + int rv; + unsigned long outlen; + char mac_base64[MAXBLOCKSIZE*2 + 1]; + + mac_len = sizeof(mac); + rv = pmac_done(&self->state, mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: pmac_done failed: %s", error_to_string(rv)); + outlen = sizeof(mac_base64); + rv = base64url_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(mac_base64, outlen); + } + OUTPUT: + RETVAL + +SV * +hexmac(Crypt::Mac::PMAC self) + CODE: + { + unsigned char mac[MAXBLOCKSIZE]; + unsigned long mac_len, i; + int rv; + char mac_hex[MAXBLOCKSIZE*2 + 1]; + + mac_len = sizeof(mac); + rv = pmac_done(&self->state, mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: pmac_done failed: %s", error_to_string(rv)); + mac_hex[0] = '\0'; + for(i=0; istate, k, (unsigned long)k_len); + if (rv != CRYPT_OK) croak("FATAL: pelican_init failed: %s", error_to_string(rv)); + } + OUTPUT: + RETVAL + +void +DESTROY(Crypt::Mac::Pelican self) + CODE: + Safefree(self); + +Crypt::Mac::Pelican +clone(Crypt::Mac::Pelican self) + CODE: + Newz(0, RETVAL, 1, struct pelican_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + Copy(&self->state, &RETVAL->state, 1, struct pelican_struct); + OUTPUT: + RETVAL + +void +_add_single(Crypt::Mac::Pelican self, SV * data) + CODE: + { + int rv; + STRLEN in_data_len; + unsigned char *in_data; + + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + if (in_data_len>0) { + rv = pelican_process(&self->state, in_data, (unsigned long)in_data_len); + if (rv != CRYPT_OK) croak("FATAL: pelican_process failed: %s", error_to_string(rv)); + } + } + +SV * +mac(Crypt::Mac::Pelican self) + CODE: + { + char mac[MAXBLOCKSIZE]; + unsigned long mac_len; + int rv; + + mac_len = 16; + rv = pelican_done(&self->state, (unsigned char*)mac); + if (rv != CRYPT_OK) croak("FATAL: pelican_done failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(mac, mac_len); + } + OUTPUT: + RETVAL + +SV * +b64mac(Crypt::Mac::Pelican self) + CODE: + { + unsigned char mac[MAXBLOCKSIZE]; + unsigned long mac_len; + int rv; + unsigned long outlen; + char mac_base64[MAXBLOCKSIZE*2 + 1]; + + mac_len = 16; + rv = pelican_done(&self->state, mac); + if (rv != CRYPT_OK) croak("FATAL: pelican_done failed: %s", error_to_string(rv)); + outlen = sizeof(mac_base64); + rv = base64_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(mac_base64, outlen); + } + OUTPUT: + RETVAL + +SV * +b64umac(Crypt::Mac::Pelican self) + CODE: + { + unsigned char mac[MAXBLOCKSIZE]; + unsigned long mac_len; + int rv; + unsigned long outlen; + char mac_base64[MAXBLOCKSIZE*2 + 1]; + + mac_len = 16; + rv = pelican_done(&self->state, mac); + if (rv != CRYPT_OK) croak("FATAL: pelican_done failed: %s", error_to_string(rv)); + outlen = sizeof(mac_base64); + rv = base64url_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(mac_base64, outlen); + } + OUTPUT: + RETVAL + +SV * +hexmac(Crypt::Mac::Pelican self) + CODE: + { + unsigned char mac[MAXBLOCKSIZE]; + unsigned long mac_len, i; + int rv; + char mac_hex[MAXBLOCKSIZE*2 + 1]; + + mac_len = 16; + rv = pelican_done(&self->state, mac); + if (rv != CRYPT_OK) croak("FATAL: pelican_done failed: %s", error_to_string(rv)); + mac_hex[0] = '\0'; + for(i=0; istate, k, (unsigned long)k_len); + if (rv != CRYPT_OK) croak("FATAL: poly1305_init failed: %s", error_to_string(rv)); + } + OUTPUT: + RETVAL + +void +DESTROY(Crypt::Mac::Poly1305 self) + CODE: + Safefree(self); + +Crypt::Mac::Poly1305 +clone(Crypt::Mac::Poly1305 self) + CODE: + Newz(0, RETVAL, 1, struct poly1305_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + Copy(&self->state, &RETVAL->state, 1, struct poly1305_struct); + OUTPUT: + RETVAL + +void +_add_single(Crypt::Mac::Poly1305 self, SV * data) + CODE: + { + int rv; + STRLEN in_data_len; + unsigned char *in_data; + + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + if (in_data_len>0) { + rv = poly1305_process(&self->state, in_data, (unsigned long)in_data_len); + if (rv != CRYPT_OK) croak("FATAL: poly1305_process failed: %s", error_to_string(rv)); + } + } + +SV * +mac(Crypt::Mac::Poly1305 self) + CODE: + { + char mac[MAXBLOCKSIZE]; + unsigned long mac_len; + int rv; + + mac_len = sizeof(mac); + rv = poly1305_done(&self->state, (unsigned char*)mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: poly1305_done failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(mac, mac_len); + } + OUTPUT: + RETVAL + +SV * +b64mac(Crypt::Mac::Poly1305 self) + CODE: + { + unsigned char mac[MAXBLOCKSIZE]; + unsigned long mac_len; + int rv; + unsigned long outlen; + char mac_base64[MAXBLOCKSIZE*2 + 1]; + + mac_len = sizeof(mac); + rv = poly1305_done(&self->state, mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: poly1305_done failed: %s", error_to_string(rv)); + outlen = sizeof(mac_base64); + rv = base64_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(mac_base64, outlen); + } + OUTPUT: + RETVAL + +SV * +b64umac(Crypt::Mac::Poly1305 self) + CODE: + { + unsigned char mac[MAXBLOCKSIZE]; + unsigned long mac_len; + int rv; + unsigned long outlen; + char mac_base64[MAXBLOCKSIZE*2 + 1]; + + mac_len = sizeof(mac); + rv = poly1305_done(&self->state, mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: poly1305_done failed: %s", error_to_string(rv)); + outlen = sizeof(mac_base64); + rv = base64url_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(mac_base64, outlen); + } + OUTPUT: + RETVAL + +SV * +hexmac(Crypt::Mac::Poly1305 self) + CODE: + { + unsigned char mac[MAXBLOCKSIZE]; + unsigned long mac_len, i; + int rv; + char mac_hex[MAXBLOCKSIZE*2 + 1]; + + mac_len = sizeof(mac); + rv = poly1305_done(&self->state, mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: poly1305_done failed: %s", error_to_string(rv)); + mac_hex[0] = '\0'; + for(i=0; istate, id, k, (unsigned long)k_len); + if (rv != CRYPT_OK) croak("FATAL: xcbc_init failed: %s", error_to_string(rv)); + } + OUTPUT: + RETVAL + +void +DESTROY(Crypt::Mac::XCBC self) + CODE: + Safefree(self); + +Crypt::Mac::XCBC +clone(Crypt::Mac::XCBC self) + CODE: + Newz(0, RETVAL, 1, struct xcbc_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + Copy(&self->state, &RETVAL->state, 1, struct xcbc_struct); + OUTPUT: + RETVAL + +void +_add_single(Crypt::Mac::XCBC self, SV * data) + CODE: + { + int rv; + STRLEN in_data_len; + unsigned char *in_data; + + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + if (in_data_len>0) { + rv = xcbc_process(&self->state, in_data, (unsigned long)in_data_len); + if (rv != CRYPT_OK) croak("FATAL: xcbc_process failed: %s", error_to_string(rv)); + } + } + +SV * +mac(Crypt::Mac::XCBC self) + CODE: + { + char mac[MAXBLOCKSIZE]; + unsigned long mac_len; + int rv; + + mac_len = sizeof(mac); + rv = xcbc_done(&self->state, (unsigned char*)mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: xcbc_done failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(mac, mac_len); + } + OUTPUT: + RETVAL + +SV * +b64mac(Crypt::Mac::XCBC self) + CODE: + { + unsigned char mac[MAXBLOCKSIZE]; + unsigned long mac_len; + int rv; + unsigned long outlen; + char mac_base64[MAXBLOCKSIZE*2 + 1]; + + mac_len = sizeof(mac); + rv = xcbc_done(&self->state, mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: xcbc_done failed: %s", error_to_string(rv)); + outlen = sizeof(mac_base64); + rv = base64_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(mac_base64, outlen); + } + OUTPUT: + RETVAL + +SV * +b64umac(Crypt::Mac::XCBC self) + CODE: + { + unsigned char mac[MAXBLOCKSIZE]; + unsigned long mac_len; + int rv; + unsigned long outlen; + char mac_base64[MAXBLOCKSIZE*2 + 1]; + + mac_len = sizeof(mac); + rv = xcbc_done(&self->state, mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: xcbc_done failed: %s", error_to_string(rv)); + outlen = sizeof(mac_base64); + rv = base64url_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(mac_base64, outlen); + } + OUTPUT: + RETVAL + +SV * +hexmac(Crypt::Mac::XCBC self) + CODE: + { + unsigned char mac[MAXBLOCKSIZE]; + unsigned long mac_len, i; + int rv; + char mac_hex[MAXBLOCKSIZE*2 + 1]; + + mac_len = sizeof(mac); + rv = xcbc_done(&self->state, mac, &mac_len); + if (rv != CRYPT_OK) croak("FATAL: xcbc_done failed: %s", error_to_string(rv)); + mac_hex[0] = '\0'; + for(i=0; ipadding_mode = padding; + RETVAL->padlen = 0; + RETVAL->direction = 0; + RETVAL->cipher_rounds = rounds; + RETVAL->cipher_id = find_cipher(cipher_name); + if(RETVAL->cipher_id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); + } + OUTPUT: + RETVAL + +void +DESTROY(Crypt::Mode::CBC self) + CODE: + Safefree(self); + +int +_get_dir(Crypt::Mode::CBC self) + CODE: + RETVAL = self->direction; + OUTPUT: + RETVAL + +void +_start(Crypt::Mode::CBC self, int dir, SV * key, SV * iv) + CODE: + { + int rv; + STRLEN k_len=0; + unsigned char *k=NULL; + STRLEN i_len=0; + unsigned char *i=NULL; + + if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); + k = (unsigned char *) SvPVbyte(key, k_len); + + if (!SvPOK(iv)) croak("FATAL: iv must be string/buffer scalar"); + i = (unsigned char *) SvPVbyte(iv, i_len); + if (i_len != (STRLEN)cipher_descriptor[self->cipher_id].block_length) { + croak ("FATAL: sizeof(iv) should be equal to blocksize (%d)", cipher_descriptor[self->cipher_id].block_length); + } + rv = cbc_start(self->cipher_id, i, k, (unsigned long)k_len, self->cipher_rounds, &self->state); + if (rv != CRYPT_OK) { + croak("FATAL: cbc_start failed: %s", error_to_string(rv)); + } + + self->direction = dir; + self->padlen = 0; + } + +SV * +_encrypt(Crypt::Mode::CBC self, SV * data) + CODE: + { + int rv, has_tmp_block, blen; + unsigned long i; + + STRLEN in_data_len, in_data_start; + unsigned char *in_data, *out_data, tmp_block[MAXBLOCKSIZE]; + + if (self->direction != 1) croak("FATAL: encrypt error, call start_encrypt first (%d)", self->direction); + + blen = (&self->state)->blocklen; + in_data_start = 0; + has_tmp_block = 0; + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + if (in_data_len==0) { + RETVAL = newSVpvn("", 0); + } + else { + if(self->padlen > 0) { + i = (blen - self->padlen); + if (in_data_len >= i) { /* enough data to fill pad */ + Copy(in_data, self->pad+self->padlen, i, unsigned char); + in_data_len -= i; + in_data_start = i; + rv = cbc_encrypt(self->pad, tmp_block, blen, &self->state); + if (rv != CRYPT_OK) croak("FATAL: cbc_encrypt failed: %s", error_to_string(rv)); + self->padlen = 0; + has_tmp_block = 1; + } + else { /* not enough data to fill pad */ + Copy(in_data, self->pad+self->padlen, in_data_len, unsigned char); + self->padlen += (int)in_data_len; + in_data_len = 0; + } + } /* padlen > 0 */ + + i = (unsigned long)(in_data_len % blen); + if (in_data_len>0 && i>0) { /* save tail of data into pad */ + Copy(in_data+in_data_start+in_data_len-i, self->pad, i, unsigned char); + self->padlen = i; + in_data_len -= i; + } + + if (in_data_len>0) { + i = (unsigned long)(has_tmp_block ? in_data_len + blen : in_data_len); + RETVAL = NEWSV(0, i); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, i); + out_data = (unsigned char *)SvPV_nolen(RETVAL); + + if (has_tmp_block) { + Copy(tmp_block, out_data, blen, unsigned char); + out_data += blen; + } + rv = cbc_encrypt(in_data+in_data_start, out_data, (unsigned long)in_data_len, &self->state); + if (rv != CRYPT_OK) croak("FATAL: cbc_encrypt failed: %s", error_to_string(rv)); + } /* in_data_len>0 */ + else if (has_tmp_block) { + RETVAL = newSVpvn((char*)tmp_block, blen); + } + else { + RETVAL = newSVpvn("", 0); + } + } + } + OUTPUT: + RETVAL + +SV * +_finish_enc(Crypt::Mode::CBC self) + CODE: + { + unsigned char tmp_block[MAXBLOCKSIZE]; + int rv, blen, i, j; + + blen = (&self->state)->blocklen; + if (self->padlen<0 || self->padlen>=blen) croak("FATAL: invalid padlen"); + + if(self->padding_mode == 1) { /* pkcs5|7 padding */ + i = blen - self->padlen; + if (i == 0) i = blen; + for(j=self->padlen; jpad[j] = (unsigned char)i; + rv = cbc_encrypt(self->pad, tmp_block, blen, &self->state); + if (rv != CRYPT_OK) croak("FATAL: cbc_encrypt failed: %s", error_to_string(rv)); + } + else if(self->padding_mode == 2) { /* oneandzeroes padding */ + self->pad[self->padlen] = 0x80; + for(j=self->padlen+1; jpad[j] = 0; + rv = cbc_encrypt(self->pad, tmp_block, blen, &self->state); + if (rv != CRYPT_OK) croak("FATAL: cbc_encrypt failed: %s", error_to_string(rv)); + } + else { + if (self->padlen>0) croak("FATAL: cbc_encrypt, input data length not multiple of %d", blen); + blen = 0; + } + + self->direction = 0; + RETVAL = newSVpvn((char*)tmp_block, blen); + } + OUTPUT: + RETVAL + +SV * +_decrypt(Crypt::Mode::CBC self, SV * data) + CODE: + { + int rv, has_tmp_block, blen; + unsigned long i; + STRLEN in_data_len, in_data_start; + unsigned char *in_data, *out_data, tmp_block[MAXBLOCKSIZE]; + + if (self->direction != -1) croak("FATAL: decrypt error, call start_decryt first (%d)", self->direction); + + blen = (&self->state)->blocklen; + in_data_start = 0; + has_tmp_block = 0; + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + if (in_data_len==0) { + RETVAL = newSVpvn("", 0); + } + else { + + if(self->padlen == blen) { + rv = cbc_decrypt(self->pad, tmp_block, blen, &self->state); + if (rv != CRYPT_OK) croak("FATAL: cbc_decrypt failed: %s", error_to_string(rv)); + self->padlen = 0; + has_tmp_block = 1; + } /* padlen == blen */ + else if(self->padlen > 0) { + i = (blen - self->padlen); /* remaining bytes in padding buffer */ + if (in_data_len >= i) { /* enough data to fill pad */ + Copy(in_data, self->pad+self->padlen, i, unsigned char); + self->padlen += i; + in_data_len -= i; + in_data_start = i; + if (in_data_len>0 || self->padding_mode == 0) { + rv = cbc_decrypt(self->pad, tmp_block, blen, &self->state); + if (rv != CRYPT_OK) croak("FATAL: cbc_decrypt failed: %s", error_to_string(rv)); + self->padlen = 0; + has_tmp_block = 1; + } + } + else { /* not enough data to fill pad */ + Copy(in_data, self->pad+self->padlen, in_data_len, unsigned char); + self->padlen += (int)in_data_len; + in_data_len = 0; + } + } /* padlen > 0 */ + + /* here: a/ padlen==1..16 && in_data_len==0; b/ padlen==0 && in_data_len>0 */ + if (in_data_len>0) { + i = (unsigned long)(in_data_len % blen); + if (i>0) { /* save tail of data into pad */ + Copy(in_data+in_data_start+in_data_len-i, self->pad, i, unsigned char); + self->padlen = i; + in_data_len -= i; + } + } + + if (in_data_len>0) { + if(self->padlen == 0 && self->padding_mode !=0) { + /* in case of padding keep full pad if no more data */ + Copy(in_data+in_data_start+in_data_len-blen, self->pad, blen, unsigned char); + self->padlen = blen; + in_data_len -= blen; + } + i = (unsigned long)(has_tmp_block ? in_data_len + blen : in_data_len); + if (i == 0) { + RETVAL = newSVpvn("", 0); + } + else { + RETVAL = NEWSV(0, i); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, i); + out_data = (unsigned char *)SvPV_nolen(RETVAL); + if (has_tmp_block) { + Copy(tmp_block, out_data, blen, unsigned char); + out_data += blen; + } + rv = cbc_decrypt(in_data+in_data_start, out_data, (unsigned long)in_data_len, &self->state); + if (rv != CRYPT_OK) croak("FATAL: cbc_decrypt failed: %s", error_to_string(rv)); + } + } /* in_data_len>0 */ + else if (has_tmp_block) { + RETVAL = newSVpvn((char*)tmp_block, blen); + } + else { + RETVAL = newSVpvn("", 0); + } + } + + } + OUTPUT: + RETVAL + +SV * +_finish_dec(Crypt::Mode::CBC self) + CODE: + { + unsigned char tmp_block[MAXBLOCKSIZE]; + unsigned char i; + int rv, rv_len, blen; + + rv_len = 0; + if (self->padlen > 0) { + blen = (&self->state)->blocklen; + if (self->padlen != blen) croak("FATAL: cipher text length has to be multiple of %d (%d)", blen, self->padlen); + rv = cbc_decrypt(self->pad, tmp_block, blen, &self->state); + if (rv != CRYPT_OK) croak("FATAL: cbc_decrypt failed: %s", error_to_string(rv)); + if(self->padding_mode == 0) { /* no padding */ + rv_len = blen; + } + else if(self->padding_mode == 1) { /* pkcs5|7 padding */ + i = tmp_block[blen-1]; + rv_len = blen - (i>blen ? blen : i); + } + else if(self->padding_mode == 2) { /* oneandzeroes padding */ + rv_len = blen; + while ((unsigned char)tmp_block[rv_len-1] == 0x00) rv_len--; + if ((unsigned char)tmp_block[rv_len-1] == 0x80) rv_len--; + if (rv_len<0) rv_len = 0; + } + } + + self->direction = 0; + RETVAL = newSVpvn((char*)tmp_block, rv_len); + } + OUTPUT: + RETVAL diff --git a/inc/CryptX_Mode_CFB.xs.inc b/inc/CryptX_Mode_CFB.xs.inc new file mode 100644 index 0000000..da36e31 --- /dev/null +++ b/inc/CryptX_Mode_CFB.xs.inc @@ -0,0 +1,98 @@ +MODULE = CryptX PACKAGE = Crypt::Mode::CFB + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +Crypt::Mode::CFB +_new(char * cipher_name, int rounds=0) + CODE: + { + Newz(0, RETVAL, 1, struct cfb_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + RETVAL->direction = 0; + RETVAL->cipher_rounds = rounds; + RETVAL->cipher_id = find_cipher(cipher_name); + if(RETVAL->cipher_id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); + } + OUTPUT: + RETVAL + +void +DESTROY(Crypt::Mode::CFB self) + CODE: + Safefree(self); + +int +_get_dir(Crypt::Mode::CFB self) + CODE: + RETVAL = self->direction; + OUTPUT: + RETVAL + +void +_start(Crypt::Mode::CFB self, int dir, SV * key, SV * iv) + CODE: + { + STRLEN k_len=0; + unsigned char *k=NULL; + STRLEN i_len=0; + unsigned char *i=NULL; + int rv; + + if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); + k = (unsigned char *) SvPVbyte(key, k_len); + + if (!SvPOK(iv)) croak("FATAL: iv must be string/buffer scalar"); + i = (unsigned char *) SvPVbyte(iv, i_len); + if (i_len != (STRLEN)cipher_descriptor[self->cipher_id].block_length) { + croak ("FATAL: sizeof(iv) should be equal to blocksize (%d)", cipher_descriptor[self->cipher_id].block_length); + } + + rv = cfb_start(self->cipher_id, i, k, (int)k_len, self->cipher_rounds, &self->state); + if (rv != CRYPT_OK) { + croak("FATAL: cfb_start failed: %s", error_to_string(rv)); + } + + self->direction = dir; + } + +SV * +_crypt(Crypt::Mode::CFB self, SV * data) + CODE: + { + int rv; + STRLEN in_data_len; + unsigned char *in_data, *out_data; + + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + if (in_data_len==0) { + RETVAL = newSVpvn("", 0); + } + else { + RETVAL = NEWSV(0, in_data_len); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, in_data_len); + out_data = (unsigned char *)SvPV_nolen(RETVAL); + + if (self->direction == 1) { + rv = cfb_encrypt(in_data, out_data, (unsigned long)in_data_len, &self->state); + if (rv != CRYPT_OK) croak("FATAL: cfb_encrypt failed: %s", error_to_string(rv)); + } + else if (self->direction == -1) { + rv = cfb_decrypt(in_data, out_data, (unsigned long)in_data_len, &self->state); + if (rv != CRYPT_OK) croak("FATAL: cfb_decrypt failed: %s", error_to_string(rv)); + } + else { + croak("FATAL: cfb_crypt failed: call start_encrypt or start_decrypt first"); + } + } + } + OUTPUT: + RETVAL + +SV * +_finish(Crypt::Mode::CFB self) + CODE: + self->direction = 0; + RETVAL = newSVpvn("", 0); + OUTPUT: + RETVAL diff --git a/inc/CryptX_Mode_CTR.xs.inc b/inc/CryptX_Mode_CTR.xs.inc new file mode 100644 index 0000000..d27af91 --- /dev/null +++ b/inc/CryptX_Mode_CTR.xs.inc @@ -0,0 +1,103 @@ +MODULE = CryptX PACKAGE = Crypt::Mode::CTR + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +Crypt::Mode::CTR +_new(char * cipher_name, int ctr_mode=0, int ctr_width=0, int rounds=0) + CODE: + { + Newz(0, RETVAL, 1, struct ctr_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + RETVAL->direction = 0; + RETVAL->cipher_rounds = rounds; + RETVAL->cipher_id = find_cipher(cipher_name); + if(RETVAL->cipher_id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); + if (ctr_mode == 0) RETVAL->ctr_mode_param = CTR_COUNTER_LITTLE_ENDIAN; + if (ctr_mode == 1) RETVAL->ctr_mode_param = CTR_COUNTER_BIG_ENDIAN; + if (ctr_mode == 2) RETVAL->ctr_mode_param = CTR_COUNTER_LITTLE_ENDIAN|LTC_CTR_RFC3686; + if (ctr_mode == 3) RETVAL->ctr_mode_param = CTR_COUNTER_BIG_ENDIAN|LTC_CTR_RFC3686; + if (ctr_width > 0 && ctr_width <= cipher_descriptor[RETVAL->cipher_id].block_length) RETVAL->ctr_mode_param |= ctr_width; + } + OUTPUT: + RETVAL + +void +DESTROY(Crypt::Mode::CTR self) + CODE: + Safefree(self); + +int +_get_dir(Crypt::Mode::CTR self) + CODE: + RETVAL = self->direction; + OUTPUT: + RETVAL + +void +_start(Crypt::Mode::CTR self, int dir, SV * key, SV * iv) + CODE: + { + STRLEN k_len=0; + unsigned char *k=NULL; + STRLEN i_len=0; + unsigned char *i=NULL; + int rv; + + if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); + k = (unsigned char *) SvPVbyte(key, k_len); + + if (!SvPOK(iv)) croak("FATAL: iv must be string/buffer scalar"); + i = (unsigned char *) SvPVbyte(iv, i_len); + if (i_len != (STRLEN)cipher_descriptor[self->cipher_id].block_length) { + croak ("FATAL: sizeof(iv) should be equal to blocksize (%d)", cipher_descriptor[self->cipher_id].block_length); + } + + rv = ctr_start(self->cipher_id, i, k, (int)k_len, self->cipher_rounds, self->ctr_mode_param, &self->state); + if (rv != CRYPT_OK) { + croak("FATAL: ctr_start failed: %s", error_to_string(rv)); + } + + self->direction = dir; + } + +SV * +_crypt(Crypt::Mode::CTR self, SV * data) + CODE: + { + int rv; + STRLEN in_data_len; + unsigned char *in_data, *out_data; + + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + if (in_data_len==0) { + RETVAL = newSVpvn("", 0); + } + else { + RETVAL = NEWSV(0, in_data_len); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, in_data_len); + out_data = (unsigned char *)SvPV_nolen(RETVAL); + + if (self->direction == 1) { + rv = ctr_encrypt(in_data, out_data, (unsigned long)in_data_len, &self->state); + if (rv != CRYPT_OK) croak("FATAL: ctr_encrypt failed: %s", error_to_string(rv)); + } + else if (self->direction == -1) { + rv = ctr_decrypt(in_data, out_data, (unsigned long)in_data_len, &self->state); + if (rv != CRYPT_OK) croak("FATAL: ctr_decrypt failed: %s", error_to_string(rv)); + } + else { + croak("FATAL: ctr_crypt failed: call start_encrypt or start_decrypt first"); + } + } + } + OUTPUT: + RETVAL + +SV * +_finish(Crypt::Mode::CTR self) + CODE: + self->direction = 0; + RETVAL = newSVpvn("", 0); + OUTPUT: + RETVAL diff --git a/inc/CryptX_Mode_ECB.xs.inc b/inc/CryptX_Mode_ECB.xs.inc new file mode 100644 index 0000000..90ab26a --- /dev/null +++ b/inc/CryptX_Mode_ECB.xs.inc @@ -0,0 +1,283 @@ +MODULE = CryptX PACKAGE = Crypt::Mode::ECB + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +Crypt::Mode::ECB +_new(char * cipher_name, int padding=1, int rounds=0) + CODE: + { + Newz(0, RETVAL, 1, struct ecb_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + RETVAL->padding_mode = padding; + RETVAL->padlen = 0; + RETVAL->direction = 0; + RETVAL->cipher_rounds = rounds; + RETVAL->cipher_id = find_cipher(cipher_name); + if(RETVAL->cipher_id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); + } + OUTPUT: + RETVAL + +void +DESTROY(Crypt::Mode::ECB self) + CODE: + Safefree(self); + +int +_get_dir(Crypt::Mode::ECB self) + CODE: + RETVAL = self->direction; + OUTPUT: + RETVAL + +void +_start(Crypt::Mode::ECB self, int dir, SV * key) + CODE: + { + int rv; + STRLEN k_len=0; + unsigned char *k=NULL; + + if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); + k = (unsigned char *) SvPVbyte(key, k_len); + + rv = ecb_start(self->cipher_id, k, (unsigned long)k_len, self->cipher_rounds, &self->state); + if (rv != CRYPT_OK) { + croak("FATAL: ecb_start failed: %s", error_to_string(rv)); + } + + self->direction = dir; + self->padlen = 0; + } + +SV * +_encrypt(Crypt::Mode::ECB self, SV * data) + CODE: + { + int rv, has_tmp_block, blen; + unsigned long i; + + STRLEN in_data_len, in_data_start; + unsigned char *in_data, *out_data, tmp_block[MAXBLOCKSIZE]; + + if (self->direction != 1) croak("FATAL: encrypt error, call start_encrypt first (%d)", self->direction); + + blen = (&self->state)->blocklen; + in_data_start = 0; + has_tmp_block = 0; + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + if (in_data_len==0) { + RETVAL = newSVpvn("", 0); + } + else { + if(self->padlen > 0) { + i = (blen - self->padlen); + if (in_data_len >= i) { /* enough data to fill pad */ + Copy(in_data, self->pad+self->padlen, i, unsigned char); + in_data_len -= i; + in_data_start = i; + rv = ecb_encrypt(self->pad, tmp_block, blen, &self->state); + if (rv != CRYPT_OK) croak("FATAL: ecb_encrypt failed: %s", error_to_string(rv)); + self->padlen = 0; + has_tmp_block = 1; + } + else { /* not enough data to fill pad */ + Copy(in_data, self->pad+self->padlen, in_data_len, unsigned char); + self->padlen += (int)in_data_len; + in_data_len = 0; + } + } /* padlen > 0 */ + + i = (unsigned long)(in_data_len % blen); + if (in_data_len>0 && i>0) { /* save tail of data into pad */ + Copy(in_data+in_data_start+in_data_len-i, self->pad, i, unsigned char); + self->padlen = i; + in_data_len -= i; + } + + if (in_data_len>0) { + i = (unsigned long)(has_tmp_block ? in_data_len + blen : in_data_len); + RETVAL = NEWSV(0, i); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, i); + out_data = (unsigned char *)SvPV_nolen(RETVAL); + + if (has_tmp_block) { + Copy(tmp_block, out_data, blen, unsigned char); + out_data += blen; + } + rv = ecb_encrypt(in_data+in_data_start, out_data, (unsigned long)in_data_len, &self->state); + if (rv != CRYPT_OK) croak("FATAL: ecb_encrypt failed: %s", error_to_string(rv)); + } /* in_data_len>0 */ + else if (has_tmp_block) { + RETVAL = newSVpvn((char*)tmp_block, blen); + } + else { + RETVAL = newSVpvn("", 0); + } + } + } + OUTPUT: + RETVAL + +SV * +_finish_enc(Crypt::Mode::ECB self) + CODE: + { + unsigned char tmp_block[MAXBLOCKSIZE]; + int rv, blen, i, j; + + blen = (&self->state)->blocklen; + if (self->padlen<0 || self->padlen>=blen) croak("FATAL: invalid padlen"); + + if(self->padding_mode == 1) { /* pkcs5|7 padding */ + i = blen - self->padlen; + if (i == 0) i = blen; + for(j=self->padlen; jpad[j] = (unsigned char)i; + rv = ecb_encrypt(self->pad, tmp_block, blen, &self->state); + if (rv != CRYPT_OK) croak("FATAL: ecb_encrypt failed: %s", error_to_string(rv)); + } + else if(self->padding_mode == 2) { /* oneandzeroes padding */ + self->pad[self->padlen] = 0x80; + for(j=self->padlen+1; jpad[j] = 0; + rv = ecb_encrypt(self->pad, tmp_block, blen, &self->state); + if (rv != CRYPT_OK) croak("FATAL: ecb_encrypt failed: %s", error_to_string(rv)); + } + else { + if (self->padlen>0) croak("FATAL: ecb_encrypt, input data length not multiple of %d", blen); + blen = 0; + } + + self->direction = 0; + RETVAL = newSVpvn((char*)tmp_block, blen); + } + OUTPUT: + RETVAL + +SV * +_decrypt(Crypt::Mode::ECB self, SV * data) + CODE: + { + int rv, has_tmp_block, blen; + unsigned long i; + STRLEN in_data_len, in_data_start; + unsigned char *in_data, *out_data, tmp_block[MAXBLOCKSIZE]; + + if (self->direction != -1) croak("FATAL: decrypt error, call start_decryt first (%d)", self->direction); + + blen = (&self->state)->blocklen; + in_data_start = 0; + has_tmp_block = 0; + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + if (in_data_len==0) { + RETVAL = newSVpvn("", 0); + } + else { + + if(self->padlen == blen) { + rv = ecb_decrypt(self->pad, tmp_block, blen, &self->state); + if (rv != CRYPT_OK) croak("FATAL: ecb_decrypt failed: %s", error_to_string(rv)); + self->padlen = 0; + has_tmp_block = 1; + } /* padlen == blen */ + else if(self->padlen > 0) { + i = (blen - self->padlen); /* remaining bytes in padding buffer */ + if (in_data_len >= i) { /* enough data to fill pad */ + Copy(in_data, self->pad+self->padlen, i, unsigned char); + self->padlen += i; + in_data_len -= i; + in_data_start = i; + if (in_data_len>0 || self->padding_mode == 0) { + rv = ecb_decrypt(self->pad, tmp_block, blen, &self->state); + if (rv != CRYPT_OK) croak("FATAL: ecb_decrypt failed: %s", error_to_string(rv)); + self->padlen = 0; + has_tmp_block = 1; + } + } + else { /* not enough data to fill pad */ + Copy(in_data, self->pad+self->padlen, in_data_len, unsigned char); + self->padlen += (int)in_data_len; + in_data_len = 0; + } + } /* padlen > 0 */ + + /* here: a/ padlen==1..16 && in_data_len==0; b/ padlen==0 && in_data_len>0 */ + if (in_data_len>0) { + i = (unsigned long)(in_data_len % blen); + if (i>0) { /* save tail of data into pad */ + Copy(in_data+in_data_start+in_data_len-i, self->pad, i, unsigned char); + self->padlen = i; + in_data_len -= i; + } + } + + if (in_data_len>0) { + if(self->padlen == 0 && self->padding_mode !=0) { + /* in case of padding keep full pad if no more data */ + Copy(in_data+in_data_start+in_data_len-blen, self->pad, blen, unsigned char); + self->padlen = blen; + in_data_len -= blen; + } + i = (unsigned long)(has_tmp_block ? in_data_len + blen : in_data_len); + if (i == 0) { + RETVAL = newSVpvn("", 0); + } + else { + RETVAL = NEWSV(0, i); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, i); + out_data = (unsigned char *)SvPV_nolen(RETVAL); + if (has_tmp_block) { + Copy(tmp_block, out_data, blen, unsigned char); + out_data += blen; + } + rv = ecb_decrypt(in_data+in_data_start, out_data, (unsigned long)in_data_len, &self->state); + if (rv != CRYPT_OK) croak("FATAL: ecb_decrypt failed: %s", error_to_string(rv)); + } + } /* in_data_len>0 */ + else if (has_tmp_block) { + RETVAL = newSVpvn((char*)tmp_block, blen); + } + else { + RETVAL = newSVpvn("", 0); + } + } + + } + OUTPUT: + RETVAL + +SV * +_finish_dec(Crypt::Mode::ECB self) + CODE: + { + unsigned char tmp_block[MAXBLOCKSIZE]; + unsigned char i; + int rv, rv_len, blen; + + rv_len = 0; + if (self->padlen > 0) { + blen = (&self->state)->blocklen; + if (self->padlen != blen) croak("FATAL: cipher text length has to be multiple of %d (%d)", blen, self->padlen); + rv = ecb_decrypt(self->pad, tmp_block, blen, &self->state); + if (rv != CRYPT_OK) croak("FATAL: ecb_decrypt failed: %s", error_to_string(rv)); + if(self->padding_mode == 0) { /* no padding */ + rv_len = blen; + } + else if(self->padding_mode == 1) { /* pkcs5|7 padding */ + i = tmp_block[blen-1]; + rv_len = blen - (i>blen ? blen : i); + } + else if(self->padding_mode == 2) { /* oneandzeroes padding */ + rv_len = blen; + while ((unsigned char)tmp_block[rv_len-1] == 0x00) rv_len--; + if ((unsigned char)tmp_block[rv_len-1] == 0x80) rv_len--; + if (rv_len<0) rv_len = 0; + } + } + + self->direction = 0; + RETVAL = newSVpvn((char*)tmp_block, rv_len); + } + OUTPUT: + RETVAL diff --git a/inc/CryptX_Mode_OFB.xs.inc b/inc/CryptX_Mode_OFB.xs.inc new file mode 100644 index 0000000..0d6ce30 --- /dev/null +++ b/inc/CryptX_Mode_OFB.xs.inc @@ -0,0 +1,98 @@ +MODULE = CryptX PACKAGE = Crypt::Mode::OFB + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +Crypt::Mode::OFB +_new(char * cipher_name, int rounds=0) + CODE: + { + Newz(0, RETVAL, 1, struct ofb_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + RETVAL->direction = 0; + RETVAL->cipher_rounds = rounds; + RETVAL->cipher_id = find_cipher(cipher_name); + if(RETVAL->cipher_id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); + } + OUTPUT: + RETVAL + +void +DESTROY(Crypt::Mode::OFB self) + CODE: + Safefree(self); + +int +_get_dir(Crypt::Mode::OFB self) + CODE: + RETVAL = self->direction; + OUTPUT: + RETVAL + +void +_start(Crypt::Mode::OFB self, int dir, SV * key, SV * iv) + CODE: + { + STRLEN k_len=0; + unsigned char *k=NULL; + STRLEN i_len=0; + unsigned char *i=NULL; + int rv; + + if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); + k = (unsigned char *) SvPVbyte(key, k_len); + + if (!SvPOK(iv)) croak("FATAL: iv must be string/buffer scalar"); + i = (unsigned char *) SvPVbyte(iv, i_len); + if (i_len != (STRLEN)cipher_descriptor[self->cipher_id].block_length) { + croak ("FATAL: sizeof(iv) should be equal to blocksize (%d)", cipher_descriptor[self->cipher_id].block_length); + } + + rv = ofb_start(self->cipher_id, i, k, (int)k_len, self->cipher_rounds, &self->state); + if (rv != CRYPT_OK) { + croak("FATAL: ofb_start failed: %s", error_to_string(rv)); + } + + self->direction = dir; + } + +SV * +_crypt(Crypt::Mode::OFB self, SV * data) + CODE: + { + int rv; + STRLEN in_data_len; + unsigned char *in_data, *out_data; + + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + if (in_data_len==0) { + RETVAL = newSVpvn("", 0); + } + else { + RETVAL = NEWSV(0, in_data_len); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, in_data_len); + out_data = (unsigned char *)SvPV_nolen(RETVAL); + + if (self->direction == 1) { + rv = ofb_encrypt(in_data, out_data, (unsigned long)in_data_len, &self->state); + if (rv != CRYPT_OK) croak("FATAL: ofb_encrypt failed: %s", error_to_string(rv)); + } + else if (self->direction == -1) { + rv = ofb_decrypt(in_data, out_data, (unsigned long)in_data_len, &self->state); + if (rv != CRYPT_OK) croak("FATAL: ofb_decrypt failed: %s", error_to_string(rv)); + } + else { + croak("FATAL: ofb_crypt failed: call start_encrypt or start_decrypt first"); + } + } + } + OUTPUT: + RETVAL + +SV * +_finish(Crypt::Mode::OFB self) + CODE: + self->direction = 0; + RETVAL = newSVpvn("", 0); + OUTPUT: + RETVAL diff --git a/inc/CryptX_PK_DH.xs.inc b/inc/CryptX_PK_DH.xs.inc new file mode 100644 index 0000000..6ec1105 --- /dev/null +++ b/inc/CryptX_PK_DH.xs.inc @@ -0,0 +1,426 @@ +MODULE = CryptX PACKAGE = Crypt::PK::DH + +Crypt::PK::DH +_new() + CODE: + { + int rv; + Newz(0, RETVAL, 1, struct dh_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + RETVAL->key.type = -1; + RETVAL->pindex = find_prng("chacha20"); + if(RETVAL->pindex==-1) croak("FATAL: find_prng('chacha20') failed"); + rv = rng_make_prng(320, RETVAL->pindex, &RETVAL->pstate, NULL); /* 320bits = 40bytes */ + if (rv != CRYPT_OK) croak("FATAL: rng_make_prng failed: %s", error_to_string(rv)); + } + OUTPUT: + RETVAL + +void +_generate_key(Crypt::PK::DH self, int key_size=256) + PPCODE: + { + int rv; + /* gen the key */ + rv = dh_make_key(&self->pstate, self->pindex, key_size, &self->key); + if (rv != CRYPT_OK) croak("FATAL: dh_make_key failed: %s", error_to_string(rv)); + XPUSHs(ST(0)); /* return self */ + } + +void +_generate_key_ex(Crypt::PK::DH self, SV * g, SV * p) + PPCODE: + { + int rv; + STRLEN p_len = 0; + STRLEN g_len = 0; + unsigned char *p_ptr=NULL; + unsigned char *g_ptr=NULL; + + p_ptr = (unsigned char *)SvPVbyte(p, p_len); + g_ptr = (unsigned char *)SvPVbyte(g, g_len); + + /* gen the key */ + rv = dh_make_key_ex(&self->pstate, self->pindex, (const char *) g_ptr, (const char *) p_ptr, &self->key); + if (rv != CRYPT_OK) croak("FATAL: dh_make_key_ex failed: %s", error_to_string(rv)); + XPUSHs(ST(0)); /* return self */ + } + +void +_import(Crypt::PK::DH self, SV * key_data) + PPCODE: + { + int rv; + unsigned char *data=NULL; + STRLEN data_len=0; + + data = (unsigned char *)SvPVbyte(key_data, data_len); + if (self->key.type != -1) { dh_free(&self->key); self->key.type = -1; } + rv = dh_import(data, (unsigned long)data_len, &self->key); + if (rv != CRYPT_OK) croak("FATAL: dh_import failed: %s", error_to_string(rv)); + XPUSHs(ST(0)); /* return self */ + } + +void +_import_raw(Crypt::PK::DH self, SV * raw_key, int type, char * g, char * p) + PPCODE: + { + int rv; + unsigned char *data=NULL; + STRLEN data_len=0; + + data = (unsigned char *)SvPVbyte(raw_key, data_len); + if (self->key.type != -1) { dh_free(&self->key); self->key.type = -1; } + /* public */ + if (type == 0) { + rv = dh_import_raw(data, (unsigned long)data_len, PK_PUBLIC, g, p, &self->key); + if (rv != CRYPT_OK) croak("FATAL: dh_import_raw failed: %s", error_to_string(rv)); + } + /* private */ + else if (type == 1) { + rv = dh_import_raw(data, (unsigned long)data_len, PK_PRIVATE, g, p, &self->key); + if (rv != CRYPT_OK) croak("FATAL: dh_import_raw failed: %s", error_to_string(rv)); + } + else { + croak("FATAL: import_raw invalid type '%d'", type); + } + + XPUSHs(ST(0)); /* return self */ + } + +int +is_private(Crypt::PK::DH self) + CODE: + if (self->key.type == -1) XSRETURN_UNDEF; + RETVAL = (self->key.type == PK_PRIVATE) ? 1 : 0; + OUTPUT: + RETVAL + +int +size(Crypt::PK::DH self) + CODE: + if (self->key.type == -1) XSRETURN_UNDEF; + RETVAL = dh_get_size(&self->key); + OUTPUT: + RETVAL + +SV* +key2hash(Crypt::PK::DH self) + PREINIT: + HV *rv_hash; + long siz; + char buf[20001]; + SV **not_used; + CODE: + if (self->key.type == -1) XSRETURN_UNDEF; + rv_hash = newHV(); + /* =====> x */ + siz = (self->key.x) ? mp_unsigned_bin_size(self->key.x) : 0; + if (siz>10000) { + croak("FATAL: key2hash failed - 'x' too big number"); + } + if (siz>0) { + mp_tohex_with_leading_zero(self->key.x, buf, 20000, 0); + not_used = hv_store(rv_hash, "x", 1, newSVpv(buf, strlen(buf)), 0); + } + else{ + not_used = hv_store(rv_hash, "x", 1, newSVpv("", 0), 0); + } + /* =====> y */ + siz = (self->key.y) ? mp_unsigned_bin_size(self->key.y) : 0; + if (siz>10000) { + croak("FATAL: key2hash failed - 'y' too big number"); + } + if (siz>0) { + mp_tohex_with_leading_zero(self->key.y, buf, 20000, 0); + not_used = hv_store(rv_hash, "y", 1, newSVpv(buf, strlen(buf)), 0); + } + else{ + not_used = hv_store(rv_hash, "y", 1, newSVpv("", 0), 0); + } + /* =====> p */ + siz = (self->key.prime) ? mp_unsigned_bin_size(self->key.prime) : 0; + if (siz>10000) { + croak("FATAL: key2hash failed - 'p' too big number"); + } + if (siz>0) { + mp_tohex_with_leading_zero(self->key.prime, buf, 20000, 0); + not_used = hv_store(rv_hash, "p", 1, newSVpv(buf, strlen(buf)), 0); + } + else { + not_used = hv_store(rv_hash, "p", 1, newSVpv("", 0), 0); + } + + /* =====> g */ + siz = (self->key.base) ? mp_unsigned_bin_size(self->key.base) : 0; + if (siz>10000) { + croak("FATAL: key2hash failed - 'g' too big number"); + } + if (siz>0) { + mp_tohex_with_leading_zero(self->key.base, buf, 20000, 0); + not_used = hv_store(rv_hash, "g", 1, newSVpv(buf, strlen(buf)), 0); + } + else { + not_used = hv_store(rv_hash, "g", 1, newSVpv("", 0), 0); + } + /* =====> size */ + not_used = hv_store(rv_hash, "size", 4, newSViv(dh_get_size(&self->key)), 0); + /* =====> type */ + not_used = hv_store(rv_hash, "type", 4, newSViv(self->key.type), 0); + if (not_used) not_used = NULL; /* just silence the warning: variable 'not_used' set but not used */ + RETVAL = newRV_noinc((SV*)rv_hash); + OUTPUT: + RETVAL + +SV* +params2hash(Crypt::PK::DH self) + PREINIT: + HV *rv_hash; + long siz; + char buf[20001]; + SV **not_used; + CODE: + if (self->key.type == -1) XSRETURN_UNDEF; + rv_hash = newHV(); + /* =====> p */ + siz = (self->key.prime) ? mp_unsigned_bin_size(self->key.prime) : 0; + if (siz>10000) { + croak("FATAL: key2hash failed - 'p' too big number"); + } + if (siz>0) { + mp_tohex_with_leading_zero(self->key.prime, buf, 20000, 0); + not_used = hv_store(rv_hash, "p", 1, newSVpv(buf, strlen(buf)), 0); + } + else { + not_used = hv_store(rv_hash, "p", 1, newSVpv("", 0), 0); + } + + /* =====> g */ + siz = (self->key.base) ? mp_unsigned_bin_size(self->key.base) : 0; + if (siz>10000) { + croak("FATAL: key2hash failed - 'g' too big number"); + } + if (siz>0) { + mp_tohex_with_leading_zero(self->key.base, buf, 20000, 0); + not_used = hv_store(rv_hash, "g", 1, newSVpv(buf, strlen(buf)), 0); + } + else { + not_used = hv_store(rv_hash, "g", 1, newSVpv("", 0), 0); + } + if (not_used) not_used = NULL; /* just silence the warning: variable 'not_used' set but not used */ + RETVAL = newRV_noinc((SV*)rv_hash); + OUTPUT: + RETVAL + +SV * +export_key(Crypt::PK::DH self, char * type) + CODE: + { + int rv; + unsigned long int out_len = 4096; + unsigned char out[4096]; + + RETVAL = newSVpvn(NULL, 0); /* undef */ + if (strnEQ(type, "private", 7)) { + rv = dh_export(out, &out_len, PK_PRIVATE, &self->key); + if (rv != CRYPT_OK) croak("FATAL: dh_export(PK_PRIVATE) failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)out, out_len); + } + else if (strnEQ(type, "public", 6)) { + rv = dh_export(out, &out_len, PK_PUBLIC, &self->key); + if (rv != CRYPT_OK) croak("FATAL: dh_export(PK_PUBLIC) failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)out, out_len); + } + else { + croak("FATAL: export_key_der invalid type '%s'", type); + } + } + OUTPUT: + RETVAL + +SV * +_encrypt(Crypt::PK::DH self, SV * data, char * hash_name) + CODE: + { + int rv, hash_id; + unsigned char *data_ptr=NULL; + STRLEN data_len=0; + unsigned long buffer_len = 1024; + unsigned char buffer[1024]; + + data_ptr = (unsigned char *)SvPVbyte(data, data_len); + + hash_id = find_hash(hash_name); + if(hash_id==-1) croak("FATAL: find_hash failed for '%s'", hash_name); + rv = dh_encrypt_key(data_ptr, (unsigned long)data_len, buffer, &buffer_len, + &self->pstate, self->pindex, + hash_id, &self->key); + if (rv != CRYPT_OK) croak("FATAL: dh_encrypt_key failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)buffer, buffer_len); + } + OUTPUT: + RETVAL + +SV * +_decrypt(Crypt::PK::DH self, SV * data) + CODE: + { + int rv; + unsigned char *data_ptr=NULL; + STRLEN data_len=0; + unsigned long buffer_len = 1024; + unsigned char buffer[1024]; + + data_ptr = (unsigned char *)SvPVbyte(data, data_len); + + rv = dh_decrypt_key(data_ptr, (unsigned long)data_len, buffer, &buffer_len, &self->key); + if (rv != CRYPT_OK) croak("FATAL: dh_decrypt_key failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)buffer, buffer_len); + } + OUTPUT: + RETVAL + +SV * +_sign(Crypt::PK::DH self, SV * data) + CODE: + { + int rv; + unsigned char *data_ptr=NULL; + STRLEN data_len=0; + unsigned long buffer_len = 1024; + unsigned char buffer[1024]; + + data_ptr = (unsigned char *)SvPVbyte(data, data_len); + + rv = dh_sign_hash(data_ptr, (unsigned long)data_len, buffer, &buffer_len, + &self->pstate, self->pindex, + &self->key); + if (rv != CRYPT_OK) croak("FATAL: dh_sign_hash failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)buffer, buffer_len); + } + OUTPUT: + RETVAL + +int +_verify(Crypt::PK::DH self, SV * sig, SV * data) + CODE: + { + int rv, stat; + unsigned char *data_ptr=NULL; + STRLEN data_len=0; + unsigned char *sig_ptr=NULL; + STRLEN sig_len=0; + + data_ptr = (unsigned char *)SvPVbyte(data, data_len); + sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len); + + RETVAL = 1; + rv = dh_verify_hash(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, &stat, &self->key); + if (rv != CRYPT_OK || stat != 1) RETVAL = 0; + } + OUTPUT: + RETVAL + +SV * +shared_secret(Crypt::PK::DH self, Crypt::PK::DH pubkey) + CODE: + { + int rv; + unsigned long buffer_len = 1024; + unsigned char buffer[1024]; + + rv = dh_shared_secret(&self->key, &pubkey->key, buffer, &buffer_len); + if (rv != CRYPT_OK) croak("FATAL: dh_shared_secret failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)buffer, buffer_len); + } + OUTPUT: + RETVAL + +SV * +export_key_raw(Crypt::PK::DH self, char * type) + CODE: + { + int rv; + unsigned long len, buffer_len = 1024; + unsigned char buffer[1024]; + void *key; + + RETVAL = newSVpvn(NULL, 0); /* undef */ + if (strnEQ(type, "private", 7)) { + key = self->key.x; + } + else if (strnEQ(type, "public", 6)) { + key = self->key.y; + } + else { + croak("FATAL: export_key_raw: invalid type '%s'", type); + } + + len = (unsigned long)mp_unsigned_bin_size(key); + if (buffer_len < len) { + croak("FATAL: %s", error_to_string(CRYPT_BUFFER_OVERFLOW)); + } + rv = mp_to_unsigned_bin(key, buffer); + if (rv != CRYPT_OK) croak("FATAL: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)buffer, len); + } + OUTPUT: + RETVAL + +int +_is_pubkey_valid(Crypt::PK::DH self); + CODE: + { + int rv, i, bits_set = 0; + mp_int one, two, p1, *y; + mp_digit digit; + + if ((rv = mp_init_multi(&one, &two, &p1, NULL)) != MP_OKAY) { + croak("FATAL: %s", error_to_string(rv)); + } + + y = self->key.y; + mp_set(&one, 1); + mp_set(&two, 2); + + /* p1 = p-1 */ + if ((rv = mp_sub(self->key.prime, &one, &p1)) != MP_OKAY) { + croak("FATAL: %s", error_to_string(rv)); + } + /* valid public key cannot be negative */ + if (y->sign == MP_NEG) { + RETVAL = 0; + } + /* valid public key != 1 */ + else if (mp_cmp(y, &one) == MP_EQ) { + RETVAL = 0; + } + /* public key cannot be > p-1 */ + else if (mp_cmp(y, &p1) == MP_GT) { + RETVAL = 0; + } + /* if base == 2, public must have more than one bit set */ + else if (mp_cmp(self->key.base, &two) == MP_EQ) { + for (i = 0; i < y->used; i++) { + digit = y->dp[i]; + while (digit > ((mp_digit) 0)) { + if (digit & ((mp_digit) 1)) + bits_set++; + digit >>= ((mp_digit) 1); + } + } + if (bits_set > 1) + RETVAL = 1; + else RETVAL = 0; + } + else RETVAL = 1; + } + OUTPUT: + RETVAL + +void +DESTROY(Crypt::PK::DH self) + CODE: + if (self->key.type != -1) { dh_free(&self->key); self->key.type = -1; } + Safefree(self); + diff --git a/inc/CryptX_PK_DSA.xs.inc b/inc/CryptX_PK_DSA.xs.inc new file mode 100644 index 0000000..0e1622d --- /dev/null +++ b/inc/CryptX_PK_DSA.xs.inc @@ -0,0 +1,275 @@ +MODULE = CryptX PACKAGE = Crypt::PK::DSA + +Crypt::PK::DSA +_new() + CODE: + { + int rv; + Newz(0, RETVAL, 1, struct dsa_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + RETVAL->key.type = -1; + RETVAL->pindex = find_prng("chacha20"); + if(RETVAL->pindex==-1) croak("FATAL: find_prng('chacha20') failed"); + rv = rng_make_prng(320, RETVAL->pindex, &RETVAL->pstate, NULL); /* 320bits = 40bytes */ + if (rv != CRYPT_OK) croak("FATAL: rng_make_prng failed: %s", error_to_string(rv)); + } + OUTPUT: + RETVAL + +void +generate_key(Crypt::PK::DSA self, int group_size=30, int modulus_size=256) + PPCODE: + { + int rv; + /* gen the key */ + rv = dsa_make_key(&self->pstate, self->pindex, group_size, modulus_size, &self->key); + if (rv != CRYPT_OK) croak("FATAL: dsa_make_key failed: %s", error_to_string(rv)); + XPUSHs(ST(0)); /* return self */ + } + +void +_import(Crypt::PK::DSA self, SV * key_data) + PPCODE: + { + int rv; + unsigned char *data=NULL; + STRLEN data_len=0; + + data = (unsigned char *)SvPVbyte(key_data, data_len); + if (self->key.type != -1) { dsa_free(&self->key); self->key.type = -1; } + rv = dsa_import(data, (unsigned long)data_len, &self->key); + if (rv != CRYPT_OK) croak("FATAL: dsa_import failed: %s", error_to_string(rv)); + XPUSHs(ST(0)); /* return self */ + } + +void +_import_hex(Crypt::PK::DSA self, char *p, char *q, char *g, char *x, char *y) + PPCODE: + { + int rv; + if (self->key.type != -1) { dsa_free(&self->key); self->key.type = -1; } + rv = dsa_import_radix(16, p, q, g, x, y, &self->key); + if (rv != CRYPT_OK) croak("FATAL: dsa_import_radix failed: %s", error_to_string(rv)); + XPUSHs(ST(0)); /* return self */ + } + +int +is_private(Crypt::PK::DSA self) + CODE: + if (self->key.type == -1 || self->key.qord <= 0) XSRETURN_UNDEF; + RETVAL = (self->key.type == PK_PRIVATE) ? 1 : 0; + OUTPUT: + RETVAL + +int +size(Crypt::PK::DSA self) + CODE: + if (self->key.type == -1 || self->key.qord <= 0) XSRETURN_UNDEF; + RETVAL = mp_unsigned_bin_size(self->key.g); + OUTPUT: + RETVAL + +int +size_q(Crypt::PK::DSA self) + CODE: + if (self->key.type == -1 || self->key.qord <= 0) XSRETURN_UNDEF; + RETVAL = self->key.qord; + OUTPUT: + RETVAL + +SV* +key2hash(Crypt::PK::DSA self) + PREINIT: + HV *rv_hash; + long siz, qsize, psize; + char buf[20001]; + SV **not_used; + CODE: + if (self->key.type == -1 || self->key.qord <= 0) XSRETURN_UNDEF; + qsize = mp_unsigned_bin_size(self->key.q); + psize = mp_unsigned_bin_size(self->key.p); + rv_hash = newHV(); + /* =====> g */ + siz = (self->key.g) ? mp_unsigned_bin_size(self->key.g) : 0; + if (siz>10000) { + croak("FATAL: key2hash failed - 'g' too big number"); + } + if (siz>0) { + mp_tohex_with_leading_zero(self->key.g, buf, 20000, 0); + not_used = hv_store(rv_hash, "g", 1, newSVpv(buf, strlen(buf)), 0); + } + else{ + not_used = hv_store(rv_hash, "g", 1, newSVpv("", 0), 0); + } + /* =====> q */ + siz = (self->key.q) ? mp_unsigned_bin_size(self->key.q) : 0; + if (siz>10000) { + croak("FATAL: key2hash failed - 'q' too big number"); + } + if (siz>0) { + mp_tohex_with_leading_zero(self->key.q, buf, 20000, 0); + not_used = hv_store(rv_hash, "q", 1, newSVpv(buf, strlen(buf)), 0); + } + else{ + not_used = hv_store(rv_hash, "q", 1, newSVpv("", 0), 0); + } + /* =====> p */ + siz = (self->key.p) ? mp_unsigned_bin_size(self->key.p) : 0; + if (siz>10000) { + croak("FATAL: key2hash failed - 'p' too big number"); + } + if (siz>0) { + mp_tohex_with_leading_zero(self->key.p, buf, 20000, 0); + not_used = hv_store(rv_hash, "p", 1, newSVpv(buf, strlen(buf)), 0); + } + else{ + not_used = hv_store(rv_hash, "p", 1, newSVpv("", 0), 0); + } + /* =====> x */ + siz = (self->key.x) ? mp_unsigned_bin_size(self->key.x) : 0; + if (siz>10000) { + croak("FATAL: key2hash failed - 'x' too big number"); + } + if (siz>0) { + mp_tohex_with_leading_zero(self->key.x, buf, 20000, qsize*2); + not_used = hv_store(rv_hash, "x", 1, newSVpv(buf, strlen(buf)), 0); + } + else{ + not_used = hv_store(rv_hash, "x", 1, newSVpv("", 0), 0); + } + /* =====> y */ + siz = (self->key.y) ? mp_unsigned_bin_size(self->key.y) : 0; + if (siz>10000) { + croak("FATAL: key2hash failed - 'y' too big number"); + } + if (siz>0) { + mp_tohex_with_leading_zero(self->key.y, buf, 20000, psize*2); + not_used = hv_store(rv_hash, "y", 1, newSVpv(buf, strlen(buf)), 0); + } + else{ + not_used = hv_store(rv_hash, "y", 1, newSVpv("", 0), 0); + } + /* =====> size */ + not_used = hv_store(rv_hash, "size", 4, newSViv(qsize), 0); + /* =====> type */ + not_used = hv_store(rv_hash, "type", 4, newSViv(self->key.type), 0); + if (not_used) not_used = NULL; /* just silence the warning: variable 'not_used' set but not used */ + RETVAL = newRV_noinc((SV*)rv_hash); + OUTPUT: + RETVAL + +SV * +export_key_der(Crypt::PK::DSA self, char * type) + CODE: + { + int rv; + unsigned char out[4096]; + unsigned long int out_len = 4096; + + RETVAL = newSVpvn(NULL, 0); /* undef */ + if (strnEQ(type, "private", 7)) { + rv = dsa_export(out, &out_len, PK_PRIVATE|PK_STD, &self->key); + if (rv != CRYPT_OK) croak("FATAL: dsa_export(PK_PRIVATE|PK_STD) failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)out, out_len); + } + else if (strnEQ(type, "public", 6)) { + rv = dsa_export(out, &out_len, PK_PUBLIC|PK_STD, &self->key); + if (rv != CRYPT_OK) croak("FATAL: dsa_export(PK_PUBLIC|PK_STD) failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)out, out_len); + } + else { + croak("FATAL: export_key_der invalid type '%s'", type); + } + } + OUTPUT: + RETVAL + +SV * +_encrypt(Crypt::PK::DSA self, SV * data, char * hash_name) + CODE: + { + int rv, hash_id; + unsigned char *data_ptr=NULL; + STRLEN data_len=0; + unsigned char buffer[1024]; + unsigned long buffer_len = 1024; + + data_ptr = (unsigned char *)SvPVbyte(data, data_len); + + hash_id = find_hash(hash_name); + if(hash_id==-1) croak("FATAL: find_hash failed for '%s'", hash_name); + rv = dsa_encrypt_key(data_ptr, (unsigned long)data_len, buffer, &buffer_len, + &self->pstate, self->pindex, + hash_id, &self->key); + if (rv != CRYPT_OK) croak("FATAL: dsa_encrypt_key failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)buffer, buffer_len); + } + OUTPUT: + RETVAL + +SV * +_decrypt(Crypt::PK::DSA self, SV * data) + CODE: + { + int rv; + unsigned char *data_ptr=NULL; + STRLEN data_len=0; + unsigned char buffer[1024]; + unsigned long buffer_len = 1024; + + data_ptr = (unsigned char *)SvPVbyte(data, data_len); + + rv = dsa_decrypt_key(data_ptr, (unsigned long)data_len, buffer, &buffer_len, &self->key); + if (rv != CRYPT_OK) croak("FATAL: dsa_decrypt_key_ex failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)buffer, buffer_len); + } + OUTPUT: + RETVAL + +SV * +_sign(Crypt::PK::DSA self, SV * data) + CODE: + { + int rv; + unsigned char *data_ptr=NULL; + STRLEN data_len=0; + unsigned char buffer[1024]; + unsigned long buffer_len = 1024; + + data_ptr = (unsigned char *)SvPVbyte(data, data_len); + + rv = dsa_sign_hash(data_ptr, (unsigned long)data_len, buffer, &buffer_len, + &self->pstate, self->pindex, + &self->key); + if (rv != CRYPT_OK) croak("FATAL: dsa_sign_hash_ex failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)buffer, buffer_len); + } + OUTPUT: + RETVAL + +int +_verify(Crypt::PK::DSA self, SV * sig, SV * data) + CODE: + { + int rv, stat; + unsigned char *data_ptr=NULL; + STRLEN data_len=0; + unsigned char *sig_ptr=NULL; + STRLEN sig_len=0; + + data_ptr = (unsigned char *)SvPVbyte(data, data_len); + sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len); + + RETVAL = 1; + rv = dsa_verify_hash(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, &stat, &self->key); + if (rv != CRYPT_OK || stat != 1) RETVAL = 0; + } + OUTPUT: + RETVAL + +void +DESTROY(Crypt::PK::DSA self) + CODE: + if (self->key.type != -1) { dsa_free(&self->key); self->key.type = -1; } + Safefree(self); + diff --git a/inc/CryptX_PK_ECC.xs.inc b/inc/CryptX_PK_ECC.xs.inc new file mode 100644 index 0000000..e3db8ff --- /dev/null +++ b/inc/CryptX_PK_ECC.xs.inc @@ -0,0 +1,390 @@ +MODULE = CryptX PACKAGE = Crypt::PK::ECC + +Crypt::PK::ECC +_new() + CODE: + { + int rv; + Newz(0, RETVAL, 1, struct ecc_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + RETVAL->pindex = find_prng("chacha20"); + RETVAL->key.type = -1; + ecc_dp_init(&RETVAL->dp); + if(RETVAL->pindex==-1) croak("FATAL: find_prng('chacha20') failed"); + rv = rng_make_prng(320, RETVAL->pindex, &RETVAL->pstate, NULL); /* 320bits = 40bytes */ + if (rv != CRYPT_OK) croak("FATAL: rng_make_prng failed: %s", error_to_string(rv)); + } + OUTPUT: + RETVAL + +void +generate_key(Crypt::PK::ECC self, SV *curve) + PPCODE: + { + int rv; + /* setup dp structure */ + _ecc_set_dp_from_SV(&self->dp, curve); /* croaks on error */ + /* gen the key */ + rv = ecc_make_key_ex(&self->pstate, self->pindex, &self->key, &self->dp); + if (rv != CRYPT_OK) croak("FATAL: ecc_make_key_ex failed: %s", error_to_string(rv)); + XPUSHs(ST(0)); /* return self */ + } + +void +_import(Crypt::PK::ECC self, SV * key_data) + PPCODE: + { + int rv; + unsigned char *data=NULL; + STRLEN data_len=0; + + data = (unsigned char *)SvPVbyte(key_data, data_len); + _ecc_free_key(&self->key, &self->dp); + rv = ecc_import_full(data, (unsigned long)data_len, &self->key, &self->dp); + if (rv != CRYPT_OK) croak("FATAL: ecc_import_full failed: %s", error_to_string(rv)); + XPUSHs(ST(0)); /* return self */ + } + +void +_import_pkcs8(Crypt::PK::ECC self, SV * key_data) + PPCODE: + { + int rv; + unsigned char *data=NULL; + STRLEN data_len=0; + + data = (unsigned char *)SvPVbyte(key_data, data_len); + _ecc_free_key(&self->key, &self->dp); + rv = ecc_import_pkcs8(data, (unsigned long)data_len, NULL, 0, &self->key, &self->dp); + if (rv != CRYPT_OK) croak("FATAL: ecc_import_pkcs8 failed: %s", error_to_string(rv)); + XPUSHs(ST(0)); /* return self */ + } + +void +import_key_raw(Crypt::PK::ECC self, SV * key_data, SV * curve) + PPCODE: + { + int rv; + unsigned char *data=NULL; + STRLEN data_len=0; + + data = (unsigned char *)SvPVbyte(key_data, data_len); + _ecc_free_key(&self->key, &self->dp); + + _ecc_set_dp_from_SV(&self->dp, curve); /* croaks on error */ + + rv = ecc_import_raw(data, (unsigned long)data_len, &self->key, &self->dp); + if (rv != CRYPT_OK) croak("FATAL: ecc_import_raw failed: %s", error_to_string(rv)); + XPUSHs(ST(0)); /* return self */ + } + +int +is_private(Crypt::PK::ECC self) + CODE: + if (self->key.type == -1) XSRETURN_UNDEF; + RETVAL = (self->key.type == PK_PRIVATE) ? 1 : 0; + OUTPUT: + RETVAL + +int +size(Crypt::PK::ECC self) + CODE: + if (self->key.type == -1) XSRETURN_UNDEF; + RETVAL = ecc_get_size(&self->key); + OUTPUT: + RETVAL + +SV* +key2hash(Crypt::PK::ECC self) + PREINIT: + HV *rv_hash; + long siz, esize; + char buf[20001]; + SV **not_used; + CODE: + if (self->key.type == -1) XSRETURN_UNDEF; + esize = ecc_get_size(&self->key); + rv_hash = newHV(); + /* =====> k */ + siz = (self->key.k) ? mp_unsigned_bin_size(self->key.k) : 0; + if (siz>10000) { + croak("FATAL: key2hash failed - 'k' too big number"); + } + if (siz>0) { + mp_tohex_with_leading_zero(self->key.k, buf, 20000, esize*2); + not_used = hv_store(rv_hash, "k", 1, newSVpv(buf, strlen(buf)), 0); + } + else{ + not_used = hv_store(rv_hash, "k", 1, newSVpv("", 0), 0); + } + /* =====> pub_x */ + siz = (self->key.pubkey.x) ? mp_unsigned_bin_size(self->key.pubkey.x) : 0; + if (siz>10000) { + croak("FATAL: key2hash failed - 'pub_x' too big number"); + } + if (siz>0) { + mp_tohex_with_leading_zero(self->key.pubkey.x, buf, 20000, esize*2); + not_used = hv_store(rv_hash, "pub_x", 5, newSVpv(buf, strlen(buf)), 0); + } + else{ + not_used = hv_store(rv_hash, "pub_x", 5, newSVpv("", 0), 0); + } + /* =====> pub_y */ + siz = (self->key.pubkey.y) ? mp_unsigned_bin_size(self->key.pubkey.y) : 0; + if (siz>10000) { + croak("FATAL: key2hash failed - 'pub_y' too big number"); + } + if (siz>0) { + mp_tohex_with_leading_zero(self->key.pubkey.y, buf, 20000, esize*2); + not_used = hv_store(rv_hash, "pub_y", 5, newSVpv(buf, strlen(buf)), 0); + } + else{ + not_used = hv_store(rv_hash, "pub_y", 5, newSVpv("", 0), 0); + } + /* =====> curve_... */ + if (self->key.dp) { + not_used = hv_store(rv_hash, "curve_cofactor", 14, newSViv(self->key.dp->cofactor), 0); + /* prepend leading zero if we have odd number of hexadecimal digits */ + strncpy(buf, self->key.dp->prime, 20000); str_add_leading_zero(buf, 20000, 0); + not_used = hv_store(rv_hash, "curve_prime", 11, newSVpv(buf, strlen(buf)), 0); + strncpy(buf, self->key.dp->A, 20000); str_add_leading_zero(buf, 20000, 0); + not_used = hv_store(rv_hash, "curve_A", 7, newSVpv(buf, strlen(buf)), 0); + strncpy(buf, self->key.dp->B, 20000); str_add_leading_zero(buf, 20000, 0); + not_used = hv_store(rv_hash, "curve_B", 7, newSVpv(buf, strlen(buf)), 0); + strncpy(buf, self->key.dp->order, 20000); str_add_leading_zero(buf, 20000, 0); + not_used = hv_store(rv_hash, "curve_order", 11, newSVpv(buf, strlen(buf)), 0); + strncpy(buf, self->key.dp->Gx, 20000); str_add_leading_zero(buf, 20000, 0); + not_used = hv_store(rv_hash, "curve_Gx", 8, newSVpv(buf, strlen(buf)), 0); + strncpy(buf, self->key.dp->Gy, 20000); str_add_leading_zero(buf, 20000, 0); + not_used = hv_store(rv_hash, "curve_Gy", 8, newSVpv(buf, strlen(buf)), 0); + /* OLD approach + not_used = hv_store(rv_hash, "curve_prime", 11, newSVpv(self->key.dp->prime, strlen(self->key.dp->prime)), 0); + not_used = hv_store(rv_hash, "curve_A", 7, newSVpv(self->key.dp->A, strlen(self->key.dp->A)), 0); + not_used = hv_store(rv_hash, "curve_B", 7, newSVpv(self->key.dp->B, strlen(self->key.dp->B)), 0); + not_used = hv_store(rv_hash, "curve_order", 11, newSVpv(self->key.dp->order, strlen(self->key.dp->order)), 0); + not_used = hv_store(rv_hash, "curve_Gx", 8, newSVpv(self->key.dp->Gx, strlen(self->key.dp->Gx)), 0); + not_used = hv_store(rv_hash, "curve_Gy", 8, newSVpv(self->key.dp->Gy, strlen(self->key.dp->Gy)), 0); + */ + { + mp_int p_num; + mp_init(&p_num); + mp_read_radix(&p_num, self->key.dp->prime, 16); + not_used = hv_store(rv_hash, "curve_bytes", 11, newSViv(mp_unsigned_bin_size(&p_num)), 0); + not_used = hv_store(rv_hash, "curve_bits", 10, newSViv(mp_count_bits(&p_num)), 0); + mp_clear(&p_num); + } + { + unsigned long i; + SV *name; + char *name_ptr; + STRLEN name_len; + + name = newSVpv(self->key.dp->name, strlen(self->key.dp->name)); + name_ptr = SvPV(name, name_len); + for (i=0; i0; i++) name_ptr[i] = toLOWER(name_ptr[i]); + not_used = hv_store(rv_hash, "curve_name", 10, name, 0); + } + if (self->key.dp->oid.OIDlen > 0) { + unsigned long i; + SV *oid = newSVpv("", 0); + for(i = 0; i < self->key.dp->oid.OIDlen - 1; i++) sv_catpvf(oid, "%lu.", self->key.dp->oid.OID[i]); + sv_catpvf(oid, "%lu", self->key.dp->oid.OID[i]); + not_used = hv_store(rv_hash, "curve_oid", 9, oid, 0); + } + } + /* =====> size */ + not_used = hv_store(rv_hash, "size", 4, newSViv(esize), 0); + /* =====> type */ + not_used = hv_store(rv_hash, "type", 4, newSViv(self->key.type), 0); + if (not_used) not_used = NULL; /* just silence the warning: variable 'not_used' set but not used */ + RETVAL = newRV_noinc((SV*)rv_hash); + OUTPUT: + RETVAL + +SV * +export_key_der(Crypt::PK::ECC self, char * type) + CODE: + { + int rv; + unsigned char out[4096]; + unsigned long int out_len = 4096; + + RETVAL = newSVpvn(NULL, 0); /* undef */ + if (strnEQ(type, "private_short", 16)) { + rv = ecc_export_full(out, &out_len, PK_PRIVATE|PK_CURVEOID, &self->key); + if (rv != CRYPT_OK) croak("FATAL: ecc_export(PK_PRIVATE|PK_CURVEOID) failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)out, out_len); + } + else if (strnEQ(type, "private", 7)) { + rv = ecc_export_full(out, &out_len, PK_PRIVATE, &self->key); + if (rv != CRYPT_OK) croak("FATAL: ecc_export(PK_PRIVATE) failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)out, out_len); + } + else if (strnEQ(type, "public_short", 15)) { + rv = ecc_export_full(out, &out_len, PK_PUBLIC|PK_CURVEOID, &self->key); + if (rv != CRYPT_OK) croak("FATAL: ecc_export(PK_PUBLIC|PK_CURVEOID) failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)out, out_len); + } + else if (strnEQ(type, "public", 6)) { + rv = ecc_export_full(out, &out_len, PK_PUBLIC, &self->key); + if (rv != CRYPT_OK) croak("FATAL: ecc_export(PK_PUBLIC) failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)out, out_len); + } + else { + croak("FATAL: export_key_der invalid type '%s'", type); + } + } + OUTPUT: + RETVAL + +SV * +export_key_raw(Crypt::PK::ECC self, char * type) + CODE: + { + int rv; + unsigned char out[4096]; + unsigned long int out_len = sizeof(out); + + RETVAL = newSVpvn(NULL, 0); /* undef */ + if (strnEQ(type, "private", 7)) { + rv = ecc_export_raw(out, &out_len, PK_PRIVATE, &self->key); + if (rv != CRYPT_OK) croak("FATAL: ecc_export_raw(private) failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)out, out_len); + } + else if (strnEQ(type, "public_compressed", 17)) { + rv = ecc_export_raw(out, &out_len, PK_PUBLIC_COMPRESSED, &self->key); + if (rv != CRYPT_OK) croak("FATAL: ecc_export_raw(public_compressed) failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)out, out_len); + } + else if (strnEQ(type, "public", 6)) { + rv = ecc_export_raw(out, &out_len, PK_PUBLIC, &self->key); + if (rv != CRYPT_OK) croak("FATAL: ecc_export_raw(public) failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)out, out_len); + } + else { + croak("FATAL: export_key_raw invalid type '%s'", type); + } + } + OUTPUT: + RETVAL + +SV * +_encrypt(Crypt::PK::ECC self, SV * data, char * hash_name) + CODE: + { + int rv, hash_id; + unsigned char *data_ptr=NULL; + STRLEN data_len=0; + unsigned char buffer[1024]; + unsigned long buffer_len = 1024; + + data_ptr = (unsigned char *)SvPVbyte(data, data_len); + + hash_id = find_hash(hash_name); + if(hash_id==-1) croak("FATAL: find_hash failed for '%s'", hash_name); + rv = ecc_encrypt_key(data_ptr, (unsigned long)data_len, buffer, &buffer_len, + &self->pstate, self->pindex, + hash_id, &self->key); + if (rv != CRYPT_OK) croak("FATAL: ecc_encrypt_key failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)buffer, buffer_len); + } + OUTPUT: + RETVAL + +SV * +_decrypt(Crypt::PK::ECC self, SV * data) + CODE: + { + int rv; + unsigned char *data_ptr=NULL; + STRLEN data_len=0; + unsigned char buffer[1024]; + unsigned long buffer_len = 1024; + + data_ptr = (unsigned char *)SvPVbyte(data, data_len); + + rv = ecc_decrypt_key(data_ptr, (unsigned long)data_len, buffer, &buffer_len, &self->key); + if (rv != CRYPT_OK) croak("FATAL: ecc_decrypt_key_ex failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)buffer, buffer_len); + } + OUTPUT: + RETVAL + +SV * +_sign(Crypt::PK::ECC self, SV * data) + ALIAS: + _sign_rfc7518 = 1 + CODE: + { + int rv; + unsigned char *data_ptr=NULL; + STRLEN data_len=0; + unsigned char buffer[1024]; + unsigned long buffer_len = 1024; + + data_ptr = (unsigned char *)SvPVbyte(data, data_len); + + if (ix == 1) { + rv = ecc_sign_hash_rfc7518(data_ptr, (unsigned long)data_len, buffer, &buffer_len, + &self->pstate, self->pindex, + &self->key); + } + else { + rv = ecc_sign_hash(data_ptr, (unsigned long)data_len, buffer, &buffer_len, + &self->pstate, self->pindex, + &self->key); + } + if (rv != CRYPT_OK) croak("FATAL: ecc_sign_hash_ex failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)buffer, buffer_len); + } + OUTPUT: + RETVAL + +int +_verify(Crypt::PK::ECC self, SV * sig, SV * data) + ALIAS: + _verify_rfc7518 = 1 + CODE: + { + int rv, stat; + unsigned char *data_ptr=NULL; + STRLEN data_len=0; + unsigned char *sig_ptr=NULL; + STRLEN sig_len=0; + + data_ptr = (unsigned char *)SvPVbyte(data, data_len); + sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len); + + RETVAL = 1; + if (ix == 1) { + rv = ecc_verify_hash_rfc7518(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, &stat, &self->key); + } + else { + rv = ecc_verify_hash(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, &stat, &self->key); + } + if (rv != CRYPT_OK || stat != 1) RETVAL = 0; + } + OUTPUT: + RETVAL + +SV * +shared_secret(Crypt::PK::ECC self, Crypt::PK::ECC pubkey) + CODE: + { + int rv; + unsigned char buffer[1024]; + unsigned long buffer_len = 1024; + + rv = ecc_shared_secret(&self->key, &pubkey->key, buffer, &buffer_len); + if (rv != CRYPT_OK) croak("FATAL: ecc_shared_secret failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)buffer, buffer_len); + } + OUTPUT: + RETVAL + +void +DESTROY(Crypt::PK::ECC self) + CODE: + _ecc_free_key(&self->key, &self->dp); + Safefree(self); + diff --git a/inc/CryptX_PK_RSA.xs.inc b/inc/CryptX_PK_RSA.xs.inc new file mode 100644 index 0000000..91bcc6e --- /dev/null +++ b/inc/CryptX_PK_RSA.xs.inc @@ -0,0 +1,419 @@ +MODULE = CryptX PACKAGE = Crypt::PK::RSA + +Crypt::PK::RSA +_new() + CODE: + { + int rv; + Newz(0, RETVAL, 1, struct rsa_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + RETVAL->key.type = -1; + RETVAL->pindex = find_prng("chacha20"); + if(RETVAL->pindex==-1) croak("FATAL: find_prng('chacha20') failed"); + rv = rng_make_prng(320, RETVAL->pindex, &RETVAL->pstate, NULL); /* 320bits = 40bytes */ + if (rv != CRYPT_OK) croak("FATAL: rng_make_prng failed: %s", error_to_string(rv)); + } + OUTPUT: + RETVAL + +void +generate_key(Crypt::PK::RSA self, int key_size=256, long key_e=65537) + PPCODE: + { + /* key_size is in octets */ + int rv; + /* gen the key */ + rv = rsa_make_key(&self->pstate, self->pindex, key_size, key_e, &self->key); + if (rv != CRYPT_OK) croak("FATAL: rsa_make_key failed: %s", error_to_string(rv)); + XPUSHs(ST(0)); /* return self */ + } + +void +_import(Crypt::PK::RSA self, SV * key_data) + PPCODE: + { + int rv; + unsigned char *data=NULL; + STRLEN data_len=0; + + data = (unsigned char *)SvPVbyte(key_data, data_len); + if (self->key.type != -1) { rsa_free(&self->key); self->key.type = -1; } + rv = rsa_import(data, (unsigned long)data_len, &self->key); + if (rv != CRYPT_OK) croak("FATAL: rsa_import failed: %s", error_to_string(rv)); + XPUSHs(ST(0)); /* return self */ + } + +void +_import_pkcs8(Crypt::PK::RSA self, SV * key_data) + PPCODE: + { + int rv; + unsigned char *data=NULL; + STRLEN data_len=0; + + data = (unsigned char *)SvPVbyte(key_data, data_len); + if (self->key.type != -1) { rsa_free(&self->key); self->key.type = -1; } + rv = rsa_import_pkcs8(data, (unsigned long)data_len, NULL, 0, &self->key); + if (rv != CRYPT_OK) croak("FATAL: rsa_import_pkcs8 failed: %s", error_to_string(rv)); + XPUSHs(ST(0)); /* return self */ + } + +void +_import_hex(Crypt::PK::RSA self, char *N, char *e, char *d=NULL, char *p=NULL, char *q=NULL, char *dP=NULL, char *dQ=NULL, char *qP=NULL) + PPCODE: + { + int rv; + if (self->key.type != -1) { rsa_free(&self->key); self->key.type = -1; } + rv = rsa_import_radix(16, N, e, d, p, q, dP, dQ, qP, &self->key); + if (rv != CRYPT_OK) croak("FATAL: rsa_import_radix failed: %s", error_to_string(rv)); + XPUSHs(ST(0)); /* return self */ + } + +int +is_private(Crypt::PK::RSA self) + CODE: + if (self->key.type == -1 || self->key.N == NULL) XSRETURN_UNDEF; + RETVAL = (self->key.type == PK_PRIVATE) ? 1 : 0; + OUTPUT: + RETVAL + +int +size(Crypt::PK::RSA self) + CODE: + if (self->key.type == -1 || self->key.N == NULL) XSRETURN_UNDEF; + RETVAL = mp_unsigned_bin_size(self->key.N); + OUTPUT: + RETVAL + +SV* +key2hash(Crypt::PK::RSA self) + PREINIT: + HV *rv_hash; + long siz, nsize; + char buf[20001]; + SV **not_used; + CODE: + if (self->key.type == -1 || self->key.N == NULL) XSRETURN_UNDEF; + nsize = mp_unsigned_bin_size(self->key.N); + rv_hash = newHV(); + /* =====> e */ + siz = (self->key.e) ? mp_unsigned_bin_size(self->key.e) : 0; + if (siz>10000) { + croak("FATAL: key2hash failed - 'e' too big number"); + } + if (siz>0) { + mp_tohex_with_leading_zero(self->key.e, buf, 20000, 0); + not_used = hv_store(rv_hash, "e", 1, newSVpv(buf, strlen(buf)), 0); + } + else{ + not_used = hv_store(rv_hash, "e", 1, newSVpv("", 0), 0); + } + /* =====> d */ + siz = (self->key.d) ? mp_unsigned_bin_size(self->key.d) : 0; + if (siz>10000) { + croak("FATAL: key2hash failed - 'd' too big number"); + } + if (siz>0) { + mp_tohex_with_leading_zero(self->key.d, buf, 20000, 0); + not_used = hv_store(rv_hash, "d", 1, newSVpv(buf, strlen(buf)), 0); + } + else{ + not_used = hv_store(rv_hash, "d", 1, newSVpv("", 0), 0); + } + /* =====> N */ + siz = (self->key.N) ? nsize : 0; + if (siz>10000) { + croak("FATAL: key2hash failed - 'N' too big number"); + } + if (siz>0) { + mp_tohex_with_leading_zero(self->key.N, buf, 20000, 0); + not_used = hv_store(rv_hash, "N", 1, newSVpv(buf, strlen(buf)), 0); + } + else{ + not_used = hv_store(rv_hash, "N", 1, newSVpv("", 0), 0); + } + /* =====> q */ + siz = (self->key.q) ? mp_unsigned_bin_size(self->key.q) : 0; + if (siz>10000) { + croak("FATAL: key2hash failed - 'q' too big number"); + } + if (siz>0) { + mp_tohex_with_leading_zero(self->key.q, buf, 20000, 0); + not_used = hv_store(rv_hash, "q", 1, newSVpv(buf, strlen(buf)), 0); + } + else{ + not_used = hv_store(rv_hash, "q", 1, newSVpv("", 0), 0); + } + /* =====> p */ + siz = (self->key.p) ? mp_unsigned_bin_size(self->key.p) : 0; + if (siz>10000) { + croak("FATAL: key2hash failed - 'p' too big number"); + } + if (siz>0) { + mp_tohex_with_leading_zero(self->key.p, buf, 20000, 0); + not_used = hv_store(rv_hash, "p", 1, newSVpv(buf, strlen(buf)), 0); + } + else{ + not_used = hv_store(rv_hash, "p", 1, newSVpv("", 0), 0); + } + /* =====> qP */ + siz = (self->key.qP) ? mp_unsigned_bin_size(self->key.qP) : 0; + if (siz>10000) { + croak("FATAL: key2hash failed - 'qP' too big number"); + } + if (siz>0) { + mp_tohex_with_leading_zero(self->key.qP, buf, 20000, 0); + not_used = hv_store(rv_hash, "qP", 2, newSVpv(buf, strlen(buf)), 0); + } + else{ + not_used = hv_store(rv_hash, "qP", 2, newSVpv("", 0), 0); + } + /* =====> dP */ + siz = (self->key.dP) ? mp_unsigned_bin_size(self->key.dP) : 0; + if (siz>10000) { + croak("FATAL: key2hash failed - 'dP' too big number"); + } + if (siz>0) { + mp_tohex_with_leading_zero(self->key.dP, buf, 20000, 0); + not_used = hv_store(rv_hash, "dP", 2, newSVpv(buf, strlen(buf)), 0); + } + else{ + not_used = hv_store(rv_hash, "dP", 2, newSVpv("", 0), 0); + } + /* =====> dQ */ + siz = (self->key.dQ) ? mp_unsigned_bin_size(self->key.dQ) : 0; + if (siz>10000) { + croak("FATAL: key2hash failed - 'dQ' too big number"); + } + if (siz>0) { + mp_tohex_with_leading_zero(self->key.dQ, buf, 20000, 0); + not_used = hv_store(rv_hash, "dQ", 2, newSVpv(buf, strlen(buf)), 0); + } + else{ + not_used = hv_store(rv_hash, "dQ", 2, newSVpv("", 0), 0); + } + /* =====> size */ + not_used = hv_store(rv_hash, "size", 4, newSViv(nsize), 0); + /* =====> type */ + not_used = hv_store(rv_hash, "type", 4, newSViv(self->key.type), 0); + if (not_used) not_used = NULL; /* just silence the warning: variable 'not_used' set but not used */ + RETVAL = newRV_noinc((SV*)rv_hash); + OUTPUT: + RETVAL + +SV* +export_key_der(Crypt::PK::RSA self, char * type) + CODE: + { + int rv; + unsigned char out[4096]; + unsigned long int out_len = 4096; + + RETVAL = newSVpvn(NULL, 0); /* undef */ + if (strnEQ(type, "private", 7)) { + rv = rsa_export(out, &out_len, PK_PRIVATE, &self->key); + if (rv != CRYPT_OK) croak("FATAL: rsa_export(PK_PRIVATE) failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)out, out_len); + } + else if (strnEQ(type, "public", 6)) { + rv = rsa_export(out, &out_len, PK_PUBLIC|PK_STD, &self->key); + if (rv != CRYPT_OK) croak("FATAL: rsa_export(PK_PUBLIC|PK_STD) failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)out, out_len); + } + else { + croak("FATAL: export_key_der invalid type '%s'", type); + } + } + OUTPUT: + RETVAL + +SV * +_encrypt(Crypt::PK::RSA self, SV * data, char * padding, char * oaep_hash, SV * oaep_lparam) + CODE: + { + int rv, hash_id; + unsigned char *lparam_ptr=NULL; + STRLEN lparam_len=0; + unsigned char *data_ptr=NULL; + STRLEN data_len=0; + unsigned char buffer[1024]; + unsigned long buffer_len = 1024; + + data_ptr = (unsigned char *)SvPVbyte(data, data_len); + + RETVAL = newSVpvn(NULL, 0); /* undef */ + if (strnEQ(padding, "oaep", 4)) { + hash_id = find_hash(oaep_hash); + if(hash_id==-1) croak("FATAL: find_hash failed for '%s'", oaep_hash); + lparam_ptr = (unsigned char *)SvPVbyte(oaep_lparam, lparam_len); + rv = rsa_encrypt_key_ex(data_ptr, (unsigned long)data_len, buffer, &buffer_len, lparam_ptr, (unsigned long)lparam_len, + &self->pstate, self->pindex, + hash_id, LTC_PKCS_1_OAEP, &self->key); + if (rv != CRYPT_OK) croak("FATAL: rsa_encrypt_key_ex failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)buffer, buffer_len); + } + else if (strnEQ(padding, "v1.5", 4)) { + rv = rsa_encrypt_key_ex(data_ptr, (unsigned long)data_len, buffer, &buffer_len, NULL, 0, + &self->pstate, self->pindex, + 0, LTC_PKCS_1_V1_5, &self->key); + if (rv != CRYPT_OK) croak("FATAL: rsa_encrypt_key_ex failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)buffer, buffer_len); + } + else if (strnEQ(padding, "none", 4)) { + /* raw RSA */ + rv = ltc_mp.rsa_me(data_ptr, (unsigned long)data_len, buffer, &buffer_len, PK_PUBLIC, &self->key); + if (rv != CRYPT_OK) croak("FATAL: rsa_me failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)buffer, buffer_len); + } + else { + croak("FATAL: rsa_encrypt invalid padding '%s'", padding); + } + } + OUTPUT: + RETVAL + +SV * +_decrypt(Crypt::PK::RSA self, SV * data, char * padding, char * oaep_hash, SV * oaep_lparam) + CODE: + { + int rv, hash_id, stat; + unsigned char *lparam_ptr=NULL; + STRLEN lparam_len=0; + unsigned char *data_ptr=NULL; + STRLEN data_len=0; + unsigned char buffer[1024]; + unsigned long buffer_len = 1024; + + data_ptr = (unsigned char *)SvPVbyte(data, data_len); + + RETVAL = newSVpvn(NULL, 0); /* undef */ + if (strnEQ(padding, "oaep", 4)) { + hash_id = find_hash(oaep_hash); + if(hash_id==-1) croak("FATAL: find_hash failed for '%s'", oaep_hash); + lparam_ptr = (unsigned char *)SvPVbyte(oaep_lparam, lparam_len); + rv = rsa_decrypt_key_ex(data_ptr, (unsigned long)data_len, buffer, &buffer_len, lparam_ptr, (unsigned long)lparam_len, + hash_id, LTC_PKCS_1_OAEP, &stat, &self->key); + if (rv != CRYPT_OK) croak("FATAL: rsa_decrypt_key_ex failed: %s", error_to_string(rv)); + if (stat != 1) croak("FATAL: rsa_decrypt - not valid OAEP packet"); + RETVAL = newSVpvn((char*)buffer, buffer_len); + } + else if (strnEQ(padding, "v1.5", 4)) { + rv = rsa_decrypt_key_ex(data_ptr, (unsigned long)data_len, buffer, &buffer_len, NULL, 0, + 0, LTC_PKCS_1_V1_5, &stat, &self->key); + if (rv != CRYPT_OK) croak("FATAL: rsa_decrypt_key_ex failed: %s", error_to_string(rv)); + if (stat != 1) croak("FATAL: rsa_decrypt - invalid"); + RETVAL = newSVpvn((char*)buffer, buffer_len); + } + else if (strnEQ(padding, "none", 4)) { + /* raw RSA */ + rv = ltc_mp.rsa_me(data_ptr, (unsigned long)data_len, buffer, &buffer_len, PK_PRIVATE, &self->key); + if (rv != CRYPT_OK) croak("FATAL: rsa_me failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)buffer, buffer_len); + } + else { + croak("FATAL: rsa_encrypt invalid padding '%s'", padding); + } + } + OUTPUT: + RETVAL + +SV * +_sign(Crypt::PK::RSA self, SV * data, char * padding, char * hash_name=NULL, unsigned long saltlen=12) + CODE: + { + int rv, hash_id; + unsigned char *data_ptr=NULL; + STRLEN data_len=0; + unsigned char buffer[1024]; + unsigned long buffer_len = 1024; + + data_ptr = (unsigned char *)SvPVbyte(data, data_len); + + RETVAL = newSVpvn(NULL, 0); /* undef */ + if (strnEQ(padding, "pss", 3)) { + hash_id = find_hash(hash_name); + if(hash_id==-1) croak("FATAL: find_hash failed for '%s'", hash_name); + rv = rsa_sign_hash_ex(data_ptr, (unsigned long)data_len, buffer, &buffer_len, LTC_PKCS_1_PSS, + &self->pstate, self->pindex, + hash_id, saltlen, &self->key); + if (rv != CRYPT_OK) croak("FATAL: rsa_sign_hash_ex failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)buffer, buffer_len); + } + else if (strnEQ(padding, "v1.5", 4)) { + hash_id = find_hash(hash_name); + if(hash_id==-1) croak("FATAL: find_hash failed for '%s'", hash_name); + rv = rsa_sign_hash_ex(data_ptr, (unsigned long)data_len, buffer, &buffer_len, LTC_PKCS_1_V1_5, + &self->pstate, self->pindex, + hash_id, 0, &self->key); + if (rv != CRYPT_OK) croak("FATAL: rsa_sign_hash_ex failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)buffer, buffer_len); + } + else if (strnEQ(padding, "none", 4)) { + /* raw RSA */ + rv = ltc_mp.rsa_me(data_ptr, (unsigned long)data_len, buffer, &buffer_len, PK_PRIVATE, &self->key); + if (rv != CRYPT_OK) croak("FATAL: rsa_me failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)buffer, buffer_len); + } + else { + croak("FATAL: rsa_sign invalid padding '%s'", padding); + } + } + OUTPUT: + RETVAL + +int +_verify(Crypt::PK::RSA self, SV * sig, SV * data, char * padding, char * hash_name=NULL, unsigned long saltlen=12) + CODE: + { + int rv, hash_id, stat; + unsigned char *data_ptr=NULL; + STRLEN data_len=0; + unsigned char *sig_ptr=NULL; + STRLEN sig_len=0; + unsigned char buffer[1024]; + unsigned long i, buffer_len = 1024; + + data_ptr = (unsigned char *)SvPVbyte(data, data_len); + sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len); + + RETVAL = 1; + if (strnEQ(padding, "pss", 3)) { + hash_id = find_hash(hash_name); + if(hash_id==-1) croak("FATAL: find_hash failed for '%s'", hash_name); + rv = rsa_verify_hash_ex(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, LTC_PKCS_1_PSS, + hash_id, saltlen, &stat, &self->key); + if (rv != CRYPT_OK || stat != 1) RETVAL = 0; + } + else if (strnEQ(padding, "v1.5", 4)) { + hash_id = find_hash(hash_name); + if(hash_id==-1) croak("FATAL: find_hash failed for '%s'", hash_name); + rv = rsa_verify_hash_ex(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, LTC_PKCS_1_V1_5, + hash_id, 0, &stat, &self->key); + if (rv != CRYPT_OK || stat != 1) RETVAL = 0; + } + else if (strnEQ(padding, "none", 4)) { + /* raw RSA */ + Zero(buffer, buffer_len, unsigned char); + rv = ltc_mp.rsa_me(sig_ptr, (unsigned long)sig_len, buffer, &buffer_len, PK_PUBLIC, &self->key); + if (rv != CRYPT_OK) croak("FATAL: rsa_me failed: %s", error_to_string(rv)); + if (data_len <= buffer_len && buffer_len > 0 && data_len > 0) { + for (i = 0; i < buffer_len - data_len; i++) if (buffer[i] != 0) RETVAL = 0; + if (memNE(data_ptr, buffer + buffer_len - data_len, data_len)) RETVAL = 0; + } + else { + RETVAL = 0; + } + } + else { + croak("FATAL: rsa_verify invalid padding '%s'", padding); + } + } + OUTPUT: + RETVAL + +void +DESTROY(Crypt::PK::RSA self) + CODE: + if (self->key.type != -1) { rsa_free(&self->key); self->key.type = -1; } + Safefree(self); + diff --git a/inc/CryptX_PRNG.xs.inc b/inc/CryptX_PRNG.xs.inc new file mode 100644 index 0000000..a5b07a7 --- /dev/null +++ b/inc/CryptX_PRNG.xs.inc @@ -0,0 +1,144 @@ +MODULE = CryptX PACKAGE = Crypt::PRNG + +Crypt::PRNG +_new(IV curpid, char * prng_name, SV * entropy=&PL_sv_undef) + CODE: + { + int rv, id; + unsigned char *ent=NULL; + STRLEN ent_len=0; + unsigned char entropy_buf[40]; + + Newz(0, RETVAL, 1, struct prng_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + + id = find_prng(prng_name); + if(id==-1) croak("FATAL: find_prng failed for '%s'", prng_name); + RETVAL->id = id; + RETVAL->last_pid = curpid; + RETVAL->desc = &prng_descriptor[id]; + + rv = RETVAL->desc->start(&RETVAL->state); + if (rv != CRYPT_OK) croak("FATAL: PRNG_start failed: %s", error_to_string(rv)); + + if(SvOK(entropy)) { + ent = (unsigned char *) SvPVbyte(entropy, ent_len); + rv = RETVAL->desc->add_entropy(ent, (unsigned long)ent_len, &RETVAL->state); + if (rv != CRYPT_OK) croak("FATAL: PRNG_add_entropy failed: %s", error_to_string(rv)); + } + else { + if (rng_get_bytes(entropy_buf, 40, NULL) != 40) croak("FATAL: rng_get_bytes failed: %s", error_to_string(rv)); + rv = RETVAL->desc->add_entropy(entropy_buf, 40, &RETVAL->state); + if (rv != CRYPT_OK) croak("FATAL: PRNG_add_entropy failed: %s", error_to_string(rv)); + } + rv = RETVAL->desc->ready(&RETVAL->state); + if (rv != CRYPT_OK) croak("FATAL: PRNG_ready failed: %s", error_to_string(rv)); + } + OUTPUT: + RETVAL + +void +DESTROY(Crypt::PRNG self) + CODE: + { + Safefree(self); + } + +void +add_entropy(Crypt::PRNG self, SV * entropy=&PL_sv_undef) + CODE: + { + STRLEN in_len=0; + unsigned char *in_buffer=NULL; + unsigned char entropy_buf[32]; + int rv; + if(SvOK(entropy)) { + in_buffer = (unsigned char *) SvPVbyte(entropy, in_len); + rv = self->desc->add_entropy(in_buffer, (unsigned long)in_len, &self->state); + if (rv != CRYPT_OK) croak("FATAL: PRNG_add_entropy failed: %s", error_to_string(rv)); + } + else { + if (rng_get_bytes(entropy_buf, 32, NULL) != 32) croak("FATAL: rng_get_bytes failed"); + rv = self->desc->add_entropy(entropy_buf, 32, &self->state); + if (rv != CRYPT_OK) croak("FATAL: PRNG_add_entropy failed: %s", error_to_string(rv)); + } + rv = self->desc->ready(&self->state); + if (rv != CRYPT_OK) croak("FATAL: PRNG_ready failed: %s", error_to_string(rv)); + } + +SV * +_bytes(Crypt::PRNG self, IV curpid, STRLEN output_len) + CODE: + { + int rv_len; + unsigned char *rdata; + unsigned char entropy_buf[32]; + + if (self->last_pid != curpid) { + rng_get_bytes(entropy_buf, 32, NULL); + self->desc->add_entropy(entropy_buf, 32, &self->state); + self->desc->ready(&self->state); + self->last_pid = curpid; + } + + RETVAL = NEWSV(0, output_len); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, output_len); + rdata = (unsigned char *)SvPV_nolen(RETVAL); + rv_len = (self->desc->read)(rdata, (unsigned long)output_len, &self->state); + if ((UV)rv_len != output_len) croak("FATAL: PRNG_read failed"); + } + OUTPUT: + RETVAL + +UV +_int32(Crypt::PRNG self, IV curpid) + CODE: + { + int i; + unsigned char rdata[4]; + unsigned char entropy_buf[32]; + + if (self->last_pid != curpid) { + rng_get_bytes(entropy_buf, 32, NULL); + self->desc->add_entropy(entropy_buf, 32, &self->state); + self->desc->ready(&self->state); + self->last_pid = curpid; + } + + i = (self->desc->read)(rdata, 4, &self->state); + if (i != 4) croak("FATAL: PRNG_read failed"); + RETVAL = ((UV)(rdata[0])<<24) + ((UV)(rdata[1])<<16) + ((UV)(rdata[2])<<8) + ((UV)(rdata[3])); + } + OUTPUT: + RETVAL + +NV +_double(Crypt::PRNG self, IV curpid, ...) + CODE: + { + int i; + unsigned long a, b; /* 32bit is enough */ + unsigned char rdata[7]; /* for double we need 53 bits */ + unsigned char entropy_buf[32]; + NV limit; + + if (self->last_pid != curpid) { + rng_get_bytes(entropy_buf, 32, NULL); + self->desc->add_entropy(entropy_buf, 32, &self->state); + self->desc->ready(&self->state); + self->last_pid = curpid; + } + + i = (self->desc->read)(rdata, 7, &self->state); + if (i != 7) croak("FATAL: PRNG_read failed"); + a = (((unsigned long)(rdata[0])<<16) + ((unsigned long)(rdata[1])<<8) + ((unsigned long)(rdata[2]))) & 0x1FFFFF; /* 21 bits */ + b = ((unsigned long)(rdata[3])<<24) + ((unsigned long)(rdata[4])<<16) + ((unsigned long)(rdata[5])<<8) + ((unsigned long)(rdata[6])); /* 32 bits */ + RETVAL = ( (NV)a * 4294967296.0 + (NV)b ) / 9007199254740992.0; /* (a * 2^32 + b) / 2^53 */ + if (items>2 && SvOK(ST(2))) { + limit = SvNV(ST(2)); + if (limit > 0 || limit < 0) RETVAL = RETVAL * limit; + } + } + OUTPUT: + RETVAL diff --git a/inc/CryptX_Stream_ChaCha.xs.inc b/inc/CryptX_Stream_ChaCha.xs.inc new file mode 100644 index 0000000..5beb836 --- /dev/null +++ b/inc/CryptX_Stream_ChaCha.xs.inc @@ -0,0 +1,91 @@ +MODULE = CryptX PACKAGE = Crypt::Stream::ChaCha + +Crypt::Stream::ChaCha +_new(SV * key, SV * nonce, UV counter = 0, int rounds = 20) + CODE: + { + int rv; + STRLEN iv_len=0, k_len=0; + unsigned char *iv=NULL, *k=NULL; + + if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); + if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar"); + k = (unsigned char *) SvPVbyte(key, k_len); + iv = (unsigned char *) SvPVbyte(nonce, iv_len); + + Newz(0, RETVAL, 1, struct chacha_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + + rv = chacha_setup(&RETVAL->state, k, (unsigned long)k_len, rounds); + if (rv != CRYPT_OK) croak("FATAL: chacha_setup failed: %s", error_to_string(rv)); + + if (iv_len == 12) { + rv = chacha_ivctr32(&RETVAL->state, iv, (unsigned long)iv_len, (ulong32)counter); + if (rv != CRYPT_OK) croak("FATAL: chacha_ivctr32 failed: %s", error_to_string(rv)); + } + else if (iv_len == 8) { + rv = chacha_ivctr64(&RETVAL->state, iv, (unsigned long)iv_len, (ulong64)counter); + if (rv != CRYPT_OK) croak("FATAL: chacha_ivctr64 failed: %s", error_to_string(rv)); + } + else { + croak("FATAL: chacha IV length must be 8 or 12 bytes"); + } + } + OUTPUT: + RETVAL + +void +DESTROY(Crypt::Stream::ChaCha self) + CODE: + chacha_done(&self->state); + Safefree(self); + +Crypt::Stream::ChaCha +clone(Crypt::Stream::ChaCha self) + CODE: + Newz(0, RETVAL, 1, struct chacha_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + Copy(&self->state, &RETVAL->state, 1, struct chacha_struct); + OUTPUT: + RETVAL + +SV * +keystream(Crypt::Stream::ChaCha self, STRLEN out_len) + CODE: + { + int rv; + unsigned char *out_data; + + RETVAL = NEWSV(0, out_len); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, out_len); + out_data = (unsigned char *)SvPV_nolen(RETVAL); + rv = chacha_keystream(&self->state, out_data, out_len); + if (rv != CRYPT_OK) croak("FATAL: chacha_keystream failed: %s", error_to_string(rv)); + } + OUTPUT: + RETVAL + +SV * +crypt(Crypt::Stream::ChaCha self, SV * data) + CODE: + { + int rv; + STRLEN in_data_len; + unsigned char *in_data, *out_data; + + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + if (in_data_len==0) { + RETVAL = newSVpvn("", 0); + } + else { + RETVAL = NEWSV(0, in_data_len); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, in_data_len); + out_data = (unsigned char *)SvPV_nolen(RETVAL); + rv = chacha_crypt(&self->state, in_data, (unsigned long)in_data_len, out_data); + if (rv != CRYPT_OK) croak("FATAL: chacha_crypt failed: %s", error_to_string(rv)); + } + } + OUTPUT: + RETVAL diff --git a/inc/CryptX_Stream_RC4.xs.inc b/inc/CryptX_Stream_RC4.xs.inc new file mode 100644 index 0000000..45a047d --- /dev/null +++ b/inc/CryptX_Stream_RC4.xs.inc @@ -0,0 +1,77 @@ +MODULE = CryptX PACKAGE = Crypt::Stream::RC4 + +Crypt::Stream::RC4 +_new(SV * key) + CODE: + { + int rv; + STRLEN k_len=0; + unsigned char *k=NULL; + + if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); + k = (unsigned char *) SvPVbyte(key, k_len); + + Newz(0, RETVAL, 1, struct rc4_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + + rv = rc4_stream_setup(&RETVAL->state, k, (unsigned long)k_len); + if (rv != CRYPT_OK) croak("FATAL: rc4_stream_setup failed: %s", error_to_string(rv)); + } + OUTPUT: + RETVAL + +void +DESTROY(Crypt::Stream::RC4 self) + CODE: + rc4_stream_done(&self->state); + Safefree(self); + +Crypt::Stream::RC4 +clone(Crypt::Stream::RC4 self) + CODE: + Newz(0, RETVAL, 1, struct rc4_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + Copy(&self->state, &RETVAL->state, 1, struct rc4_struct); + OUTPUT: + RETVAL + +SV * +keystream(Crypt::Stream::RC4 self, STRLEN out_len) + CODE: + { + int rv; + unsigned char *out_data; + + RETVAL = NEWSV(0, out_len); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, out_len); + out_data = (unsigned char *)SvPV_nolen(RETVAL); + rv = rc4_stream_keystream(&self->state, out_data, out_len); + if (rv != CRYPT_OK) croak("FATAL: rc4_stream_keystream failed: %s", error_to_string(rv)); + } + OUTPUT: + RETVAL + +SV * +crypt(Crypt::Stream::RC4 self, SV * data) + CODE: + { + int rv; + STRLEN in_data_len; + unsigned char *in_data, *out_data; + + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + if (in_data_len==0) { + RETVAL = newSVpvn("", 0); + } + else { + RETVAL = NEWSV(0, in_data_len); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, in_data_len); + out_data = (unsigned char *)SvPV_nolen(RETVAL); + rv = rc4_stream_crypt(&self->state, in_data, (unsigned long)in_data_len, out_data); + if (rv != CRYPT_OK) croak("FATAL: rc4_stream_crypt failed: %s", error_to_string(rv)); + } + } + OUTPUT: + RETVAL diff --git a/inc/CryptX_Stream_Sober128.xs.inc b/inc/CryptX_Stream_Sober128.xs.inc new file mode 100644 index 0000000..5269afc --- /dev/null +++ b/inc/CryptX_Stream_Sober128.xs.inc @@ -0,0 +1,82 @@ +MODULE = CryptX PACKAGE = Crypt::Stream::Sober128 + +Crypt::Stream::Sober128 +_new(SV * key, SV * nonce) + CODE: + { + int rv; + STRLEN iv_len=0, k_len=0; + unsigned char *iv=NULL, *k=NULL; + + if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); + if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar"); + k = (unsigned char *) SvPVbyte(key, k_len); + iv = (unsigned char *) SvPVbyte(nonce, iv_len); + + Newz(0, RETVAL, 1, struct sober128_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + + rv = sober128_stream_setup(&RETVAL->state, k, (unsigned long)k_len); + if (rv != CRYPT_OK) croak("FATAL: sober128_stream_setup failed: %s", error_to_string(rv)); + + rv = sober128_stream_setiv(&RETVAL->state, iv, (unsigned long)iv_len); + if (rv != CRYPT_OK) croak("FATAL: sober128_stream_setiv failed: %s", error_to_string(rv)); + } + OUTPUT: + RETVAL + +void +DESTROY(Crypt::Stream::Sober128 self) + CODE: + sober128_stream_done(&self->state); + Safefree(self); + +Crypt::Stream::Sober128 +clone(Crypt::Stream::Sober128 self) + CODE: + Newz(0, RETVAL, 1, struct sober128_struct); + if (!RETVAL) croak("FATAL: Newz failed"); + Copy(&self->state, &RETVAL->state, 1, struct sober128_struct); + OUTPUT: + RETVAL + +SV * +keystream(Crypt::Stream::Sober128 self, STRLEN out_len) + CODE: + { + int rv; + unsigned char *out_data; + + RETVAL = NEWSV(0, out_len); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, out_len); + out_data = (unsigned char *)SvPV_nolen(RETVAL); + rv = sober128_stream_keystream(&self->state, out_data, out_len); + if (rv != CRYPT_OK) croak("FATAL: sober128_stream_keystream failed: %s", error_to_string(rv)); + } + OUTPUT: + RETVAL + +SV * +crypt(Crypt::Stream::Sober128 self, SV * data) + CODE: + { + int rv; + STRLEN in_data_len; + unsigned char *in_data, *out_data; + + in_data = (unsigned char *)SvPVbyte(data, in_data_len); + if (in_data_len==0) { + RETVAL = newSVpvn("", 0); + } + else { + RETVAL = NEWSV(0, in_data_len); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, in_data_len); + out_data = (unsigned char *)SvPV_nolen(RETVAL); + rv = sober128_stream_crypt(&self->state, in_data, (unsigned long)in_data_len, out_data); + if (rv != CRYPT_OK) croak("FATAL: sober128_stream_crypt failed: %s", error_to_string(rv)); + } + } + OUTPUT: + RETVAL diff --git a/lib/Crypt/AuthEnc.pm b/lib/Crypt/AuthEnc.pm new file mode 100644 index 0000000..b596078 --- /dev/null +++ b/lib/Crypt/AuthEnc.pm @@ -0,0 +1,17 @@ +package Crypt::AuthEnc; + +use strict; +use warnings; +our $VERSION = '0.048'; + +sub CLONE_SKIP { 1 } # prevent cloning + +1; + +__END__ + +=head1 NAME + +Crypt::AuthEnc - [internal only] + +=cut \ No newline at end of file diff --git a/lib/Crypt/AuthEnc/CCM.pm b/lib/Crypt/AuthEnc/CCM.pm new file mode 100644 index 0000000..0ba3e39 --- /dev/null +++ b/lib/Crypt/AuthEnc/CCM.pm @@ -0,0 +1,100 @@ +package Crypt::AuthEnc::CCM; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::AuthEnc Exporter); +our %EXPORT_TAGS = ( all => [qw( ccm_encrypt_authenticate ccm_decrypt_verify )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +use Crypt::Cipher; + +### the following functions are implemented in XS: +# - _memory_encrypt +# - _memory_decrypt + +sub ccm_encrypt_authenticate { + my $cipher_name = shift; + my $key = shift; + my $nonce = shift; + my $adata = shift; + my $tag_len = shift; + my $plaintext = shift; + return _memory_encrypt(Crypt::Cipher::_trans_cipher_name($cipher_name), $key, $nonce, $adata, $tag_len, $plaintext); +} + +sub ccm_decrypt_verify { + my $cipher_name = shift; + my $key = shift; + my $nonce = shift; + my $adata = shift; + my $ciphertext = shift; + my $tag = shift; + return _memory_decrypt(Crypt::Cipher::_trans_cipher_name($cipher_name), $key, $nonce, $adata, $ciphertext, $tag); +} + +1; + +=pod + +=head1 NAME + +Crypt::AuthEnc::CCM - Authenticated encryption in CCM mode + +=head1 SYNOPSIS + + ### functional interface + use Crypt::AuthEnc::CCM qw(ccm_encrypt_authenticate ccm_decrypt_verify); + + my ($ciphertext, $tag) = ccm_encrypt_authenticate('AES', $key, $nonce, $adata, $tag_len, $plaintext); + my $plaintext = ccm_decrypt_verify('AES', $key, $nonce, $adata, $ciphertext, $tag); + +=head1 DESCRIPTION + +CCM is a encrypt+authenticate mode that is centered around using AES (or any 16-byte cipher) as aprimitive. +Unlike EAX and OCB mode, it is only meant for packet mode where the length of the input is known in advance. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::AuthEnc::CCM qw(ccm_encrypt_authenticate ccm_decrypt_verify); + +=head1 FUNCTIONS + +=head2 ccm_encrypt_authenticate + + my ($ciphertext, $tag) = ccm_encrypt_authenticate($cipher, $key, $nonce, $adata, $tag_len, $plaintext); + + # $cipher .. 'AES' or name of any other cipher with 16-byte block len + # $key ..... key of proper length (e.g. 128/192/256bits for AES) + # $nonce ... unique nonce/salt (no need to keep it secret) + # $adata ... additional authenticated data + # $tag_len . required length of output tag + +CCM parameters should follow L + + # tag length: 4, 6, 8, 10, 12, 14, 16 (reasonable minimum is 8) + # nonce length: 7, 8, 9, 10, 11, 12, 13 (if you are not sure, use 11) + # BEWARE nonce length determines max. enc/dec data size: max_data_size = 2^(8*(15-nonce_len)) + +=head2 ccm_decrypt_verify + + my $plaintext = ccm_decrypt_verify($cipher, $key, $nonce, $adata, $ciphertext, $tag); + + # on error returns undef + +=head1 SEE ALSO + +=over + +=item * L, L, L, L + +=item * L + +=back diff --git a/lib/Crypt/AuthEnc/ChaCha20Poly1305.pm b/lib/Crypt/AuthEnc/ChaCha20Poly1305.pm new file mode 100644 index 0000000..c134a54 --- /dev/null +++ b/lib/Crypt/AuthEnc/ChaCha20Poly1305.pm @@ -0,0 +1,164 @@ +package Crypt::AuthEnc::ChaCha20Poly1305; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::AuthEnc Exporter); +our %EXPORT_TAGS = ( all => [qw( chacha20poly1305_encrypt_authenticate chacha20poly1305_decrypt_verify )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; + +sub new { my $class = shift; _new(@_) } + +sub chacha20poly1305_encrypt_authenticate { + my $key = shift; + my $iv = shift; + my $adata = shift; + my $plaintext = shift; + + my $m = Crypt::AuthEnc::ChaCha20Poly1305->new($key, $iv); + $m->adata_add(defined $adata ? $adata : ''); #XXX-TODO if no aad we have to pass empty string + my $ct = $m->encrypt_add($plaintext); + my $tag = $m->encrypt_done; + return ($ct, $tag); +} + +sub chacha20poly1305_decrypt_verify { + my $key = shift; + my $iv = shift; + my $adata = shift; + my $ciphertext = shift; + my $tag = shift; + + my $m = Crypt::AuthEnc::ChaCha20Poly1305->new($key, $iv); + $m->adata_add(defined $adata ? $adata : ''); #XXX-TODO if no aad we have to pass empty string + my $ct = $m->decrypt_add($ciphertext); + return $m->decrypt_done($tag) ? $ct : undef; +} + +1; + +=pod + +=head1 NAME + +Crypt::AuthEnc::ChaCha20Poly1305 - Authenticated encryption in ChaCha20Poly1305 mode + +=head1 SYNOPSIS + + ### OO interface + use Crypt::AuthEnc::ChaCha20Poly1305; + + # encrypt and authenticate + my $ae = Crypt::AuthEnc::ChaCha20Poly1305->new($key, $iv); + $ae->aad_add('additional_authenticated_data1'); + $ae->aad_add('additional_authenticated_data2'); + $ct = $ae->encrypt_add('data1'); + $ct = $ae->encrypt_add('data2'); + $ct = $ae->encrypt_add('data3'); + $tag = $ae->encrypt_done(); + + # decrypt and verify + my $ae = Crypt::AuthEnc::ChaCha20Poly1305->new($key, $iv); + $ae->aad_add('additional_authenticated_data1'); + $ae->aad_add('additional_authenticated_data2'); + $pt = $ae->decrypt_add('ciphertext1'); + $pt = $ae->decrypt_add('ciphertext2'); + $pt = $ae->decrypt_add('ciphertext3'); + $tag = $ae->decrypt_done(); + die "decrypt failed" unless $tag eq $expected_tag; + + #or + my $result = $ae->decrypt_done($expected_tag) die "decrypt failed"; + + ### functional interface + use Crypt::AuthEnc::ChaCha20Poly1305 qw(chacha20poly1305_encrypt_authenticate chacha20poly1305_decrypt_verify); + + my ($ciphertext, $tag) = chacha20poly1305_encrypt_authenticate($key, $iv, $adata, $plaintext); + my $plaintext = chacha20poly1305_decrypt_verify($key, $iv, $adata, $ciphertext, $tag); + +=head1 DESCRIPTION + +Provides encryption and authentication based on ChaCha20 + Poly1305 as defined in RFC 7539 - L + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::AuthEnc::ChaCha20Poly1305 qw(chacha20poly1305_encrypt_authenticate chacha20poly1305_decrypt_verify); + +=head1 FUNCTIONS + +=head2 chacha20poly1305_encrypt_authenticate + + my ($ciphertext, $tag) = chacha20poly1305_encrypt_authenticate($key, $iv, $adata, $plaintext); + + # $key ..... key of proper length (128 or 256 bits / 16 or 32 bytes) + # $iv ...... initialization vector (64 or 96 bits / 8 or 12 bytes) + # $adata ... additional authenticated data (optional) + +=head2 chacha20poly1305_decrypt_verify + + my $plaintext = chacha20poly1305_decrypt_verify($key, $iv, $adata, $ciphertext, $tag); + + # on error returns undef + +=head1 METHODS + +=head2 new + + my $ae = Crypt::AuthEnc::ChaCha20Poly1305->new($key, $iv); + + # $key ..... encryption key of proper length (128 or 256 bits / 16 or 32 bytes) + # $iv ...... initialization vector (64 or 96 bits / 8 or 12 bytes) + +=head2 aad_add + +Can be called before the first C or C; + + $ae->aad_add($aad_data); #can be called multiple times + +=head2 encrypt_add + + $ciphertext = $ae->encrypt_add($data); #can be called multiple times + +=head2 encrypt_done + + $tag = $ae->encrypt_done(); + +=head2 decrypt_add + + $plaintext = $ae->decrypt_add($ciphertext); #can be called multiple times + +=head2 decrypt_done + + my $result = $ae->decrypt_done($tag); # returns 1 (success) or 0 (failure) + #or + my $tag = $ae->decrypt_done; # returns $tag value + +=head2 clone + + my $ae_new = $ae->clone; + +=head2 set_iv + + $ae->set_iv($iv); + +=head2 set_iv_rfc7905 + + $ae->set_iv_rfc7905($iv, $seqnum); + +=head1 SEE ALSO + +=over + +=item * L, L, L, L, L + +=item * L + +=back diff --git a/lib/Crypt/AuthEnc/EAX.pm b/lib/Crypt/AuthEnc/EAX.pm new file mode 100644 index 0000000..e5e7095 --- /dev/null +++ b/lib/Crypt/AuthEnc/EAX.pm @@ -0,0 +1,179 @@ +package Crypt::AuthEnc::EAX; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::AuthEnc Exporter); +our %EXPORT_TAGS = ( all => [qw( eax_encrypt_authenticate eax_decrypt_verify )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +use Crypt::Cipher; + +### the following methods/functions are implemented in XS: +# - _new +# - DESTROY +# - clone +# - encrypt_add +# - encrypt_done +# - decrypt_add +# - decrypt_done +# - aad_add + +sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } + +sub eax_encrypt_authenticate { + my $cipher_name = shift; + my $key = shift; + my $iv = shift; + my $adata = shift; + my $plaintext = shift; + + my $m = Crypt::AuthEnc::EAX->new($cipher_name, $key, $iv); + $m->aad_add($adata) if defined $adata; + my $ct = $m->encrypt_add($plaintext); + my $tag = $m->encrypt_done; + return ($ct, $tag); +} + +sub eax_decrypt_verify { + my $cipher_name = shift; + my $key = shift; + my $iv = shift; + my $adata = shift; + my $ciphertext = shift; + my $tag = shift; + + my $m = Crypt::AuthEnc::EAX->new($cipher_name, $key, $iv); + $m->aad_add($adata) if defined $adata; + my $ct = $m->decrypt_add($ciphertext); + return $m->decrypt_done($tag) ? $ct : undef; +} + +sub header_add { + # obsolete, only for backwards compatibility + shift->aad_add(@_); +} + +1; + +=pod + +=head1 NAME + +Crypt::AuthEnc::EAX - Authenticated encryption in EAX mode + +=head1 SYNOPSIS + + ### OO interface + use Crypt::AuthEnc::EAX; + + # encrypt and authenticate + my $ae = Crypt::AuthEnc::EAX->new("AES", $key, $iv); + $ae->aad_add('additional_authenticated_data1'); + $ae->aad_add('additional_authenticated_data2'); + $ct = $ae->encrypt_add('data1'); + $ct = $ae->encrypt_add('data2'); + $ct = $ae->encrypt_add('data3'); + $tag = $ae->encrypt_done(); + + # decrypt and verify + my $ae = Crypt::AuthEnc::EAX->new("AES", $key, $iv); + $ae->aad_add('additional_authenticated_data1'); + $ae->aad_add('additional_authenticated_data2'); + $pt = $ae->decrypt_add('ciphertext1'); + $pt = $ae->decrypt_add('ciphertext2'); + $pt = $ae->decrypt_add('ciphertext3'); + $tag = $ae->decrypt_done(); + die "decrypt failed" unless $tag eq $expected_tag; + + #or + my $result = $ae->decrypt_done($expected_tag) die "decrypt failed"; + + ### functional interface + use Crypt::AuthEnc::EAX qw(eax_encrypt_authenticate eax_decrypt_verify); + + my ($ciphertext, $tag) = eax_encrypt_authenticate('AES', $key, $iv, $adata, $plaintext); + my $plaintext = eax_decrypt_verify('AES', $key, $iv, $adata, $ciphertext, $tag); + +=head1 DESCRIPTION + +EAX is a mode that requires a cipher, CTR and OMAC support and provides encryption and authentication. +It is initialized with a random IV that can be shared publicly, additional authenticated data which can +be fixed and public, and a random secret symmetric key. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::AuthEnc::EAX qw(eax_encrypt_authenticate eax_decrypt_verify); + +=head1 FUNCTIONS + +=head2 eax_encrypt_authenticate + + my ($ciphertext, $tag) = eax_encrypt_authenticate($cipher, $key, $iv, $adata, $plaintext); + + # $cipher .. 'AES' or name of any other cipher with 16-byte block len + # $key ..... AES key of proper length (128/192/256bits) + # $iv ...... unique initialization vector (no need to keep it secret) + # $adata ... additional authenticated data + +=head2 eax_decrypt_verify + + my $plaintext = eax_decrypt_verify($cipher, $key, $iv, $adata, $ciphertext, $tag); + + # on error returns undef + +=head1 METHODS + +=head2 new + + my $ae = Crypt::AuthEnc::EAX->new($cipher, $key, $iv); + #or + my $ae = Crypt::AuthEnc::EAX->new($cipher, $key, $iv, $adata); + + # $cipher .. 'AES' or name of any other cipher with 16-byte block len + # $key ..... AES key of proper length (128/192/256bits) + # $iv ...... unique initialization vector (no need to keep it secret) + # $adata ... additional authenticated data (optional) + +=head2 aad_add + + $ae->aad_add($adata); #can be called multiple times + +=head2 encrypt_add + + $ciphertext = $ae->encrypt_add($data); #can be called multiple times + +=head2 encrypt_done + + $tag = $ae->encrypt_done(); + +=head2 decrypt_add + + $plaintext = $ae->decrypt_add($ciphertext); #can be called multiple times + +=head2 decrypt_done + + my $result = $ae->decrypt_done($tag); # returns 1 (success) or 0 (failure) + #or + my $tag = $ae->decrypt_done; # returns $tag value + +=head2 clone + + my $ae_new = $ae->clone; + +=head1 SEE ALSO + +=over + +=item * L, L, L, L + +=item * L + +=back diff --git a/lib/Crypt/AuthEnc/GCM.pm b/lib/Crypt/AuthEnc/GCM.pm new file mode 100644 index 0000000..4d9b98f --- /dev/null +++ b/lib/Crypt/AuthEnc/GCM.pm @@ -0,0 +1,179 @@ +package Crypt::AuthEnc::GCM; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::AuthEnc Exporter); +our %EXPORT_TAGS = ( all => [qw( gcm_encrypt_authenticate gcm_decrypt_verify )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +use Crypt::Cipher; + +sub new { + my ($class, $cipher, $key, $iv) = @_; + my $self = _new(Crypt::Cipher::_trans_cipher_name($cipher), $key); + # for backwards compatibility the $iv is optional + $self->iv_add($iv) if defined $iv; + return $self; +} + +sub gcm_encrypt_authenticate { + my $cipher_name = shift; + my $key = shift; + my $iv = shift; + my $adata = shift; + my $plaintext = shift; + + my $m = Crypt::AuthEnc::GCM->new($cipher_name, $key); + $m->iv_add($iv); + $m->adata_add(defined $adata ? $adata : ''); #XXX-TODO if no aad we have to pass empty string + my $ct = $m->encrypt_add($plaintext); + my $tag = $m->encrypt_done; + return ($ct, $tag); +} + +sub gcm_decrypt_verify { + my $cipher_name = shift; + my $key = shift; + my $iv = shift; + my $adata = shift; + my $ciphertext = shift; + my $tag = shift; + + my $m = Crypt::AuthEnc::GCM->new($cipher_name, $key); + $m->iv_add($iv); + $m->adata_add(defined $adata ? $adata : ''); #XXX-TODO if no aad we have to pass empty string + my $ct = $m->decrypt_add($ciphertext); + return $m->decrypt_done($tag) ? $ct : undef; +} + +1; + +=pod + +=head1 NAME + +Crypt::AuthEnc::GCM - Authenticated encryption in GCM mode + +=head1 SYNOPSIS + + ### OO interface + use Crypt::AuthEnc::GCM; + + # encrypt and authenticate + my $ae = Crypt::AuthEnc::GCM->new("AES", $key, $iv); + $ae->aad_add('additional_authenticated_data1'); + $ae->aad_add('additional_authenticated_data2'); + $ct = $ae->encrypt_add('data1'); + $ct = $ae->encrypt_add('data2'); + $ct = $ae->encrypt_add('data3'); + $tag = $ae->encrypt_done(); + + # decrypt and verify + my $ae = Crypt::AuthEnc::GCM->new("AES", $key, $iv); + $ae->aad_add('additional_authenticated_data1'); + $ae->aad_add('additional_authenticated_data2'); + $pt = $ae->decrypt_add('ciphertext1'); + $pt = $ae->decrypt_add('ciphertext2'); + $pt = $ae->decrypt_add('ciphertext3'); + $tag = $ae->decrypt_done(); + die "decrypt failed" unless $tag eq $expected_tag; + + #or + my $result = $ae->decrypt_done($expected_tag) die "decrypt failed"; + + ### functional interface + use Crypt::AuthEnc::GCM qw(gcm_encrypt_authenticate gcm_decrypt_verify); + + my ($ciphertext, $tag) = gcm_encrypt_authenticate('AES', $key, $iv, $adata, $plaintext); + my $plaintext = gcm_decrypt_verify('AES', $key, $iv, $adata, $ciphertext, $tag); + +=head1 DESCRIPTION + +Galois/Counter Mode (GCM) - provides encryption and authentication. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::AuthEnc::GCM qw(gcm_encrypt_authenticate gcm_decrypt_verify); + +=head1 FUNCTIONS + +=head2 gcm_encrypt_authenticate + + my ($ciphertext, $tag) = gcm_encrypt_authenticate($cipher, $key, $iv, $adata, $plaintext); + + # $cipher .. 'AES' or name of any other cipher with 16-byte block len + # $key ..... AES key of proper length (128/192/256bits) + # $iv ...... initialization vector + # $adata ... additional authenticated data + +=head2 gcm_decrypt_verify + + my $plaintext = gcm_decrypt_verify($cipher, $key, $iv, $adata, $ciphertext, $tag); + + # on error returns undef + +=head1 METHODS + +=head2 new + + my $ae = Crypt::AuthEnc::GCM->new($cipher, $key); + #or + my $ae = Crypt::AuthEnc::GCM->new($cipher, $key, $iv); + + # $cipher .. 'AES' or name of any other cipher + # $key ..... encryption key of proper length + # $iv ...... initialization vector (optional, you can set it later via iv_add method) + +=head2 iv_add + + $ae->iv_add($iv_data); #can be called multiple times + +=head2 aad_add + +Can be called B all C calls but before the first C or C; + + $ae->aad_add($aad_data); #can be called multiple times + +=head2 encrypt_add + + $ciphertext = $ae->encrypt_add($data); #can be called multiple times + +=head2 encrypt_done + + $tag = $ae->encrypt_done(); + +=head2 decrypt_add + + $plaintext = $ae->decrypt_add($ciphertext); #can be called multiple times + +=head2 decrypt_done + + my $result = $ae->decrypt_done($tag); # returns 1 (success) or 0 (failure) + #or + my $tag = $ae->decrypt_done; # returns $tag value + +=head2 reset + + $ae->reset; + +=head2 clone + + my $ae_new = $ae->clone; + +=head1 SEE ALSO + +=over + +=item * L, L, L, L + +=item * L + +=back diff --git a/lib/Crypt/AuthEnc/OCB.pm b/lib/Crypt/AuthEnc/OCB.pm new file mode 100644 index 0000000..aabab36 --- /dev/null +++ b/lib/Crypt/AuthEnc/OCB.pm @@ -0,0 +1,174 @@ +package Crypt::AuthEnc::OCB; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::AuthEnc Exporter); +our %EXPORT_TAGS = ( all => [qw( ocb_encrypt_authenticate ocb_decrypt_verify )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +use Crypt::Cipher; + +sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } + +sub ocb_encrypt_authenticate { + my $cipher_name = shift; + my $key = shift; + my $nonce = shift; + my $adata = shift; + my $plaintext = shift; + + my $m = Crypt::AuthEnc::OCB->new($cipher_name, $key, $nonce); + $m->aad_add($adata) if defined $adata; + my $ct = $m->encrypt_last($plaintext); + my $tag = $m->encrypt_done; + return ($ct, $tag); +} + +sub ocb_decrypt_verify { + my $cipher_name = shift; + my $key = shift; + my $nonce = shift; + my $adata = shift; + my $ciphertext = shift; + my $tag = shift; + + my $m = Crypt::AuthEnc::OCB->new($cipher_name, $key, $nonce); + $m->aad_add($adata) if defined $adata; + my $ct = $m->decrypt_last($ciphertext); + return $m->decrypt_done($tag) ? $ct : undef; +} + +sub adata_add { + # obsolete, only for backwards compatibility + shift->aad_add(@_); +} + +1; + +=pod + +=head1 NAME + +Crypt::AuthEnc::OCB - Authenticated encryption in OCBv3 mode + +=head1 SYNOPSIS + + ### OO interface + use Crypt::AuthEnc::OCB; + + # encrypt and authenticate + my $ae = Crypt::AuthEnc::OCB->new("AES", $key, $nonce); + $ae->aad_add('additional_authenticated_data1'); + $ae->aad_add('additional_authenticated_data2'); + $ct = $ae->encrypt_add('data1'); + $ct = $ae->encrypt_add('data2'); + $ct = $ae->encrypt_add('data3'); + $ct = $ae->encrypt_last('rest of data'); + ($ct,$tag) = $ae->encrypt_done(); + + # decrypt and verify + my $ae = Crypt::AuthEnc::OCB->new("AES", $key, $nonce); + $ae->aad_add('additional_authenticated_data1'); + $ae->aad_add('additional_authenticated_data2'); + $pt = $ae->decrypt_add('ciphertext1'); + $pt = $ae->decrypt_add('ciphertext2'); + $pt = $ae->decrypt_add('ciphertext3'); + $pt = $ae->decrypt_last('rest of data'); + ($pt,$tag) = $ae->decrypt_done(); + + ### functional interface + use Crypt::AuthEnc::OCB qw(ocb_encrypt_authenticate ocb_decrypt_verify); + + my ($ciphertext, $tag) = ocb_encrypt_authenticate('AES', $key, $nonce, $adata, $plaintext); + my $plaintext = ocb_decrypt_verify('AES', $key, $nonce, $adata, $ciphertext, $tag); + +=head1 DESCRIPTION + +This module implements OCB version 3 according http://datatracker.ietf.org/doc/draft-irtf-cfrg-ocb/ + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::AuthEnc::OCB qw(ocb_encrypt_authenticate ocb_decrypt_verify); + +=head1 FUNCTIONS + +=head2 ocb_encrypt_authenticate + + my ($ciphertext, $tag) = ocb_encrypt_authenticate($cipher, $key, $nonce, $adata, $plaintext); + + # $cipher .. 'AES' or name of any other cipher with 16-byte block len + # $key ..... AES key of proper length (128/192/256bits) + # $nonce ... unique nonce/salt (no need to keep it secret) + # $adata ... additional authenticated data + +=head2 ocb_decrypt_verify + + my $plaintext = ocb_decrypt_verify($cipher, $key, $nonce, $adata, $ciphertext, $tag); + + # on error returns undef + +=head1 METHODS + +=head2 new + + my $ae = Crypt::AuthEnc::OCB->new($cipher, $key, $nonce); + + # $cipher .. 'AES' or name of any other cipher with 16-byte block len + # $key ..... AES key of proper length (128/192/256bits) + # $nonce ... unique nonce/salt (no need to keep it secret) + +=head2 aad_add + + $ae->aad_add($adata); #can be called multiple times + +=head2 encrypt_add + + $ciphertext = $ae->encrypt_add($data); #can be called multiple times + + #BEWARE: size of $data has to be multiple of blocklen (16 for AES) + +=head2 encrypt_last + + $ciphertext = $ae->encrypt_last($data); + +=head2 encrypt_done + + $tag = $ae->encrypt_done(); + +=head2 decrypt_add + + $plaintext = $ae->decrypt_add($ciphertext); #can be called multiple times + + #BEWARE: size of $ciphertext has to be multiple of blocklen (16 for AES) + +=head2 encrypt_last + + $plaintext = $ae->decrypt_last($data); + +=head2 decrypt_done + + my $result = $ae->decrypt_done($tag); # returns 1 (success) or 0 (failure) + #or + my $tag = $ae->decrypt_done; # returns $tag value + +=head2 clone + + my $ae_new = $ae->clone; + +=head1 SEE ALSO + +=over + +=item * L, L, L, L + +=item * L + +=back \ No newline at end of file diff --git a/lib/Crypt/Checksum.pm b/lib/Crypt/Checksum.pm new file mode 100644 index 0000000..23d2351 --- /dev/null +++ b/lib/Crypt/Checksum.pm @@ -0,0 +1,197 @@ +package Crypt::Checksum; + +use strict; +use warnings; +our $VERSION = '0.048'; + +require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; +our %EXPORT_TAGS = ( all => [qw/ + adler32_data adler32_data_hex adler32_data_int adler32_file adler32_file_hex adler32_file_int + crc32_data crc32_data_hex crc32_data_int crc32_file crc32_file_hex crc32_file_int + /] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +use Crypt::Checksum::Adler32; +use Crypt::Checksum::CRC32; + +sub adler32_data { Crypt::Checksum::Adler32->new->add(@_)->digest } +sub adler32_data_hex { Crypt::Checksum::Adler32->new->add(@_)->hexdigest } +sub adler32_data_int { unpack("N", Crypt::Checksum::Adler32->new->add(@_)->digest) } +sub adler32_file { Crypt::Checksum::Adler32->new->addfile(@_)->digest } +sub adler32_file_hex { Crypt::Checksum::Adler32->new->addfile(@_)->hexdigest } +sub adler32_file_int { unpack("N", Crypt::Checksum::Adler32->new->addfile(@_)->digest) } +sub crc32_data { Crypt::Checksum::CRC32->new->add(@_)->digest } +sub crc32_data_hex { Crypt::Checksum::CRC32->new->add(@_)->hexdigest } +sub crc32_data_int { unpack("N", Crypt::Checksum::CRC32->new->add(@_)->digest) } +sub crc32_file { Crypt::Checksum::CRC32->new->addfile(@_)->digest } +sub crc32_file_hex { Crypt::Checksum::CRC32->new->addfile(@_)->hexdigest } +sub crc32_file_int { unpack("N", Crypt::Checksum::CRC32->new->addfile(@_)->digest) } + +1; + +=pod + +=head1 NAME + +Crypt::Checksum - functional interface to CRC32 and Adler32 checksums + +=head1 SYNOPSIS + + use Crypt::Checksum ':all'; + + # calculate Adler32 checksum from string/buffer + $checksum_raw = adler32_data($data); + $checksum_hex = adler32_data_hex($data); + + # calculate Adler32 checksum from file + $checksum_raw = adler32_file('filename.dat'); + $checksum_hex = adler32_file_hex('filename.dat'); + + # calculate Adler32 checksum from filehandle + $checksum_raw = adler32_file(*FILEHANDLE); + $checksum_hex = adler32_file_hex(*FILEHANDLE); + + # calculate CRC32 checksum from string/buffer + $checksum_raw = crc32_data($data); + $checksum_hex = crc32_data_hex($data); + + # calculate CRC32 checksum from file + $checksum_raw = crc32_file('filename.dat'); + $checksum_hex = crc32_file_hex('filename.dat'); + + # calculate CRC32 checksum from filehandle + $checksum_raw = crc32_file(*FILEHANDLE); + $checksum_hex = crc32_file_hex(*FILEHANDLE); + +=head1 DESCRIPTION + +Calculating CRC32 and Adler32 checksums (functional interface); + +I + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Checksum qw( adler32_data adler32_data_hex adler32_file adler32_file_hex + crc32_data crc32_data_hex crc32_file crc32_file_hex ); + +Or all of them at once: + + use Crypt::Checksum ':all'; + +=head1 FUNCTIONS + +=head2 adler32_data + +Returns checksum as raw octects. + + $checksum_raw = adler32_data('data string'); + #or + $checksum_raw = adler32_data('any data', 'more data', 'even more data'); + +=head2 adler32_data_hex + +Returns checksum as a hexadecimal string. + + $checksum_hex = adler32_data_hex('data string'); + #or + $checksum_hex = adler32_data_hex('any data', 'more data', 'even more data'); + +=head2 adler32_data_int + +Returns checksum as unsingned 32bit integer. + + $checksum_hex = adler32_data_int('data string'); + #or + $checksum_hex = adler32_data_int('any data', 'more data', 'even more data'); + +=head2 adler32_file + +Returns checksum as raw octects. + + $checksum_raw = adler32_file('filename.dat'); + #or + $checksum_raw = adler32_file(*FILEHANDLE); + +=head2 adler32_file_hex + +Returns checksum as a hexadecimal string. + + $checksum_hex = adler32_file_hex('filename.dat'); + #or + $checksum_hex = adler32_file_hex(*FILEHANDLE); + +=head2 adler32_file_int + +Returns checksum as unsingned 32bit integer. + + $checksum_hex = adler32_file_int('data string'); + #or + $checksum_hex = adler32_file_int('any data', 'more data', 'even more data'); + +=head2 crc32_data + +Returns checksum as raw octects. + + $checksum_raw = crc32_data('data string'); + #or + $checksum_raw = crc32_data('any data', 'more data', 'even more data'); + +=head2 crc32_data_hex + +Returns checksum as a hexadecimal string. + + $checksum_hex = crc32_data_hex('data string'); + #or + $checksum_hex = crc32_data_hex('any data', 'more data', 'even more data'); + +=head2 crc32_data_int + +Returns checksum as unsingned 32bit integer. + + $checksum_hex = crc32_data_int('data string'); + #or + $checksum_hex = crc32_data_int('any data', 'more data', 'even more data'); + +=head2 crc32_file + +Returns checksum as raw octects. + + $checksum_raw = crc32_file('filename.dat'); + #or + $checksum_raw = crc32_file(*FILEHANDLE); + +=head2 crc32_file_hex + +Returns checksum as a hexadecimal string. + + $checksum_hex = crc32_file_hex('filename.dat'); + #or + $checksum_hex = crc32_file_hex(*FILEHANDLE); + +=head2 crc32_file_int + +Returns checksum as unsingned 32bit integer. + + $checksum_hex = crc32_file_int('data string'); + #or + $checksum_hex = crc32_file_int('any data', 'more data', 'even more data'); + +=head1 SEE ALSO + +=over + +=item * L, L, L + +=item * L + +=item * L + +=back + +=cut \ No newline at end of file diff --git a/lib/Crypt/Checksum/Adler32.pm b/lib/Crypt/Checksum/Adler32.pm new file mode 100644 index 0000000..5691805 --- /dev/null +++ b/lib/Crypt/Checksum/Adler32.pm @@ -0,0 +1,121 @@ +package Crypt::Checksum::Adler32; + +use strict; +use warnings; +our $VERSION = '0.048'; +use Carp; +use CryptX; + +sub addfile { + my ($self, $file) = @_; + + my $handle; + if (ref(\$file) eq 'SCALAR') { #filename + open($handle, "<", $file) || croak "FATAL: cannot open '$file': $!"; + binmode($handle); + } + else { #handle + $handle = $file + } + croak "FATAL: invalid handle" unless defined $handle; + + my $n; + my $buf = ""; + while (($n = read($handle, $buf, 32*1024))) { + $self->add($buf) + } + croak "FATAL: read failed: $!" unless defined $n; + + return $self; +} + +sub CLONE_SKIP { 1 } # prevent cloning + +1; + +=pod + +=head1 NAME + +Crypt::Checksum::Adler32 - Compute Adler32 checksum + +=head1 SYNOPSIS + + use Crypt::Checksum::Adler32; + + $d = Crypt::Checksum::Adler32->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $checksum_raw = $d->digest; # raw bytes + $checksum_hex = $d->hexdigest; # hexadecimal form + +=head1 DESCRIPTION + +Calculating Adler32 checksums (OO interface); + +I + +=head1 METHODS + +=head2 new + +Constructor, returns a reference to the checksum object. + + $d = Crypt::Checksum::Adler32->new; + +=head2 clone + +Creates a copy of the checksum object state and returns a reference to the copy. + + $d->clone(); + +=head2 reset + +Reinitialize the checksum object state and returns a reference to the checksum object. + + $d->reset(); + +=head2 add + +All arguments are appended to the message we calculate checksum for. +The return value is the checksum object itself. + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + +The content of the file (or filehandle) is appended to the message we calculate checksum for. +The return value is the checksum object itself. + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 digest + +Returns the binary checksum (raw bytes). + + $result_raw = $d->digest(); + +=head2 hexdigest + +Returns the checksum encoded as a hexadecimal string. + + $result_hex = $d->hexdigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut \ No newline at end of file diff --git a/lib/Crypt/Checksum/CRC32.pm b/lib/Crypt/Checksum/CRC32.pm new file mode 100644 index 0000000..72cd662 --- /dev/null +++ b/lib/Crypt/Checksum/CRC32.pm @@ -0,0 +1,121 @@ +package Crypt::Checksum::CRC32; + +use strict; +use warnings; +our $VERSION = '0.048'; +use Carp; +use CryptX; + +sub addfile { + my ($self, $file) = @_; + + my $handle; + if (ref(\$file) eq 'SCALAR') { #filename + open($handle, "<", $file) || croak "FATAL: cannot open '$file': $!"; + binmode($handle); + } + else { #handle + $handle = $file + } + croak "FATAL: invalid handle" unless defined $handle; + + my $n; + my $buf = ""; + while (($n = read($handle, $buf, 32*1024))) { + $self->add($buf) + } + croak "FATAL: read failed: $!" unless defined $n; + + return $self; +} + +sub CLONE_SKIP { 1 } # prevent cloning + +1; + +=pod + +=head1 NAME + +Crypt::Checksum::CRC32 - Compute CRC32 checksum + +=head1 SYNOPSIS + + use Crypt::Checksum::CRC32; + + $d = Crypt::Checksum::CRC32->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $checksum_raw = $d->digest; # raw bytes + $checksum_hex = $d->hexdigest; # hexadecimal form + +=head1 DESCRIPTION + +Calculating CRC32 checksums (OO interface); + +I + +=head1 METHODS + +=head2 new + +Constructor, returns a reference to the checksum object. + + $d = Crypt::Checksum::CRC32->new; + +=head2 clone + +Creates a copy of the checksum object state and returns a reference to the copy. + + $d->clone(); + +=head2 reset + +Reinitialize the checksum object state and returns a reference to the checksum object. + + $d->reset(); + +=head2 add + +All arguments are appended to the message we calculate checksum for. +The return value is the checksum object itself. + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + +The content of the file (or filehandle) is appended to the message we calculate checksum for. +The return value is the checksum object itself. + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 digest + +Returns the binary checksum (raw bytes). + + $result_raw = $d->digest(); + +=head2 hexdigest + +Returns the checksum encoded as a hexadecimal string. + + $result_hex = $d->hexdigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut \ No newline at end of file diff --git a/lib/Crypt/Cipher.pm b/lib/Crypt/Cipher.pm new file mode 100644 index 0000000..686780f --- /dev/null +++ b/lib/Crypt/Cipher.pm @@ -0,0 +1,217 @@ +package Crypt::Cipher; + +use strict; +use warnings; +our $VERSION = '0.048'; +use CryptX; + +### the following methods/functions are implemented in XS: +# - _new +# - DESTROY +# - _keysize +# - _max_keysize +# - _min_keysize +# - _blocksize +# - _default_rounds +# - encrypt +# - decrypt +#functions, not methods: +# - _block_length_by_name +# - _min_key_length_by_name +# - _max_key_length_by_name +# - _default_rounds_by_name + +sub _trans_cipher_name { + my $name = shift; + my %trans = ( + DES_EDE => '3des', + SAFERP => 'safer+', + SAFER_K128 => 'safer-k128', + SAFER_K64 => 'safer-k64', + SAFER_SK128 => 'safer-sk128', + SAFER_SK64 => 'safer-sk64', + ); + $name =~ s/^Crypt::Cipher:://; + return $trans{uc($name)} if defined $trans{uc($name)}; + return lc($name); +} + +### METHODS + +sub new { + my $pkg = shift; + my $cipher_name = $pkg eq __PACKAGE__ ? _trans_cipher_name(shift) : _trans_cipher_name($pkg); + return _new($cipher_name, @_); +} + +sub blocksize { + my $self = shift; + return $self->_blocksize if ref($self); + $self = _trans_cipher_name(shift) if $self eq __PACKAGE__; + return _block_length_by_name(_trans_cipher_name($self)); +} + +sub keysize { + max_keysize(@_); +} + +sub max_keysize +{ + my $self = shift; + return unless defined $self; + return $self->_max_keysize if ref($self); + $self = _trans_cipher_name(shift) if $self eq __PACKAGE__; + return _max_key_length_by_name(_trans_cipher_name($self)); +} + +sub min_keysize { + my $self = shift; + return unless defined $self; + return $self->_min_keysize if ref($self); + $self = _trans_cipher_name(shift) if $self eq __PACKAGE__; + return _min_key_length_by_name(_trans_cipher_name($self)); +} + +sub default_rounds { + my $self = shift; + return unless defined $self; + return $self->_default_rounds if ref($self); + $self = _trans_cipher_name(shift) if $self eq __PACKAGE__; + return _default_rounds_by_name(_trans_cipher_name($self)); +} + +sub CLONE_SKIP { 1 } # prevent cloning + +1; + +=pod + +=head1 NAME + +Crypt::Cipher - Generic interface to cipher functions + +=head1 SYNOPSIS + + #### example 1 (encrypting single block) + use Crypt::Cipher; + + my $key = '...'; # length has to be valid key size for this cipher + my $c = Crypt::Cipher->new('AES', $key); + my $blocksize = $c->blocksize; + my $ciphertext = $c->encrypt('plain text block'); #encrypt 1 block + my $plaintext = $c->decrypt($ciphertext); #decrypt 1 block + + ### example 2 (using CBC mode) + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('AES'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + #### example 3 (compatibility with Crypt::CBC) + use Crypt::CBC; + use Crypt::Cipher; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cipher = Crypt::Cipher('AES', $key); + my $cbc = Crypt::CBC->new( -cipher=>$cipher, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +Provides an interface to various symetric cipher algorithms. + +B This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L, L or L (which will be slower). + +=head1 METHODS + +=head2 new + +Constructor, returns a reference to the cipher object. + + ## basic scenario + $d = Crypt::Cipher->new($name, $key); + # $name = one of 'AES', 'Anubis', 'Blowfish', 'CAST5', 'Camellia', 'DES', 'DES_EDE', + # 'KASUMI', 'Khazad', 'MULTI2', 'Noekeon', 'RC2', 'RC5', 'RC6', + # 'SAFERP', 'SAFER_K128', 'SAFER_K64', 'SAFER_SK128', 'SAFER_SK64', + # 'SEED', 'Skipjack', 'Twofish', 'XTEA' + # simply any for which there exists Crypt::Cipher:: + # $key = binary key (keysize should comply with selected cipher requirements) + + ## some of the ciphers (e.g. MULTI2, RC5, SAFER) allows to set number of rounds + $d = Crypt::Cipher->new('MULTI2', $key, $rounds); + # $rounds = positive integer (should comply with selected cipher requirements) + +=head2 encrypt + +Encrypts $plaintext and returns the $ciphertext where $plaintext and $ciphertext should be of B bytes. + + $ciphertext = $d->encrypt($plaintext); + +=head2 decrypt + +Decrypts $ciphertext and returns the $plaintext where $plaintext and $ciphertext should be of B bytes. + + $plaintext = $d->encrypt($ciphertext); + +=head2 keysize + +Just an alias for B (needed for L compatibility). + +=head2 max_keysize + +Returns the maximal allowed key size (in bytes) for given cipher. + + $d->max_keysize; + #or + Crypt::Cipher->max_keysize('AES'); + #or + Crypt::Cipher::max_keysize('AES'); + +=head2 min_keysize + +Returns the minimal allowed key size (in bytes) for given cipher. + + $d->min_keysize; + #or + Crypt::Cipher->min_keysize('AES'); + #or + Crypt::Cipher::min_keysize('AES'); + +=head2 blocksize + +Returns block size (in bytes) for given cipher. + + $d->blocksize; + #or + Crypt::Cipher->blocksize('AES'); + #or + Crypt::Cipher::blocksize('AES'); + +=head2 default_rounds + +Returns default number of rounds for given cipher. NOTE: only some cipher (e.g. MULTI2, RC5, SAFER) allows to set number of rounds via new(). + + $d->default_rounds; + #or + Crypt::Cipher->default_rounds('AES'); + #or + Crypt::Cipher::default_rounds('AES'); + +=head1 SEE ALSO + +=over + +=item * L + +=item * Check subclasses like L, L, ... + +=back + +=cut + +__END__ diff --git a/lib/Crypt/Cipher/AES.pm b/lib/Crypt/Cipher/AES.pm new file mode 100644 index 0000000..1d4e97d --- /dev/null +++ b/lib/Crypt/Cipher/AES.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::AES; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::AES - Symetric cipher AES (aka Rijndael), key size: 128/192/256 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('AES'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::AES; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::AES', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the AES cipher. Provided interface is compliant with L module. + +B This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L, L or L (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::AES->new($key); + #or + $c = Crypt::Cipher::AES->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::AES->keysize; + #or + Crypt::Cipher::AES::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::AES->blocksize; + #or + Crypt::Cipher::AES::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::AES->max_keysize; + #or + Crypt::Cipher::AES::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::AES->min_keysize; + #or + Crypt::Cipher::AES::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::AES->default_rounds; + #or + Crypt::Cipher::AES::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Cipher/Anubis.pm b/lib/Crypt/Cipher/Anubis.pm new file mode 100644 index 0000000..e06b5cd --- /dev/null +++ b/lib/Crypt/Cipher/Anubis.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::Anubis; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::Anubis - Symetric cipher Anubis, key size: 128-320 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('Anubis'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::Anubis; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::Anubis', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the Anubis cipher. Provided interface is compliant with L module. + +B This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L, L or L (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::Anubis->new($key); + #or + $c = Crypt::Cipher::Anubis->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::Anubis->keysize; + #or + Crypt::Cipher::Anubis::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::Anubis->blocksize; + #or + Crypt::Cipher::Anubis::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::Anubis->max_keysize; + #or + Crypt::Cipher::Anubis::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::Anubis->min_keysize; + #or + Crypt::Cipher::Anubis::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::Anubis->default_rounds; + #or + Crypt::Cipher::Anubis::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Cipher/Blowfish.pm b/lib/Crypt/Cipher/Blowfish.pm new file mode 100644 index 0000000..0e98a2c --- /dev/null +++ b/lib/Crypt/Cipher/Blowfish.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::Blowfish; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::Blowfish - Symetric cipher Blowfish, key size: 64-448 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('Blowfish'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::Blowfish; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::Blowfish', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the Blowfish cipher. Provided interface is compliant with L module. + +B This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L, L or L (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::Blowfish->new($key); + #or + $c = Crypt::Cipher::Blowfish->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::Blowfish->keysize; + #or + Crypt::Cipher::Blowfish::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::Blowfish->blocksize; + #or + Crypt::Cipher::Blowfish::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::Blowfish->max_keysize; + #or + Crypt::Cipher::Blowfish::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::Blowfish->min_keysize; + #or + Crypt::Cipher::Blowfish::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::Blowfish->default_rounds; + #or + Crypt::Cipher::Blowfish::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Cipher/CAST5.pm b/lib/Crypt/Cipher/CAST5.pm new file mode 100644 index 0000000..fbfd240 --- /dev/null +++ b/lib/Crypt/Cipher/CAST5.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::CAST5; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::CAST5 - Symetric cipher CAST5 (aka CAST-128), key size: 40-128 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('CAST5'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::CAST5; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::CAST5', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the CAST5 cipher. Provided interface is compliant with L module. + +B This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L, L or L (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::CAST5->new($key); + #or + $c = Crypt::Cipher::CAST5->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::CAST5->keysize; + #or + Crypt::Cipher::CAST5::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::CAST5->blocksize; + #or + Crypt::Cipher::CAST5::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::CAST5->max_keysize; + #or + Crypt::Cipher::CAST5::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::CAST5->min_keysize; + #or + Crypt::Cipher::CAST5::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::CAST5->default_rounds; + #or + Crypt::Cipher::CAST5::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Cipher/Camellia.pm b/lib/Crypt/Cipher/Camellia.pm new file mode 100644 index 0000000..0415ef2 --- /dev/null +++ b/lib/Crypt/Cipher/Camellia.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::Camellia; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::Camellia - Symetric cipher Camellia, key size: 128/192/256 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('Camellia'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::Camellia; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::Camellia', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the Camellia cipher. Provided interface is compliant with L module. + +B This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L, L or L (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::Camellia->new($key); + #or + $c = Crypt::Cipher::Camellia->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::Camellia->keysize; + #or + Crypt::Cipher::Camellia::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::Camellia->blocksize; + #or + Crypt::Cipher::Camellia::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::Camellia->max_keysize; + #or + Crypt::Cipher::Camellia::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::Camellia->min_keysize; + #or + Crypt::Cipher::Camellia::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::Camellia->default_rounds; + #or + Crypt::Cipher::Camellia::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Cipher/DES.pm b/lib/Crypt/Cipher/DES.pm new file mode 100644 index 0000000..486cae8 --- /dev/null +++ b/lib/Crypt/Cipher/DES.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::DES; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::DES - Symetric cipher DES, key size: 64[56] bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('DES'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::DES; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::DES', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the DES cipher. Provided interface is compliant with L module. + +B This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L, L or L (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::DES->new($key); + #or + $c = Crypt::Cipher::DES->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::DES->keysize; + #or + Crypt::Cipher::DES::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::DES->blocksize; + #or + Crypt::Cipher::DES::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::DES->max_keysize; + #or + Crypt::Cipher::DES::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::DES->min_keysize; + #or + Crypt::Cipher::DES::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::DES->default_rounds; + #or + Crypt::Cipher::DES::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Cipher/DES_EDE.pm b/lib/Crypt/Cipher/DES_EDE.pm new file mode 100644 index 0000000..ea4b31d --- /dev/null +++ b/lib/Crypt/Cipher/DES_EDE.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::DES_EDE; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::DES_EDE - Symetric cipher DES_EDE (aka Tripple-DES, 3DES), key size: 192[168] bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('DES_EDE'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::DES_EDE; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::DES_EDE', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the DES_EDE cipher. Provided interface is compliant with L module. + +B This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L, L or L (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::DES_EDE->new($key); + #or + $c = Crypt::Cipher::DES_EDE->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::DES_EDE->keysize; + #or + Crypt::Cipher::DES_EDE::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::DES_EDE->blocksize; + #or + Crypt::Cipher::DES_EDE::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::DES_EDE->max_keysize; + #or + Crypt::Cipher::DES_EDE::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::DES_EDE->min_keysize; + #or + Crypt::Cipher::DES_EDE::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::DES_EDE->default_rounds; + #or + Crypt::Cipher::DES_EDE::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Cipher/KASUMI.pm b/lib/Crypt/Cipher/KASUMI.pm new file mode 100644 index 0000000..f1dc727 --- /dev/null +++ b/lib/Crypt/Cipher/KASUMI.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::KASUMI; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::KASUMI - Symetric cipher KASUMI, key size: 128 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('KASUMI'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::KASUMI; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::KASUMI', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the KASUMI cipher. Provided interface is compliant with L module. + +B This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L, L or L (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::KASUMI->new($key); + #or + $c = Crypt::Cipher::KASUMI->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::KASUMI->keysize; + #or + Crypt::Cipher::KASUMI::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::KASUMI->blocksize; + #or + Crypt::Cipher::KASUMI::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::KASUMI->max_keysize; + #or + Crypt::Cipher::KASUMI::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::KASUMI->min_keysize; + #or + Crypt::Cipher::KASUMI::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::KASUMI->default_rounds; + #or + Crypt::Cipher::KASUMI::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Cipher/Khazad.pm b/lib/Crypt/Cipher/Khazad.pm new file mode 100644 index 0000000..bc6217f --- /dev/null +++ b/lib/Crypt/Cipher/Khazad.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::Khazad; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::Khazad - Symetric cipher Khazad, key size: 128 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('Khazad'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::Khazad; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::Khazad', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the Khazad cipher. Provided interface is compliant with L module. + +B This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L, L or L (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::Khazad->new($key); + #or + $c = Crypt::Cipher::Khazad->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::Khazad->keysize; + #or + Crypt::Cipher::Khazad::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::Khazad->blocksize; + #or + Crypt::Cipher::Khazad::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::Khazad->max_keysize; + #or + Crypt::Cipher::Khazad::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::Khazad->min_keysize; + #or + Crypt::Cipher::Khazad::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::Khazad->default_rounds; + #or + Crypt::Cipher::Khazad::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Cipher/MULTI2.pm b/lib/Crypt/Cipher/MULTI2.pm new file mode 100644 index 0000000..895b242 --- /dev/null +++ b/lib/Crypt/Cipher/MULTI2.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::MULTI2; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::MULTI2 - Symetric cipher MULTI2, key size: 320 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('MULTI2'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::MULTI2; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::MULTI2', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the MULTI2 cipher. Provided interface is compliant with L module. + +B This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L, L or L (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::MULTI2->new($key); + #or + $c = Crypt::Cipher::MULTI2->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::MULTI2->keysize; + #or + Crypt::Cipher::MULTI2::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::MULTI2->blocksize; + #or + Crypt::Cipher::MULTI2::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::MULTI2->max_keysize; + #or + Crypt::Cipher::MULTI2::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::MULTI2->min_keysize; + #or + Crypt::Cipher::MULTI2::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::MULTI2->default_rounds; + #or + Crypt::Cipher::MULTI2::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Cipher/Noekeon.pm b/lib/Crypt/Cipher/Noekeon.pm new file mode 100644 index 0000000..4a73159 --- /dev/null +++ b/lib/Crypt/Cipher/Noekeon.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::Noekeon; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::Noekeon - Symetric cipher Noekeon, key size: 128 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('Noekeon'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::Noekeon; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::Noekeon', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the Noekeon cipher. Provided interface is compliant with L module. + +B This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L, L or L (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::Noekeon->new($key); + #or + $c = Crypt::Cipher::Noekeon->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::Noekeon->keysize; + #or + Crypt::Cipher::Noekeon::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::Noekeon->blocksize; + #or + Crypt::Cipher::Noekeon::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::Noekeon->max_keysize; + #or + Crypt::Cipher::Noekeon::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::Noekeon->min_keysize; + #or + Crypt::Cipher::Noekeon::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::Noekeon->default_rounds; + #or + Crypt::Cipher::Noekeon::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Cipher/RC2.pm b/lib/Crypt/Cipher/RC2.pm new file mode 100644 index 0000000..8529a4b --- /dev/null +++ b/lib/Crypt/Cipher/RC2.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::RC2; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::RC2 - Symetric cipher RC2, key size: 64-1024 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('RC2'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::RC2; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::RC2', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the RC2 cipher. Provided interface is compliant with L module. + +B This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L, L or L (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::RC2->new($key); + #or + $c = Crypt::Cipher::RC2->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::RC2->keysize; + #or + Crypt::Cipher::RC2::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::RC2->blocksize; + #or + Crypt::Cipher::RC2::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::RC2->max_keysize; + #or + Crypt::Cipher::RC2::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::RC2->min_keysize; + #or + Crypt::Cipher::RC2::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::RC2->default_rounds; + #or + Crypt::Cipher::RC2::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Cipher/RC5.pm b/lib/Crypt/Cipher/RC5.pm new file mode 100644 index 0000000..f358c25 --- /dev/null +++ b/lib/Crypt/Cipher/RC5.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::RC5; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::RC5 - Symetric cipher RC5, key size: 64-1024 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('RC5'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::RC5; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::RC5', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the RC5 cipher. Provided interface is compliant with L module. + +B This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L, L or L (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::RC5->new($key); + #or + $c = Crypt::Cipher::RC5->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::RC5->keysize; + #or + Crypt::Cipher::RC5::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::RC5->blocksize; + #or + Crypt::Cipher::RC5::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::RC5->max_keysize; + #or + Crypt::Cipher::RC5::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::RC5->min_keysize; + #or + Crypt::Cipher::RC5::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::RC5->default_rounds; + #or + Crypt::Cipher::RC5::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Cipher/RC6.pm b/lib/Crypt/Cipher/RC6.pm new file mode 100644 index 0000000..f185f3b --- /dev/null +++ b/lib/Crypt/Cipher/RC6.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::RC6; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::RC6 - Symetric cipher RC6, key size: 64-1024 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('RC6'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::RC6; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::RC6', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the RC6 cipher. Provided interface is compliant with L module. + +B This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L, L or L (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::RC6->new($key); + #or + $c = Crypt::Cipher::RC6->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::RC6->keysize; + #or + Crypt::Cipher::RC6::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::RC6->blocksize; + #or + Crypt::Cipher::RC6::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::RC6->max_keysize; + #or + Crypt::Cipher::RC6::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::RC6->min_keysize; + #or + Crypt::Cipher::RC6::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::RC6->default_rounds; + #or + Crypt::Cipher::RC6::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Cipher/SAFERP.pm b/lib/Crypt/Cipher/SAFERP.pm new file mode 100644 index 0000000..05f989f --- /dev/null +++ b/lib/Crypt/Cipher/SAFERP.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::SAFERP; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::SAFERP - Symetric cipher SAFER+, key size: 128/192/256 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('SAFERP'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::SAFERP; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::SAFERP', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the SAFERP cipher. Provided interface is compliant with L module. + +B This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L, L or L (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::SAFERP->new($key); + #or + $c = Crypt::Cipher::SAFERP->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::SAFERP->keysize; + #or + Crypt::Cipher::SAFERP::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::SAFERP->blocksize; + #or + Crypt::Cipher::SAFERP::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::SAFERP->max_keysize; + #or + Crypt::Cipher::SAFERP::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::SAFERP->min_keysize; + #or + Crypt::Cipher::SAFERP::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::SAFERP->default_rounds; + #or + Crypt::Cipher::SAFERP::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Cipher/SAFER_K128.pm b/lib/Crypt/Cipher/SAFER_K128.pm new file mode 100644 index 0000000..c373260 --- /dev/null +++ b/lib/Crypt/Cipher/SAFER_K128.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::SAFER_K128; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::SAFER_K128 - Symetric cipher SAFER_K128, key size: 128 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('SAFER_K128'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::SAFER_K128; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::SAFER_K128', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the SAFER_K128 cipher. Provided interface is compliant with L module. + +B This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L, L or L (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::SAFER_K128->new($key); + #or + $c = Crypt::Cipher::SAFER_K128->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::SAFER_K128->keysize; + #or + Crypt::Cipher::SAFER_K128::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::SAFER_K128->blocksize; + #or + Crypt::Cipher::SAFER_K128::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::SAFER_K128->max_keysize; + #or + Crypt::Cipher::SAFER_K128::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::SAFER_K128->min_keysize; + #or + Crypt::Cipher::SAFER_K128::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::SAFER_K128->default_rounds; + #or + Crypt::Cipher::SAFER_K128::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Cipher/SAFER_K64.pm b/lib/Crypt/Cipher/SAFER_K64.pm new file mode 100644 index 0000000..52741af --- /dev/null +++ b/lib/Crypt/Cipher/SAFER_K64.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::SAFER_K64; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::SAFER_K64 - Symetric cipher SAFER_K64, key size: 64 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('SAFER_K64'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::SAFER_K64; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::SAFER_K64', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the SAFER_K64 cipher. Provided interface is compliant with L module. + +B This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L, L or L (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::SAFER_K64->new($key); + #or + $c = Crypt::Cipher::SAFER_K64->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::SAFER_K64->keysize; + #or + Crypt::Cipher::SAFER_K64::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::SAFER_K64->blocksize; + #or + Crypt::Cipher::SAFER_K64::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::SAFER_K64->max_keysize; + #or + Crypt::Cipher::SAFER_K64::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::SAFER_K64->min_keysize; + #or + Crypt::Cipher::SAFER_K64::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::SAFER_K64->default_rounds; + #or + Crypt::Cipher::SAFER_K64::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Cipher/SAFER_SK128.pm b/lib/Crypt/Cipher/SAFER_SK128.pm new file mode 100644 index 0000000..32193ff --- /dev/null +++ b/lib/Crypt/Cipher/SAFER_SK128.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::SAFER_SK128; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::SAFER_SK128 - Symetric cipher SAFER_SK128, key size: 128 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('SAFER_SK128'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::SAFER_SK128; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::SAFER_SK128', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the SAFER_SK128 cipher. Provided interface is compliant with L module. + +B This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L, L or L (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::SAFER_SK128->new($key); + #or + $c = Crypt::Cipher::SAFER_SK128->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::SAFER_SK128->keysize; + #or + Crypt::Cipher::SAFER_SK128::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::SAFER_SK128->blocksize; + #or + Crypt::Cipher::SAFER_SK128::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::SAFER_SK128->max_keysize; + #or + Crypt::Cipher::SAFER_SK128::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::SAFER_SK128->min_keysize; + #or + Crypt::Cipher::SAFER_SK128::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::SAFER_SK128->default_rounds; + #or + Crypt::Cipher::SAFER_SK128::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Cipher/SAFER_SK64.pm b/lib/Crypt/Cipher/SAFER_SK64.pm new file mode 100644 index 0000000..73ac371 --- /dev/null +++ b/lib/Crypt/Cipher/SAFER_SK64.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::SAFER_SK64; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::SAFER_SK64 - Symetric cipher SAFER_SK64, key size: 64 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('SAFER_SK64'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::SAFER_SK64; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::SAFER_SK64', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the SAFER_SK64 cipher. Provided interface is compliant with L module. + +B This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L, L or L (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::SAFER_SK64->new($key); + #or + $c = Crypt::Cipher::SAFER_SK64->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::SAFER_SK64->keysize; + #or + Crypt::Cipher::SAFER_SK64::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::SAFER_SK64->blocksize; + #or + Crypt::Cipher::SAFER_SK64::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::SAFER_SK64->max_keysize; + #or + Crypt::Cipher::SAFER_SK64::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::SAFER_SK64->min_keysize; + #or + Crypt::Cipher::SAFER_SK64::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::SAFER_SK64->default_rounds; + #or + Crypt::Cipher::SAFER_SK64::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Cipher/SEED.pm b/lib/Crypt/Cipher/SEED.pm new file mode 100644 index 0000000..c81553b --- /dev/null +++ b/lib/Crypt/Cipher/SEED.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::SEED; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::SEED - Symetric cipher SEED, key size: 128 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('SEED'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::SEED; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::SEED', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the SEED cipher. Provided interface is compliant with L module. + +B This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L, L or L (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::SEED->new($key); + #or + $c = Crypt::Cipher::SEED->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::SEED->keysize; + #or + Crypt::Cipher::SEED::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::SEED->blocksize; + #or + Crypt::Cipher::SEED::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::SEED->max_keysize; + #or + Crypt::Cipher::SEED::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::SEED->min_keysize; + #or + Crypt::Cipher::SEED::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::SEED->default_rounds; + #or + Crypt::Cipher::SEED::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Cipher/Skipjack.pm b/lib/Crypt/Cipher/Skipjack.pm new file mode 100644 index 0000000..41f6f2c --- /dev/null +++ b/lib/Crypt/Cipher/Skipjack.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::Skipjack; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::Skipjack - Symetric cipher Skipjack, key size: 80 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('Skipjack'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::Skipjack; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::Skipjack', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the Skipjack cipher. Provided interface is compliant with L module. + +B This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L, L or L (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::Skipjack->new($key); + #or + $c = Crypt::Cipher::Skipjack->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::Skipjack->keysize; + #or + Crypt::Cipher::Skipjack::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::Skipjack->blocksize; + #or + Crypt::Cipher::Skipjack::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::Skipjack->max_keysize; + #or + Crypt::Cipher::Skipjack::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::Skipjack->min_keysize; + #or + Crypt::Cipher::Skipjack::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::Skipjack->default_rounds; + #or + Crypt::Cipher::Skipjack::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Cipher/Twofish.pm b/lib/Crypt/Cipher/Twofish.pm new file mode 100644 index 0000000..85a20d2 --- /dev/null +++ b/lib/Crypt/Cipher/Twofish.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::Twofish; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::Twofish - Symetric cipher Twofish, key size: 128/192/256 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('Twofish'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::Twofish; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::Twofish', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the Twofish cipher. Provided interface is compliant with L module. + +B This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L, L or L (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::Twofish->new($key); + #or + $c = Crypt::Cipher::Twofish->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::Twofish->keysize; + #or + Crypt::Cipher::Twofish::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::Twofish->blocksize; + #or + Crypt::Cipher::Twofish::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::Twofish->max_keysize; + #or + Crypt::Cipher::Twofish::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::Twofish->min_keysize; + #or + Crypt::Cipher::Twofish::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::Twofish->default_rounds; + #or + Crypt::Cipher::Twofish::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Cipher/XTEA.pm b/lib/Crypt/Cipher/XTEA.pm new file mode 100644 index 0000000..ce325ba --- /dev/null +++ b/lib/Crypt/Cipher/XTEA.pm @@ -0,0 +1,121 @@ +package Crypt::Cipher::XTEA; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; +use base 'Crypt::Cipher'; + +sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } +sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } +sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } +sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } +sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } + +1; + +=pod + +=head1 NAME + +Crypt::Cipher::XTEA - Symetric cipher XTEA, key size: 128 bits (Crypt::CBC compliant) + +=head1 SYNOPSIS + + ### example 1 + use Crypt::Mode::CBC; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::Mode::CBC->new('XTEA'); + my $ciphertext = $cbc->encrypt("secret data", $key, $iv); + + ### example 2 + use Crypt::CBC; + use Crypt::Cipher::XTEA; + + my $key = '...'; # length has to be valid key size for this cipher + my $iv = '...'; # 16 bytes + my $cbc = Crypt::CBC->new( -cipher=>'Cipher::XTEA', -key=>$key, -iv=>$iv ); + my $ciphertext = $cbc->encrypt("secret data"); + +=head1 DESCRIPTION + +This module implements the XTEA cipher. Provided interface is compliant with L module. + +B This module implements just elementary "one-block-(en|de)cryption" operation - if you want to +encrypt/decrypt generic data you have to use some of the cipher block modes - check for example +L, L or L (which will be slower). + +=head1 METHODS + +=head2 new + + $c = Crypt::Cipher::XTEA->new($key); + #or + $c = Crypt::Cipher::XTEA->new($key, $rounds); + +=head2 encrypt + + $ciphertext = $c->encrypt($plaintext); + +=head2 decrypt + + $plaintext = $c->decrypt($ciphertext); + +=head2 keysize + + $c->keysize; + #or + Crypt::Cipher::XTEA->keysize; + #or + Crypt::Cipher::XTEA::keysize; + +=head2 blocksize + + $c->blocksize; + #or + Crypt::Cipher::XTEA->blocksize; + #or + Crypt::Cipher::XTEA::blocksize; + +=head2 max_keysize + + $c->max_keysize; + #or + Crypt::Cipher::XTEA->max_keysize; + #or + Crypt::Cipher::XTEA::max_keysize; + +=head2 min_keysize + + $c->min_keysize; + #or + Crypt::Cipher::XTEA->min_keysize; + #or + Crypt::Cipher::XTEA::min_keysize; + +=head2 default_rounds + + $c->default_rounds; + #or + Crypt::Cipher::XTEA->default_rounds; + #or + Crypt::Cipher::XTEA::default_rounds; + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest.pm b/lib/Crypt/Digest.pm new file mode 100644 index 0000000..a1ec914 --- /dev/null +++ b/lib/Crypt/Digest.pm @@ -0,0 +1,382 @@ +package Crypt::Digest; + +use strict; +use warnings; +our $VERSION = '0.048'; + +require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; +our %EXPORT_TAGS = ( all => [qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +### the following methods/functions are implemented in XS: +# - _new +# - _hashsize +# - _hashsize_by_name (function, not method) +# - clone +# - reset +# - digest +# - hexdigest +# - b64digest +# - add +# - DESTROY + +sub _trans_digest_name { + my $name = shift; + my %trans = ( + CHAES => 'chc_hash', + RIPEMD128 => 'rmd128', + RIPEMD160 => 'rmd160', + RIPEMD256 => 'rmd256', + RIPEMD320 => 'rmd320', + TIGER192 => 'tiger', + SHA512_224 => 'sha512-224', + SHA512_256 => 'sha512-256', + SHA3_224 => 'sha3-224', + SHA3_256 => 'sha3-256', + SHA3_384 => 'sha3-384', + SHA3_512 => 'sha3-512', + BLAKE2B_160 => 'blake2b-160', + BLAKE2B_256 => 'blake2b-256', + BLAKE2B_384 => 'blake2b-384', + BLAKE2B_512 => 'blake2b-512', + BLAKE2S_128 => 'blake2s-128', + BLAKE2S_160 => 'blake2s-160', + BLAKE2S_224 => 'blake2s-224', + BLAKE2S_256 => 'blake2s-256', + ); + $name =~ s/^Crypt::Digest:://i; + return $trans{uc($name)} if defined $trans{uc($name)}; + return lc($name); +} + +### METHODS + +sub new { + my $pkg = shift; + unshift @_, ($pkg eq 'Crypt::Digest' ? _trans_digest_name(shift) : _trans_digest_name($pkg)); + ###return _new(@_); + goto \&_new; # keep the real caller for croak() +} + +sub hashsize { + return unless defined $_[0]; + + if (ref $_[0]) { + ###return _hashsize(@_); + goto \&_hashsize if ref $_[0]; # keep the real caller for croak() + } + else { + my $pkg = shift; + unshift @_, ($pkg eq 'Crypt::Digest' ? _trans_digest_name(shift) : _trans_digest_name($pkg)); + ###return _hashsize_by_name(@_); + goto \&_hashsize_by_name; # keep the real caller for croak() + } +} + +sub addfile { + my ($self, $file) = @_; + + my $handle; + if (ref(\$file) eq 'SCALAR') { #filename + open($handle, "<", $file) || croak "FATAL: cannot open '$file': $!"; + binmode($handle); + } + else { #handle + $handle = $file + } + croak "FATAL: invalid handle" unless defined $handle; + + my $n; + my $buf = ""; + while (($n = read($handle, $buf, 32*1024))) { + $self->add($buf) + } + croak "FATAL: read failed: $!" unless defined $n; + + return $self; +} + +sub CLONE_SKIP { 1 } # prevent cloning + +### FUNCTIONS + +sub digest_data { my $rv = eval {Crypt::Digest->new(shift)->add(@_)->digest}; _croak($@); $rv } +sub digest_data_hex { my $rv = eval {Crypt::Digest->new(shift)->add(@_)->hexdigest}; _croak($@); $rv } +sub digest_data_b64 { my $rv = eval {Crypt::Digest->new(shift)->add(@_)->b64digest}; _croak($@); $rv } +sub digest_data_b64u { my $rv = eval {Crypt::Digest->new(shift)->add(@_)->b64udigest}; _croak($@); $rv } + +sub digest_file { my $rv = eval {Crypt::Digest->new(shift)->addfile(@_)->digest}; _croak($@); $rv } +sub digest_file_hex { my $rv = eval {Crypt::Digest->new(shift)->addfile(@_)->hexdigest}; _croak($@); $rv } +sub digest_file_b64 { my $rv = eval {Crypt::Digest->new(shift)->addfile(@_)->b64digest}; _croak($@); $rv } +sub digest_file_b64u { my $rv = eval {Crypt::Digest->new(shift)->addfile(@_)->b64udigest}; _croak($@); $rv } + +sub _croak { #XXX-FIXME ugly hack for reporting real caller from XS croaks + if ($_[0]) { + $_[0] =~ s/ at .*?\.pm line \d+.[\n\r]*$//g; + croak $_[0]; + } +} + +1; + +=pod + +=head1 NAME + +Crypt::Digest - Generic interface to hash/digest functions + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u + digest_file digest_file_hex digest_file_b64 digest_file_b64u ); + + # calculate digest from string/buffer + $digest_raw = digest_data('SHA1', 'data string'); + $digest_hex = digest_data_hex('SHA1', 'data string'); + $digest_b64 = digest_data_b64('SHA1', 'data string'); + $digest_b64u = digest_data_b64u('SHA1', 'data string'); + # calculate digest from file + $digest_raw = digest_file('SHA1', 'filename.dat'); + $digest_hex = digest_file_hex('SHA1', 'filename.dat'); + $digest_b64 = digest_file_b64('SHA1', 'filename.dat'); + $digest_b64u = digest_file_b64u('SHA1', 'filename.dat'); + # calculate digest from filehandle + $digest_raw = digest_file('SHA1', *FILEHANDLE); + $digest_hex = digest_file_hex('SHA1', *FILEHANDLE); + $digest_b64 = digest_file_b64('SHA1', *FILEHANDLE); + $digest_b64u = digest_file_b64u('SHA1', *FILEHANDLE); + + ### OO interface: + use Crypt::Digest; + + $d = Crypt::Digest->new('SHA1'); + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to various hash/digest algorithms. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u + digest_file digest_file_hex digest_file_b64 digest_file_b64u ); + +Or all of them at once: + + use Crypt::Digest ':all'; + +=head1 FUNCTIONS + +Please note that all functions take as its first argument the algoritm name, supported values are: + + 'CHAES', 'MD2', 'MD4', 'MD5', 'RIPEMD128', 'RIPEMD160', + 'RIPEMD256', 'RIPEMD320', 'SHA1', 'SHA224', 'SHA256', + 'SHA384', 'SHA512', 'SHA512_224', 'SHA512_256', 'Tiger192', 'Whirlpool', + 'SHA3_224', 'SHA3_256', 'SHA3_384', 'SHA3_512' + + (simply any for which there is Crypt::Digest:: module) + +=head2 digest_data + +Logically joins all arguments into a single string, and returns its SHA1 digest encoded as a binary string. + + $digest_raw = digest_data('SHA1', 'data string'); + #or + $digest_raw = digest_data('SHA1', 'any data', 'more data', 'even more data'); + +=head2 digest_data_hex + +Logically joins all arguments into a single string, and returns its SHA1 digest encoded as a hexadecimal string. + + $digest_hex = digest_data_hex('SHA1', 'data string'); + #or + $digest_hex = digest_data_hex('SHA1', 'any data', 'more data', 'even more data'); + +=head2 digest_data_b64 + +Logically joins all arguments into a single string, and returns its SHA1 digest encoded as a Base64 string, B trailing '=' padding. + + $digest_b64 = digest_data_b64('SHA1', 'data string'); + #or + $digest_b64 = digest_data_b64('SHA1', 'any data', 'more data', 'even more data'); + +=head2 digest_data_b64u + +Logically joins all arguments into a single string, and returns its SHA1 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $digest_b64url = digest_data_b64u('SHA1', 'data string'); + #or + $digest_b64url = digest_data_b64u('SHA1', 'any data', 'more data', 'even more data'); + +=head2 digest_file + +Reads file (defined by filename or filehandle) content, and returns its digest encoded as a binary string. + + $digest_raw = digest_file('SHA1', 'filename.dat'); + #or + $digest_raw = digest_file('SHA1', *FILEHANDLE); + +=head2 digest_file_hex + +Reads file (defined by filename or filehandle) content, and returns its digest encoded as a hexadecimal string. + + $digest_hex = digest_file_hex('SHA1', 'filename.dat'); + #or + $digest_hex = digest_file_hex('SHA1', *FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 digest_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its digest encoded as a Base64 string, B trailing '=' padding. + + $digest_b64 = digest_file_b64('SHA1', 'filename.dat'); + #or + $digest_b64 = digest_file_b64('SHA1', *FILEHANDLE); + +=head2 digest_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $digest_b64url = digest_file_b64u('SHA1', 'filename.dat'); + #or + $digest_b64url = digest_file_b64u('SHA1', *FILEHANDLE); + +=head1 METHODS + +=head2 new + +Constructor, returns a reference to the digest object. + + $d = Crypt::Digest->new($name); + # $name could be: 'CHAES', 'MD2', 'MD4', 'MD5', 'RIPEMD128', 'RIPEMD160', + # 'RIPEMD256', 'RIPEMD320', 'SHA1', 'SHA224', 'SHA256', 'SHA384', + # 'SHA512', 'SHA512_224', 'SHA512_256', 'Tiger192', 'Whirlpool' + # + # simply any for which there is Crypt::Digest:: module + +=head2 clone + +Creates a copy of the digest object state and returns a reference to the copy. + + $d->clone(); + +=head2 reset + +Reinitialize the digest object state and returns a reference to the digest object. + + $d->reset(); + +=head2 add + +All arguments are appended to the message we calculate digest for. +The return value is the digest object itself. + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +Note that all the following cases are equivalent: + + # case 1 + $d->add('aa', 'bb', 'cc'); + + # case 2 + $d->add('aa'); + $d->add('bb'); + $d->add('cc'); + + # case 3 + $d->add('aabbcc'); + + # case 4 + $d->add('aa')->add('bb')->add('cc'); + +=head2 addfile + +The content of the file (or filehandle) is appended to the message we calculate digest for. +The return value is the digest object itself. + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 add_bits + +This method is available mostly for compatibility with other Digest::SOMETHING modules on CPAN, you are very unlikely to need it. +The return value is the digest object itself. + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +B It is not possible to add bits that are not a multiple of 8. + +=head2 hashsize + +Returns the length of calculated digest in bytes (e.g. 32 for SHA-256). + + $d->hashsize; + #or + Crypt::Digest->hashsize('SHA1'); + #or + Crypt::Digest::hashsize('SHA1'); + +=head2 digest + +Returns the binary digest (raw bytes). + + $result_raw = $d->digest(); + +=head2 hexdigest + +Returns the digest encoded as a hexadecimal string. + + $result_hex = $d->hexdigest(); + +=head2 b64digest + +Returns the digest encoded as a Base64 string, B trailing '=' padding (B this padding +style might differ from other Digest::SOMETHING modules on CPAN). + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + +Returns the digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L + +=item * L tries to be compatible with L interface. + +=item * Check subclasses like L, L, ... + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/BLAKE2b_160.pm b/lib/Crypt/Digest/BLAKE2b_160.pm new file mode 100644 index 0000000..bb829e1 --- /dev/null +++ b/lib/Crypt/Digest/BLAKE2b_160.pm @@ -0,0 +1,229 @@ +package Crypt::Digest::BLAKE2b_160; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( blake2b_160 blake2b_160_hex blake2b_160_b64 blake2b_160_b64u blake2b_160_file blake2b_160_file_hex blake2b_160_file_b64 blake2b_160_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub blake2b_160 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub blake2b_160_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub blake2b_160_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub blake2b_160_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub blake2b_160_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub blake2b_160_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub blake2b_160_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub blake2b_160_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::BLAKE2b_160 - Hash function BLAKE2b [size: 160 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::BLAKE2b_160 qw( blake2b_160 blake2b_160_hex blake2b_160_b64 blake2b_160_b64u + blake2b_160_file blake2b_160_file_hex blake2b_160_file_b64 blake2b_160_file_b64u ); + + # calculate digest from string/buffer + $blake2b_160_raw = blake2b_160('data string'); + $blake2b_160_hex = blake2b_160_hex('data string'); + $blake2b_160_b64 = blake2b_160_b64('data string'); + $blake2b_160_b64u = blake2b_160_b64u('data string'); + # calculate digest from file + $blake2b_160_raw = blake2b_160_file('filename.dat'); + $blake2b_160_hex = blake2b_160_file_hex('filename.dat'); + $blake2b_160_b64 = blake2b_160_file_b64('filename.dat'); + $blake2b_160_b64u = blake2b_160_file_b64u('filename.dat'); + # calculate digest from filehandle + $blake2b_160_raw = blake2b_160_file(*FILEHANDLE); + $blake2b_160_hex = blake2b_160_file_hex(*FILEHANDLE); + $blake2b_160_b64 = blake2b_160_file_b64(*FILEHANDLE); + $blake2b_160_b64u = blake2b_160_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::BLAKE2b_160; + + $d = Crypt::Digest::BLAKE2b_160->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the BLAKE2b_160 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::BLAKE2b_160 qw(blake2b_160 blake2b_160_hex blake2b_160_b64 blake2b_160_b64u + blake2b_160_file blake2b_160_file_hex blake2b_160_file_b64 blake2b_160_file_b64u); + +Or all of them at once: + + use Crypt::Digest::BLAKE2b_160 ':all'; + +=head1 FUNCTIONS + +=head2 blake2b_160 + +Logically joins all arguments into a single string, and returns its BLAKE2b_160 digest encoded as a binary string. + + $blake2b_160_raw = blake2b_160('data string'); + #or + $blake2b_160_raw = blake2b_160('any data', 'more data', 'even more data'); + +=head2 blake2b_160_hex + +Logically joins all arguments into a single string, and returns its BLAKE2b_160 digest encoded as a hexadecimal string. + + $blake2b_160_hex = blake2b_160_hex('data string'); + #or + $blake2b_160_hex = blake2b_160_hex('any data', 'more data', 'even more data'); + +=head2 blake2b_160_b64 + +Logically joins all arguments into a single string, and returns its BLAKE2b_160 digest encoded as a Base64 string, B trailing '=' padding. + + $blake2b_160_b64 = blake2b_160_b64('data string'); + #or + $blake2b_160_b64 = blake2b_160_b64('any data', 'more data', 'even more data'); + +=head2 blake2b_160_b64u + +Logically joins all arguments into a single string, and returns its BLAKE2b_160 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2b_160_b64url = blake2b_160_b64u('data string'); + #or + $blake2b_160_b64url = blake2b_160_b64u('any data', 'more data', 'even more data'); + +=head2 blake2b_160_file + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_160 digest encoded as a binary string. + + $blake2b_160_raw = blake2b_160_file('filename.dat'); + #or + $blake2b_160_raw = blake2b_160_file(*FILEHANDLE); + +=head2 blake2b_160_file_hex + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_160 digest encoded as a hexadecimal string. + + $blake2b_160_hex = blake2b_160_file_hex('filename.dat'); + #or + $blake2b_160_hex = blake2b_160_file_hex(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 blake2b_160_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_160 digest encoded as a Base64 string, B trailing '=' padding. + + $blake2b_160_b64 = blake2b_160_file_b64('filename.dat'); + #or + $blake2b_160_b64 = blake2b_160_file_b64(*FILEHANDLE); + +=head2 blake2b_160_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_160 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2b_160_b64url = blake2b_160_file_b64u('filename.dat'); + #or + $blake2b_160_b64url = blake2b_160_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L. + +=head2 new + + $d = Crypt::Digest::BLAKE2b_160->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::BLAKE2b_160->hashsize(); + #or + Crypt::Digest::BLAKE2b_160::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/BLAKE2b_256.pm b/lib/Crypt/Digest/BLAKE2b_256.pm new file mode 100644 index 0000000..c9a5a2a --- /dev/null +++ b/lib/Crypt/Digest/BLAKE2b_256.pm @@ -0,0 +1,229 @@ +package Crypt::Digest::BLAKE2b_256; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( blake2b_256 blake2b_256_hex blake2b_256_b64 blake2b_256_b64u blake2b_256_file blake2b_256_file_hex blake2b_256_file_b64 blake2b_256_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub blake2b_256 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub blake2b_256_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub blake2b_256_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub blake2b_256_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub blake2b_256_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub blake2b_256_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub blake2b_256_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub blake2b_256_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::BLAKE2b_256 - Hash function BLAKE2b [size: 256 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::BLAKE2b_256 qw( blake2b_256 blake2b_256_hex blake2b_256_b64 blake2b_256_b64u + blake2b_256_file blake2b_256_file_hex blake2b_256_file_b64 blake2b_256_file_b64u ); + + # calculate digest from string/buffer + $blake2b_256_raw = blake2b_256('data string'); + $blake2b_256_hex = blake2b_256_hex('data string'); + $blake2b_256_b64 = blake2b_256_b64('data string'); + $blake2b_256_b64u = blake2b_256_b64u('data string'); + # calculate digest from file + $blake2b_256_raw = blake2b_256_file('filename.dat'); + $blake2b_256_hex = blake2b_256_file_hex('filename.dat'); + $blake2b_256_b64 = blake2b_256_file_b64('filename.dat'); + $blake2b_256_b64u = blake2b_256_file_b64u('filename.dat'); + # calculate digest from filehandle + $blake2b_256_raw = blake2b_256_file(*FILEHANDLE); + $blake2b_256_hex = blake2b_256_file_hex(*FILEHANDLE); + $blake2b_256_b64 = blake2b_256_file_b64(*FILEHANDLE); + $blake2b_256_b64u = blake2b_256_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::BLAKE2b_256; + + $d = Crypt::Digest::BLAKE2b_256->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the BLAKE2b_256 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::BLAKE2b_256 qw(blake2b_256 blake2b_256_hex blake2b_256_b64 blake2b_256_b64u + blake2b_256_file blake2b_256_file_hex blake2b_256_file_b64 blake2b_256_file_b64u); + +Or all of them at once: + + use Crypt::Digest::BLAKE2b_256 ':all'; + +=head1 FUNCTIONS + +=head2 blake2b_256 + +Logically joins all arguments into a single string, and returns its BLAKE2b_256 digest encoded as a binary string. + + $blake2b_256_raw = blake2b_256('data string'); + #or + $blake2b_256_raw = blake2b_256('any data', 'more data', 'even more data'); + +=head2 blake2b_256_hex + +Logically joins all arguments into a single string, and returns its BLAKE2b_256 digest encoded as a hexadecimal string. + + $blake2b_256_hex = blake2b_256_hex('data string'); + #or + $blake2b_256_hex = blake2b_256_hex('any data', 'more data', 'even more data'); + +=head2 blake2b_256_b64 + +Logically joins all arguments into a single string, and returns its BLAKE2b_256 digest encoded as a Base64 string, B trailing '=' padding. + + $blake2b_256_b64 = blake2b_256_b64('data string'); + #or + $blake2b_256_b64 = blake2b_256_b64('any data', 'more data', 'even more data'); + +=head2 blake2b_256_b64u + +Logically joins all arguments into a single string, and returns its BLAKE2b_256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2b_256_b64url = blake2b_256_b64u('data string'); + #or + $blake2b_256_b64url = blake2b_256_b64u('any data', 'more data', 'even more data'); + +=head2 blake2b_256_file + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_256 digest encoded as a binary string. + + $blake2b_256_raw = blake2b_256_file('filename.dat'); + #or + $blake2b_256_raw = blake2b_256_file(*FILEHANDLE); + +=head2 blake2b_256_file_hex + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_256 digest encoded as a hexadecimal string. + + $blake2b_256_hex = blake2b_256_file_hex('filename.dat'); + #or + $blake2b_256_hex = blake2b_256_file_hex(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 blake2b_256_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_256 digest encoded as a Base64 string, B trailing '=' padding. + + $blake2b_256_b64 = blake2b_256_file_b64('filename.dat'); + #or + $blake2b_256_b64 = blake2b_256_file_b64(*FILEHANDLE); + +=head2 blake2b_256_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2b_256_b64url = blake2b_256_file_b64u('filename.dat'); + #or + $blake2b_256_b64url = blake2b_256_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L. + +=head2 new + + $d = Crypt::Digest::BLAKE2b_256->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::BLAKE2b_256->hashsize(); + #or + Crypt::Digest::BLAKE2b_256::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/BLAKE2b_384.pm b/lib/Crypt/Digest/BLAKE2b_384.pm new file mode 100644 index 0000000..3657a35 --- /dev/null +++ b/lib/Crypt/Digest/BLAKE2b_384.pm @@ -0,0 +1,229 @@ +package Crypt::Digest::BLAKE2b_384; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( blake2b_384 blake2b_384_hex blake2b_384_b64 blake2b_384_b64u blake2b_384_file blake2b_384_file_hex blake2b_384_file_b64 blake2b_384_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub blake2b_384 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub blake2b_384_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub blake2b_384_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub blake2b_384_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub blake2b_384_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub blake2b_384_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub blake2b_384_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub blake2b_384_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::BLAKE2b_384 - Hash function BLAKE2b [size: 384 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::BLAKE2b_384 qw( blake2b_384 blake2b_384_hex blake2b_384_b64 blake2b_384_b64u + blake2b_384_file blake2b_384_file_hex blake2b_384_file_b64 blake2b_384_file_b64u ); + + # calculate digest from string/buffer + $blake2b_384_raw = blake2b_384('data string'); + $blake2b_384_hex = blake2b_384_hex('data string'); + $blake2b_384_b64 = blake2b_384_b64('data string'); + $blake2b_384_b64u = blake2b_384_b64u('data string'); + # calculate digest from file + $blake2b_384_raw = blake2b_384_file('filename.dat'); + $blake2b_384_hex = blake2b_384_file_hex('filename.dat'); + $blake2b_384_b64 = blake2b_384_file_b64('filename.dat'); + $blake2b_384_b64u = blake2b_384_file_b64u('filename.dat'); + # calculate digest from filehandle + $blake2b_384_raw = blake2b_384_file(*FILEHANDLE); + $blake2b_384_hex = blake2b_384_file_hex(*FILEHANDLE); + $blake2b_384_b64 = blake2b_384_file_b64(*FILEHANDLE); + $blake2b_384_b64u = blake2b_384_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::BLAKE2b_384; + + $d = Crypt::Digest::BLAKE2b_384->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the BLAKE2b_384 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::BLAKE2b_384 qw(blake2b_384 blake2b_384_hex blake2b_384_b64 blake2b_384_b64u + blake2b_384_file blake2b_384_file_hex blake2b_384_file_b64 blake2b_384_file_b64u); + +Or all of them at once: + + use Crypt::Digest::BLAKE2b_384 ':all'; + +=head1 FUNCTIONS + +=head2 blake2b_384 + +Logically joins all arguments into a single string, and returns its BLAKE2b_384 digest encoded as a binary string. + + $blake2b_384_raw = blake2b_384('data string'); + #or + $blake2b_384_raw = blake2b_384('any data', 'more data', 'even more data'); + +=head2 blake2b_384_hex + +Logically joins all arguments into a single string, and returns its BLAKE2b_384 digest encoded as a hexadecimal string. + + $blake2b_384_hex = blake2b_384_hex('data string'); + #or + $blake2b_384_hex = blake2b_384_hex('any data', 'more data', 'even more data'); + +=head2 blake2b_384_b64 + +Logically joins all arguments into a single string, and returns its BLAKE2b_384 digest encoded as a Base64 string, B trailing '=' padding. + + $blake2b_384_b64 = blake2b_384_b64('data string'); + #or + $blake2b_384_b64 = blake2b_384_b64('any data', 'more data', 'even more data'); + +=head2 blake2b_384_b64u + +Logically joins all arguments into a single string, and returns its BLAKE2b_384 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2b_384_b64url = blake2b_384_b64u('data string'); + #or + $blake2b_384_b64url = blake2b_384_b64u('any data', 'more data', 'even more data'); + +=head2 blake2b_384_file + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_384 digest encoded as a binary string. + + $blake2b_384_raw = blake2b_384_file('filename.dat'); + #or + $blake2b_384_raw = blake2b_384_file(*FILEHANDLE); + +=head2 blake2b_384_file_hex + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_384 digest encoded as a hexadecimal string. + + $blake2b_384_hex = blake2b_384_file_hex('filename.dat'); + #or + $blake2b_384_hex = blake2b_384_file_hex(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 blake2b_384_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_384 digest encoded as a Base64 string, B trailing '=' padding. + + $blake2b_384_b64 = blake2b_384_file_b64('filename.dat'); + #or + $blake2b_384_b64 = blake2b_384_file_b64(*FILEHANDLE); + +=head2 blake2b_384_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_384 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2b_384_b64url = blake2b_384_file_b64u('filename.dat'); + #or + $blake2b_384_b64url = blake2b_384_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L. + +=head2 new + + $d = Crypt::Digest::BLAKE2b_384->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::BLAKE2b_384->hashsize(); + #or + Crypt::Digest::BLAKE2b_384::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/BLAKE2b_512.pm b/lib/Crypt/Digest/BLAKE2b_512.pm new file mode 100644 index 0000000..fd06784 --- /dev/null +++ b/lib/Crypt/Digest/BLAKE2b_512.pm @@ -0,0 +1,229 @@ +package Crypt::Digest::BLAKE2b_512; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( blake2b_512 blake2b_512_hex blake2b_512_b64 blake2b_512_b64u blake2b_512_file blake2b_512_file_hex blake2b_512_file_b64 blake2b_512_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub blake2b_512 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub blake2b_512_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub blake2b_512_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub blake2b_512_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub blake2b_512_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub blake2b_512_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub blake2b_512_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub blake2b_512_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::BLAKE2b_512 - Hash function BLAKE2b [size: 512 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::BLAKE2b_512 qw( blake2b_512 blake2b_512_hex blake2b_512_b64 blake2b_512_b64u + blake2b_512_file blake2b_512_file_hex blake2b_512_file_b64 blake2b_512_file_b64u ); + + # calculate digest from string/buffer + $blake2b_512_raw = blake2b_512('data string'); + $blake2b_512_hex = blake2b_512_hex('data string'); + $blake2b_512_b64 = blake2b_512_b64('data string'); + $blake2b_512_b64u = blake2b_512_b64u('data string'); + # calculate digest from file + $blake2b_512_raw = blake2b_512_file('filename.dat'); + $blake2b_512_hex = blake2b_512_file_hex('filename.dat'); + $blake2b_512_b64 = blake2b_512_file_b64('filename.dat'); + $blake2b_512_b64u = blake2b_512_file_b64u('filename.dat'); + # calculate digest from filehandle + $blake2b_512_raw = blake2b_512_file(*FILEHANDLE); + $blake2b_512_hex = blake2b_512_file_hex(*FILEHANDLE); + $blake2b_512_b64 = blake2b_512_file_b64(*FILEHANDLE); + $blake2b_512_b64u = blake2b_512_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::BLAKE2b_512; + + $d = Crypt::Digest::BLAKE2b_512->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the BLAKE2b_512 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::BLAKE2b_512 qw(blake2b_512 blake2b_512_hex blake2b_512_b64 blake2b_512_b64u + blake2b_512_file blake2b_512_file_hex blake2b_512_file_b64 blake2b_512_file_b64u); + +Or all of them at once: + + use Crypt::Digest::BLAKE2b_512 ':all'; + +=head1 FUNCTIONS + +=head2 blake2b_512 + +Logically joins all arguments into a single string, and returns its BLAKE2b_512 digest encoded as a binary string. + + $blake2b_512_raw = blake2b_512('data string'); + #or + $blake2b_512_raw = blake2b_512('any data', 'more data', 'even more data'); + +=head2 blake2b_512_hex + +Logically joins all arguments into a single string, and returns its BLAKE2b_512 digest encoded as a hexadecimal string. + + $blake2b_512_hex = blake2b_512_hex('data string'); + #or + $blake2b_512_hex = blake2b_512_hex('any data', 'more data', 'even more data'); + +=head2 blake2b_512_b64 + +Logically joins all arguments into a single string, and returns its BLAKE2b_512 digest encoded as a Base64 string, B trailing '=' padding. + + $blake2b_512_b64 = blake2b_512_b64('data string'); + #or + $blake2b_512_b64 = blake2b_512_b64('any data', 'more data', 'even more data'); + +=head2 blake2b_512_b64u + +Logically joins all arguments into a single string, and returns its BLAKE2b_512 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2b_512_b64url = blake2b_512_b64u('data string'); + #or + $blake2b_512_b64url = blake2b_512_b64u('any data', 'more data', 'even more data'); + +=head2 blake2b_512_file + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_512 digest encoded as a binary string. + + $blake2b_512_raw = blake2b_512_file('filename.dat'); + #or + $blake2b_512_raw = blake2b_512_file(*FILEHANDLE); + +=head2 blake2b_512_file_hex + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_512 digest encoded as a hexadecimal string. + + $blake2b_512_hex = blake2b_512_file_hex('filename.dat'); + #or + $blake2b_512_hex = blake2b_512_file_hex(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 blake2b_512_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_512 digest encoded as a Base64 string, B trailing '=' padding. + + $blake2b_512_b64 = blake2b_512_file_b64('filename.dat'); + #or + $blake2b_512_b64 = blake2b_512_file_b64(*FILEHANDLE); + +=head2 blake2b_512_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2b_512 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2b_512_b64url = blake2b_512_file_b64u('filename.dat'); + #or + $blake2b_512_b64url = blake2b_512_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L. + +=head2 new + + $d = Crypt::Digest::BLAKE2b_512->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::BLAKE2b_512->hashsize(); + #or + Crypt::Digest::BLAKE2b_512::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/BLAKE2s_128.pm b/lib/Crypt/Digest/BLAKE2s_128.pm new file mode 100644 index 0000000..54b873c --- /dev/null +++ b/lib/Crypt/Digest/BLAKE2s_128.pm @@ -0,0 +1,229 @@ +package Crypt::Digest::BLAKE2s_128; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( blake2s_128 blake2s_128_hex blake2s_128_b64 blake2s_128_b64u blake2s_128_file blake2s_128_file_hex blake2s_128_file_b64 blake2s_128_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub blake2s_128 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub blake2s_128_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub blake2s_128_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub blake2s_128_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub blake2s_128_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub blake2s_128_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub blake2s_128_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub blake2s_128_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::BLAKE2s_128 - Hash function BLAKE2s [size: 128 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::BLAKE2s_128 qw( blake2s_128 blake2s_128_hex blake2s_128_b64 blake2s_128_b64u + blake2s_128_file blake2s_128_file_hex blake2s_128_file_b64 blake2s_128_file_b64u ); + + # calculate digest from string/buffer + $blake2s_128_raw = blake2s_128('data string'); + $blake2s_128_hex = blake2s_128_hex('data string'); + $blake2s_128_b64 = blake2s_128_b64('data string'); + $blake2s_128_b64u = blake2s_128_b64u('data string'); + # calculate digest from file + $blake2s_128_raw = blake2s_128_file('filename.dat'); + $blake2s_128_hex = blake2s_128_file_hex('filename.dat'); + $blake2s_128_b64 = blake2s_128_file_b64('filename.dat'); + $blake2s_128_b64u = blake2s_128_file_b64u('filename.dat'); + # calculate digest from filehandle + $blake2s_128_raw = blake2s_128_file(*FILEHANDLE); + $blake2s_128_hex = blake2s_128_file_hex(*FILEHANDLE); + $blake2s_128_b64 = blake2s_128_file_b64(*FILEHANDLE); + $blake2s_128_b64u = blake2s_128_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::BLAKE2s_128; + + $d = Crypt::Digest::BLAKE2s_128->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the BLAKE2s_128 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::BLAKE2s_128 qw(blake2s_128 blake2s_128_hex blake2s_128_b64 blake2s_128_b64u + blake2s_128_file blake2s_128_file_hex blake2s_128_file_b64 blake2s_128_file_b64u); + +Or all of them at once: + + use Crypt::Digest::BLAKE2s_128 ':all'; + +=head1 FUNCTIONS + +=head2 blake2s_128 + +Logically joins all arguments into a single string, and returns its BLAKE2s_128 digest encoded as a binary string. + + $blake2s_128_raw = blake2s_128('data string'); + #or + $blake2s_128_raw = blake2s_128('any data', 'more data', 'even more data'); + +=head2 blake2s_128_hex + +Logically joins all arguments into a single string, and returns its BLAKE2s_128 digest encoded as a hexadecimal string. + + $blake2s_128_hex = blake2s_128_hex('data string'); + #or + $blake2s_128_hex = blake2s_128_hex('any data', 'more data', 'even more data'); + +=head2 blake2s_128_b64 + +Logically joins all arguments into a single string, and returns its BLAKE2s_128 digest encoded as a Base64 string, B trailing '=' padding. + + $blake2s_128_b64 = blake2s_128_b64('data string'); + #or + $blake2s_128_b64 = blake2s_128_b64('any data', 'more data', 'even more data'); + +=head2 blake2s_128_b64u + +Logically joins all arguments into a single string, and returns its BLAKE2s_128 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2s_128_b64url = blake2s_128_b64u('data string'); + #or + $blake2s_128_b64url = blake2s_128_b64u('any data', 'more data', 'even more data'); + +=head2 blake2s_128_file + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_128 digest encoded as a binary string. + + $blake2s_128_raw = blake2s_128_file('filename.dat'); + #or + $blake2s_128_raw = blake2s_128_file(*FILEHANDLE); + +=head2 blake2s_128_file_hex + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_128 digest encoded as a hexadecimal string. + + $blake2s_128_hex = blake2s_128_file_hex('filename.dat'); + #or + $blake2s_128_hex = blake2s_128_file_hex(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 blake2s_128_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_128 digest encoded as a Base64 string, B trailing '=' padding. + + $blake2s_128_b64 = blake2s_128_file_b64('filename.dat'); + #or + $blake2s_128_b64 = blake2s_128_file_b64(*FILEHANDLE); + +=head2 blake2s_128_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_128 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2s_128_b64url = blake2s_128_file_b64u('filename.dat'); + #or + $blake2s_128_b64url = blake2s_128_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L. + +=head2 new + + $d = Crypt::Digest::BLAKE2s_128->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::BLAKE2s_128->hashsize(); + #or + Crypt::Digest::BLAKE2s_128::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/BLAKE2s_160.pm b/lib/Crypt/Digest/BLAKE2s_160.pm new file mode 100644 index 0000000..97c33b4 --- /dev/null +++ b/lib/Crypt/Digest/BLAKE2s_160.pm @@ -0,0 +1,229 @@ +package Crypt::Digest::BLAKE2s_160; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( blake2s_160 blake2s_160_hex blake2s_160_b64 blake2s_160_b64u blake2s_160_file blake2s_160_file_hex blake2s_160_file_b64 blake2s_160_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub blake2s_160 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub blake2s_160_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub blake2s_160_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub blake2s_160_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub blake2s_160_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub blake2s_160_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub blake2s_160_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub blake2s_160_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::BLAKE2s_160 - Hash function BLAKE2s [size: 160 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::BLAKE2s_160 qw( blake2s_160 blake2s_160_hex blake2s_160_b64 blake2s_160_b64u + blake2s_160_file blake2s_160_file_hex blake2s_160_file_b64 blake2s_160_file_b64u ); + + # calculate digest from string/buffer + $blake2s_160_raw = blake2s_160('data string'); + $blake2s_160_hex = blake2s_160_hex('data string'); + $blake2s_160_b64 = blake2s_160_b64('data string'); + $blake2s_160_b64u = blake2s_160_b64u('data string'); + # calculate digest from file + $blake2s_160_raw = blake2s_160_file('filename.dat'); + $blake2s_160_hex = blake2s_160_file_hex('filename.dat'); + $blake2s_160_b64 = blake2s_160_file_b64('filename.dat'); + $blake2s_160_b64u = blake2s_160_file_b64u('filename.dat'); + # calculate digest from filehandle + $blake2s_160_raw = blake2s_160_file(*FILEHANDLE); + $blake2s_160_hex = blake2s_160_file_hex(*FILEHANDLE); + $blake2s_160_b64 = blake2s_160_file_b64(*FILEHANDLE); + $blake2s_160_b64u = blake2s_160_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::BLAKE2s_160; + + $d = Crypt::Digest::BLAKE2s_160->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the BLAKE2s_160 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::BLAKE2s_160 qw(blake2s_160 blake2s_160_hex blake2s_160_b64 blake2s_160_b64u + blake2s_160_file blake2s_160_file_hex blake2s_160_file_b64 blake2s_160_file_b64u); + +Or all of them at once: + + use Crypt::Digest::BLAKE2s_160 ':all'; + +=head1 FUNCTIONS + +=head2 blake2s_160 + +Logically joins all arguments into a single string, and returns its BLAKE2s_160 digest encoded as a binary string. + + $blake2s_160_raw = blake2s_160('data string'); + #or + $blake2s_160_raw = blake2s_160('any data', 'more data', 'even more data'); + +=head2 blake2s_160_hex + +Logically joins all arguments into a single string, and returns its BLAKE2s_160 digest encoded as a hexadecimal string. + + $blake2s_160_hex = blake2s_160_hex('data string'); + #or + $blake2s_160_hex = blake2s_160_hex('any data', 'more data', 'even more data'); + +=head2 blake2s_160_b64 + +Logically joins all arguments into a single string, and returns its BLAKE2s_160 digest encoded as a Base64 string, B trailing '=' padding. + + $blake2s_160_b64 = blake2s_160_b64('data string'); + #or + $blake2s_160_b64 = blake2s_160_b64('any data', 'more data', 'even more data'); + +=head2 blake2s_160_b64u + +Logically joins all arguments into a single string, and returns its BLAKE2s_160 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2s_160_b64url = blake2s_160_b64u('data string'); + #or + $blake2s_160_b64url = blake2s_160_b64u('any data', 'more data', 'even more data'); + +=head2 blake2s_160_file + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_160 digest encoded as a binary string. + + $blake2s_160_raw = blake2s_160_file('filename.dat'); + #or + $blake2s_160_raw = blake2s_160_file(*FILEHANDLE); + +=head2 blake2s_160_file_hex + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_160 digest encoded as a hexadecimal string. + + $blake2s_160_hex = blake2s_160_file_hex('filename.dat'); + #or + $blake2s_160_hex = blake2s_160_file_hex(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 blake2s_160_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_160 digest encoded as a Base64 string, B trailing '=' padding. + + $blake2s_160_b64 = blake2s_160_file_b64('filename.dat'); + #or + $blake2s_160_b64 = blake2s_160_file_b64(*FILEHANDLE); + +=head2 blake2s_160_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_160 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2s_160_b64url = blake2s_160_file_b64u('filename.dat'); + #or + $blake2s_160_b64url = blake2s_160_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L. + +=head2 new + + $d = Crypt::Digest::BLAKE2s_160->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::BLAKE2s_160->hashsize(); + #or + Crypt::Digest::BLAKE2s_160::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/BLAKE2s_224.pm b/lib/Crypt/Digest/BLAKE2s_224.pm new file mode 100644 index 0000000..c47e810 --- /dev/null +++ b/lib/Crypt/Digest/BLAKE2s_224.pm @@ -0,0 +1,229 @@ +package Crypt::Digest::BLAKE2s_224; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( blake2s_224 blake2s_224_hex blake2s_224_b64 blake2s_224_b64u blake2s_224_file blake2s_224_file_hex blake2s_224_file_b64 blake2s_224_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub blake2s_224 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub blake2s_224_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub blake2s_224_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub blake2s_224_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub blake2s_224_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub blake2s_224_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub blake2s_224_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub blake2s_224_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::BLAKE2s_224 - Hash function BLAKE2s [size: 224 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::BLAKE2s_224 qw( blake2s_224 blake2s_224_hex blake2s_224_b64 blake2s_224_b64u + blake2s_224_file blake2s_224_file_hex blake2s_224_file_b64 blake2s_224_file_b64u ); + + # calculate digest from string/buffer + $blake2s_224_raw = blake2s_224('data string'); + $blake2s_224_hex = blake2s_224_hex('data string'); + $blake2s_224_b64 = blake2s_224_b64('data string'); + $blake2s_224_b64u = blake2s_224_b64u('data string'); + # calculate digest from file + $blake2s_224_raw = blake2s_224_file('filename.dat'); + $blake2s_224_hex = blake2s_224_file_hex('filename.dat'); + $blake2s_224_b64 = blake2s_224_file_b64('filename.dat'); + $blake2s_224_b64u = blake2s_224_file_b64u('filename.dat'); + # calculate digest from filehandle + $blake2s_224_raw = blake2s_224_file(*FILEHANDLE); + $blake2s_224_hex = blake2s_224_file_hex(*FILEHANDLE); + $blake2s_224_b64 = blake2s_224_file_b64(*FILEHANDLE); + $blake2s_224_b64u = blake2s_224_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::BLAKE2s_224; + + $d = Crypt::Digest::BLAKE2s_224->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the BLAKE2s_224 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::BLAKE2s_224 qw(blake2s_224 blake2s_224_hex blake2s_224_b64 blake2s_224_b64u + blake2s_224_file blake2s_224_file_hex blake2s_224_file_b64 blake2s_224_file_b64u); + +Or all of them at once: + + use Crypt::Digest::BLAKE2s_224 ':all'; + +=head1 FUNCTIONS + +=head2 blake2s_224 + +Logically joins all arguments into a single string, and returns its BLAKE2s_224 digest encoded as a binary string. + + $blake2s_224_raw = blake2s_224('data string'); + #or + $blake2s_224_raw = blake2s_224('any data', 'more data', 'even more data'); + +=head2 blake2s_224_hex + +Logically joins all arguments into a single string, and returns its BLAKE2s_224 digest encoded as a hexadecimal string. + + $blake2s_224_hex = blake2s_224_hex('data string'); + #or + $blake2s_224_hex = blake2s_224_hex('any data', 'more data', 'even more data'); + +=head2 blake2s_224_b64 + +Logically joins all arguments into a single string, and returns its BLAKE2s_224 digest encoded as a Base64 string, B trailing '=' padding. + + $blake2s_224_b64 = blake2s_224_b64('data string'); + #or + $blake2s_224_b64 = blake2s_224_b64('any data', 'more data', 'even more data'); + +=head2 blake2s_224_b64u + +Logically joins all arguments into a single string, and returns its BLAKE2s_224 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2s_224_b64url = blake2s_224_b64u('data string'); + #or + $blake2s_224_b64url = blake2s_224_b64u('any data', 'more data', 'even more data'); + +=head2 blake2s_224_file + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_224 digest encoded as a binary string. + + $blake2s_224_raw = blake2s_224_file('filename.dat'); + #or + $blake2s_224_raw = blake2s_224_file(*FILEHANDLE); + +=head2 blake2s_224_file_hex + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_224 digest encoded as a hexadecimal string. + + $blake2s_224_hex = blake2s_224_file_hex('filename.dat'); + #or + $blake2s_224_hex = blake2s_224_file_hex(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 blake2s_224_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_224 digest encoded as a Base64 string, B trailing '=' padding. + + $blake2s_224_b64 = blake2s_224_file_b64('filename.dat'); + #or + $blake2s_224_b64 = blake2s_224_file_b64(*FILEHANDLE); + +=head2 blake2s_224_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_224 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2s_224_b64url = blake2s_224_file_b64u('filename.dat'); + #or + $blake2s_224_b64url = blake2s_224_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L. + +=head2 new + + $d = Crypt::Digest::BLAKE2s_224->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::BLAKE2s_224->hashsize(); + #or + Crypt::Digest::BLAKE2s_224::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/BLAKE2s_256.pm b/lib/Crypt/Digest/BLAKE2s_256.pm new file mode 100644 index 0000000..5c15cfd --- /dev/null +++ b/lib/Crypt/Digest/BLAKE2s_256.pm @@ -0,0 +1,229 @@ +package Crypt::Digest::BLAKE2s_256; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( blake2s_256 blake2s_256_hex blake2s_256_b64 blake2s_256_b64u blake2s_256_file blake2s_256_file_hex blake2s_256_file_b64 blake2s_256_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub blake2s_256 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub blake2s_256_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub blake2s_256_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub blake2s_256_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub blake2s_256_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub blake2s_256_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub blake2s_256_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub blake2s_256_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::BLAKE2s_256 - Hash function BLAKE2s [size: 256 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::BLAKE2s_256 qw( blake2s_256 blake2s_256_hex blake2s_256_b64 blake2s_256_b64u + blake2s_256_file blake2s_256_file_hex blake2s_256_file_b64 blake2s_256_file_b64u ); + + # calculate digest from string/buffer + $blake2s_256_raw = blake2s_256('data string'); + $blake2s_256_hex = blake2s_256_hex('data string'); + $blake2s_256_b64 = blake2s_256_b64('data string'); + $blake2s_256_b64u = blake2s_256_b64u('data string'); + # calculate digest from file + $blake2s_256_raw = blake2s_256_file('filename.dat'); + $blake2s_256_hex = blake2s_256_file_hex('filename.dat'); + $blake2s_256_b64 = blake2s_256_file_b64('filename.dat'); + $blake2s_256_b64u = blake2s_256_file_b64u('filename.dat'); + # calculate digest from filehandle + $blake2s_256_raw = blake2s_256_file(*FILEHANDLE); + $blake2s_256_hex = blake2s_256_file_hex(*FILEHANDLE); + $blake2s_256_b64 = blake2s_256_file_b64(*FILEHANDLE); + $blake2s_256_b64u = blake2s_256_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::BLAKE2s_256; + + $d = Crypt::Digest::BLAKE2s_256->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the BLAKE2s_256 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::BLAKE2s_256 qw(blake2s_256 blake2s_256_hex blake2s_256_b64 blake2s_256_b64u + blake2s_256_file blake2s_256_file_hex blake2s_256_file_b64 blake2s_256_file_b64u); + +Or all of them at once: + + use Crypt::Digest::BLAKE2s_256 ':all'; + +=head1 FUNCTIONS + +=head2 blake2s_256 + +Logically joins all arguments into a single string, and returns its BLAKE2s_256 digest encoded as a binary string. + + $blake2s_256_raw = blake2s_256('data string'); + #or + $blake2s_256_raw = blake2s_256('any data', 'more data', 'even more data'); + +=head2 blake2s_256_hex + +Logically joins all arguments into a single string, and returns its BLAKE2s_256 digest encoded as a hexadecimal string. + + $blake2s_256_hex = blake2s_256_hex('data string'); + #or + $blake2s_256_hex = blake2s_256_hex('any data', 'more data', 'even more data'); + +=head2 blake2s_256_b64 + +Logically joins all arguments into a single string, and returns its BLAKE2s_256 digest encoded as a Base64 string, B trailing '=' padding. + + $blake2s_256_b64 = blake2s_256_b64('data string'); + #or + $blake2s_256_b64 = blake2s_256_b64('any data', 'more data', 'even more data'); + +=head2 blake2s_256_b64u + +Logically joins all arguments into a single string, and returns its BLAKE2s_256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2s_256_b64url = blake2s_256_b64u('data string'); + #or + $blake2s_256_b64url = blake2s_256_b64u('any data', 'more data', 'even more data'); + +=head2 blake2s_256_file + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_256 digest encoded as a binary string. + + $blake2s_256_raw = blake2s_256_file('filename.dat'); + #or + $blake2s_256_raw = blake2s_256_file(*FILEHANDLE); + +=head2 blake2s_256_file_hex + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_256 digest encoded as a hexadecimal string. + + $blake2s_256_hex = blake2s_256_file_hex('filename.dat'); + #or + $blake2s_256_hex = blake2s_256_file_hex(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 blake2s_256_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_256 digest encoded as a Base64 string, B trailing '=' padding. + + $blake2s_256_b64 = blake2s_256_file_b64('filename.dat'); + #or + $blake2s_256_b64 = blake2s_256_file_b64(*FILEHANDLE); + +=head2 blake2s_256_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its BLAKE2s_256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2s_256_b64url = blake2s_256_file_b64u('filename.dat'); + #or + $blake2s_256_b64url = blake2s_256_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L. + +=head2 new + + $d = Crypt::Digest::BLAKE2s_256->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::BLAKE2s_256->hashsize(); + #or + Crypt::Digest::BLAKE2s_256::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/CHAES.pm b/lib/Crypt/Digest/CHAES.pm new file mode 100644 index 0000000..7ae167e --- /dev/null +++ b/lib/Crypt/Digest/CHAES.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::CHAES; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( chaes chaes_hex chaes_b64 chaes_b64u chaes_file chaes_file_hex chaes_file_b64 chaes_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub chaes { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub chaes_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub chaes_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub chaes_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub chaes_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub chaes_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub chaes_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub chaes_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::CHAES - Hash function - CipherHash based on AES [size: 128 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::CHAES qw( chaes chaes_hex chaes_b64 chaes_b64u + chaes_file chaes_file_hex chaes_file_b64 chaes_file_b64u ); + + # calculate digest from string/buffer + $chaes_raw = chaes('data string'); + $chaes_hex = chaes_hex('data string'); + $chaes_b64 = chaes_b64('data string'); + $chaes_b64u = chaes_b64u('data string'); + # calculate digest from file + $chaes_raw = chaes_file('filename.dat'); + $chaes_hex = chaes_file_hex('filename.dat'); + $chaes_b64 = chaes_file_b64('filename.dat'); + $chaes_b64u = chaes_file_b64u('filename.dat'); + # calculate digest from filehandle + $chaes_raw = chaes_file(*FILEHANDLE); + $chaes_hex = chaes_file_hex(*FILEHANDLE); + $chaes_b64 = chaes_file_b64(*FILEHANDLE); + $chaes_b64u = chaes_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::CHAES; + + $d = Crypt::Digest::CHAES->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the CHAES digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::CHAES qw(chaes chaes_hex chaes_b64 chaes_b64u + chaes_file chaes_file_hex chaes_file_b64 chaes_file_b64u); + +Or all of them at once: + + use Crypt::Digest::CHAES ':all'; + +=head1 FUNCTIONS + +=head2 chaes + +Logically joins all arguments into a single string, and returns its CHAES digest encoded as a binary string. + + $chaes_raw = chaes('data string'); + #or + $chaes_raw = chaes('any data', 'more data', 'even more data'); + +=head2 chaes_hex + +Logically joins all arguments into a single string, and returns its CHAES digest encoded as a hexadecimal string. + + $chaes_hex = chaes_hex('data string'); + #or + $chaes_hex = chaes_hex('any data', 'more data', 'even more data'); + +=head2 chaes_b64 + +Logically joins all arguments into a single string, and returns its CHAES digest encoded as a Base64 string, B trailing '=' padding. + + $chaes_b64 = chaes_b64('data string'); + #or + $chaes_b64 = chaes_b64('any data', 'more data', 'even more data'); + +=head2 chaes_b64u + +Logically joins all arguments into a single string, and returns its CHAES digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $chaes_b64url = chaes_b64u('data string'); + #or + $chaes_b64url = chaes_b64u('any data', 'more data', 'even more data'); + +=head2 chaes_file + +Reads file (defined by filename or filehandle) content, and returns its CHAES digest encoded as a binary string. + + $chaes_raw = chaes_file('filename.dat'); + #or + $chaes_raw = chaes_file(*FILEHANDLE); + +=head2 chaes_file_hex + +Reads file (defined by filename or filehandle) content, and returns its CHAES digest encoded as a hexadecimal string. + + $chaes_hex = chaes_file_hex('filename.dat'); + #or + $chaes_hex = chaes_file_hex(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 chaes_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its CHAES digest encoded as a Base64 string, B trailing '=' padding. + + $chaes_b64 = chaes_file_b64('filename.dat'); + #or + $chaes_b64 = chaes_file_b64(*FILEHANDLE); + +=head2 chaes_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its CHAES digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $chaes_b64url = chaes_file_b64u('filename.dat'); + #or + $chaes_b64url = chaes_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L. + +=head2 new + + $d = Crypt::Digest::CHAES->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::CHAES->hashsize(); + #or + Crypt::Digest::CHAES::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/MD2.pm b/lib/Crypt/Digest/MD2.pm new file mode 100644 index 0000000..12d3441 --- /dev/null +++ b/lib/Crypt/Digest/MD2.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::MD2; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( md2 md2_hex md2_b64 md2_b64u md2_file md2_file_hex md2_file_b64 md2_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub md2 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub md2_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub md2_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub md2_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub md2_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub md2_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub md2_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub md2_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::MD2 - Hash function MD2 [size: 128 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::MD2 qw( md2 md2_hex md2_b64 md2_b64u + md2_file md2_file_hex md2_file_b64 md2_file_b64u ); + + # calculate digest from string/buffer + $md2_raw = md2('data string'); + $md2_hex = md2_hex('data string'); + $md2_b64 = md2_b64('data string'); + $md2_b64u = md2_b64u('data string'); + # calculate digest from file + $md2_raw = md2_file('filename.dat'); + $md2_hex = md2_file_hex('filename.dat'); + $md2_b64 = md2_file_b64('filename.dat'); + $md2_b64u = md2_file_b64u('filename.dat'); + # calculate digest from filehandle + $md2_raw = md2_file(*FILEHANDLE); + $md2_hex = md2_file_hex(*FILEHANDLE); + $md2_b64 = md2_file_b64(*FILEHANDLE); + $md2_b64u = md2_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::MD2; + + $d = Crypt::Digest::MD2->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the MD2 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::MD2 qw(md2 md2_hex md2_b64 md2_b64u + md2_file md2_file_hex md2_file_b64 md2_file_b64u); + +Or all of them at once: + + use Crypt::Digest::MD2 ':all'; + +=head1 FUNCTIONS + +=head2 md2 + +Logically joins all arguments into a single string, and returns its MD2 digest encoded as a binary string. + + $md2_raw = md2('data string'); + #or + $md2_raw = md2('any data', 'more data', 'even more data'); + +=head2 md2_hex + +Logically joins all arguments into a single string, and returns its MD2 digest encoded as a hexadecimal string. + + $md2_hex = md2_hex('data string'); + #or + $md2_hex = md2_hex('any data', 'more data', 'even more data'); + +=head2 md2_b64 + +Logically joins all arguments into a single string, and returns its MD2 digest encoded as a Base64 string, B trailing '=' padding. + + $md2_b64 = md2_b64('data string'); + #or + $md2_b64 = md2_b64('any data', 'more data', 'even more data'); + +=head2 md2_b64u + +Logically joins all arguments into a single string, and returns its MD2 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $md2_b64url = md2_b64u('data string'); + #or + $md2_b64url = md2_b64u('any data', 'more data', 'even more data'); + +=head2 md2_file + +Reads file (defined by filename or filehandle) content, and returns its MD2 digest encoded as a binary string. + + $md2_raw = md2_file('filename.dat'); + #or + $md2_raw = md2_file(*FILEHANDLE); + +=head2 md2_file_hex + +Reads file (defined by filename or filehandle) content, and returns its MD2 digest encoded as a hexadecimal string. + + $md2_hex = md2_file_hex('filename.dat'); + #or + $md2_hex = md2_file_hex(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 md2_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its MD2 digest encoded as a Base64 string, B trailing '=' padding. + + $md2_b64 = md2_file_b64('filename.dat'); + #or + $md2_b64 = md2_file_b64(*FILEHANDLE); + +=head2 md2_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its MD2 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $md2_b64url = md2_file_b64u('filename.dat'); + #or + $md2_b64url = md2_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L. + +=head2 new + + $d = Crypt::Digest::MD2->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::MD2->hashsize(); + #or + Crypt::Digest::MD2::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/MD4.pm b/lib/Crypt/Digest/MD4.pm new file mode 100644 index 0000000..0725cde --- /dev/null +++ b/lib/Crypt/Digest/MD4.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::MD4; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( md4 md4_hex md4_b64 md4_b64u md4_file md4_file_hex md4_file_b64 md4_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub md4 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub md4_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub md4_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub md4_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub md4_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub md4_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub md4_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub md4_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::MD4 - Hash function MD4 [size: 128 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::MD4 qw( md4 md4_hex md4_b64 md4_b64u + md4_file md4_file_hex md4_file_b64 md4_file_b64u ); + + # calculate digest from string/buffer + $md4_raw = md4('data string'); + $md4_hex = md4_hex('data string'); + $md4_b64 = md4_b64('data string'); + $md4_b64u = md4_b64u('data string'); + # calculate digest from file + $md4_raw = md4_file('filename.dat'); + $md4_hex = md4_file_hex('filename.dat'); + $md4_b64 = md4_file_b64('filename.dat'); + $md4_b64u = md4_file_b64u('filename.dat'); + # calculate digest from filehandle + $md4_raw = md4_file(*FILEHANDLE); + $md4_hex = md4_file_hex(*FILEHANDLE); + $md4_b64 = md4_file_b64(*FILEHANDLE); + $md4_b64u = md4_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::MD4; + + $d = Crypt::Digest::MD4->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the MD4 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::MD4 qw(md4 md4_hex md4_b64 md4_b64u + md4_file md4_file_hex md4_file_b64 md4_file_b64u); + +Or all of them at once: + + use Crypt::Digest::MD4 ':all'; + +=head1 FUNCTIONS + +=head2 md4 + +Logically joins all arguments into a single string, and returns its MD4 digest encoded as a binary string. + + $md4_raw = md4('data string'); + #or + $md4_raw = md4('any data', 'more data', 'even more data'); + +=head2 md4_hex + +Logically joins all arguments into a single string, and returns its MD4 digest encoded as a hexadecimal string. + + $md4_hex = md4_hex('data string'); + #or + $md4_hex = md4_hex('any data', 'more data', 'even more data'); + +=head2 md4_b64 + +Logically joins all arguments into a single string, and returns its MD4 digest encoded as a Base64 string, B trailing '=' padding. + + $md4_b64 = md4_b64('data string'); + #or + $md4_b64 = md4_b64('any data', 'more data', 'even more data'); + +=head2 md4_b64u + +Logically joins all arguments into a single string, and returns its MD4 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $md4_b64url = md4_b64u('data string'); + #or + $md4_b64url = md4_b64u('any data', 'more data', 'even more data'); + +=head2 md4_file + +Reads file (defined by filename or filehandle) content, and returns its MD4 digest encoded as a binary string. + + $md4_raw = md4_file('filename.dat'); + #or + $md4_raw = md4_file(*FILEHANDLE); + +=head2 md4_file_hex + +Reads file (defined by filename or filehandle) content, and returns its MD4 digest encoded as a hexadecimal string. + + $md4_hex = md4_file_hex('filename.dat'); + #or + $md4_hex = md4_file_hex(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 md4_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its MD4 digest encoded as a Base64 string, B trailing '=' padding. + + $md4_b64 = md4_file_b64('filename.dat'); + #or + $md4_b64 = md4_file_b64(*FILEHANDLE); + +=head2 md4_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its MD4 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $md4_b64url = md4_file_b64u('filename.dat'); + #or + $md4_b64url = md4_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L. + +=head2 new + + $d = Crypt::Digest::MD4->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::MD4->hashsize(); + #or + Crypt::Digest::MD4::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/MD5.pm b/lib/Crypt/Digest/MD5.pm new file mode 100644 index 0000000..ef82f7a --- /dev/null +++ b/lib/Crypt/Digest/MD5.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::MD5; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( md5 md5_hex md5_b64 md5_b64u md5_file md5_file_hex md5_file_b64 md5_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub md5 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub md5_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub md5_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub md5_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub md5_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub md5_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub md5_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub md5_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::MD5 - Hash function MD5 [size: 128 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::MD5 qw( md5 md5_hex md5_b64 md5_b64u + md5_file md5_file_hex md5_file_b64 md5_file_b64u ); + + # calculate digest from string/buffer + $md5_raw = md5('data string'); + $md5_hex = md5_hex('data string'); + $md5_b64 = md5_b64('data string'); + $md5_b64u = md5_b64u('data string'); + # calculate digest from file + $md5_raw = md5_file('filename.dat'); + $md5_hex = md5_file_hex('filename.dat'); + $md5_b64 = md5_file_b64('filename.dat'); + $md5_b64u = md5_file_b64u('filename.dat'); + # calculate digest from filehandle + $md5_raw = md5_file(*FILEHANDLE); + $md5_hex = md5_file_hex(*FILEHANDLE); + $md5_b64 = md5_file_b64(*FILEHANDLE); + $md5_b64u = md5_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::MD5; + + $d = Crypt::Digest::MD5->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the MD5 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::MD5 qw(md5 md5_hex md5_b64 md5_b64u + md5_file md5_file_hex md5_file_b64 md5_file_b64u); + +Or all of them at once: + + use Crypt::Digest::MD5 ':all'; + +=head1 FUNCTIONS + +=head2 md5 + +Logically joins all arguments into a single string, and returns its MD5 digest encoded as a binary string. + + $md5_raw = md5('data string'); + #or + $md5_raw = md5('any data', 'more data', 'even more data'); + +=head2 md5_hex + +Logically joins all arguments into a single string, and returns its MD5 digest encoded as a hexadecimal string. + + $md5_hex = md5_hex('data string'); + #or + $md5_hex = md5_hex('any data', 'more data', 'even more data'); + +=head2 md5_b64 + +Logically joins all arguments into a single string, and returns its MD5 digest encoded as a Base64 string, B trailing '=' padding. + + $md5_b64 = md5_b64('data string'); + #or + $md5_b64 = md5_b64('any data', 'more data', 'even more data'); + +=head2 md5_b64u + +Logically joins all arguments into a single string, and returns its MD5 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $md5_b64url = md5_b64u('data string'); + #or + $md5_b64url = md5_b64u('any data', 'more data', 'even more data'); + +=head2 md5_file + +Reads file (defined by filename or filehandle) content, and returns its MD5 digest encoded as a binary string. + + $md5_raw = md5_file('filename.dat'); + #or + $md5_raw = md5_file(*FILEHANDLE); + +=head2 md5_file_hex + +Reads file (defined by filename or filehandle) content, and returns its MD5 digest encoded as a hexadecimal string. + + $md5_hex = md5_file_hex('filename.dat'); + #or + $md5_hex = md5_file_hex(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 md5_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its MD5 digest encoded as a Base64 string, B trailing '=' padding. + + $md5_b64 = md5_file_b64('filename.dat'); + #or + $md5_b64 = md5_file_b64(*FILEHANDLE); + +=head2 md5_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its MD5 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $md5_b64url = md5_file_b64u('filename.dat'); + #or + $md5_b64url = md5_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L. + +=head2 new + + $d = Crypt::Digest::MD5->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::MD5->hashsize(); + #or + Crypt::Digest::MD5::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/RIPEMD128.pm b/lib/Crypt/Digest/RIPEMD128.pm new file mode 100644 index 0000000..ec91f8b --- /dev/null +++ b/lib/Crypt/Digest/RIPEMD128.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::RIPEMD128; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( ripemd128 ripemd128_hex ripemd128_b64 ripemd128_b64u ripemd128_file ripemd128_file_hex ripemd128_file_b64 ripemd128_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub ripemd128 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub ripemd128_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub ripemd128_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub ripemd128_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub ripemd128_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub ripemd128_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub ripemd128_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub ripemd128_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::RIPEMD128 - Hash function RIPEMD-128 [size: 128 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::RIPEMD128 qw( ripemd128 ripemd128_hex ripemd128_b64 ripemd128_b64u + ripemd128_file ripemd128_file_hex ripemd128_file_b64 ripemd128_file_b64u ); + + # calculate digest from string/buffer + $ripemd128_raw = ripemd128('data string'); + $ripemd128_hex = ripemd128_hex('data string'); + $ripemd128_b64 = ripemd128_b64('data string'); + $ripemd128_b64u = ripemd128_b64u('data string'); + # calculate digest from file + $ripemd128_raw = ripemd128_file('filename.dat'); + $ripemd128_hex = ripemd128_file_hex('filename.dat'); + $ripemd128_b64 = ripemd128_file_b64('filename.dat'); + $ripemd128_b64u = ripemd128_file_b64u('filename.dat'); + # calculate digest from filehandle + $ripemd128_raw = ripemd128_file(*FILEHANDLE); + $ripemd128_hex = ripemd128_file_hex(*FILEHANDLE); + $ripemd128_b64 = ripemd128_file_b64(*FILEHANDLE); + $ripemd128_b64u = ripemd128_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::RIPEMD128; + + $d = Crypt::Digest::RIPEMD128->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the RIPEMD128 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::RIPEMD128 qw(ripemd128 ripemd128_hex ripemd128_b64 ripemd128_b64u + ripemd128_file ripemd128_file_hex ripemd128_file_b64 ripemd128_file_b64u); + +Or all of them at once: + + use Crypt::Digest::RIPEMD128 ':all'; + +=head1 FUNCTIONS + +=head2 ripemd128 + +Logically joins all arguments into a single string, and returns its RIPEMD128 digest encoded as a binary string. + + $ripemd128_raw = ripemd128('data string'); + #or + $ripemd128_raw = ripemd128('any data', 'more data', 'even more data'); + +=head2 ripemd128_hex + +Logically joins all arguments into a single string, and returns its RIPEMD128 digest encoded as a hexadecimal string. + + $ripemd128_hex = ripemd128_hex('data string'); + #or + $ripemd128_hex = ripemd128_hex('any data', 'more data', 'even more data'); + +=head2 ripemd128_b64 + +Logically joins all arguments into a single string, and returns its RIPEMD128 digest encoded as a Base64 string, B trailing '=' padding. + + $ripemd128_b64 = ripemd128_b64('data string'); + #or + $ripemd128_b64 = ripemd128_b64('any data', 'more data', 'even more data'); + +=head2 ripemd128_b64u + +Logically joins all arguments into a single string, and returns its RIPEMD128 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $ripemd128_b64url = ripemd128_b64u('data string'); + #or + $ripemd128_b64url = ripemd128_b64u('any data', 'more data', 'even more data'); + +=head2 ripemd128_file + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD128 digest encoded as a binary string. + + $ripemd128_raw = ripemd128_file('filename.dat'); + #or + $ripemd128_raw = ripemd128_file(*FILEHANDLE); + +=head2 ripemd128_file_hex + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD128 digest encoded as a hexadecimal string. + + $ripemd128_hex = ripemd128_file_hex('filename.dat'); + #or + $ripemd128_hex = ripemd128_file_hex(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 ripemd128_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD128 digest encoded as a Base64 string, B trailing '=' padding. + + $ripemd128_b64 = ripemd128_file_b64('filename.dat'); + #or + $ripemd128_b64 = ripemd128_file_b64(*FILEHANDLE); + +=head2 ripemd128_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD128 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $ripemd128_b64url = ripemd128_file_b64u('filename.dat'); + #or + $ripemd128_b64url = ripemd128_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L. + +=head2 new + + $d = Crypt::Digest::RIPEMD128->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::RIPEMD128->hashsize(); + #or + Crypt::Digest::RIPEMD128::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/RIPEMD160.pm b/lib/Crypt/Digest/RIPEMD160.pm new file mode 100644 index 0000000..b13d948 --- /dev/null +++ b/lib/Crypt/Digest/RIPEMD160.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::RIPEMD160; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( ripemd160 ripemd160_hex ripemd160_b64 ripemd160_b64u ripemd160_file ripemd160_file_hex ripemd160_file_b64 ripemd160_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub ripemd160 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub ripemd160_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub ripemd160_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub ripemd160_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub ripemd160_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub ripemd160_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub ripemd160_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub ripemd160_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::RIPEMD160 - Hash function RIPEMD-160 [size: 160 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::RIPEMD160 qw( ripemd160 ripemd160_hex ripemd160_b64 ripemd160_b64u + ripemd160_file ripemd160_file_hex ripemd160_file_b64 ripemd160_file_b64u ); + + # calculate digest from string/buffer + $ripemd160_raw = ripemd160('data string'); + $ripemd160_hex = ripemd160_hex('data string'); + $ripemd160_b64 = ripemd160_b64('data string'); + $ripemd160_b64u = ripemd160_b64u('data string'); + # calculate digest from file + $ripemd160_raw = ripemd160_file('filename.dat'); + $ripemd160_hex = ripemd160_file_hex('filename.dat'); + $ripemd160_b64 = ripemd160_file_b64('filename.dat'); + $ripemd160_b64u = ripemd160_file_b64u('filename.dat'); + # calculate digest from filehandle + $ripemd160_raw = ripemd160_file(*FILEHANDLE); + $ripemd160_hex = ripemd160_file_hex(*FILEHANDLE); + $ripemd160_b64 = ripemd160_file_b64(*FILEHANDLE); + $ripemd160_b64u = ripemd160_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::RIPEMD160; + + $d = Crypt::Digest::RIPEMD160->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the RIPEMD160 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::RIPEMD160 qw(ripemd160 ripemd160_hex ripemd160_b64 ripemd160_b64u + ripemd160_file ripemd160_file_hex ripemd160_file_b64 ripemd160_file_b64u); + +Or all of them at once: + + use Crypt::Digest::RIPEMD160 ':all'; + +=head1 FUNCTIONS + +=head2 ripemd160 + +Logically joins all arguments into a single string, and returns its RIPEMD160 digest encoded as a binary string. + + $ripemd160_raw = ripemd160('data string'); + #or + $ripemd160_raw = ripemd160('any data', 'more data', 'even more data'); + +=head2 ripemd160_hex + +Logically joins all arguments into a single string, and returns its RIPEMD160 digest encoded as a hexadecimal string. + + $ripemd160_hex = ripemd160_hex('data string'); + #or + $ripemd160_hex = ripemd160_hex('any data', 'more data', 'even more data'); + +=head2 ripemd160_b64 + +Logically joins all arguments into a single string, and returns its RIPEMD160 digest encoded as a Base64 string, B trailing '=' padding. + + $ripemd160_b64 = ripemd160_b64('data string'); + #or + $ripemd160_b64 = ripemd160_b64('any data', 'more data', 'even more data'); + +=head2 ripemd160_b64u + +Logically joins all arguments into a single string, and returns its RIPEMD160 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $ripemd160_b64url = ripemd160_b64u('data string'); + #or + $ripemd160_b64url = ripemd160_b64u('any data', 'more data', 'even more data'); + +=head2 ripemd160_file + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD160 digest encoded as a binary string. + + $ripemd160_raw = ripemd160_file('filename.dat'); + #or + $ripemd160_raw = ripemd160_file(*FILEHANDLE); + +=head2 ripemd160_file_hex + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD160 digest encoded as a hexadecimal string. + + $ripemd160_hex = ripemd160_file_hex('filename.dat'); + #or + $ripemd160_hex = ripemd160_file_hex(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 ripemd160_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD160 digest encoded as a Base64 string, B trailing '=' padding. + + $ripemd160_b64 = ripemd160_file_b64('filename.dat'); + #or + $ripemd160_b64 = ripemd160_file_b64(*FILEHANDLE); + +=head2 ripemd160_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD160 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $ripemd160_b64url = ripemd160_file_b64u('filename.dat'); + #or + $ripemd160_b64url = ripemd160_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L. + +=head2 new + + $d = Crypt::Digest::RIPEMD160->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::RIPEMD160->hashsize(); + #or + Crypt::Digest::RIPEMD160::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/RIPEMD256.pm b/lib/Crypt/Digest/RIPEMD256.pm new file mode 100644 index 0000000..d1ed349 --- /dev/null +++ b/lib/Crypt/Digest/RIPEMD256.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::RIPEMD256; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( ripemd256 ripemd256_hex ripemd256_b64 ripemd256_b64u ripemd256_file ripemd256_file_hex ripemd256_file_b64 ripemd256_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub ripemd256 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub ripemd256_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub ripemd256_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub ripemd256_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub ripemd256_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub ripemd256_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub ripemd256_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub ripemd256_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::RIPEMD256 - Hash function RIPEMD-256 [size: 256 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::RIPEMD256 qw( ripemd256 ripemd256_hex ripemd256_b64 ripemd256_b64u + ripemd256_file ripemd256_file_hex ripemd256_file_b64 ripemd256_file_b64u ); + + # calculate digest from string/buffer + $ripemd256_raw = ripemd256('data string'); + $ripemd256_hex = ripemd256_hex('data string'); + $ripemd256_b64 = ripemd256_b64('data string'); + $ripemd256_b64u = ripemd256_b64u('data string'); + # calculate digest from file + $ripemd256_raw = ripemd256_file('filename.dat'); + $ripemd256_hex = ripemd256_file_hex('filename.dat'); + $ripemd256_b64 = ripemd256_file_b64('filename.dat'); + $ripemd256_b64u = ripemd256_file_b64u('filename.dat'); + # calculate digest from filehandle + $ripemd256_raw = ripemd256_file(*FILEHANDLE); + $ripemd256_hex = ripemd256_file_hex(*FILEHANDLE); + $ripemd256_b64 = ripemd256_file_b64(*FILEHANDLE); + $ripemd256_b64u = ripemd256_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::RIPEMD256; + + $d = Crypt::Digest::RIPEMD256->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the RIPEMD256 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::RIPEMD256 qw(ripemd256 ripemd256_hex ripemd256_b64 ripemd256_b64u + ripemd256_file ripemd256_file_hex ripemd256_file_b64 ripemd256_file_b64u); + +Or all of them at once: + + use Crypt::Digest::RIPEMD256 ':all'; + +=head1 FUNCTIONS + +=head2 ripemd256 + +Logically joins all arguments into a single string, and returns its RIPEMD256 digest encoded as a binary string. + + $ripemd256_raw = ripemd256('data string'); + #or + $ripemd256_raw = ripemd256('any data', 'more data', 'even more data'); + +=head2 ripemd256_hex + +Logically joins all arguments into a single string, and returns its RIPEMD256 digest encoded as a hexadecimal string. + + $ripemd256_hex = ripemd256_hex('data string'); + #or + $ripemd256_hex = ripemd256_hex('any data', 'more data', 'even more data'); + +=head2 ripemd256_b64 + +Logically joins all arguments into a single string, and returns its RIPEMD256 digest encoded as a Base64 string, B trailing '=' padding. + + $ripemd256_b64 = ripemd256_b64('data string'); + #or + $ripemd256_b64 = ripemd256_b64('any data', 'more data', 'even more data'); + +=head2 ripemd256_b64u + +Logically joins all arguments into a single string, and returns its RIPEMD256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $ripemd256_b64url = ripemd256_b64u('data string'); + #or + $ripemd256_b64url = ripemd256_b64u('any data', 'more data', 'even more data'); + +=head2 ripemd256_file + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD256 digest encoded as a binary string. + + $ripemd256_raw = ripemd256_file('filename.dat'); + #or + $ripemd256_raw = ripemd256_file(*FILEHANDLE); + +=head2 ripemd256_file_hex + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD256 digest encoded as a hexadecimal string. + + $ripemd256_hex = ripemd256_file_hex('filename.dat'); + #or + $ripemd256_hex = ripemd256_file_hex(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 ripemd256_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD256 digest encoded as a Base64 string, B trailing '=' padding. + + $ripemd256_b64 = ripemd256_file_b64('filename.dat'); + #or + $ripemd256_b64 = ripemd256_file_b64(*FILEHANDLE); + +=head2 ripemd256_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $ripemd256_b64url = ripemd256_file_b64u('filename.dat'); + #or + $ripemd256_b64url = ripemd256_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L. + +=head2 new + + $d = Crypt::Digest::RIPEMD256->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::RIPEMD256->hashsize(); + #or + Crypt::Digest::RIPEMD256::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/RIPEMD320.pm b/lib/Crypt/Digest/RIPEMD320.pm new file mode 100644 index 0000000..816ad93 --- /dev/null +++ b/lib/Crypt/Digest/RIPEMD320.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::RIPEMD320; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( ripemd320 ripemd320_hex ripemd320_b64 ripemd320_b64u ripemd320_file ripemd320_file_hex ripemd320_file_b64 ripemd320_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub ripemd320 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub ripemd320_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub ripemd320_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub ripemd320_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub ripemd320_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub ripemd320_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub ripemd320_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub ripemd320_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::RIPEMD320 - Hash function RIPEMD-320 [size: 320 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::RIPEMD320 qw( ripemd320 ripemd320_hex ripemd320_b64 ripemd320_b64u + ripemd320_file ripemd320_file_hex ripemd320_file_b64 ripemd320_file_b64u ); + + # calculate digest from string/buffer + $ripemd320_raw = ripemd320('data string'); + $ripemd320_hex = ripemd320_hex('data string'); + $ripemd320_b64 = ripemd320_b64('data string'); + $ripemd320_b64u = ripemd320_b64u('data string'); + # calculate digest from file + $ripemd320_raw = ripemd320_file('filename.dat'); + $ripemd320_hex = ripemd320_file_hex('filename.dat'); + $ripemd320_b64 = ripemd320_file_b64('filename.dat'); + $ripemd320_b64u = ripemd320_file_b64u('filename.dat'); + # calculate digest from filehandle + $ripemd320_raw = ripemd320_file(*FILEHANDLE); + $ripemd320_hex = ripemd320_file_hex(*FILEHANDLE); + $ripemd320_b64 = ripemd320_file_b64(*FILEHANDLE); + $ripemd320_b64u = ripemd320_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::RIPEMD320; + + $d = Crypt::Digest::RIPEMD320->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the RIPEMD320 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::RIPEMD320 qw(ripemd320 ripemd320_hex ripemd320_b64 ripemd320_b64u + ripemd320_file ripemd320_file_hex ripemd320_file_b64 ripemd320_file_b64u); + +Or all of them at once: + + use Crypt::Digest::RIPEMD320 ':all'; + +=head1 FUNCTIONS + +=head2 ripemd320 + +Logically joins all arguments into a single string, and returns its RIPEMD320 digest encoded as a binary string. + + $ripemd320_raw = ripemd320('data string'); + #or + $ripemd320_raw = ripemd320('any data', 'more data', 'even more data'); + +=head2 ripemd320_hex + +Logically joins all arguments into a single string, and returns its RIPEMD320 digest encoded as a hexadecimal string. + + $ripemd320_hex = ripemd320_hex('data string'); + #or + $ripemd320_hex = ripemd320_hex('any data', 'more data', 'even more data'); + +=head2 ripemd320_b64 + +Logically joins all arguments into a single string, and returns its RIPEMD320 digest encoded as a Base64 string, B trailing '=' padding. + + $ripemd320_b64 = ripemd320_b64('data string'); + #or + $ripemd320_b64 = ripemd320_b64('any data', 'more data', 'even more data'); + +=head2 ripemd320_b64u + +Logically joins all arguments into a single string, and returns its RIPEMD320 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $ripemd320_b64url = ripemd320_b64u('data string'); + #or + $ripemd320_b64url = ripemd320_b64u('any data', 'more data', 'even more data'); + +=head2 ripemd320_file + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD320 digest encoded as a binary string. + + $ripemd320_raw = ripemd320_file('filename.dat'); + #or + $ripemd320_raw = ripemd320_file(*FILEHANDLE); + +=head2 ripemd320_file_hex + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD320 digest encoded as a hexadecimal string. + + $ripemd320_hex = ripemd320_file_hex('filename.dat'); + #or + $ripemd320_hex = ripemd320_file_hex(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 ripemd320_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD320 digest encoded as a Base64 string, B trailing '=' padding. + + $ripemd320_b64 = ripemd320_file_b64('filename.dat'); + #or + $ripemd320_b64 = ripemd320_file_b64(*FILEHANDLE); + +=head2 ripemd320_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its RIPEMD320 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $ripemd320_b64url = ripemd320_file_b64u('filename.dat'); + #or + $ripemd320_b64url = ripemd320_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L. + +=head2 new + + $d = Crypt::Digest::RIPEMD320->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::RIPEMD320->hashsize(); + #or + Crypt::Digest::RIPEMD320::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/SHA1.pm b/lib/Crypt/Digest/SHA1.pm new file mode 100644 index 0000000..80e6afa --- /dev/null +++ b/lib/Crypt/Digest/SHA1.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::SHA1; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( sha1 sha1_hex sha1_b64 sha1_b64u sha1_file sha1_file_hex sha1_file_b64 sha1_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub sha1 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub sha1_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub sha1_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub sha1_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub sha1_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub sha1_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub sha1_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub sha1_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::SHA1 - Hash function SHA-1 [size: 160 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::SHA1 qw( sha1 sha1_hex sha1_b64 sha1_b64u + sha1_file sha1_file_hex sha1_file_b64 sha1_file_b64u ); + + # calculate digest from string/buffer + $sha1_raw = sha1('data string'); + $sha1_hex = sha1_hex('data string'); + $sha1_b64 = sha1_b64('data string'); + $sha1_b64u = sha1_b64u('data string'); + # calculate digest from file + $sha1_raw = sha1_file('filename.dat'); + $sha1_hex = sha1_file_hex('filename.dat'); + $sha1_b64 = sha1_file_b64('filename.dat'); + $sha1_b64u = sha1_file_b64u('filename.dat'); + # calculate digest from filehandle + $sha1_raw = sha1_file(*FILEHANDLE); + $sha1_hex = sha1_file_hex(*FILEHANDLE); + $sha1_b64 = sha1_file_b64(*FILEHANDLE); + $sha1_b64u = sha1_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::SHA1; + + $d = Crypt::Digest::SHA1->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the SHA1 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::SHA1 qw(sha1 sha1_hex sha1_b64 sha1_b64u + sha1_file sha1_file_hex sha1_file_b64 sha1_file_b64u); + +Or all of them at once: + + use Crypt::Digest::SHA1 ':all'; + +=head1 FUNCTIONS + +=head2 sha1 + +Logically joins all arguments into a single string, and returns its SHA1 digest encoded as a binary string. + + $sha1_raw = sha1('data string'); + #or + $sha1_raw = sha1('any data', 'more data', 'even more data'); + +=head2 sha1_hex + +Logically joins all arguments into a single string, and returns its SHA1 digest encoded as a hexadecimal string. + + $sha1_hex = sha1_hex('data string'); + #or + $sha1_hex = sha1_hex('any data', 'more data', 'even more data'); + +=head2 sha1_b64 + +Logically joins all arguments into a single string, and returns its SHA1 digest encoded as a Base64 string, B trailing '=' padding. + + $sha1_b64 = sha1_b64('data string'); + #or + $sha1_b64 = sha1_b64('any data', 'more data', 'even more data'); + +=head2 sha1_b64u + +Logically joins all arguments into a single string, and returns its SHA1 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha1_b64url = sha1_b64u('data string'); + #or + $sha1_b64url = sha1_b64u('any data', 'more data', 'even more data'); + +=head2 sha1_file + +Reads file (defined by filename or filehandle) content, and returns its SHA1 digest encoded as a binary string. + + $sha1_raw = sha1_file('filename.dat'); + #or + $sha1_raw = sha1_file(*FILEHANDLE); + +=head2 sha1_file_hex + +Reads file (defined by filename or filehandle) content, and returns its SHA1 digest encoded as a hexadecimal string. + + $sha1_hex = sha1_file_hex('filename.dat'); + #or + $sha1_hex = sha1_file_hex(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 sha1_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its SHA1 digest encoded as a Base64 string, B trailing '=' padding. + + $sha1_b64 = sha1_file_b64('filename.dat'); + #or + $sha1_b64 = sha1_file_b64(*FILEHANDLE); + +=head2 sha1_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its SHA1 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha1_b64url = sha1_file_b64u('filename.dat'); + #or + $sha1_b64url = sha1_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L. + +=head2 new + + $d = Crypt::Digest::SHA1->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::SHA1->hashsize(); + #or + Crypt::Digest::SHA1::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/SHA224.pm b/lib/Crypt/Digest/SHA224.pm new file mode 100644 index 0000000..9d34257 --- /dev/null +++ b/lib/Crypt/Digest/SHA224.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::SHA224; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( sha224 sha224_hex sha224_b64 sha224_b64u sha224_file sha224_file_hex sha224_file_b64 sha224_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub sha224 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub sha224_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub sha224_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub sha224_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub sha224_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub sha224_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub sha224_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub sha224_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::SHA224 - Hash function SHA-224 [size: 224 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::SHA224 qw( sha224 sha224_hex sha224_b64 sha224_b64u + sha224_file sha224_file_hex sha224_file_b64 sha224_file_b64u ); + + # calculate digest from string/buffer + $sha224_raw = sha224('data string'); + $sha224_hex = sha224_hex('data string'); + $sha224_b64 = sha224_b64('data string'); + $sha224_b64u = sha224_b64u('data string'); + # calculate digest from file + $sha224_raw = sha224_file('filename.dat'); + $sha224_hex = sha224_file_hex('filename.dat'); + $sha224_b64 = sha224_file_b64('filename.dat'); + $sha224_b64u = sha224_file_b64u('filename.dat'); + # calculate digest from filehandle + $sha224_raw = sha224_file(*FILEHANDLE); + $sha224_hex = sha224_file_hex(*FILEHANDLE); + $sha224_b64 = sha224_file_b64(*FILEHANDLE); + $sha224_b64u = sha224_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::SHA224; + + $d = Crypt::Digest::SHA224->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the SHA224 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::SHA224 qw(sha224 sha224_hex sha224_b64 sha224_b64u + sha224_file sha224_file_hex sha224_file_b64 sha224_file_b64u); + +Or all of them at once: + + use Crypt::Digest::SHA224 ':all'; + +=head1 FUNCTIONS + +=head2 sha224 + +Logically joins all arguments into a single string, and returns its SHA224 digest encoded as a binary string. + + $sha224_raw = sha224('data string'); + #or + $sha224_raw = sha224('any data', 'more data', 'even more data'); + +=head2 sha224_hex + +Logically joins all arguments into a single string, and returns its SHA224 digest encoded as a hexadecimal string. + + $sha224_hex = sha224_hex('data string'); + #or + $sha224_hex = sha224_hex('any data', 'more data', 'even more data'); + +=head2 sha224_b64 + +Logically joins all arguments into a single string, and returns its SHA224 digest encoded as a Base64 string, B trailing '=' padding. + + $sha224_b64 = sha224_b64('data string'); + #or + $sha224_b64 = sha224_b64('any data', 'more data', 'even more data'); + +=head2 sha224_b64u + +Logically joins all arguments into a single string, and returns its SHA224 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha224_b64url = sha224_b64u('data string'); + #or + $sha224_b64url = sha224_b64u('any data', 'more data', 'even more data'); + +=head2 sha224_file + +Reads file (defined by filename or filehandle) content, and returns its SHA224 digest encoded as a binary string. + + $sha224_raw = sha224_file('filename.dat'); + #or + $sha224_raw = sha224_file(*FILEHANDLE); + +=head2 sha224_file_hex + +Reads file (defined by filename or filehandle) content, and returns its SHA224 digest encoded as a hexadecimal string. + + $sha224_hex = sha224_file_hex('filename.dat'); + #or + $sha224_hex = sha224_file_hex(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 sha224_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its SHA224 digest encoded as a Base64 string, B trailing '=' padding. + + $sha224_b64 = sha224_file_b64('filename.dat'); + #or + $sha224_b64 = sha224_file_b64(*FILEHANDLE); + +=head2 sha224_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its SHA224 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha224_b64url = sha224_file_b64u('filename.dat'); + #or + $sha224_b64url = sha224_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L. + +=head2 new + + $d = Crypt::Digest::SHA224->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::SHA224->hashsize(); + #or + Crypt::Digest::SHA224::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/SHA256.pm b/lib/Crypt/Digest/SHA256.pm new file mode 100644 index 0000000..4e68b95 --- /dev/null +++ b/lib/Crypt/Digest/SHA256.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::SHA256; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( sha256 sha256_hex sha256_b64 sha256_b64u sha256_file sha256_file_hex sha256_file_b64 sha256_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub sha256 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub sha256_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub sha256_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub sha256_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub sha256_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub sha256_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub sha256_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub sha256_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::SHA256 - Hash function SHA-256 [size: 256 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::SHA256 qw( sha256 sha256_hex sha256_b64 sha256_b64u + sha256_file sha256_file_hex sha256_file_b64 sha256_file_b64u ); + + # calculate digest from string/buffer + $sha256_raw = sha256('data string'); + $sha256_hex = sha256_hex('data string'); + $sha256_b64 = sha256_b64('data string'); + $sha256_b64u = sha256_b64u('data string'); + # calculate digest from file + $sha256_raw = sha256_file('filename.dat'); + $sha256_hex = sha256_file_hex('filename.dat'); + $sha256_b64 = sha256_file_b64('filename.dat'); + $sha256_b64u = sha256_file_b64u('filename.dat'); + # calculate digest from filehandle + $sha256_raw = sha256_file(*FILEHANDLE); + $sha256_hex = sha256_file_hex(*FILEHANDLE); + $sha256_b64 = sha256_file_b64(*FILEHANDLE); + $sha256_b64u = sha256_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::SHA256; + + $d = Crypt::Digest::SHA256->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the SHA256 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::SHA256 qw(sha256 sha256_hex sha256_b64 sha256_b64u + sha256_file sha256_file_hex sha256_file_b64 sha256_file_b64u); + +Or all of them at once: + + use Crypt::Digest::SHA256 ':all'; + +=head1 FUNCTIONS + +=head2 sha256 + +Logically joins all arguments into a single string, and returns its SHA256 digest encoded as a binary string. + + $sha256_raw = sha256('data string'); + #or + $sha256_raw = sha256('any data', 'more data', 'even more data'); + +=head2 sha256_hex + +Logically joins all arguments into a single string, and returns its SHA256 digest encoded as a hexadecimal string. + + $sha256_hex = sha256_hex('data string'); + #or + $sha256_hex = sha256_hex('any data', 'more data', 'even more data'); + +=head2 sha256_b64 + +Logically joins all arguments into a single string, and returns its SHA256 digest encoded as a Base64 string, B trailing '=' padding. + + $sha256_b64 = sha256_b64('data string'); + #or + $sha256_b64 = sha256_b64('any data', 'more data', 'even more data'); + +=head2 sha256_b64u + +Logically joins all arguments into a single string, and returns its SHA256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha256_b64url = sha256_b64u('data string'); + #or + $sha256_b64url = sha256_b64u('any data', 'more data', 'even more data'); + +=head2 sha256_file + +Reads file (defined by filename or filehandle) content, and returns its SHA256 digest encoded as a binary string. + + $sha256_raw = sha256_file('filename.dat'); + #or + $sha256_raw = sha256_file(*FILEHANDLE); + +=head2 sha256_file_hex + +Reads file (defined by filename or filehandle) content, and returns its SHA256 digest encoded as a hexadecimal string. + + $sha256_hex = sha256_file_hex('filename.dat'); + #or + $sha256_hex = sha256_file_hex(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 sha256_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its SHA256 digest encoded as a Base64 string, B trailing '=' padding. + + $sha256_b64 = sha256_file_b64('filename.dat'); + #or + $sha256_b64 = sha256_file_b64(*FILEHANDLE); + +=head2 sha256_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its SHA256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha256_b64url = sha256_file_b64u('filename.dat'); + #or + $sha256_b64url = sha256_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L. + +=head2 new + + $d = Crypt::Digest::SHA256->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::SHA256->hashsize(); + #or + Crypt::Digest::SHA256::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/SHA384.pm b/lib/Crypt/Digest/SHA384.pm new file mode 100644 index 0000000..f8ddfe2 --- /dev/null +++ b/lib/Crypt/Digest/SHA384.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::SHA384; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( sha384 sha384_hex sha384_b64 sha384_b64u sha384_file sha384_file_hex sha384_file_b64 sha384_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub sha384 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub sha384_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub sha384_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub sha384_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub sha384_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub sha384_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub sha384_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub sha384_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::SHA384 - Hash function SHA-384 [size: 384 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::SHA384 qw( sha384 sha384_hex sha384_b64 sha384_b64u + sha384_file sha384_file_hex sha384_file_b64 sha384_file_b64u ); + + # calculate digest from string/buffer + $sha384_raw = sha384('data string'); + $sha384_hex = sha384_hex('data string'); + $sha384_b64 = sha384_b64('data string'); + $sha384_b64u = sha384_b64u('data string'); + # calculate digest from file + $sha384_raw = sha384_file('filename.dat'); + $sha384_hex = sha384_file_hex('filename.dat'); + $sha384_b64 = sha384_file_b64('filename.dat'); + $sha384_b64u = sha384_file_b64u('filename.dat'); + # calculate digest from filehandle + $sha384_raw = sha384_file(*FILEHANDLE); + $sha384_hex = sha384_file_hex(*FILEHANDLE); + $sha384_b64 = sha384_file_b64(*FILEHANDLE); + $sha384_b64u = sha384_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::SHA384; + + $d = Crypt::Digest::SHA384->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the SHA384 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::SHA384 qw(sha384 sha384_hex sha384_b64 sha384_b64u + sha384_file sha384_file_hex sha384_file_b64 sha384_file_b64u); + +Or all of them at once: + + use Crypt::Digest::SHA384 ':all'; + +=head1 FUNCTIONS + +=head2 sha384 + +Logically joins all arguments into a single string, and returns its SHA384 digest encoded as a binary string. + + $sha384_raw = sha384('data string'); + #or + $sha384_raw = sha384('any data', 'more data', 'even more data'); + +=head2 sha384_hex + +Logically joins all arguments into a single string, and returns its SHA384 digest encoded as a hexadecimal string. + + $sha384_hex = sha384_hex('data string'); + #or + $sha384_hex = sha384_hex('any data', 'more data', 'even more data'); + +=head2 sha384_b64 + +Logically joins all arguments into a single string, and returns its SHA384 digest encoded as a Base64 string, B trailing '=' padding. + + $sha384_b64 = sha384_b64('data string'); + #or + $sha384_b64 = sha384_b64('any data', 'more data', 'even more data'); + +=head2 sha384_b64u + +Logically joins all arguments into a single string, and returns its SHA384 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha384_b64url = sha384_b64u('data string'); + #or + $sha384_b64url = sha384_b64u('any data', 'more data', 'even more data'); + +=head2 sha384_file + +Reads file (defined by filename or filehandle) content, and returns its SHA384 digest encoded as a binary string. + + $sha384_raw = sha384_file('filename.dat'); + #or + $sha384_raw = sha384_file(*FILEHANDLE); + +=head2 sha384_file_hex + +Reads file (defined by filename or filehandle) content, and returns its SHA384 digest encoded as a hexadecimal string. + + $sha384_hex = sha384_file_hex('filename.dat'); + #or + $sha384_hex = sha384_file_hex(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 sha384_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its SHA384 digest encoded as a Base64 string, B trailing '=' padding. + + $sha384_b64 = sha384_file_b64('filename.dat'); + #or + $sha384_b64 = sha384_file_b64(*FILEHANDLE); + +=head2 sha384_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its SHA384 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha384_b64url = sha384_file_b64u('filename.dat'); + #or + $sha384_b64url = sha384_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L. + +=head2 new + + $d = Crypt::Digest::SHA384->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::SHA384->hashsize(); + #or + Crypt::Digest::SHA384::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/SHA3_224.pm b/lib/Crypt/Digest/SHA3_224.pm new file mode 100644 index 0000000..192c044 --- /dev/null +++ b/lib/Crypt/Digest/SHA3_224.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::SHA3_224; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( sha3_224 sha3_224_hex sha3_224_b64 sha3_224_b64u sha3_224_file sha3_224_file_hex sha3_224_file_b64 sha3_224_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub sha3_224 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub sha3_224_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub sha3_224_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub sha3_224_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub sha3_224_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub sha3_224_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub sha3_224_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub sha3_224_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::SHA3_224 - Hash function SHA3-224 [size: 224 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::SHA3_224 qw( sha3_224 sha3_224_hex sha3_224_b64 sha3_224_b64u + sha3_224_file sha3_224_file_hex sha3_224_file_b64 sha3_224_file_b64u ); + + # calculate digest from string/buffer + $sha3_224_raw = sha3_224('data string'); + $sha3_224_hex = sha3_224_hex('data string'); + $sha3_224_b64 = sha3_224_b64('data string'); + $sha3_224_b64u = sha3_224_b64u('data string'); + # calculate digest from file + $sha3_224_raw = sha3_224_file('filename.dat'); + $sha3_224_hex = sha3_224_file_hex('filename.dat'); + $sha3_224_b64 = sha3_224_file_b64('filename.dat'); + $sha3_224_b64u = sha3_224_file_b64u('filename.dat'); + # calculate digest from filehandle + $sha3_224_raw = sha3_224_file(*FILEHANDLE); + $sha3_224_hex = sha3_224_file_hex(*FILEHANDLE); + $sha3_224_b64 = sha3_224_file_b64(*FILEHANDLE); + $sha3_224_b64u = sha3_224_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::SHA3_224; + + $d = Crypt::Digest::SHA3_224->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the SHA3_224 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::SHA3_224 qw(sha3_224 sha3_224_hex sha3_224_b64 sha3_224_b64u + sha3_224_file sha3_224_file_hex sha3_224_file_b64 sha3_224_file_b64u); + +Or all of them at once: + + use Crypt::Digest::SHA3_224 ':all'; + +=head1 FUNCTIONS + +=head2 sha3_224 + +Logically joins all arguments into a single string, and returns its SHA3_224 digest encoded as a binary string. + + $sha3_224_raw = sha3_224('data string'); + #or + $sha3_224_raw = sha3_224('any data', 'more data', 'even more data'); + +=head2 sha3_224_hex + +Logically joins all arguments into a single string, and returns its SHA3_224 digest encoded as a hexadecimal string. + + $sha3_224_hex = sha3_224_hex('data string'); + #or + $sha3_224_hex = sha3_224_hex('any data', 'more data', 'even more data'); + +=head2 sha3_224_b64 + +Logically joins all arguments into a single string, and returns its SHA3_224 digest encoded as a Base64 string, B trailing '=' padding. + + $sha3_224_b64 = sha3_224_b64('data string'); + #or + $sha3_224_b64 = sha3_224_b64('any data', 'more data', 'even more data'); + +=head2 sha3_224_b64u + +Logically joins all arguments into a single string, and returns its SHA3_224 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha3_224_b64url = sha3_224_b64u('data string'); + #or + $sha3_224_b64url = sha3_224_b64u('any data', 'more data', 'even more data'); + +=head2 sha3_224_file + +Reads file (defined by filename or filehandle) content, and returns its SHA3_224 digest encoded as a binary string. + + $sha3_224_raw = sha3_224_file('filename.dat'); + #or + $sha3_224_raw = sha3_224_file(*FILEHANDLE); + +=head2 sha3_224_file_hex + +Reads file (defined by filename or filehandle) content, and returns its SHA3_224 digest encoded as a hexadecimal string. + + $sha3_224_hex = sha3_224_file_hex('filename.dat'); + #or + $sha3_224_hex = sha3_224_file_hex(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 sha3_224_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its SHA3_224 digest encoded as a Base64 string, B trailing '=' padding. + + $sha3_224_b64 = sha3_224_file_b64('filename.dat'); + #or + $sha3_224_b64 = sha3_224_file_b64(*FILEHANDLE); + +=head2 sha3_224_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its SHA3_224 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha3_224_b64url = sha3_224_file_b64u('filename.dat'); + #or + $sha3_224_b64url = sha3_224_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L. + +=head2 new + + $d = Crypt::Digest::SHA3_224->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::SHA3_224->hashsize(); + #or + Crypt::Digest::SHA3_224::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/SHA3_256.pm b/lib/Crypt/Digest/SHA3_256.pm new file mode 100644 index 0000000..9a13a52 --- /dev/null +++ b/lib/Crypt/Digest/SHA3_256.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::SHA3_256; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( sha3_256 sha3_256_hex sha3_256_b64 sha3_256_b64u sha3_256_file sha3_256_file_hex sha3_256_file_b64 sha3_256_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub sha3_256 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub sha3_256_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub sha3_256_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub sha3_256_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub sha3_256_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub sha3_256_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub sha3_256_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub sha3_256_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::SHA3_256 - Hash function SHA3-256 [size: 256 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::SHA3_256 qw( sha3_256 sha3_256_hex sha3_256_b64 sha3_256_b64u + sha3_256_file sha3_256_file_hex sha3_256_file_b64 sha3_256_file_b64u ); + + # calculate digest from string/buffer + $sha3_256_raw = sha3_256('data string'); + $sha3_256_hex = sha3_256_hex('data string'); + $sha3_256_b64 = sha3_256_b64('data string'); + $sha3_256_b64u = sha3_256_b64u('data string'); + # calculate digest from file + $sha3_256_raw = sha3_256_file('filename.dat'); + $sha3_256_hex = sha3_256_file_hex('filename.dat'); + $sha3_256_b64 = sha3_256_file_b64('filename.dat'); + $sha3_256_b64u = sha3_256_file_b64u('filename.dat'); + # calculate digest from filehandle + $sha3_256_raw = sha3_256_file(*FILEHANDLE); + $sha3_256_hex = sha3_256_file_hex(*FILEHANDLE); + $sha3_256_b64 = sha3_256_file_b64(*FILEHANDLE); + $sha3_256_b64u = sha3_256_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::SHA3_256; + + $d = Crypt::Digest::SHA3_256->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the SHA3_256 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::SHA3_256 qw(sha3_256 sha3_256_hex sha3_256_b64 sha3_256_b64u + sha3_256_file sha3_256_file_hex sha3_256_file_b64 sha3_256_file_b64u); + +Or all of them at once: + + use Crypt::Digest::SHA3_256 ':all'; + +=head1 FUNCTIONS + +=head2 sha3_256 + +Logically joins all arguments into a single string, and returns its SHA3_256 digest encoded as a binary string. + + $sha3_256_raw = sha3_256('data string'); + #or + $sha3_256_raw = sha3_256('any data', 'more data', 'even more data'); + +=head2 sha3_256_hex + +Logically joins all arguments into a single string, and returns its SHA3_256 digest encoded as a hexadecimal string. + + $sha3_256_hex = sha3_256_hex('data string'); + #or + $sha3_256_hex = sha3_256_hex('any data', 'more data', 'even more data'); + +=head2 sha3_256_b64 + +Logically joins all arguments into a single string, and returns its SHA3_256 digest encoded as a Base64 string, B trailing '=' padding. + + $sha3_256_b64 = sha3_256_b64('data string'); + #or + $sha3_256_b64 = sha3_256_b64('any data', 'more data', 'even more data'); + +=head2 sha3_256_b64u + +Logically joins all arguments into a single string, and returns its SHA3_256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha3_256_b64url = sha3_256_b64u('data string'); + #or + $sha3_256_b64url = sha3_256_b64u('any data', 'more data', 'even more data'); + +=head2 sha3_256_file + +Reads file (defined by filename or filehandle) content, and returns its SHA3_256 digest encoded as a binary string. + + $sha3_256_raw = sha3_256_file('filename.dat'); + #or + $sha3_256_raw = sha3_256_file(*FILEHANDLE); + +=head2 sha3_256_file_hex + +Reads file (defined by filename or filehandle) content, and returns its SHA3_256 digest encoded as a hexadecimal string. + + $sha3_256_hex = sha3_256_file_hex('filename.dat'); + #or + $sha3_256_hex = sha3_256_file_hex(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 sha3_256_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its SHA3_256 digest encoded as a Base64 string, B trailing '=' padding. + + $sha3_256_b64 = sha3_256_file_b64('filename.dat'); + #or + $sha3_256_b64 = sha3_256_file_b64(*FILEHANDLE); + +=head2 sha3_256_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its SHA3_256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha3_256_b64url = sha3_256_file_b64u('filename.dat'); + #or + $sha3_256_b64url = sha3_256_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L. + +=head2 new + + $d = Crypt::Digest::SHA3_256->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::SHA3_256->hashsize(); + #or + Crypt::Digest::SHA3_256::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/SHA3_384.pm b/lib/Crypt/Digest/SHA3_384.pm new file mode 100644 index 0000000..cf98a9e --- /dev/null +++ b/lib/Crypt/Digest/SHA3_384.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::SHA3_384; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( sha3_384 sha3_384_hex sha3_384_b64 sha3_384_b64u sha3_384_file sha3_384_file_hex sha3_384_file_b64 sha3_384_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub sha3_384 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub sha3_384_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub sha3_384_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub sha3_384_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub sha3_384_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub sha3_384_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub sha3_384_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub sha3_384_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::SHA3_384 - Hash function SHA3-384 [size: 384 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::SHA3_384 qw( sha3_384 sha3_384_hex sha3_384_b64 sha3_384_b64u + sha3_384_file sha3_384_file_hex sha3_384_file_b64 sha3_384_file_b64u ); + + # calculate digest from string/buffer + $sha3_384_raw = sha3_384('data string'); + $sha3_384_hex = sha3_384_hex('data string'); + $sha3_384_b64 = sha3_384_b64('data string'); + $sha3_384_b64u = sha3_384_b64u('data string'); + # calculate digest from file + $sha3_384_raw = sha3_384_file('filename.dat'); + $sha3_384_hex = sha3_384_file_hex('filename.dat'); + $sha3_384_b64 = sha3_384_file_b64('filename.dat'); + $sha3_384_b64u = sha3_384_file_b64u('filename.dat'); + # calculate digest from filehandle + $sha3_384_raw = sha3_384_file(*FILEHANDLE); + $sha3_384_hex = sha3_384_file_hex(*FILEHANDLE); + $sha3_384_b64 = sha3_384_file_b64(*FILEHANDLE); + $sha3_384_b64u = sha3_384_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::SHA3_384; + + $d = Crypt::Digest::SHA3_384->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the SHA3_384 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::SHA3_384 qw(sha3_384 sha3_384_hex sha3_384_b64 sha3_384_b64u + sha3_384_file sha3_384_file_hex sha3_384_file_b64 sha3_384_file_b64u); + +Or all of them at once: + + use Crypt::Digest::SHA3_384 ':all'; + +=head1 FUNCTIONS + +=head2 sha3_384 + +Logically joins all arguments into a single string, and returns its SHA3_384 digest encoded as a binary string. + + $sha3_384_raw = sha3_384('data string'); + #or + $sha3_384_raw = sha3_384('any data', 'more data', 'even more data'); + +=head2 sha3_384_hex + +Logically joins all arguments into a single string, and returns its SHA3_384 digest encoded as a hexadecimal string. + + $sha3_384_hex = sha3_384_hex('data string'); + #or + $sha3_384_hex = sha3_384_hex('any data', 'more data', 'even more data'); + +=head2 sha3_384_b64 + +Logically joins all arguments into a single string, and returns its SHA3_384 digest encoded as a Base64 string, B trailing '=' padding. + + $sha3_384_b64 = sha3_384_b64('data string'); + #or + $sha3_384_b64 = sha3_384_b64('any data', 'more data', 'even more data'); + +=head2 sha3_384_b64u + +Logically joins all arguments into a single string, and returns its SHA3_384 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha3_384_b64url = sha3_384_b64u('data string'); + #or + $sha3_384_b64url = sha3_384_b64u('any data', 'more data', 'even more data'); + +=head2 sha3_384_file + +Reads file (defined by filename or filehandle) content, and returns its SHA3_384 digest encoded as a binary string. + + $sha3_384_raw = sha3_384_file('filename.dat'); + #or + $sha3_384_raw = sha3_384_file(*FILEHANDLE); + +=head2 sha3_384_file_hex + +Reads file (defined by filename or filehandle) content, and returns its SHA3_384 digest encoded as a hexadecimal string. + + $sha3_384_hex = sha3_384_file_hex('filename.dat'); + #or + $sha3_384_hex = sha3_384_file_hex(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 sha3_384_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its SHA3_384 digest encoded as a Base64 string, B trailing '=' padding. + + $sha3_384_b64 = sha3_384_file_b64('filename.dat'); + #or + $sha3_384_b64 = sha3_384_file_b64(*FILEHANDLE); + +=head2 sha3_384_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its SHA3_384 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha3_384_b64url = sha3_384_file_b64u('filename.dat'); + #or + $sha3_384_b64url = sha3_384_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L. + +=head2 new + + $d = Crypt::Digest::SHA3_384->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::SHA3_384->hashsize(); + #or + Crypt::Digest::SHA3_384::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/SHA3_512.pm b/lib/Crypt/Digest/SHA3_512.pm new file mode 100644 index 0000000..3762a6b --- /dev/null +++ b/lib/Crypt/Digest/SHA3_512.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::SHA3_512; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( sha3_512 sha3_512_hex sha3_512_b64 sha3_512_b64u sha3_512_file sha3_512_file_hex sha3_512_file_b64 sha3_512_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub sha3_512 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub sha3_512_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub sha3_512_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub sha3_512_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub sha3_512_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub sha3_512_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub sha3_512_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub sha3_512_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::SHA3_512 - Hash function SHA3-512 [size: 512 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::SHA3_512 qw( sha3_512 sha3_512_hex sha3_512_b64 sha3_512_b64u + sha3_512_file sha3_512_file_hex sha3_512_file_b64 sha3_512_file_b64u ); + + # calculate digest from string/buffer + $sha3_512_raw = sha3_512('data string'); + $sha3_512_hex = sha3_512_hex('data string'); + $sha3_512_b64 = sha3_512_b64('data string'); + $sha3_512_b64u = sha3_512_b64u('data string'); + # calculate digest from file + $sha3_512_raw = sha3_512_file('filename.dat'); + $sha3_512_hex = sha3_512_file_hex('filename.dat'); + $sha3_512_b64 = sha3_512_file_b64('filename.dat'); + $sha3_512_b64u = sha3_512_file_b64u('filename.dat'); + # calculate digest from filehandle + $sha3_512_raw = sha3_512_file(*FILEHANDLE); + $sha3_512_hex = sha3_512_file_hex(*FILEHANDLE); + $sha3_512_b64 = sha3_512_file_b64(*FILEHANDLE); + $sha3_512_b64u = sha3_512_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::SHA3_512; + + $d = Crypt::Digest::SHA3_512->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the SHA3_512 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::SHA3_512 qw(sha3_512 sha3_512_hex sha3_512_b64 sha3_512_b64u + sha3_512_file sha3_512_file_hex sha3_512_file_b64 sha3_512_file_b64u); + +Or all of them at once: + + use Crypt::Digest::SHA3_512 ':all'; + +=head1 FUNCTIONS + +=head2 sha3_512 + +Logically joins all arguments into a single string, and returns its SHA3_512 digest encoded as a binary string. + + $sha3_512_raw = sha3_512('data string'); + #or + $sha3_512_raw = sha3_512('any data', 'more data', 'even more data'); + +=head2 sha3_512_hex + +Logically joins all arguments into a single string, and returns its SHA3_512 digest encoded as a hexadecimal string. + + $sha3_512_hex = sha3_512_hex('data string'); + #or + $sha3_512_hex = sha3_512_hex('any data', 'more data', 'even more data'); + +=head2 sha3_512_b64 + +Logically joins all arguments into a single string, and returns its SHA3_512 digest encoded as a Base64 string, B trailing '=' padding. + + $sha3_512_b64 = sha3_512_b64('data string'); + #or + $sha3_512_b64 = sha3_512_b64('any data', 'more data', 'even more data'); + +=head2 sha3_512_b64u + +Logically joins all arguments into a single string, and returns its SHA3_512 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha3_512_b64url = sha3_512_b64u('data string'); + #or + $sha3_512_b64url = sha3_512_b64u('any data', 'more data', 'even more data'); + +=head2 sha3_512_file + +Reads file (defined by filename or filehandle) content, and returns its SHA3_512 digest encoded as a binary string. + + $sha3_512_raw = sha3_512_file('filename.dat'); + #or + $sha3_512_raw = sha3_512_file(*FILEHANDLE); + +=head2 sha3_512_file_hex + +Reads file (defined by filename or filehandle) content, and returns its SHA3_512 digest encoded as a hexadecimal string. + + $sha3_512_hex = sha3_512_file_hex('filename.dat'); + #or + $sha3_512_hex = sha3_512_file_hex(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 sha3_512_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its SHA3_512 digest encoded as a Base64 string, B trailing '=' padding. + + $sha3_512_b64 = sha3_512_file_b64('filename.dat'); + #or + $sha3_512_b64 = sha3_512_file_b64(*FILEHANDLE); + +=head2 sha3_512_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its SHA3_512 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha3_512_b64url = sha3_512_file_b64u('filename.dat'); + #or + $sha3_512_b64url = sha3_512_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L. + +=head2 new + + $d = Crypt::Digest::SHA3_512->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::SHA3_512->hashsize(); + #or + Crypt::Digest::SHA3_512::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/SHA512.pm b/lib/Crypt/Digest/SHA512.pm new file mode 100644 index 0000000..6b109fa --- /dev/null +++ b/lib/Crypt/Digest/SHA512.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::SHA512; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( sha512 sha512_hex sha512_b64 sha512_b64u sha512_file sha512_file_hex sha512_file_b64 sha512_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub sha512 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub sha512_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub sha512_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub sha512_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub sha512_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub sha512_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub sha512_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub sha512_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::SHA512 - Hash function SHA-512 [size: 512 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::SHA512 qw( sha512 sha512_hex sha512_b64 sha512_b64u + sha512_file sha512_file_hex sha512_file_b64 sha512_file_b64u ); + + # calculate digest from string/buffer + $sha512_raw = sha512('data string'); + $sha512_hex = sha512_hex('data string'); + $sha512_b64 = sha512_b64('data string'); + $sha512_b64u = sha512_b64u('data string'); + # calculate digest from file + $sha512_raw = sha512_file('filename.dat'); + $sha512_hex = sha512_file_hex('filename.dat'); + $sha512_b64 = sha512_file_b64('filename.dat'); + $sha512_b64u = sha512_file_b64u('filename.dat'); + # calculate digest from filehandle + $sha512_raw = sha512_file(*FILEHANDLE); + $sha512_hex = sha512_file_hex(*FILEHANDLE); + $sha512_b64 = sha512_file_b64(*FILEHANDLE); + $sha512_b64u = sha512_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::SHA512; + + $d = Crypt::Digest::SHA512->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the SHA512 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::SHA512 qw(sha512 sha512_hex sha512_b64 sha512_b64u + sha512_file sha512_file_hex sha512_file_b64 sha512_file_b64u); + +Or all of them at once: + + use Crypt::Digest::SHA512 ':all'; + +=head1 FUNCTIONS + +=head2 sha512 + +Logically joins all arguments into a single string, and returns its SHA512 digest encoded as a binary string. + + $sha512_raw = sha512('data string'); + #or + $sha512_raw = sha512('any data', 'more data', 'even more data'); + +=head2 sha512_hex + +Logically joins all arguments into a single string, and returns its SHA512 digest encoded as a hexadecimal string. + + $sha512_hex = sha512_hex('data string'); + #or + $sha512_hex = sha512_hex('any data', 'more data', 'even more data'); + +=head2 sha512_b64 + +Logically joins all arguments into a single string, and returns its SHA512 digest encoded as a Base64 string, B trailing '=' padding. + + $sha512_b64 = sha512_b64('data string'); + #or + $sha512_b64 = sha512_b64('any data', 'more data', 'even more data'); + +=head2 sha512_b64u + +Logically joins all arguments into a single string, and returns its SHA512 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha512_b64url = sha512_b64u('data string'); + #or + $sha512_b64url = sha512_b64u('any data', 'more data', 'even more data'); + +=head2 sha512_file + +Reads file (defined by filename or filehandle) content, and returns its SHA512 digest encoded as a binary string. + + $sha512_raw = sha512_file('filename.dat'); + #or + $sha512_raw = sha512_file(*FILEHANDLE); + +=head2 sha512_file_hex + +Reads file (defined by filename or filehandle) content, and returns its SHA512 digest encoded as a hexadecimal string. + + $sha512_hex = sha512_file_hex('filename.dat'); + #or + $sha512_hex = sha512_file_hex(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 sha512_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its SHA512 digest encoded as a Base64 string, B trailing '=' padding. + + $sha512_b64 = sha512_file_b64('filename.dat'); + #or + $sha512_b64 = sha512_file_b64(*FILEHANDLE); + +=head2 sha512_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its SHA512 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha512_b64url = sha512_file_b64u('filename.dat'); + #or + $sha512_b64url = sha512_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L. + +=head2 new + + $d = Crypt::Digest::SHA512->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::SHA512->hashsize(); + #or + Crypt::Digest::SHA512::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/SHA512_224.pm b/lib/Crypt/Digest/SHA512_224.pm new file mode 100644 index 0000000..eec53e8 --- /dev/null +++ b/lib/Crypt/Digest/SHA512_224.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::SHA512_224; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( sha512_224 sha512_224_hex sha512_224_b64 sha512_224_b64u sha512_224_file sha512_224_file_hex sha512_224_file_b64 sha512_224_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub sha512_224 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub sha512_224_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub sha512_224_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub sha512_224_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub sha512_224_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub sha512_224_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub sha512_224_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub sha512_224_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::SHA512_224 - Hash function SHA-512/224 [size: 224 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::SHA512_224 qw( sha512_224 sha512_224_hex sha512_224_b64 sha512_224_b64u + sha512_224_file sha512_224_file_hex sha512_224_file_b64 sha512_224_file_b64u ); + + # calculate digest from string/buffer + $sha512_224_raw = sha512_224('data string'); + $sha512_224_hex = sha512_224_hex('data string'); + $sha512_224_b64 = sha512_224_b64('data string'); + $sha512_224_b64u = sha512_224_b64u('data string'); + # calculate digest from file + $sha512_224_raw = sha512_224_file('filename.dat'); + $sha512_224_hex = sha512_224_file_hex('filename.dat'); + $sha512_224_b64 = sha512_224_file_b64('filename.dat'); + $sha512_224_b64u = sha512_224_file_b64u('filename.dat'); + # calculate digest from filehandle + $sha512_224_raw = sha512_224_file(*FILEHANDLE); + $sha512_224_hex = sha512_224_file_hex(*FILEHANDLE); + $sha512_224_b64 = sha512_224_file_b64(*FILEHANDLE); + $sha512_224_b64u = sha512_224_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::SHA512_224; + + $d = Crypt::Digest::SHA512_224->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the SHA512_224 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::SHA512_224 qw(sha512_224 sha512_224_hex sha512_224_b64 sha512_224_b64u + sha512_224_file sha512_224_file_hex sha512_224_file_b64 sha512_224_file_b64u); + +Or all of them at once: + + use Crypt::Digest::SHA512_224 ':all'; + +=head1 FUNCTIONS + +=head2 sha512_224 + +Logically joins all arguments into a single string, and returns its SHA512_224 digest encoded as a binary string. + + $sha512_224_raw = sha512_224('data string'); + #or + $sha512_224_raw = sha512_224('any data', 'more data', 'even more data'); + +=head2 sha512_224_hex + +Logically joins all arguments into a single string, and returns its SHA512_224 digest encoded as a hexadecimal string. + + $sha512_224_hex = sha512_224_hex('data string'); + #or + $sha512_224_hex = sha512_224_hex('any data', 'more data', 'even more data'); + +=head2 sha512_224_b64 + +Logically joins all arguments into a single string, and returns its SHA512_224 digest encoded as a Base64 string, B trailing '=' padding. + + $sha512_224_b64 = sha512_224_b64('data string'); + #or + $sha512_224_b64 = sha512_224_b64('any data', 'more data', 'even more data'); + +=head2 sha512_224_b64u + +Logically joins all arguments into a single string, and returns its SHA512_224 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha512_224_b64url = sha512_224_b64u('data string'); + #or + $sha512_224_b64url = sha512_224_b64u('any data', 'more data', 'even more data'); + +=head2 sha512_224_file + +Reads file (defined by filename or filehandle) content, and returns its SHA512_224 digest encoded as a binary string. + + $sha512_224_raw = sha512_224_file('filename.dat'); + #or + $sha512_224_raw = sha512_224_file(*FILEHANDLE); + +=head2 sha512_224_file_hex + +Reads file (defined by filename or filehandle) content, and returns its SHA512_224 digest encoded as a hexadecimal string. + + $sha512_224_hex = sha512_224_file_hex('filename.dat'); + #or + $sha512_224_hex = sha512_224_file_hex(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 sha512_224_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its SHA512_224 digest encoded as a Base64 string, B trailing '=' padding. + + $sha512_224_b64 = sha512_224_file_b64('filename.dat'); + #or + $sha512_224_b64 = sha512_224_file_b64(*FILEHANDLE); + +=head2 sha512_224_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its SHA512_224 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha512_224_b64url = sha512_224_file_b64u('filename.dat'); + #or + $sha512_224_b64url = sha512_224_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L. + +=head2 new + + $d = Crypt::Digest::SHA512_224->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::SHA512_224->hashsize(); + #or + Crypt::Digest::SHA512_224::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/SHA512_256.pm b/lib/Crypt/Digest/SHA512_256.pm new file mode 100644 index 0000000..d02044b --- /dev/null +++ b/lib/Crypt/Digest/SHA512_256.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::SHA512_256; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( sha512_256 sha512_256_hex sha512_256_b64 sha512_256_b64u sha512_256_file sha512_256_file_hex sha512_256_file_b64 sha512_256_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub sha512_256 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub sha512_256_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub sha512_256_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub sha512_256_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub sha512_256_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub sha512_256_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub sha512_256_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub sha512_256_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::SHA512_256 - Hash function SHA-512/256 [size: 256 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::SHA512_256 qw( sha512_256 sha512_256_hex sha512_256_b64 sha512_256_b64u + sha512_256_file sha512_256_file_hex sha512_256_file_b64 sha512_256_file_b64u ); + + # calculate digest from string/buffer + $sha512_256_raw = sha512_256('data string'); + $sha512_256_hex = sha512_256_hex('data string'); + $sha512_256_b64 = sha512_256_b64('data string'); + $sha512_256_b64u = sha512_256_b64u('data string'); + # calculate digest from file + $sha512_256_raw = sha512_256_file('filename.dat'); + $sha512_256_hex = sha512_256_file_hex('filename.dat'); + $sha512_256_b64 = sha512_256_file_b64('filename.dat'); + $sha512_256_b64u = sha512_256_file_b64u('filename.dat'); + # calculate digest from filehandle + $sha512_256_raw = sha512_256_file(*FILEHANDLE); + $sha512_256_hex = sha512_256_file_hex(*FILEHANDLE); + $sha512_256_b64 = sha512_256_file_b64(*FILEHANDLE); + $sha512_256_b64u = sha512_256_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::SHA512_256; + + $d = Crypt::Digest::SHA512_256->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the SHA512_256 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::SHA512_256 qw(sha512_256 sha512_256_hex sha512_256_b64 sha512_256_b64u + sha512_256_file sha512_256_file_hex sha512_256_file_b64 sha512_256_file_b64u); + +Or all of them at once: + + use Crypt::Digest::SHA512_256 ':all'; + +=head1 FUNCTIONS + +=head2 sha512_256 + +Logically joins all arguments into a single string, and returns its SHA512_256 digest encoded as a binary string. + + $sha512_256_raw = sha512_256('data string'); + #or + $sha512_256_raw = sha512_256('any data', 'more data', 'even more data'); + +=head2 sha512_256_hex + +Logically joins all arguments into a single string, and returns its SHA512_256 digest encoded as a hexadecimal string. + + $sha512_256_hex = sha512_256_hex('data string'); + #or + $sha512_256_hex = sha512_256_hex('any data', 'more data', 'even more data'); + +=head2 sha512_256_b64 + +Logically joins all arguments into a single string, and returns its SHA512_256 digest encoded as a Base64 string, B trailing '=' padding. + + $sha512_256_b64 = sha512_256_b64('data string'); + #or + $sha512_256_b64 = sha512_256_b64('any data', 'more data', 'even more data'); + +=head2 sha512_256_b64u + +Logically joins all arguments into a single string, and returns its SHA512_256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha512_256_b64url = sha512_256_b64u('data string'); + #or + $sha512_256_b64url = sha512_256_b64u('any data', 'more data', 'even more data'); + +=head2 sha512_256_file + +Reads file (defined by filename or filehandle) content, and returns its SHA512_256 digest encoded as a binary string. + + $sha512_256_raw = sha512_256_file('filename.dat'); + #or + $sha512_256_raw = sha512_256_file(*FILEHANDLE); + +=head2 sha512_256_file_hex + +Reads file (defined by filename or filehandle) content, and returns its SHA512_256 digest encoded as a hexadecimal string. + + $sha512_256_hex = sha512_256_file_hex('filename.dat'); + #or + $sha512_256_hex = sha512_256_file_hex(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 sha512_256_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its SHA512_256 digest encoded as a Base64 string, B trailing '=' padding. + + $sha512_256_b64 = sha512_256_file_b64('filename.dat'); + #or + $sha512_256_b64 = sha512_256_file_b64(*FILEHANDLE); + +=head2 sha512_256_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its SHA512_256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $sha512_256_b64url = sha512_256_file_b64u('filename.dat'); + #or + $sha512_256_b64url = sha512_256_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L. + +=head2 new + + $d = Crypt::Digest::SHA512_256->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::SHA512_256->hashsize(); + #or + Crypt::Digest::SHA512_256::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/SHAKE.pm b/lib/Crypt/Digest/SHAKE.pm new file mode 100644 index 0000000..efdb077 --- /dev/null +++ b/lib/Crypt/Digest/SHAKE.pm @@ -0,0 +1,106 @@ +package Crypt::Digest::SHAKE; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub new { my $class = shift; _new(@_) } + +sub addfile { + my ($self, $file) = @_; + + my $handle; + if (ref(\$file) eq 'SCALAR') { #filename + open($handle, "<", $file) || croak "FATAL: cannot open '$file': $!"; + binmode($handle); + } + else { #handle + $handle = $file + } + croak "FATAL: invalid handle" unless defined $handle; + + my $n; + my $buf = ""; + while (($n = read($handle, $buf, 32*1024))) { + $self->add($buf) + } + croak "FATAL: read failed: $!" unless defined $n; + + return $self; +} + +sub CLONE_SKIP { 1 } # prevent cloning + +1; + +=pod + +=head1 NAME + +Crypt::Digest::SHAKE - Hash functions SHAKE128, SHAKE256 from SHA3 family + +=head1 SYNOPSIS + + use Crypt::Digest::SHAKE + + $d = Crypt::Digest::SHAKE->new(128); + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $part1 = $d->done(100); # 100 raw bytes + $part2 = $d->done(100); # another 100 raw bytes + #... + +=head1 DESCRIPTION + +Provides an interface to the SHA3's sponge function SHAKE. + +=head1 METHODS + +=head2 new + + $d = Crypt::Digest::SHA3-SHAKE->new($num); + # $num ... 128 or 256 + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 done + + $result_raw = $d->done($len); + # can be called multiple times + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/Tiger192.pm b/lib/Crypt/Digest/Tiger192.pm new file mode 100644 index 0000000..1e66a4c --- /dev/null +++ b/lib/Crypt/Digest/Tiger192.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::Tiger192; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( tiger192 tiger192_hex tiger192_b64 tiger192_b64u tiger192_file tiger192_file_hex tiger192_file_b64 tiger192_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub tiger192 { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub tiger192_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub tiger192_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub tiger192_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub tiger192_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub tiger192_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub tiger192_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub tiger192_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::Tiger192 - Hash function Tiger-192 [size: 192 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::Tiger192 qw( tiger192 tiger192_hex tiger192_b64 tiger192_b64u + tiger192_file tiger192_file_hex tiger192_file_b64 tiger192_file_b64u ); + + # calculate digest from string/buffer + $tiger192_raw = tiger192('data string'); + $tiger192_hex = tiger192_hex('data string'); + $tiger192_b64 = tiger192_b64('data string'); + $tiger192_b64u = tiger192_b64u('data string'); + # calculate digest from file + $tiger192_raw = tiger192_file('filename.dat'); + $tiger192_hex = tiger192_file_hex('filename.dat'); + $tiger192_b64 = tiger192_file_b64('filename.dat'); + $tiger192_b64u = tiger192_file_b64u('filename.dat'); + # calculate digest from filehandle + $tiger192_raw = tiger192_file(*FILEHANDLE); + $tiger192_hex = tiger192_file_hex(*FILEHANDLE); + $tiger192_b64 = tiger192_file_b64(*FILEHANDLE); + $tiger192_b64u = tiger192_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::Tiger192; + + $d = Crypt::Digest::Tiger192->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the Tiger192 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::Tiger192 qw(tiger192 tiger192_hex tiger192_b64 tiger192_b64u + tiger192_file tiger192_file_hex tiger192_file_b64 tiger192_file_b64u); + +Or all of them at once: + + use Crypt::Digest::Tiger192 ':all'; + +=head1 FUNCTIONS + +=head2 tiger192 + +Logically joins all arguments into a single string, and returns its Tiger192 digest encoded as a binary string. + + $tiger192_raw = tiger192('data string'); + #or + $tiger192_raw = tiger192('any data', 'more data', 'even more data'); + +=head2 tiger192_hex + +Logically joins all arguments into a single string, and returns its Tiger192 digest encoded as a hexadecimal string. + + $tiger192_hex = tiger192_hex('data string'); + #or + $tiger192_hex = tiger192_hex('any data', 'more data', 'even more data'); + +=head2 tiger192_b64 + +Logically joins all arguments into a single string, and returns its Tiger192 digest encoded as a Base64 string, B trailing '=' padding. + + $tiger192_b64 = tiger192_b64('data string'); + #or + $tiger192_b64 = tiger192_b64('any data', 'more data', 'even more data'); + +=head2 tiger192_b64u + +Logically joins all arguments into a single string, and returns its Tiger192 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $tiger192_b64url = tiger192_b64u('data string'); + #or + $tiger192_b64url = tiger192_b64u('any data', 'more data', 'even more data'); + +=head2 tiger192_file + +Reads file (defined by filename or filehandle) content, and returns its Tiger192 digest encoded as a binary string. + + $tiger192_raw = tiger192_file('filename.dat'); + #or + $tiger192_raw = tiger192_file(*FILEHANDLE); + +=head2 tiger192_file_hex + +Reads file (defined by filename or filehandle) content, and returns its Tiger192 digest encoded as a hexadecimal string. + + $tiger192_hex = tiger192_file_hex('filename.dat'); + #or + $tiger192_hex = tiger192_file_hex(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 tiger192_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its Tiger192 digest encoded as a Base64 string, B trailing '=' padding. + + $tiger192_b64 = tiger192_file_b64('filename.dat'); + #or + $tiger192_b64 = tiger192_file_b64(*FILEHANDLE); + +=head2 tiger192_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its Tiger192 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $tiger192_b64url = tiger192_file_b64u('filename.dat'); + #or + $tiger192_b64url = tiger192_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L. + +=head2 new + + $d = Crypt::Digest::Tiger192->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::Tiger192->hashsize(); + #or + Crypt::Digest::Tiger192::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Digest/Whirlpool.pm b/lib/Crypt/Digest/Whirlpool.pm new file mode 100644 index 0000000..553dc6d --- /dev/null +++ b/lib/Crypt/Digest/Whirlpool.pm @@ -0,0 +1,227 @@ +package Crypt::Digest::Whirlpool; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( whirlpool whirlpool_hex whirlpool_b64 whirlpool_b64u whirlpool_file whirlpool_file_hex whirlpool_file_b64 whirlpool_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use CryptX; + +sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } + +sub whirlpool { Crypt::Digest::digest_data(__PACKAGE__, @_) } +sub whirlpool_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } +sub whirlpool_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } +sub whirlpool_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } + +sub whirlpool_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } +sub whirlpool_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } +sub whirlpool_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } +sub whirlpool_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::Whirlpool - Hash function Whirlpool [size: 512 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::Whirlpool qw( whirlpool whirlpool_hex whirlpool_b64 whirlpool_b64u + whirlpool_file whirlpool_file_hex whirlpool_file_b64 whirlpool_file_b64u ); + + # calculate digest from string/buffer + $whirlpool_raw = whirlpool('data string'); + $whirlpool_hex = whirlpool_hex('data string'); + $whirlpool_b64 = whirlpool_b64('data string'); + $whirlpool_b64u = whirlpool_b64u('data string'); + # calculate digest from file + $whirlpool_raw = whirlpool_file('filename.dat'); + $whirlpool_hex = whirlpool_file_hex('filename.dat'); + $whirlpool_b64 = whirlpool_file_b64('filename.dat'); + $whirlpool_b64u = whirlpool_file_b64u('filename.dat'); + # calculate digest from filehandle + $whirlpool_raw = whirlpool_file(*FILEHANDLE); + $whirlpool_hex = whirlpool_file_hex(*FILEHANDLE); + $whirlpool_b64 = whirlpool_file_b64(*FILEHANDLE); + $whirlpool_b64u = whirlpool_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::Whirlpool; + + $d = Crypt::Digest::Whirlpool->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the Whirlpool digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::Whirlpool qw(whirlpool whirlpool_hex whirlpool_b64 whirlpool_b64u + whirlpool_file whirlpool_file_hex whirlpool_file_b64 whirlpool_file_b64u); + +Or all of them at once: + + use Crypt::Digest::Whirlpool ':all'; + +=head1 FUNCTIONS + +=head2 whirlpool + +Logically joins all arguments into a single string, and returns its Whirlpool digest encoded as a binary string. + + $whirlpool_raw = whirlpool('data string'); + #or + $whirlpool_raw = whirlpool('any data', 'more data', 'even more data'); + +=head2 whirlpool_hex + +Logically joins all arguments into a single string, and returns its Whirlpool digest encoded as a hexadecimal string. + + $whirlpool_hex = whirlpool_hex('data string'); + #or + $whirlpool_hex = whirlpool_hex('any data', 'more data', 'even more data'); + +=head2 whirlpool_b64 + +Logically joins all arguments into a single string, and returns its Whirlpool digest encoded as a Base64 string, B trailing '=' padding. + + $whirlpool_b64 = whirlpool_b64('data string'); + #or + $whirlpool_b64 = whirlpool_b64('any data', 'more data', 'even more data'); + +=head2 whirlpool_b64u + +Logically joins all arguments into a single string, and returns its Whirlpool digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $whirlpool_b64url = whirlpool_b64u('data string'); + #or + $whirlpool_b64url = whirlpool_b64u('any data', 'more data', 'even more data'); + +=head2 whirlpool_file + +Reads file (defined by filename or filehandle) content, and returns its Whirlpool digest encoded as a binary string. + + $whirlpool_raw = whirlpool_file('filename.dat'); + #or + $whirlpool_raw = whirlpool_file(*FILEHANDLE); + +=head2 whirlpool_file_hex + +Reads file (defined by filename or filehandle) content, and returns its Whirlpool digest encoded as a hexadecimal string. + + $whirlpool_hex = whirlpool_file_hex('filename.dat'); + #or + $whirlpool_hex = whirlpool_file_hex(*FILEHANDLE); + +B You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 whirlpool_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its Whirlpool digest encoded as a Base64 string, B trailing '=' padding. + + $whirlpool_b64 = whirlpool_file_b64('filename.dat'); + #or + $whirlpool_b64 = whirlpool_file_b64(*FILEHANDLE); + +=head2 whirlpool_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its Whirlpool digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $whirlpool_b64url = whirlpool_file_b64u('filename.dat'); + #or + $whirlpool_b64url = whirlpool_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L. + +=head2 new + + $d = Crypt::Digest::Whirlpool->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::Whirlpool->hashsize(); + #or + Crypt::Digest::Whirlpool::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/KeyDerivation.pm b/lib/Crypt/KeyDerivation.pm new file mode 100644 index 0000000..921f484 --- /dev/null +++ b/lib/Crypt/KeyDerivation.pm @@ -0,0 +1,167 @@ +package Crypt::KeyDerivation; + +use strict; +use warnings; +our $VERSION = '0.048'; + +require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; +our %EXPORT_TAGS = ( all => [qw(pbkdf1 pbkdf2 hkdf hkdf_expand hkdf_extract)] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +use Crypt::Digest; + +sub pbkdf1 { + my ($password, $salt, $iteration_count, $hash_name, $len) = @_; + $iteration_count ||= 5000; + $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA256'); + $len ||= 32; + return _pkcs_5_alg1($password, $salt, $iteration_count, $hash_name, $len); +} + +sub pbkdf2 { + my ($password, $salt, $iteration_count, $hash_name, $len) = @_; + $iteration_count ||= 5000; + $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA256'); + $len ||= 32; + return _pkcs_5_alg2($password, $salt, $iteration_count, $hash_name, $len); +} + +sub hkdf_extract { + # RFC: HKDF-Extract(salt, IKM, [Hash]) -> PRK + #my ($hash_name, $salt, $keying_material) = @_; + my ($keying_material, $salt, $hash_name) = @_; + $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA256'); + $salt = pack("H*", "00" x Crypt::Digest->hashsize($hash_name)) unless defined $salt; # according to rfc5869 defaults to HashLen zero octets + return _hkdf_extract($hash_name, $salt, $keying_material); +} + +sub hkdf_expand { + # RFC: HKDF-Expand(PRK, info, L, [Hash]) -> OKM + #my ($hash_name, $info, $keying_material, $len) = @_; + my ($keying_material, $hash_name, $len, $info) = @_; + $len ||= 32; + $info ||= ''; + $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA256'); + return _hkdf_expand($hash_name, $info, $keying_material, $len); +} + +sub hkdf { + #my ($hash_name, $salt, $info, $keying_material, $len) = @_; + my ($keying_material, $salt, $hash_name, $len, $info) = @_; + $len ||= 32; + $info ||= ''; + $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA256'); + $salt = pack("H*", "00" x Crypt::Digest->hashsize($hash_name)) unless defined $salt; # according to rfc5869 defaults to HashLen zero octets + return _hkdf($hash_name, $salt, $info, $keying_material, $len); +} + +1; + +=pod + +=head1 NAME + +Crypt::KeyDerivation - PBKDF1, PBKFD2 and HKDF key derivation functions + +=head1 SYNOPSIS + + ### PBKDF1/2 + $derived_key1 = pbkdf1($password, $salt, $iteration_count, $hash_name, $len); + $derived_key2 = pbkdf2($password, $salt, $iteration_count, $hash_name, $len); + + ### HKDF & co. + $derived_key3 = hkdf($keying_material, $salt, $hash_name, $len, $info); + $prk = hkdf_extract($keying_material, $salt, $hash_name); + $okm1 = hkdf_expand($prk, $hash_name, $len, $info); + +=head1 DESCRIPTION + +Provides an interface to Key derivation functions: + +=over + +=item * PBKFD1 and PBKDF according to PKCS#5 v2.0 L + +=item * HKDF (+ related) according to L + +=back + +=head1 FUNCTIONS + +=head2 pbkdf1 + +B if you are not sure, do not use C but rather choose C. + + $derived_key = pbkdf1($password, $salt, $iteration_count, $hash_name, $len); + #or + $derived_key = pbkdf1($password, $salt, $iteration_count, $hash_name); + #or + $derived_key = pbkdf1($password, $salt, $iteration_count); + #or + $derived_key = pbkdf1($password, $salt); + + # $password ......... input keying material (password) + # $salt ............. salt/nonce (expected length: 8) + # $iteration_count .. optional, DEFAULT: 5000 + # $hash_name ........ optional, DEFAULT: 'SHA256' + # $len .............. optional, derived key len, DEFAULT: 32 + +=head2 pbkdf2 + + $derived_key = pbkdf2($password, $salt, $iteration_count, $hash_name, $len); + #or + $derived_key = pbkdf2($password, $salt, $iteration_count, $hash_name); + #or + $derived_key = pbkdf2($password, $salt, $iteration_count); + #or + $derived_key = pbkdf2($password, $salt); + + # $password ......... input keying material (password) + # $salt ............. salt/nonce + # $iteration_count .. optional, DEFAULT: 5000 + # $hash_name ........ optional, DEFAULT: 'SHA256' + # $len .............. optional, derived key len, DEFAULT: 32 + +=head2 hkdf + + $okm2 = hkdf($password, $salt, $hash_name, $len, $info); + #or + $okm2 = hkdf($password, $salt, $hash_name, $len); + #or + $okm2 = hkdf($password, $salt, $hash_name); + #or + $okm2 = hkdf($password, $salt); + + # $password ... input keying material (password) + # $salt ....... salt/nonce, if undef defaults to HashLen zero octets + # $hash_name .. optional, DEFAULT: 'SHA256' + # $len ........ optional, derived key len, DEFAULT: 32 + # $info ....... optional context and application specific information, DEFAULT: '' + +=head2 hkdf_extract + + $prk = hkdf_extract($password, $salt, $hash_name); + #or + $prk = hkdf_extract($password, $salt, $hash_name); + + # $password ... input keying material (password) + # $salt ....... salt/nonce, if undef defaults to HashLen zero octets + # $hash_name .. optional, DEFAULT: 'SHA256' + + +=head2 hkdf_expand + + $okm = hkdf_expand($pseudokey, $hash_name, $len, $info); + #or + $okm = hkdf_expand($pseudokey, $hash_name, $len); + #or + $okm = hkdf_expand($pseudokey, $hash_name); + #or + $okm = hkdf_expand($pseudokey); + + # $pseudokey .. input keying material + # $hash_name .. optional, DEFAULT: 'SHA256' + # $len ........ optional, derived key len, DEFAULT: 32 + # $info ....... optional context and application specific information, DEFAULT: '' diff --git a/lib/Crypt/Mac.pm b/lib/Crypt/Mac.pm new file mode 100644 index 0000000..a52ae8a --- /dev/null +++ b/lib/Crypt/Mac.pm @@ -0,0 +1,53 @@ +package Crypt::Mac; + +use strict; +use warnings; +our $VERSION = '0.048'; + +require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; +our %EXPORT_TAGS = ( all => [qw( mac mac_hex )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +sub add { + my $self = shift; + $self->_add_single($_) for (@_); + return $self; +} + +sub addfile { + my ($self, $file) = @_; + + my $handle; + if (ref(\$file) eq 'SCALAR') { + #filename + open($handle, "<", $file) || die "FATAL: cannot open '$file': $!"; + binmode($handle); + } + else { + #handle + $handle = $file + } + die "FATAL: invalid handle" unless defined $handle; + + my $n; + my $buf = ""; + while (($n = read($handle, $buf, 32*1024))) { + $self->_add_single($buf) + } + die "FATAL: read failed: $!" unless defined $n; + + return $self; +} + +sub CLONE_SKIP { 1 } # prevent cloning + +1; + +__END__ + +=head1 NAME + +Crypt::mode - [internal only] + +=cut \ No newline at end of file diff --git a/lib/Crypt/Mac/BLAKE2b.pm b/lib/Crypt/Mac/BLAKE2b.pm new file mode 100644 index 0000000..657a94c --- /dev/null +++ b/lib/Crypt/Mac/BLAKE2b.pm @@ -0,0 +1,156 @@ +package Crypt::Mac::BLAKE2b; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Mac Exporter); +our %EXPORT_TAGS = ( all => [qw( blake2b blake2b_hex blake2b_b64 blake2b_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +sub new { my $class = shift; _new(@_) } +sub blake2b { Crypt::Mac::BLAKE2b->new(shift, shift)->add(@_)->mac } +sub blake2b_hex { Crypt::Mac::BLAKE2b->new(shift, shift)->add(@_)->hexmac } +sub blake2b_b64 { Crypt::Mac::BLAKE2b->new(shift, shift)->add(@_)->b64mac } +sub blake2b_b64u { Crypt::Mac::BLAKE2b->new(shift, shift)->add(@_)->b64umac } + +1; + +=pod + +=head1 NAME + +Crypt::Mac::BLAKE2b - Message authentication code BLAKE2b MAC (RFC 7693) + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Mac::BLAKE2b qw( blake2b blake2b_hex ); + + # calculate MAC from string/buffer + $blake2b_raw = blake2b($size, $key, 'data buffer'); + $blake2b_hex = blake2b_hex($size, $key, 'data buffer'); + $blake2b_b64 = blake2b_b64($size, $key, 'data buffer'); + $blake2b_b64u = blake2b_b64u($size, $key, 'data buffer'); + + ### OO interface: + use Crypt::Mac::BLAKE2b; + + $d = Crypt::Mac::BLAKE2b->new($size, $key); + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->mac; # raw bytes + $result_hex = $d->hexmac; # hexadecimal form + $result_b64 = $d->b64mac; # Base64 form + $result_b64u = $d->b64umac; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the BLAKE2b message authentication code (MAC) algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Mac::BLAKE2b qw(blake2b blake2b_hex ); + +Or all of them at once: + + use Crypt::Mac::BLAKE2b ':all'; + +=head1 FUNCTIONS + +=head2 blake2b + +Logically joins all arguments into a single string, and returns its BLAKE2b message authentication code encoded as a binary string. + + $blake2b_raw = blake2b($size, $key, 'data buffer'); + #or + $blake2b_raw = blake2b($size, $key, 'any data', 'more data', 'even more data'); + +=head2 blake2b_hex + +Logically joins all arguments into a single string, and returns its BLAKE2b message authentication code encoded as a hexadecimal string. + + $blake2b_hex = blake2b_hex($size, $key, 'data buffer'); + #or + $blake2b_hex = blake2b_hex($size, $key, 'any data', 'more data', 'even more data'); + +=head2 blake2b_b64 + +Logically joins all arguments into a single string, and returns its BLAKE2b message authentication code encoded as a Base64 string. + + $blake2b_b64 = blake2b_b64($size, $key, 'data buffer'); + #or + $blake2b_b64 = blake2b_b64($size, $key, 'any data', 'more data', 'even more data'); + +=head2 blake2b_b64u + +Logically joins all arguments into a single string, and returns its BLAKE2b message authentication code encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2b_b64url = blake2b_b64u($size, $key, 'data buffer'); + #or + $blake2b_b64url = blake2b_b64u($size, $key, 'any data', 'more data', 'even more data'); + +=head1 METHODS + +=head2 new + + $d = Crypt::Mac::BLAKE2b->new($size, $key); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 mac + + $result_raw = $d->mac(); + +=head2 hexmac + + $result_hex = $d->hexmac(); + +=head2 b64mac + + $result_b64 = $d->b64mac(); + +=head2 b64umac + + $result_b64url = $d->b64umac(); + +=head1 SEE ALSO + +=over + +=item * L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Mac/BLAKE2s.pm b/lib/Crypt/Mac/BLAKE2s.pm new file mode 100644 index 0000000..c696abc --- /dev/null +++ b/lib/Crypt/Mac/BLAKE2s.pm @@ -0,0 +1,156 @@ +package Crypt::Mac::BLAKE2s; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Mac Exporter); +our %EXPORT_TAGS = ( all => [qw( blake2s blake2s_hex blake2s_b64 blake2s_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +sub new { my $class = shift; _new(@_) } +sub blake2s { Crypt::Mac::BLAKE2s->new(shift, shift)->add(@_)->mac } +sub blake2s_hex { Crypt::Mac::BLAKE2s->new(shift, shift)->add(@_)->hexmac } +sub blake2s_b64 { Crypt::Mac::BLAKE2s->new(shift, shift)->add(@_)->b64mac } +sub blake2s_b64u { Crypt::Mac::BLAKE2s->new(shift, shift)->add(@_)->b64umac } + +1; + +=pod + +=head1 NAME + +Crypt::Mac::BLAKE2s - Message authentication code BLAKE2s MAC (RFC 7693) + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Mac::BLAKE2s qw( blake2s blake2s_hex ); + + # calculate MAC from string/buffer + $blake2s_raw = blake2s($size, $key, 'data buffer'); + $blake2s_hex = blake2s_hex($size, $key, 'data buffer'); + $blake2s_b64 = blake2s_b64($size, $key, 'data buffer'); + $blake2s_b64u = blake2s_b64u($size, $key, 'data buffer'); + + ### OO interface: + use Crypt::Mac::BLAKE2s; + + $d = Crypt::Mac::BLAKE2s->new($size, $key); + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->mac; # raw bytes + $result_hex = $d->hexmac; # hexadecimal form + $result_b64 = $d->b64mac; # Base64 form + $result_b64u = $d->b64umac; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the BLAKE2s message authentication code (MAC) algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Mac::BLAKE2s qw(blake2s blake2s_hex ); + +Or all of them at once: + + use Crypt::Mac::BLAKE2s ':all'; + +=head1 FUNCTIONS + +=head2 blake2s + +Logically joins all arguments into a single string, and returns its BLAKE2s message authentication code encoded as a binary string. + + $blake2s_raw = blake2s($size, $key, 'data buffer'); + #or + $blake2s_raw = blake2s($size, $key, 'any data', 'more data', 'even more data'); + +=head2 blake2s_hex + +Logically joins all arguments into a single string, and returns its BLAKE2s message authentication code encoded as a hexadecimal string. + + $blake2s_hex = blake2s_hex($size, $key, 'data buffer'); + #or + $blake2s_hex = blake2s_hex($size, $key, 'any data', 'more data', 'even more data'); + +=head2 blake2s_b64 + +Logically joins all arguments into a single string, and returns its BLAKE2s message authentication code encoded as a Base64 string. + + $blake2s_b64 = blake2s_b64($size, $key, 'data buffer'); + #or + $blake2s_b64 = blake2s_b64($size, $key, 'any data', 'more data', 'even more data'); + +=head2 blake2s_b64u + +Logically joins all arguments into a single string, and returns its BLAKE2s message authentication code encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $blake2s_b64url = blake2s_b64u($size, $key, 'data buffer'); + #or + $blake2s_b64url = blake2s_b64u($size, $key, 'any data', 'more data', 'even more data'); + +=head1 METHODS + +=head2 new + + $d = Crypt::Mac::BLAKE2s->new($size, $key); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 mac + + $result_raw = $d->mac(); + +=head2 hexmac + + $result_hex = $d->hexmac(); + +=head2 b64mac + + $result_b64 = $d->b64mac(); + +=head2 b64umac + + $result_b64url = $d->b64umac(); + +=head1 SEE ALSO + +=over + +=item * L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Mac/F9.pm b/lib/Crypt/Mac/F9.pm new file mode 100644 index 0000000..3caf72c --- /dev/null +++ b/lib/Crypt/Mac/F9.pm @@ -0,0 +1,156 @@ +package Crypt::Mac::F9; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Mac Exporter); +our %EXPORT_TAGS = ( all => [qw( f9 f9_hex f9_b64 f9_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +use Crypt::Cipher; + +sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } +sub f9 { Crypt::Mac::F9->new(shift, shift)->add(@_)->mac } +sub f9_hex { Crypt::Mac::F9->new(shift, shift)->add(@_)->hexmac } +sub f9_b64 { Crypt::Mac::F9->new(shift, shift)->add(@_)->b64mac } +sub f9_b64u { Crypt::Mac::F9->new(shift, shift)->add(@_)->b64umac } + +1; + +=pod + +=head1 NAME + +Crypt::Mac::F9 - Message authentication code F9 + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Mac::F9 qw( f9 f9_hex ); + + # calculate MAC from string/buffer + $f9_raw = f9($cipher_name, $key, 'data buffer'); + $f9_hex = f9_hex($cipher_name, $key, 'data buffer'); + $f9_b64 = f9_b64($cipher_name, $key, 'data buffer'); + $f9_b64u = f9_b64u($cipher_name, $key, 'data buffer'); + + ### OO interface: + use Crypt::Mac::F9; + + $d = Crypt::Mac::F9->new($cipher_name, $key); + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->mac; # raw bytes + $result_hex = $d->hexmac; # hexadecimal form + $result_b64 = $d->b64mac; # Base64 form + $result_b64u = $d->b64umac; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the F9 message authentication code (MAC) algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Mac::F9 qw(f9 f9_hex ); + +Or all of them at once: + + use Crypt::Mac::F9 ':all'; + +=head1 FUNCTIONS + +=head2 f9 + +Logically joins all arguments into a single string, and returns its F9 message authentication code encoded as a binary string. + + $f9_raw = f9($cipher_name, $key, 'data buffer'); + #or + $f9_raw = f9($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head2 f9_hex + +Logically joins all arguments into a single string, and returns its F9 message authentication code encoded as a hexadecimal string. + + $f9_hex = f9_hex($cipher_name, $key, 'data buffer'); + #or + $f9_hex = f9_hex($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head2 f9_b64 + +Logically joins all arguments into a single string, and returns its F9 message authentication code encoded as a Base64 string. + + $f9_b64 = f9_b64($cipher_name, $key, 'data buffer'); + #or + $f9_b64 = f9_b64($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head2 f9_b64u + +Logically joins all arguments into a single string, and returns its F9 message authentication code encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $f9_b64url = f9_b64u($cipher_name, $key, 'data buffer'); + #or + $f9_b64url = f9_b64u($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head1 METHODS + +=head2 new + + $d = Crypt::Mac::F9->new($cipher_name, $key); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 mac + + $result_raw = $d->mac(); + +=head2 hexmac + + $result_hex = $d->hexmac(); + +=head2 b64mac + + $result_b64 = $d->b64mac(); + +=head2 b64umac + + $result_b64url = $d->b64umac(); + +=head1 SEE ALSO + +=over + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Mac/HMAC.pm b/lib/Crypt/Mac/HMAC.pm new file mode 100644 index 0000000..8a2567f --- /dev/null +++ b/lib/Crypt/Mac/HMAC.pm @@ -0,0 +1,160 @@ +package Crypt::Mac::HMAC; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Mac Exporter); +our %EXPORT_TAGS = ( all => [qw( hmac hmac_hex hmac_b64 hmac_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +use Crypt::Digest; + +sub new { my $class = shift; _new(Crypt::Digest::_trans_digest_name(shift), @_) } +sub hmac { Crypt::Mac::HMAC->new(shift, shift)->add(@_)->mac } +sub hmac_hex { Crypt::Mac::HMAC->new(shift, shift)->add(@_)->hexmac } +sub hmac_b64 { Crypt::Mac::HMAC->new(shift, shift)->add(@_)->b64mac } +sub hmac_b64u { Crypt::Mac::HMAC->new(shift, shift)->add(@_)->b64umac } + +1; + +=pod + +=head1 NAME + +Crypt::Mac::HMAC - Message authentication code HMAC + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Mac::HMAC qw( hmac hmac_hex ); + + # calculate MAC from string/buffer + $hmac_raw = hmac('SHA256', $key, 'data buffer'); + $hmac_hex = hmac_hex('SHA256', $key, 'data buffer'); + $hmac_b64 = hmac_b64('SHA256', $key, 'data buffer'); + $hmac_b64u = hmac_b64u('SHA256', $key, 'data buffer'); + + ### OO interface: + use Crypt::Mac::HMAC; + + $d = Crypt::Mac::HMAC->new('SHA256', $key); + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->mac; # raw bytes + $result_hex = $d->hexmac; # hexadecimal form + $result_b64 = $d->b64mac; # Base64 form + $result_b64u = $d->b64umac; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the HMAC message authentication code (MAC) algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Mac::HMAC qw(hmac hmac_hex ); + +Or all of them at once: + + use Crypt::Mac::HMAC ':all'; + +=head1 FUNCTIONS + +=head2 hmac + +Logically joins all arguments into a single string, and returns its HMAC message authentication code encoded as a binary string. + + $hmac_raw = hmac($hash_name, $key, 'data buffer'); + #or + $hmac_raw = hmac($hash_name, $key, 'any data', 'more data', 'even more data'); + +=head2 hmac_hex + +Logically joins all arguments into a single string, and returns its HMAC message authentication code encoded as a hexadecimal string. + + $hmac_hex = hmac_hex($hash_name, $key, 'data buffer'); + #or + $hmac_hex = hmac_hex($hash_name, $key, 'any data', 'more data', 'even more data'); + +=head2 hmac_b64 + +Logically joins all arguments into a single string, and returns its HMAC message authentication code encoded as a Base64 string. + + $hmac_b64 = hmac_b64($hash_name, $key, 'data buffer'); + #or + $hmac_b64 = hmac_b64($hash_name, $key, 'any data', 'more data', 'even more data'); + +=head2 hmac_b64u + +Logically joins all arguments into a single string, and returns its HMAC message authentication code encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $hmac_b64url = hmac_b64u($hash_name, $key, 'data buffer'); + #or + $hmac_b64url = hmac_b64u($hash_name, $key, 'any data', 'more data', 'even more data'); + +=head1 METHODS + +=head2 new + + $d = Crypt::Mac::HMAC->new($hash_name, $key); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 mac + + $result_raw = $d->mac(); + +=head2 hexmac + + $result_hex = $d->hexmac(); + +=head2 b64mac + + $result_b64 = $d->b64mac(); + +=head2 b64umac + + $result_b64url = $d->b64umac(); + +=head1 SEE ALSO + +=over + +=item * L + +=item * L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Mac/OMAC.pm b/lib/Crypt/Mac/OMAC.pm new file mode 100644 index 0000000..3d752f0 --- /dev/null +++ b/lib/Crypt/Mac/OMAC.pm @@ -0,0 +1,158 @@ +package Crypt::Mac::OMAC; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Mac Exporter); +our %EXPORT_TAGS = ( all => [qw( omac omac_hex omac_b64 omac_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +use Crypt::Cipher; + +sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } +sub omac { Crypt::Mac::OMAC->new(shift, shift)->add(@_)->mac } +sub omac_hex { Crypt::Mac::OMAC->new(shift, shift)->add(@_)->hexmac } +sub omac_b64 { Crypt::Mac::OMAC->new(shift, shift)->add(@_)->b64mac } +sub omac_b64u { Crypt::Mac::OMAC->new(shift, shift)->add(@_)->b64umac } + +1; + +=pod + +=head1 NAME + +Crypt::Mac::OMAC - Message authentication code OMAC + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Mac::OMAC qw( omac omac_hex ); + + # calculate MAC from string/buffer + $omac_raw = omac($cipher_name, $key, 'data buffer'); + $omac_hex = omac_hex($cipher_name, $key, 'data buffer'); + $omac_b64 = omac_b64($cipher_name, $key, 'data buffer'); + $omac_b64u = omac_b64u($cipher_name, $key, 'data buffer'); + + ### OO interface: + use Crypt::Mac::OMAC; + + $d = Crypt::Mac::OMAC->new($cipher_name, $key); + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->mac; # raw bytes + $result_hex = $d->hexmac; # hexadecimal form + $result_b64 = $d->b64mac; # Base64 form + $result_b64u = $d->b64umac; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the OMAC message authentication code (MAC) algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Mac::OMAC qw(omac omac_hex ); + +Or all of them at once: + + use Crypt::Mac::OMAC ':all'; + +=head1 FUNCTIONS + +=head2 omac + +Logically joins all arguments into a single string, and returns its OMAC message authentication code encoded as a binary string. + + $omac_raw = omac($cipher_name, $key, 'data buffer'); + #or + $omac_raw = omac($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head2 omac_hex + +Logically joins all arguments into a single string, and returns its OMAC message authentication code encoded as a hexadecimal string. + + $omac_hex = omac_hex($cipher_name, $key, 'data buffer'); + #or + $omac_hex = omac_hex($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head2 omac_b64 + +Logically joins all arguments into a single string, and returns its OMAC message authentication code encoded as a Base64 string. + + $omac_b64 = omac_b64($cipher_name, $key, 'data buffer'); + #or + $omac_b64 = omac_b64($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head2 omac_b64u + +Logically joins all arguments into a single string, and returns its OMAC message authentication code encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $omac_b64url = omac_b64u($cipher_name, $key, 'data buffer'); + #or + $omac_b64url = omac_b64u($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head1 METHODS + +=head2 new + + $d = Crypt::Mac::OMAC->new($cipher_name, $key); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 mac + + $result_raw = $d->mac(); + +=head2 hexmac + + $result_hex = $d->hexmac(); + +=head2 b64mac + + $result_b64 = $d->b64mac(); + +=head2 b64umac + + $result_b64url = $d->b64umac(); + +=head1 SEE ALSO + +=over + +=item * L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Mac/PMAC.pm b/lib/Crypt/Mac/PMAC.pm new file mode 100644 index 0000000..04917de --- /dev/null +++ b/lib/Crypt/Mac/PMAC.pm @@ -0,0 +1,158 @@ +package Crypt::Mac::PMAC; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Mac Exporter); +our %EXPORT_TAGS = ( all => [qw( pmac pmac_hex pmac_b64 pmac_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +use Crypt::Cipher; + +sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } +sub pmac { Crypt::Mac::PMAC->new(shift, shift)->add(@_)->mac } +sub pmac_hex { Crypt::Mac::PMAC->new(shift, shift)->add(@_)->hexmac } +sub pmac_b64 { Crypt::Mac::PMAC->new(shift, shift)->add(@_)->b64mac } +sub pmac_b64u { Crypt::Mac::PMAC->new(shift, shift)->add(@_)->b64umac } + +1; + +=pod + +=head1 NAME + +Crypt::Mac::PMAC - Message authentication code PMAC + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Mac::PMAC qw( pmac pmac_hex ); + + # calculate MAC from string/buffer + $pmac_raw = pmac($cipher_name, $key, 'data buffer'); + $pmac_hex = pmac_hex($cipher_name, $key, 'data buffer'); + $pmac_b64 = pmac_b64($cipher_name, $key, 'data buffer'); + $pmac_b64u = pmac_b64u($cipher_name, $key, 'data buffer'); + + ### OO interface: + use Crypt::Mac::PMAC; + + $d = Crypt::Mac::PMAC->new($cipher_name, $key); + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->mac; # raw bytes + $result_hex = $d->hexmac; # hexadecimal form + $result_b64 = $d->b64mac; # Base64 form + $result_b64u = $d->b64umac; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the PMAC message authentication code (MAC) algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Mac::PMAC qw(pmac pmac_hex ); + +Or all of them at once: + + use Crypt::Mac::PMAC ':all'; + +=head1 FUNCTIONS + +=head2 pmac + +Logically joins all arguments into a single string, and returns its PMAC message authentication code encoded as a binary string. + + $pmac_raw = pmac($cipher_name, $key, 'data buffer'); + #or + $pmac_raw = pmac($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head2 pmac_hex + +Logically joins all arguments into a single string, and returns its PMAC message authentication code encoded as a hexadecimal string. + + $pmac_hex = pmac_hex($cipher_name, $key, 'data buffer'); + #or + $pmac_hex = pmac_hex($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head2 pmac_b64 + +Logically joins all arguments into a single string, and returns its PMAC message authentication code encoded as a Base64 string. + + $pmac_b64 = pmac_b64($cipher_name, $key, 'data buffer'); + #or + $pmac_b64 = pmac_b64($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head2 pmac_b64u + +Logically joins all arguments into a single string, and returns its PMAC message authentication code encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $pmac_b64url = pmac_b64u($cipher_name, $key, 'data buffer'); + #or + $pmac_b64url = pmac_b64u($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head1 METHODS + +=head2 new + + $d = Crypt::Mac::PMAC->new($cipher_name, $key); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 mac + + $result_raw = $d->mac(); + +=head2 hexmac + + $result_hex = $d->hexmac(); + +=head2 b64mac + + $result_b64 = $d->b64mac(); + +=head2 b64umac + + $result_b64url = $d->b64umac(); + +=head1 SEE ALSO + +=over + +=item * L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Mac/Pelican.pm b/lib/Crypt/Mac/Pelican.pm new file mode 100644 index 0000000..374b5c9 --- /dev/null +++ b/lib/Crypt/Mac/Pelican.pm @@ -0,0 +1,156 @@ +package Crypt::Mac::Pelican; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Mac Exporter); +our %EXPORT_TAGS = ( all => [qw( pelican pelican_hex pelican_b64 pelican_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +sub new { my $class = shift; _new(@_) } +sub pelican { Crypt::Mac::Pelican->new(shift)->add(@_)->mac } +sub pelican_hex { Crypt::Mac::Pelican->new(shift)->add(@_)->hexmac } +sub pelican_b64 { Crypt::Mac::Pelican->new(shift)->add(@_)->b64mac } +sub pelican_b64u { Crypt::Mac::Pelican->new(shift)->add(@_)->b64umac } + +1; + +=pod + +=head1 NAME + +Crypt::Mac::Pelican - Message authentication code Pelican (AES based MAC) + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Mac::Pelican qw( pelican pelican_hex ); + + # calculate MAC from string/buffer + $pelican_raw = pelican($key, 'data buffer'); + $pelican_hex = pelican_hex($key, 'data buffer'); + $pelican_b64 = pelican_b64($key, 'data buffer'); + $pelican_b64u = pelican_b64u($key, 'data buffer'); + + ### OO interface: + use Crypt::Mac::Pelican; + + $d = Crypt::Mac::Pelican->new($key); + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->mac; # raw bytes + $result_hex = $d->hexmac; # hexadecimal form + $result_b64 = $d->b64mac; # Base64 form + $result_b64u = $d->b64umac; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the Pelican message authentication code (MAC) algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Mac::Pelican qw(pelican pelican_hex ); + +Or all of them at once: + + use Crypt::Mac::Pelican ':all'; + +=head1 FUNCTIONS + +=head2 pelican + +Logically joins all arguments into a single string, and returns its Pelican message authentication code encoded as a binary string. + + $pelican_raw = pelican($key, 'data buffer'); + #or + $pelican_raw = pelican($key, 'any data', 'more data', 'even more data'); + +=head2 pelican_hex + +Logically joins all arguments into a single string, and returns its Pelican message authentication code encoded as a hexadecimal string. + + $pelican_hex = pelican_hex($key, 'data buffer'); + #or + $pelican_hex = pelican_hex($key, 'any data', 'more data', 'even more data'); + +=head2 pelican_b64 + +Logically joins all arguments into a single string, and returns its Pelican message authentication code encoded as a Base64 string. + + $pelican_b64 = pelican_b64($key, 'data buffer'); + #or + $pelican_b64 = pelican_b64($key, 'any data', 'more data', 'even more data'); + +=head2 pelican_b64u + +Logically joins all arguments into a single string, and returns its Pelican message authentication code encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $pelican_b64url = pelican_b64u($key, 'data buffer'); + #or + $pelican_b64url = pelican_b64u($key, 'any data', 'more data', 'even more data'); + +=head1 METHODS + +=head2 new + + $d = Crypt::Mac::Pelican->new($key); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 mac + + $result_raw = $d->mac(); + +=head2 hexmac + + $result_hex = $d->hexmac(); + +=head2 b64mac + + $result_b64 = $d->b64mac(); + +=head2 b64umac + + $result_b64url = $d->b64umac(); + +=head1 SEE ALSO + +=over + +=item * L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Mac/Poly1305.pm b/lib/Crypt/Mac/Poly1305.pm new file mode 100644 index 0000000..1d9bf08 --- /dev/null +++ b/lib/Crypt/Mac/Poly1305.pm @@ -0,0 +1,156 @@ +package Crypt::Mac::Poly1305; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Mac Exporter); +our %EXPORT_TAGS = ( all => [qw( poly1305 poly1305_hex poly1305_b64 poly1305_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +sub new { my $class = shift; _new(@_) } +sub poly1305 { Crypt::Mac::Poly1305->new(shift)->add(@_)->mac } +sub poly1305_hex { Crypt::Mac::Poly1305->new(shift)->add(@_)->hexmac } +sub poly1305_b64 { Crypt::Mac::Poly1305->new(shift)->add(@_)->b64mac } +sub poly1305_b64u { Crypt::Mac::Poly1305->new(shift)->add(@_)->b64umac } + +1; + +=pod + +=head1 NAME + +Crypt::Mac::Poly1305 - Message authentication code Poly1305 (RFC 7539) + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Mac::Poly1305 qw( poly1305 poly1305_hex ); + + # calculate MAC from string/buffer + $poly1305_raw = poly1305($key, 'data buffer'); + $poly1305_hex = poly1305_hex($key, 'data buffer'); + $poly1305_b64 = poly1305_b64($key, 'data buffer'); + $poly1305_b64u = poly1305_b64u($key, 'data buffer'); + + ### OO interface: + use Crypt::Mac::Poly1305; + + $d = Crypt::Mac::Poly1305->new($key); + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->mac; # raw bytes + $result_hex = $d->hexmac; # hexadecimal form + $result_b64 = $d->b64mac; # Base64 form + $result_b64u = $d->b64umac; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the Poly1305 message authentication code (MAC) algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Mac::Poly1305 qw(poly1305 poly1305_hex ); + +Or all of them at once: + + use Crypt::Mac::Poly1305 ':all'; + +=head1 FUNCTIONS + +=head2 poly1305 + +Logically joins all arguments into a single string, and returns its Poly1305 message authentication code encoded as a binary string. + + $poly1305_raw = poly1305($key, 'data buffer'); + #or + $poly1305_raw = poly1305($key, 'any data', 'more data', 'even more data'); + +=head2 poly1305_hex + +Logically joins all arguments into a single string, and returns its Poly1305 message authentication code encoded as a hexadecimal string. + + $poly1305_hex = poly1305_hex($key, 'data buffer'); + #or + $poly1305_hex = poly1305_hex($key, 'any data', 'more data', 'even more data'); + +=head2 poly1305_b64 + +Logically joins all arguments into a single string, and returns its Poly1305 message authentication code encoded as a Base64 string. + + $poly1305_b64 = poly1305_b64($key, 'data buffer'); + #or + $poly1305_b64 = poly1305_b64($key, 'any data', 'more data', 'even more data'); + +=head2 poly1305_b64u + +Logically joins all arguments into a single string, and returns its Poly1305 message authentication code encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $poly1305_b64url = poly1305_b64u($key, 'data buffer'); + #or + $poly1305_b64url = poly1305_b64u($key, 'any data', 'more data', 'even more data'); + +=head1 METHODS + +=head2 new + + $d = Crypt::Mac::Poly1305->new($key); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 mac + + $result_raw = $d->mac(); + +=head2 hexmac + + $result_hex = $d->hexmac(); + +=head2 b64mac + + $result_b64 = $d->b64mac(); + +=head2 b64umac + + $result_b64url = $d->b64umac(); + +=head1 SEE ALSO + +=over + +=item * L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Mac/XCBC.pm b/lib/Crypt/Mac/XCBC.pm new file mode 100644 index 0000000..61da224 --- /dev/null +++ b/lib/Crypt/Mac/XCBC.pm @@ -0,0 +1,158 @@ +package Crypt::Mac::XCBC; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::Mac Exporter); +our %EXPORT_TAGS = ( all => [qw( xcbc xcbc_hex xcbc_b64 xcbc_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +use Crypt::Cipher; + +sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } +sub xcbc { Crypt::Mac::XCBC->new(shift, shift)->add(@_)->mac } +sub xcbc_hex { Crypt::Mac::XCBC->new(shift, shift)->add(@_)->hexmac } +sub xcbc_b64 { Crypt::Mac::XCBC->new(shift, shift)->add(@_)->b64mac } +sub xcbc_b64u { Crypt::Mac::XCBC->new(shift, shift)->add(@_)->b64umac } + +1; + +=pod + +=head1 NAME + +Crypt::Mac::XCBC - Message authentication code XCBC (RFC 3566) + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Mac::XCBC qw( xcbc xcbc_hex ); + + # calculate MAC from string/buffer + $xcbc_raw = xcbc($cipher_name, $key, 'data buffer'); + $xcbc_hex = xcbc_hex($cipher_name, $key, 'data buffer'); + $xcbc_b64 = xcbc_b64($cipher_name, $key, 'data buffer'); + $xcbc_b64u = xcbc_b64u($cipher_name, $key, 'data buffer'); + + ### OO interface: + use Crypt::Mac::XCBC; + + $d = Crypt::Mac::XCBC->new($cipher_name, $key); + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->mac; # raw bytes + $result_hex = $d->hexmac; # hexadecimal form + $result_b64 = $d->b64mac; # Base64 form + $result_b64u = $d->b64umac; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the XCBC message authentication code (MAC) algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Mac::XCBC qw(xcbc xcbc_hex ); + +Or all of them at once: + + use Crypt::Mac::XCBC ':all'; + +=head1 FUNCTIONS + +=head2 xcbc + +Logically joins all arguments into a single string, and returns its XCBC message authentication code encoded as a binary string. + + $xcbc_raw = xcbc($cipher_name, $key, 'data buffer'); + #or + $xcbc_raw = xcbc($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head2 xcbc_hex + +Logically joins all arguments into a single string, and returns its XCBC message authentication code encoded as a hexadecimal string. + + $xcbc_hex = xcbc_hex($cipher_name, $key, 'data buffer'); + #or + $xcbc_hex = xcbc_hex($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head2 xcbc_b64 + +Logically joins all arguments into a single string, and returns its XCBC message authentication code encoded as a Base64 string. + + $xcbc_b64 = xcbc_b64($cipher_name, $key, 'data buffer'); + #or + $xcbc_b64 = xcbc_b64($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head2 xcbc_b64u + +Logically joins all arguments into a single string, and returns its XCBC message authentication code encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $xcbc_b64url = xcbc_b64u($cipher_name, $key, 'data buffer'); + #or + $xcbc_b64url = xcbc_b64u($cipher_name, $key, 'any data', 'more data', 'even more data'); + +=head1 METHODS + +=head2 new + + $d = Crypt::Mac::XCBC->new($cipher_name, $key); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 mac + + $result_raw = $d->mac(); + +=head2 hexmac + + $result_hex = $d->hexmac(); + +=head2 b64mac + + $result_b64 = $d->b64mac(); + +=head2 b64umac + + $result_b64url = $d->b64umac(); + +=head1 SEE ALSO + +=over + +=item * L + +=item * L + +=back + +=cut + +__END__ \ No newline at end of file diff --git a/lib/Crypt/Misc.pm b/lib/Crypt/Misc.pm new file mode 100644 index 0000000..74cea07 --- /dev/null +++ b/lib/Crypt/Misc.pm @@ -0,0 +1,363 @@ +package Crypt::Misc; + +use strict; +use warnings; +our $VERSION = '0.048'; + +require Exporter; our @ISA = qw(Exporter); ### use Exporter 5.57 'import'; +use Carp 'croak'; +our %EXPORT_TAGS = ( all => [qw(encode_b64 decode_b64 encode_b64u decode_b64u + pem_to_der der_to_pem + read_rawfile write_rawfile + slow_eq is_v4uuid random_v4uuid + increment_octets_be increment_octets_le + )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp 'carp'; +use CryptX; +use Crypt::Digest 'digest_data'; +use Crypt::Mode::CBC; +use Crypt::Mode::CFB; +use Crypt::Mode::ECB; +use Crypt::Mode::OFB; +use Crypt::Cipher; +use Crypt::PRNG 'random_bytes'; + +sub encode_b64 { + CryptX::_encode_base64(@_); +} + +sub decode_b64 { + CryptX::_decode_base64(@_); +} + +sub encode_b64u { + CryptX::_encode_base64url(@_); +} + +sub decode_b64u { + CryptX::_decode_base64url(@_); +} + +sub increment_octets_be { + CryptX::_increment_octets_be(@_); + #$_[0] = CryptX::_increment_octets_be($_[0]); +} + +sub increment_octets_le { + CryptX::_increment_octets_le(@_); + #$_[0] = CryptX::_increment_octets_le($_[0]); +} + +sub pem_to_der { + my ($data, $password) = @_; + + my ($begin, $obj1, $content, $end, $obj2) = $data =~ m/(----[- ]BEGIN ([^\r\n\-]+KEY)[ -]----)(.*?)(----[- ]END ([^\r\n\-]+)[ -]----)/s; + return undef unless $content; + + $content =~ s/^\s+//sg; + $content =~ s/\s+$//sg; + $content =~ s/\r\n/\n/sg; # CR-LF >> LF + $content =~ s/\r/\n/sg; # CR >> LF + $content =~ s/\\\n//sg; # \ + LF + + my ($headers, undef, $b64) = $content =~ /^(([^:]+:.*?\n)*)(.*)$/s; + return undef unless $b64; + + my $binary = decode_b64($b64); + return undef unless $binary; + + my ($ptype, $cipher_name, $iv_hex); + for my $h (split /\n/, ($headers||'')) { + my ($k, $v) = split /:\s*/, $h, 2; + $ptype = $v if $k eq 'Proc-Type'; + ($cipher_name, $iv_hex) = $v =~ /^\s*(.*?)\s*,\s*([0-9a-fA-F]+)\s*$/ if $k eq 'DEK-Info'; + } + if ($cipher_name && $iv_hex && $ptype && $ptype eq '4,ENCRYPTED') { + croak "FATAL: encrypted PEM but no password provided" unless defined $password; + my $iv = pack("H*", $iv_hex); + my ($mode, $klen) = _name2mode($cipher_name); + my $key = _password2key($password, $klen, $iv, 'MD5'); + return $mode->decrypt($binary, $key, $iv); + } + return $binary; +} + +sub der_to_pem { + my ($data, $header_name, $password, $cipher_name) = @_; + my $content = $data; + my @headers; + + if ($password) { + $cipher_name ||= 'AES-256-CBC'; + my ($mode, $klen, $ilen) = _name2mode($cipher_name); + my $iv = random_bytes($ilen); + my $key = _password2key($password, $klen, $iv, 'MD5'); + $content = $mode->encrypt($data, $key, $iv); + push @headers, 'Proc-Type: 4,ENCRYPTED', "DEK-Info: ".uc($cipher_name).",".unpack("H*", $iv); + } + + my $pem = "-----BEGIN $header_name-----\n"; + if (@headers) { + $pem .= "$_\n" for @headers; + $pem .= "\n"; + } + my @l = encode_b64($content) =~ /.{1,64}/g; + $pem .= join("\n", @l) . "\n"; + $pem .= "-----END $header_name-----\n"; + return $pem; +} + +sub read_rawfile { + my $f = shift; + croak "FATAL: read_rawfile() non-existing file '$f'" unless -f $f; + open my $fh, "<", $f or croak "FATAL: read_rawfile() cannot open file '$f': $!"; + binmode $fh; + return do { local $/; <$fh> }; +} + +sub write_rawfile { + # write_rawfile($filename, $data); + croak "FATAL: write_rawfile() no data" unless defined $_[1]; + open my $fh, ">", $_[0] or croak "FATAL: write_rawfile() cannot open file '$_[0]': $!"; + binmode $fh; + print $fh $_[1] or croak "FATAL: write_rawfile() cannot write to '$_[0]': $!"; + close $fh or croak "FATAL: write_rawfile() cannot close '$_[0]': $!"; + return; +} + +sub slow_eq { + my ($a, $b) = @_; + return unless defined $a && defined $b; + my $diff = length $a ^ length $b; + for(my $i = 0; $i < length $a && $i < length $b; $i++) { + $diff |= ord(substr $a, $i) ^ ord(substr $b, $i); + } + return $diff == 0; +} + +sub random_v4uuid() { + # Version 4 - random - UUID: xxxxxxxx-xxxx-4xxx-Yxxx-xxxxxxxxxxxx + # where x is any hexadecimal digit and Y is one of 8, 9, A, B (1000, 1001, 1010, 1011) + # e.g. f47ac10b-58cc-4372-a567-0e02b2c3d479 + my $raw = random_bytes(16); + # xxxxxxxxxxxx4xxxYxxxxxxxxxxxxxxx + $raw &= pack("H*", "FFFFFFFFFFFF0FFFFFFFFFFFFFFFFFFF"); + $raw |= pack("H*", "00000000000040000000000000000000"); + $raw &= pack("H*", "FFFFFFFFFFFFFFFF3FFFFFFFFFFFFFFF"); # 0x3 == 0011b + $raw |= pack("H*", "00000000000000008000000000000000"); # 0x8 == 1000b + my $hex = unpack("H*", $raw); + $hex =~ s/^(.{8})(.{4})(.{4})(.{4})(.{12}).*$/$1-$2-$3-$4-$5/; + return $hex; +} + +sub is_v4uuid($) { + my $uuid = shift; + return 0 if !$uuid; + return 1 if $uuid =~ /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; + return 0; +} + +### private functions + +sub _name2mode { + my $cipher_name = uc(shift); + my %trans = ( 'DES-EDE3' => 'DES_EDE' ); + + my ($cipher, undef, $klen, $mode) = $cipher_name =~ /^(AES|CAMELLIA|DES|DES-EDE3|SEED)(-(\d+))?-(CBC|CFB|ECB|OFB)$/i; + croak "FATAL: unsupported cipher '$cipher_name'" unless $cipher && $mode; + $cipher = $trans{$cipher} || $cipher; + $klen = $klen ? int($klen/8) : Crypt::Cipher::min_keysize($cipher); + my $ilen = Crypt::Cipher::blocksize($cipher); + croak "FATAL: unsupported cipher '$cipher_name'" unless $klen && $ilen; + + return (Crypt::Mode::CBC->new($cipher), $klen, $ilen) if $mode eq 'CBC'; + return (Crypt::Mode::CFB->new($cipher), $klen, $ilen) if $mode eq 'CFB'; + return (Crypt::Mode::ECB->new($cipher), $klen, $ilen) if $mode eq 'ECB'; + return (Crypt::Mode::OFB->new($cipher), $klen, $ilen) if $mode eq 'OFB'; +} + +sub _password2key { + my ($password, $klen, $iv, $hash) = @_; + my $salt = substr($iv, 0, 8); + my $key = ''; + while (length($key) < $klen) { + $key .= digest_data($hash, $key . $password . $salt); + } + return substr($key, 0, $klen); +} + +1; + +=pod + +=head1 NAME + +Crypt::Misc - miscellaneous functions related to (or used by) CryptX + +=head1 SYNOPSIS + +This module contains a collection of mostly unsorted functions loosely-related to CryptX distribution but not implementing cryptography. + +Most of them are also available in other perl modules but once you utilize CryptX you might avoid dependencies on other modules by using +functions from Crypt::Misc. + +=head1 DESCRIPTION + + use Crypt::Misc ':all'; + + # Base64 and Base64/URL-safe functions + $base64 = encode_b64($rawbytes); + $rawbytes = decode_b64($base64); + $base64url = encode_b64u($encode_b64u); + $rawbytes = decode_b64u($base64url); + + # read/write file + $rawdata = read_rawfile($filename); + write_rawfile($filename, $rawdata); + + # convert PEM/DER + $der_data = pem_to_der($pem_data); + $pem_data = der_to_pem($der_data); + + # others + die "mismatch" unless slow_eq($str1, $str2); + +=head1 FUNCTIONS + +By default, Crypt::Misc doesn't import any function. You can import individual functions like this: + + use Crypt::Misc qw(read_rawfile); + +Or import all available functions: + + use Crypt::Misc ':all'; + +=head2 encode_b64 + +I + + $base64string = encode_b64($rawdata); + +Encode $rawbytes into Base64 string, no line-endings in the output string. + +=head2 decode_b64 + +I + + $rawdata = encode_b64($base64string); + +Decode a Base64 string. + +=head2 encode_b64u + +I + + $base64url_string = encode_b64($rawdata); + +Encode $rawbytes into Base64/URL-Safe string, no line-endings in the output string. + +=head2 decode_b64u + +I + + $rawdata = encode_b64($base64url_string); + +Decode a Base64/URL-Safe string. + +=head2 read_rawfile + +I + + $rawdata = read_rawfile($filename); + +Read file C<$filename> into a scalar as a binary data (without decoding/transformation). + +=head2 write_rawfile + +I + + write_rawfile($filename, $rawdata); + +Write C<$rawdata> to file <$filename> as binary data. + +=head2 slow_eq + +I + + if (slow_eq($data1, $data2)) { ... } + +Constant time compare (to avoid timing side-channel). + +=head2 pem_to_der + +I + + $der_data = pem_to_der($pem_data); + #or + $der_data = pem_to_der($pem_data, $password); + +Convert PEM to DER representation. Supports also password protected PEM data. + +=head2 der_to_pem + +I + + $pem_data = der_to_pem($pem_data, $header_name); + #or + $pem_data = der_to_pem($pem_data, $header_name, $password); + #or + $pem_data = der_to_pem($pem_data, $header_name, $passord, $cipher_name); + + # $header_name e.g. "PUBLIC KEY", "RSA PRIVATE KEY" ... + # $cipher_name e.g. "DES-EDE3-CBC", "AES-256-CBC" (DEFAULT) ... + +Convert DER to PEM representation. Supports also password protected PEM data. + +=head2 random_v4uuid + +I + + my $uuid = random_v4uuid(); + +Returns cryptographically strong Version 4 random UUID: C +where C is any hexadecimal digit and C is one of 8, 9, A, B (1000, 1001, 1010, 1011) +e.g. C. + +=head2 is_v4uuid + +I + + if (is_v4uuid($uuid)) { + ... + } + +Checks the given C<$uuid> string whether it matches V4 UUID format and returns C<0> (mismatch) or C<1> (match). + +=head2 increment_octets_le + +I + + $octects = increment_octets_le($octets); + +Take input C<$octets> as a little-endian big number and return an increment. + +=head2 increment_octets_be + +I + + $octects = increment_octets_be($octets); + +Take input C<$octets> as a big-endian big number and return an increment. + +=head1 SEE ALSO + +=over + +=item * L + +=back + +=cut diff --git a/lib/Crypt/Mode.pm b/lib/Crypt/Mode.pm new file mode 100644 index 0000000..0db6b5b --- /dev/null +++ b/lib/Crypt/Mode.pm @@ -0,0 +1,72 @@ +package Crypt::Mode; + +use strict; +use warnings; +our $VERSION = '0.048'; + +### METHODS + +sub new { die } # overriden in subclass + +sub encrypt { + my ($self, $pt) = (shift, shift); + $self->_start(1, @_); + return $self->add($pt) . $self->finish; +} + +sub decrypt { + my ($self, $ct) = (shift, shift); + $self->_start(-1, @_); + return $self->add($ct) . $self->finish; +} + +sub start_encrypt { + my $self = shift; + $self->_start(1, @_); + return $self; +} + +sub start_decrypt { + my $self = shift; + $self->_start(-1, @_); + return $self; +} + +sub finish { + shift->_finish(@_); +} + +sub add { + my $self = shift; + my $rv = ''; + $rv .= $self->_crypt($_) for (@_); + return $rv; +} + +sub _crypt { + my $self = shift; + my $dir = $self->_get_dir; + return $self->_encrypt(@_) if $dir == 1; + return $self->_decrypt(@_) if $dir == -1; + return; +} + +sub _finish { + my $self = shift; + my $dir = $self->_get_dir; + return $self->_finish_enc(@_) if $dir == 1; + return $self->_finish_dec(@_) if $dir == -1; + return; +} + +sub CLONE_SKIP { 1 } # prevent cloning + +1; + +__END__ + +=head1 NAME + +Crypt::Mode - [internal only] + +=cut \ No newline at end of file diff --git a/lib/Crypt/Mode/CBC.pm b/lib/Crypt/Mode/CBC.pm new file mode 100644 index 0000000..be15194 --- /dev/null +++ b/lib/Crypt/Mode/CBC.pm @@ -0,0 +1,108 @@ +package Crypt::Mode::CBC; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use Crypt::Cipher; +use base 'Crypt::Mode'; + +sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Mode::CBC - Block cipher mode CBC [Cipher-block chaining] + +=head1 SYNOPSIS + + use Crypt::Mode::CBC; + my $m = Crypt::Mode::CBC->new('AES'); + + #(en|de)crypt at once + my $ciphertext = $m->encrypt($plaintext, $key, $iv); + my $plaintext = $m->decrypt($ciphertext, $key, $iv); + + #encrypt more chunks + $m->start_encrypt($key, $iv); + my $ciphertext = $m->add('some data'); + $ciphertext .= $m->add('more data'); + $ciphertext .= $m->finish; + + #decrypt more chunks + $m->start_decrypt($key, $iv); + my $plaintext = $m->add($some_ciphertext); + $plaintext .= $m->add($more_ciphertext); + $plaintext .= $m->finish; + +=head1 DESCRIPTION + +This module implements CBC cipher mode. B it works only with ciphers from L (Crypt::Cipher::NNNN). + +=head1 METHODS + +=head2 new + + my $m = Crypt::Mode::CBC->new('AES'); + #or + my $m = Crypt::Mode::CBC->new('AES', $padding); + #or + my $m = Crypt::Mode::CBC->new('AES', $padding, $cipher_rounds); + + # $padding .... 0 no padding (plaintext size has to be myltiple of block length) + # 1 PKCS5 padding, Crypt::CBC's "standard" - DEFAULT + # 2 Crypt::CBC's "oneandzeroes" + # $cipher_rounds ... optional num of rounds for given cipher + +=head2 encrypt + + my $ciphertext = $m->encrypt($plaintext, $key, $iv); + +=head2 decrypt + + my $plaintext = $m->decrypt($ciphertext, $key, $iv); + +=head2 start_encrypt + +See example below L. + +=head2 start_decrypt + +See example below L. + +=head2 add + +See example below L. + +=head2 finish + + #encrypt more chunks + $m->start_encrypt($key, $iv); + my $ciphertext = ''; + $ciphertext .= $m->add('some data'); + $ciphertext .= $m->add('more data'); + $ciphertext .= $m->finish; + + #decrypt more chunks + $m->start_decrypt($key, $iv); + my $plaintext = ''; + $plaintext .= $m->add($some_ciphertext); + $plaintext .= $m->add($more_ciphertext); + $plaintext .= $m->finish; + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L, L, ... + +=item * L + +=back diff --git a/lib/Crypt/Mode/CFB.pm b/lib/Crypt/Mode/CFB.pm new file mode 100644 index 0000000..6dc55f4 --- /dev/null +++ b/lib/Crypt/Mode/CFB.pm @@ -0,0 +1,99 @@ +package Crypt::Mode::CFB; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use Crypt::Cipher; +use base 'Crypt::Mode'; + +sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Mode::CFB - Block cipher mode CFB [Cipher feedback] + +=head1 SYNOPSIS + + use Crypt::Mode::CFB; + my $m = Crypt::Mode::CFB->new('AES'); + + #(en|de)crypt at once + my $ciphertext = $m->encrypt($plaintext, $key, $iv); + my $plaintext = $m->decrypt($ciphertext, $key, $iv); + + #encrypt more chunks + $m->start_encrypt($key, $iv); + my $ciphertext = $m->add('some data'); + $ciphertext .= $m->add('more data'); + + #decrypt more chunks + $m->start_decrypt($key, $iv); + my $plaintext = $m->add($some_ciphertext); + $plaintext .= $m->add($more_ciphertext); + +=head1 DESCRIPTION + +This module implements CFB cipher mode. B it works only with ciphers from L (Crypt::Cipher::NNNN). + +=head1 METHODS + +=head2 new + + my $m = Crypt::Mode::CFB->new('AES'); + #or + my $m = Crypt::Mode::CFB->new('AES', $cipher_rounds); + + # $cipher_rounds ... optional num of rounds for given cipher + +=head2 encrypt + + my $ciphertext = $m->encrypt($plaintext, $key, $iv); + +=head2 decrypt + + my $plaintext = $m->decrypt($ciphertext, $key, $iv); + +=head2 start_encrypt + +See example below L. + +=head2 start_decrypt + +See example below L. + +=head2 add + +See example below L. + +=head2 finish + + #encrypt more chunks + $m->start_encrypt($key, $iv); + my $ciphertext = ''; + $ciphertext .= $m->add('some data'); + $ciphertext .= $m->add('more data'); + + #decrypt more chunks + $m->start_decrypt($key, $iv); + my $plaintext = ''; + $plaintext .= $m->add($some_ciphertext); + $plaintext .= $m->add($more_ciphertext); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L, L, ... + +=item * L + +=back diff --git a/lib/Crypt/Mode/CTR.pm b/lib/Crypt/Mode/CTR.pm new file mode 100644 index 0000000..060e814 --- /dev/null +++ b/lib/Crypt/Mode/CTR.pm @@ -0,0 +1,106 @@ +package Crypt::Mode::CTR; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use Crypt::Cipher; +use base 'Crypt::Mode'; + +sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Mode::CTR - Block cipher mode CTR [Counter mode] + +=head1 SYNOPSIS + + use Crypt::Mode::CTR; + my $m = Crypt::Mode::CTR->new('AES'); + + #(en|de)crypt at once + my $ciphertext = $m->encrypt($plaintext, $key, $iv); + my $plaintext = $m->decrypt($ciphertext, $key, $iv); + + #encrypt more chunks + $m->start_encrypt($key, $iv); + my $ciphertext = $m->add('some data'); + $ciphertext .= $m->add('more data'); + + #decrypt more chunks + $m->start_decrypt($key, $iv); + my $plaintext = $m->add($some_ciphertext); + $plaintext .= $m->add($more_ciphertext); + +=head1 DESCRIPTION + +This module implements CTR cipher mode. B it works only with ciphers from L (Crypt::Cipher::NNNN). + +=head1 METHODS + +=head2 new + + my $m = Crypt::Mode::CTR->new($cipher_name); + #or + my $m = Crypt::Mode::CTR->new($cipher_name, $ctr_mode, $ctr_width); + #or + my $m = Crypt::Mode::CTR->new($cipher_name, $ctr_mode, $ctr_width, $cipher_rounds); + + # $ctr_mode .... 0 little-endian counter (DEFAULT) + # 1 big-endian counter + # 2 little-endian + RFC3686 incrementing + # 3 big-endian + RFC3686 incrementing + # $ctr_width ... counter width in bytes (DEFAULT = full block width) + # $cipher_rounds ... optional num of rounds for given cipher + +=head2 encrypt + + my $ciphertext = $m->encrypt($plaintext, $key, $iv); + +=head2 decrypt + + my $plaintext = $m->decrypt($ciphertext, $key, $iv); + +=head2 start_encrypt + +See example below L. + +=head2 start_decrypt + +See example below L. + +=head2 add + +See example below L. + +=head2 finish + + #encrypt more chunks + $m->start_encrypt($key, $iv); + my $ciphertext = ''; + $ciphertext .= $m->add('some data'); + $ciphertext .= $m->add('more data'); + + #decrypt more chunks + $m->start_decrypt($key, $iv); + my $plaintext = ''; + $plaintext .= $m->add($some_ciphertext); + $plaintext .= $m->add($more_ciphertext); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L, L, ... + +=item * L + +=back diff --git a/lib/Crypt/Mode/ECB.pm b/lib/Crypt/Mode/ECB.pm new file mode 100644 index 0000000..2fa877e --- /dev/null +++ b/lib/Crypt/Mode/ECB.pm @@ -0,0 +1,109 @@ +package Crypt::Mode::ECB; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use Crypt::Cipher; +use base 'Crypt::Mode'; + +sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Mode::ECB - Block cipher mode ECB [Electronic codebook] + +=head1 SYNOPSIS + + use Crypt::Mode::ECB; + my $m = Crypt::Mode::ECB->new('AES'); + + #(en|de)crypt at once + my $ciphertext = $m->encrypt($plaintext, $key); + my $plaintext = $m->decrypt($ciphertext, $key); + + #encrypt more chunks + $m->start_encrypt($key); + my $ciphertext = $m->add('some data'); + $ciphertext .= $m->add('more data'); + $ciphertext .= $m->finish; + + #decrypt more chunks + $m->start_decrypt($key); + my $plaintext = $m->add($some_ciphertext); + $plaintext .= $m->add($more_ciphertext); + $plaintext .= $m->finish; + +=head1 DESCRIPTION + +This module implements ECB cipher mode. B it works only with ciphers from L (Crypt::Cipher::NNNN). +B, if you are not sure go for L! + +=head1 METHODS + +=head2 new + + my $m = Crypt::Mode::ECB->new('AES'); + #or + my $m = Crypt::Mode::ECB->new('AES', $padding); + #or + my $m = Crypt::Mode::ECB->new('AES', $padding, $cipher_rounds); + + # $padding .... 0 no padding (plaintext size has to be myltiple of block length) + # 1 PKCS5 padding, Crypt::CBC's "standard" - DEFAULT + # 2 Crypt::CBC's "oneandzeroes" + # $cipher_rounds ... optional num of rounds for given cipher + +=head2 encrypt + + my $ciphertext = $m->encrypt($plaintext, $key); + +=head2 decrypt + + my $plaintext = $m->decrypt($ciphertext, $key); + +=head2 start_encrypt + +See example below L. + +=head2 start_decrypt + +See example below L. + +=head2 add + +See example below L. + +=head2 finish + + #encrypt more chunks + $m->start_encrypt($key); + my $ciphertext = ''; + $ciphertext .= $m->add('some data'); + $ciphertext .= $m->add('more data'); + $ciphertext .= $m->finish; + + #decrypt more chunks + $m->start_decrypt($key); + my $plaintext = ''; + $plaintext .= $m->add($some_ciphertext); + $plaintext .= $m->add($more_ciphertext); + $plaintext .= $m->finish; + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L, L, ... + +=item * L + +=back diff --git a/lib/Crypt/Mode/OFB.pm b/lib/Crypt/Mode/OFB.pm new file mode 100644 index 0000000..efd888e --- /dev/null +++ b/lib/Crypt/Mode/OFB.pm @@ -0,0 +1,99 @@ +package Crypt::Mode::OFB; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.048'; + +use Crypt::Cipher; +use base 'Crypt::Mode'; + +sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Mode::OFB - Block cipher mode OFB [Output feedback] + +=head1 SYNOPSIS + + use Crypt::Mode::OFB; + my $m = Crypt::Mode::OFB->new('AES'); + + #(en|de)crypt at once + my $ciphertext = $m->encrypt($plaintext, $key, $iv); + my $plaintext = $m->decrypt($ciphertext, $key, $iv); + + #encrypt more chunks + $m->start_encrypt($key, $iv); + my $ciphertext = $m->add('some data'); + $ciphertext .= $m->add('more data'); + + #decrypt more chunks + $m->start_decrypt($key, $iv); + my $plaintext = $m->add($some_ciphertext); + $plaintext .= $m->add($more_ciphertext); + +=head1 DESCRIPTION + +This module implements OFB cipher mode. B it works only with ciphers from L (Crypt::Cipher::NNNN). + +=head1 METHODS + +=head2 new + + my $m = Crypt::Mode::OFB->new('AES'); + #or + my $m = Crypt::Mode::OFB->new('AES', $cipher_rounds); + + # $cipher_rounds ... optional num of rounds for given cipher + +=head2 encrypt + + my $ciphertext = $m->encrypt($plaintext, $key, $iv); + +=head2 decrypt + + my $plaintext = $m->decrypt($ciphertext, $key, $iv); + +=head2 start_encrypt + +See example below L. + +=head2 start_decrypt + +See example below L. + +=head2 add + +See example below L. + +=head2 finish + + #encrypt more chunks + $m->start_encrypt($key, $iv); + my $ciphertext = ''; + $ciphertext .= $m->add('some data'); + $ciphertext .= $m->add('more data'); + + #decrypt more chunks + $m->start_decrypt($key, $iv); + my $plaintext = ''; + $plaintext .= $m->add($some_ciphertext); + $plaintext .= $m->add($more_ciphertext); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L, L, ... + +=item * L + +=back diff --git a/lib/Crypt/PK.pm b/lib/Crypt/PK.pm new file mode 100644 index 0000000..c240ab4 --- /dev/null +++ b/lib/Crypt/PK.pm @@ -0,0 +1,33 @@ +package Crypt::PK; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use Carp; + +sub _ssh_parse { + my $raw = shift; + return unless defined $raw; + my $len = length($raw); + my @parts = (); + my $i = 0; + while (1) { + last unless $i + 4 <= $len; + my $part_len = unpack("N4", substr($raw, $i, 4)); + last unless $i + 4 + $part_len <= $len; + push @parts, substr($raw, $i + 4, $part_len); + $i += $part_len + 4; + } + return @parts; +} + +1; + +__END__ + +=head1 NAME + +Crypt::PK - [internal only] + +=cut \ No newline at end of file diff --git a/lib/Crypt/PK/DH.pm b/lib/Crypt/PK/DH.pm new file mode 100644 index 0000000..445aea4 --- /dev/null +++ b/lib/Crypt/PK/DH.pm @@ -0,0 +1,643 @@ +package Crypt::PK::DH; + +use strict; +use warnings; +our $VERSION = '0.048'; + +require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; +our %EXPORT_TAGS = ( all => [qw( dh_encrypt dh_decrypt dh_sign_message dh_verify_message dh_sign_hash dh_verify_hash dh_shared_secret )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +use CryptX; +use Crypt::Digest 'digest_data'; +use Crypt::Misc qw(read_rawfile); + +my %DH_PARAMS = ( + ike768 => { g => 2, p => 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'. + '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'. + 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'. + 'E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF' + }, + ike1024 => { g => 2, p => 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'. + '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'. + 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'. + 'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED'. + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381'. + 'FFFFFFFFFFFFFFFF' + }, + ike1536 => { g => 2, p => 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'. + '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'. + 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'. + 'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED'. + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D'. + 'C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F'. + '83655D23DCA3AD961C62F356208552BB9ED529077096966D'. + '670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF' + }, + ike2048 => { g => 2, p => 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'. + '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'. + 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'. + 'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED'. + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D'. + 'C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F'. + '83655D23DCA3AD961C62F356208552BB9ED529077096966D'. + '670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B'. + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9'. + 'DE2BCBF6955817183995497CEA956AE515D2261898FA0510'. + '15728E5A8AACAA68FFFFFFFFFFFFFFFF' + }, + ike3072 => { g => 2, p => 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'. + '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'. + 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'. + 'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED'. + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D'. + 'C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F'. + '83655D23DCA3AD961C62F356208552BB9ED529077096966D'. + '670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B'. + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9'. + 'DE2BCBF6955817183995497CEA956AE515D2261898FA0510'. + '15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64'. + 'ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7'. + 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B'. + 'F12FFA06D98A0864D87602733EC86A64521F2B18177B200C'. + 'BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31'. + '43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF' + }, + ike4096 => { g => 2, p => 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'. + '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'. + 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'. + 'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED'. + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D'. + 'C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F'. + '83655D23DCA3AD961C62F356208552BB9ED529077096966D'. + '670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B'. + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9'. + 'DE2BCBF6955817183995497CEA956AE515D2261898FA0510'. + '15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64'. + 'ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7'. + 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B'. + 'F12FFA06D98A0864D87602733EC86A64521F2B18177B200C'. + 'BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31'. + '43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7'. + '88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA'. + '2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6'. + '287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED'. + '1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9'. + '93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199'. + 'FFFFFFFFFFFFFFFF' + }, + ike6144 => { g => 2, p => 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'. + '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'. + 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'. + 'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED'. + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D'. + 'C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F'. + '83655D23DCA3AD961C62F356208552BB9ED529077096966D'. + '670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B'. + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9'. + 'DE2BCBF6955817183995497CEA956AE515D2261898FA0510'. + '15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64'. + 'ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7'. + 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B'. + 'F12FFA06D98A0864D87602733EC86A64521F2B18177B200C'. + 'BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31'. + '43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7'. + '88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA'. + '2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6'. + '287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED'. + '1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9'. + '93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492'. + '36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD'. + 'F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831'. + '179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B'. + 'DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF'. + '5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6'. + 'D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3'. + '23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA'. + 'CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328'. + '06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C'. + 'DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE'. + '12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF' + }, + ike8192 => { g => 2, p => 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'. + '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'. + 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'. + 'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED'. + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D'. + 'C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F'. + '83655D23DCA3AD961C62F356208552BB9ED529077096966D'. + '670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B'. + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9'. + 'DE2BCBF6955817183995497CEA956AE515D2261898FA0510'. + '15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64'. + 'ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7'. + 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B'. + 'F12FFA06D98A0864D87602733EC86A64521F2B18177B200C'. + 'BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31'. + '43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7'. + '88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA'. + '2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6'. + '287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED'. + '1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9'. + '93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492'. + '36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD'. + 'F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831'. + '179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B'. + 'DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF'. + '5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6'. + 'D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3'. + '23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA'. + 'CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328'. + '06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C'. + 'DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE'. + '12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4'. + '38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300'. + '741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F568'. + '3423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9'. + '22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B'. + '4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A'. + '062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A36'. + '4597E899A0255DC164F31CC50846851DF9AB48195DED7EA1'. + 'B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92'. + '4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E47'. + '9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71'. + '60C980DD98EDD3DFFFFFFFFFFFFFFFFF' + } +); + +sub new { + my ($class, $f) = @_; + my $self = _new(); + $self->import_key($f) if $f; + return $self; +} + +sub import_key { + my ($self, $key) = @_; + croak "FATAL: undefined key" unless $key; + my $data; + if (ref($key) eq 'SCALAR') { + $data = $$key; + } + elsif (-f $key) { + $data = read_rawfile($key); + } + else { + croak "FATAL: non-existing file '$key'"; + } + croak "FATAL: invalid key format" unless $data; + return $self->_import($data); +} + +sub import_key_raw { + my ($self, $raw_bytes, $type, $param) = @_; + my ($g, $p, $x, $y); + + if (ref $param eq 'HASH') { + $g = $param->{g} or croak "FATAL: 'g' param not specified"; + $p = $param->{p} or croak "FATAL: 'p' param not specified"; + $g =~ s/^0x//; + $p =~ s/^0x//; + } elsif (my $dhparam = $DH_PARAMS{$param}) { + $g = $dhparam->{g}; + $p = $dhparam->{p}; + } else { + croak "FATAL: invalid parameter"; + } + + if ($type eq 'private') { + $type = 1; + } elsif ($type eq 'public') { + $type = 0; + } else { + croak "FATAL: invalid key type '$type'"; + } + my $rv = $self->_import_raw($raw_bytes, $type, $g, $p); + croak "FATAL: invalid public key" unless $self->_is_pubkey_valid; + return $rv; +} + +sub encrypt { + my ($self, $data, $hash_name) = @_; + $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); + return $self->_encrypt($data, $hash_name); +} + +sub decrypt { + my ($self, $data) = @_; + return $self->_decrypt($data); +} + +sub sign_message { + my ($self, $data, $hash_name) = @_; + $hash_name ||= 'SHA1'; + my $data_hash = digest_data($hash_name, $data); + return $self->_sign($data_hash); +} + +sub verify_message { + my ($self, $sig, $data, $hash_name) = @_; + $hash_name ||= 'SHA1'; + my $data_hash = digest_data($hash_name, $data); + return $self->_verify($sig, $data_hash); +} + +sub sign_hash { + my ($self, $data_hash) = @_; + return $self->_sign($data_hash); +} + +sub verify_hash { + my ($self, $sig, $data_hash) = @_; + return $self->_verify($sig, $data_hash); +} + +sub generate_key { + my ($key,$param) = @_; + + if (!ref $param) { + if (my $dhparam = $DH_PARAMS{$param}) { + $param = $dhparam; + } else { + croak "FATAL: invalid key length" unless ($param >= 96 || $param <= 512); + return $key->_generate_key($param); + } + } + my $g = $param->{g} or croak "FATAL: 'g' param not specified"; + my $p = $param->{p} or croak "FATAL: 'p' param not specified"; + $g =~ s/^0x//; + $p =~ s/^0x//; + return $key->_generate_key_ex($g, $p); +} + +### FUNCTIONS + +sub dh_encrypt { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->encrypt(@_); +} + +sub dh_decrypt { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->decrypt(@_); +} + +sub dh_sign_message { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->sign_message(@_); +} + +sub dh_verify_message { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->verify_message(@_); +} + +sub dh_sign_hash { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->sign_hash(@_); +} + +sub dh_verify_hash { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->verify_hash(@_); +} + +sub dh_shared_secret { + my ($privkey, $pubkey) = @_; + $privkey = __PACKAGE__->new($privkey) unless ref $privkey; + $pubkey = __PACKAGE__->new($pubkey) unless ref $pubkey; + carp "FATAL: invalid 'privkey' param" unless ref($privkey) eq __PACKAGE__ && $privkey->is_private; + carp "FATAL: invalid 'pubkey' param" unless ref($pubkey) eq __PACKAGE__; + return $privkey->shared_secret($pubkey); +} + +sub CLONE_SKIP { 1 } # prevent cloning + +1; + +=pod + +=head1 NAME + +Crypt::PK::DH - Public key cryptography based on Diffie-Hellman + +=head1 SYNOPSIS + + ### OO interface + + #Encryption: Alice + my $pub = Crypt::PK::DH->new('Bob_pub_dh1.key'); + my $ct = $pub->encrypt("secret message"); + # + #Encryption: Bob (received ciphertext $ct) + my $priv = Crypt::PK::DH->new('Bob_priv_dh1.key'); + my $pt = $priv->decrypt($ct); + + #Signature: Alice + my $priv = Crypt::PK::DH->new('Alice_priv_dh1.key'); + my $sig = $priv->sign_message($message); + # + #Signature: Bob (received $message + $sig) + my $pub = Crypt::PK::DH->new('Alice_pub_dh1.key'); + $pub->verify_message($sig, $message) or die "ERROR"; + + #Shared secret + my $priv = Crypt::PK::DH->new('Alice_priv_dh1.key'); + my $pub = Crypt::PK::DH->new('Bob_pub_dh1.key'); + my $shared_secret = $priv->shared_secret($pub); + + #Key generation + my $pk = Crypt::PK::DH->new(); + $pk->generate_key(128); + my $private = $pk->export_key('private'); + my $public = $pk->export_key('public'); + + or + + my $pk = Crypt::PK::DH->new(); + $pk->generate_key('ike2048'); + my $private = $pk->export_key('private'); + my $public = $pk->export_key('public'); + + or + + my $pk = Crypt::PK::DH->new(); + $pk->generate_key({ p => $p, g => $g }); + my $private = $pk->export_key('private'); + my $public = $pk->export_key('public'); + + ### Functional interface + + #Encryption: Alice + my $ct = dh_encrypt('Bob_pub_dh1.key', "secret message"); + #Encryption: Bob (received ciphertext $ct) + my $pt = dh_decrypt('Bob_priv_dh1.key', $ct); + + #Signature: Alice + my $sig = dh_sign_message('Alice_priv_dh1.key', $message); + #Signature: Bob (received $message + $sig) + dh_verify_message('Alice_pub_dh1.key', $sig, $message) or die "ERROR"; + + #Shared secret + my $shared_secret = dh_shared_secret('Alice_priv_dh1.key', 'Bob_pub_dh1.key'); + +=head1 METHODS + +=head2 new + + my $pk = Crypt::PK::DH->new(); + #or + my $pk = Crypt::PK::DH->new($priv_or_pub_key_filename); + #or + my $pk = Crypt::PK::DH->new(\$buffer_containing_priv_or_pub_key); + +=head2 generate_key + +Uses Yarrow-based cryptographically strong random number generator seeded with +random data taken from C (UNIX) or C (Win32). + + $pk->generate_key($keysize); + ### $keysize (in bytes) corresponds to DH params (p, g) predefined by libtomcrypt + # 96 => DH-768 + # 128 => DH-1024 + # 160 => DH-1280 + # 192 => DH-1536 + # 224 => DH-1792 + # 256 => DH-2048 + # 320 => DH-2560 + # 384 => DH-3072 + # 512 => DH-4096 + +The following variants are available since CryptX-0.032 + + $pk->generate_key($name) + ### $name corresponds to values defined in RFC7296 and RFC3526 + # ike768 => 768-bit MODP (Group 1) + # ike1024 => 1024-bit MODP (Group 2) + # ike1536 => 1536-bit MODP (Group 5) + # ike2048 => 2048-bit MODP (Group 14) + # ike3072 => 3072-bit MODP (Group 15) + # ike4096 => 4096-bit MODP (Group 16) + # ike6144 => 6144-bit MODP (Group 17) + # ike8192 => 8192-bit MODP (Group 18) + + $pk->generate_key($param_hash) + ## $param_hash is { g => $g, p => $p } + ## where $g is the generator (base) in a hex string and $p is the prime in a hex string + +=head2 import_key + +Loads private or public key (exported by L). + + $pk->import_key($filename); + #or + $pk->import_key(\$buffer_containing_key); + +=head2 import_key_raw + +I + + $pk->import_key_raw($raw_bytes, $type, $params) + ### $raw_bytes is a binary string containing the key + ### $type is either 'private' or 'public' + ### $param is either a name ('ike2038') or hash containing the p,g values { g=>$g, p=>$p } + ### in hex strings + +=head2 export_key + + my $private = $pk->export_key('private'); + #or + my $public = $pk->export_key('public'); + +=head2 export_key_raw + +I + + $raw_bytes = $dh->export_key_raw('public') + #or + $raw_bytes = $dh->export_key_raw('private') + +=head2 encrypt + + my $pk = Crypt::PK::DH->new($pub_key_filename); + my $ct = $pk->encrypt($message); + #or + my $ct = $pk->encrypt($message, $hash_name); + + #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + +=head2 decrypt + + my $pk = Crypt::PK::DH->new($priv_key_filename); + my $pt = $pk->decrypt($ciphertext); + +=head2 sign_message + + my $pk = Crypt::PK::DH->new($priv_key_filename); + my $signature = $priv->sign_message($message); + #or + my $signature = $priv->sign_message($message, $hash_name); + + #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + +=head2 verify_message + + my $pk = Crypt::PK::DH->new($pub_key_filename); + my $valid = $pub->verify_message($signature, $message) + #or + my $valid = $pub->verify_message($signature, $message, $hash_name); + + #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + +=head2 sign_hash + + my $pk = Crypt::PK::DH->new($priv_key_filename); + my $signature = $priv->sign_hash($message_hash); + +=head2 verify_hash + + my $pk = Crypt::PK::DH->new($pub_key_filename); + my $valid = $pub->verify_hash($signature, $message_hash); + +=head2 shared_secret + + # Alice having her priv key $pk and Bob's public key $pkb + my $pk = Crypt::PK::DH->new($priv_key_filename); + my $pkb = Crypt::PK::DH->new($pub_key_filename); + my $shared_secret = $pk->shared_secret($pkb); + + # Bob having his priv key $pk and Alice's public key $pka + my $pk = Crypt::PK::DH->new($priv_key_filename); + my $pka = Crypt::PK::DH->new($pub_key_filename); + my $shared_secret = $pk->shared_secret($pka); # same value as computed by Alice + +=head2 is_private + + my $rv = $pk->is_private; + # 1 .. private key loaded + # 0 .. public key loaded + # undef .. no key loaded + +=head2 size + + my $size = $pk->size; + # returns key size in bytes or undef if no key loaded + +=head2 key2hash + + my $hash = $pk->key2hash; + + # returns hash like this (or undef if no key loaded): + { + type => 0, # integer: 1 .. private, 0 .. public + size => 256, # integer: key size in bytes + x => "FBC1062F73B9A17BB8473A2F5A074911FA7F20D28FB...", #private key + y => "AB9AAA40774D3CD476B52F82E7EE2D8A8D40CD88BF4...", #public key + g => "2", # generator/base + p => "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80D...", # prime +} + +=head2 params2hash + +I + + my $params = $pk->params2hash; + + # returns hash like this (or undef if no key loaded): + { + g => "2", # generator/base + p => "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80D...", # prime +} + +=head1 FUNCTIONS + +=head2 dh_encrypt + +DH based encryption as implemented by libtomcrypt. See method L below. + + my $ct = dh_encrypt($pub_key_filename, $message); + #or + my $ct = dh_encrypt(\$buffer_containing_pub_key, $message); + #or + my $ct = dh_encrypt($pub_key_filename, $message, $hash_name); + + #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + +Encryption works similar to the L encryption whereas shared DH key is computed, and +the hash of the shared key XOR'ed against the plaintext forms the ciphertext. + +=head2 dh_decrypt + +DH based decryption as implemented by libtomcrypt. See method L below. + + my $pt = dh_decrypt($priv_key_filename, $ciphertext); + #or + my $pt = dh_decrypt(\$buffer_containing_priv_key, $ciphertext); + +=head2 dh_sign_message + +Generate DH signature as implemented by libtomcrypt. See method L below. + + my $sig = dh_sign_message($priv_key_filename, $message); + #or + my $sig = dh_sign_message(\$buffer_containing_priv_key, $message); + #or + my $sig = dh_sign_message($priv_key, $message, $hash_name); + +=head2 dh_verify_message + +Verify DH signature as implemented by libtomcrypt. See method L below. + + dh_verify_message($pub_key_filename, $signature, $message) or die "ERROR"; + #or + dh_verify_message(\$buffer_containing_pub_key, $signature, $message) or die "ERROR"; + #or + dh_verify_message($pub_key, $signature, $message, $hash_name) or die "ERROR"; + +=head2 dh_sign_hash + +Generate DH signature as implemented by libtomcrypt. See method L below. + + my $sig = dh_sign_hash($priv_key_filename, $message_hash); + #or + my $sig = dh_sign_hash(\$buffer_containing_priv_key, $message_hash); + +=head2 dh_verify_hash + +Verify DH signature as implemented by libtomcrypt. See method L below. + + dh_verify_hash($pub_key_filename, $signature, $message_hash) or die "ERROR"; + #or + dh_verify_hash(\$buffer_containing_pub_key, $signature, $message_hash) or die "ERROR"; + +=head2 dh_shared_secret + +DH based shared secret generation. See method L below. + + #on Alice side + my $shared_secret = dh_shared_secret('Alice_priv_dh1.key', 'Bob_pub_dh1.key'); + + #on Bob side + my $shared_secret = dh_shared_secret('Bob_priv_dh1.key', 'Alice_pub_dh1.key'); + +=head1 SEE ALSO + +=over + +=item * L + +=back diff --git a/lib/Crypt/PK/DSA.pm b/lib/Crypt/PK/DSA.pm new file mode 100644 index 0000000..79cbcdf --- /dev/null +++ b/lib/Crypt/PK/DSA.pm @@ -0,0 +1,617 @@ +package Crypt::PK::DSA; + +use strict; +use warnings; +our $VERSION = '0.048'; + +require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; +our %EXPORT_TAGS = ( all => [qw( dsa_encrypt dsa_decrypt dsa_sign_message dsa_verify_message dsa_sign_hash dsa_verify_hash )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +use CryptX qw(_encode_json _decode_json); +use Crypt::Digest 'digest_data'; +use Crypt::Misc qw(read_rawfile encode_b64u decode_b64u encode_b64 decode_b64 pem_to_der der_to_pem); +use Crypt::PK; + +sub new { + my ($class, $f, $p) = @_; + my $self = _new(); + $self->import_key($f, $p) if $f; + return $self; +} + +sub export_key_pem { + my ($self, $type, $password, $cipher) = @_; + my $key = $self->export_key_der($type||''); + return unless $key; + return der_to_pem($key, "DSA PRIVATE KEY", $password, $cipher) if $type eq 'private'; + return der_to_pem($key, "DSA PUBLIC KEY") if $type eq 'public'; + return der_to_pem($key, "PUBLIC KEY") if $type eq 'public_x509'; +} + +sub import_key { + my ($self, $key, $password) = @_; + croak "FATAL: undefined key" unless $key; + + # special case + if (ref($key) eq 'HASH') { + if ($key->{p} && $key->{q} && $key->{g} && $key->{y}) { + # hash exported via key2hash + return $self->_import_hex($key->{p}, $key->{q}, $key->{g}, $key->{x}, $key->{y}); + } + } + + my $data; + if (ref($key) eq 'SCALAR') { + $data = $$key; + } + elsif (-f $key) { + $data = read_rawfile($key); + } + else { + croak "FATAL: non-existing file '$key'"; + } + croak "FATAL: invalid key data" unless $data; + + if ($data =~ /-----BEGIN (DSA PRIVATE|DSA PUBLIC|PRIVATE|PUBLIC) KEY-----(.*?)-----END/sg) { + $data = pem_to_der($data, $password); + return $self->_import($data); + } + elsif ($data =~ /---- BEGIN SSH2 PUBLIC KEY ----(.*?)---- END SSH2 PUBLIC KEY ----/sg) { + $data = pem_to_der($data); + my ($typ, $p, $q, $g, $y) = Crypt::PK::_ssh_parse($data); + return $self->_import_hex(unpack('H*',$p), unpack('H*',$q), unpack('H*',$g), undef, unpack('H*',$y)) if $typ && $p && $q && $g && $y && $typ eq 'ssh-dss'; + } + elsif ($data =~ /ssh-dss\s+(\S+)/) { + $data = decode_b64("$1"); + my ($typ, $p, $q, $g, $y) = Crypt::PK::_ssh_parse($data); + return $self->_import_hex(unpack('H*',$p), unpack('H*',$q), unpack('H*',$g), undef, unpack('H*',$y)) if $typ && $p && $q && $g && $y && $typ eq 'ssh-dss'; + } + else { + return $self->_import($data); + } + croak "FATAL: invalid or unsupported DSA key format"; +} + +sub encrypt { + my ($self, $data, $hash_name) = @_; + $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); + return $self->_encrypt($data, $hash_name); +} + +sub decrypt { + my ($self, $data) = @_; + return $self->_decrypt($data); +} + +sub _truncate { + my ($self, $hash) = @_; + ### section 4.6 of FIPS 186-4 + # let N be the bit length of q + # z = the leftmost min(N, outlen) bits of Hash(M). + my $q = $self->size_q; # = size in bytes + return $hash if $q >= length($hash); + return substr($hash, 0, $q); +} + +sub sign_message { + my ($self, $data, $hash_name) = @_; + $hash_name ||= 'SHA1'; + my $data_hash = digest_data($hash_name, $data); + return $self->_sign($self->_truncate($data_hash)); +} + +sub verify_message { + my ($self, $sig, $data, $hash_name) = @_; + $hash_name ||= 'SHA1'; + my $data_hash = digest_data($hash_name, $data); + return $self->_verify($sig, $self->_truncate($data_hash)); +} + +sub sign_hash { + my ($self, $data_hash) = @_; + return $self->_sign($self->_truncate($data_hash)); +} + +sub verify_hash { + my ($self, $sig, $data_hash) = @_; + return $self->_verify($sig, $self->_truncate($data_hash)); +} + +### FUNCTIONS + +sub dsa_encrypt { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->encrypt(@_); +} + +sub dsa_decrypt { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->decrypt(@_); +} + +sub dsa_sign_message { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->sign_message(@_); +} + +sub dsa_verify_message { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->verify_message(@_); +} + +sub dsa_sign_hash { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->sign_hash(@_); +} + +sub dsa_verify_hash { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->verify_hash(@_); +} + +sub CLONE_SKIP { 1 } # prevent cloning + +1; + +=pod + +=head1 NAME + +Crypt::PK::DSA - Public key cryptography based on DSA + +=head1 SYNOPSIS + + ### OO interface + + #Encryption: Alice + my $pub = Crypt::PK::DSA->new('Bob_pub_dsa1.der'); + my $ct = $pub->encrypt("secret message"); + # + #Encryption: Bob (received ciphertext $ct) + my $priv = Crypt::PK::DSA->new('Bob_priv_dsa1.der'); + my $pt = $priv->decrypt($ct); + + #Signature: Alice + my $priv = Crypt::PK::DSA->new('Alice_priv_dsa1.der'); + my $sig = $priv->sign_message($message); + # + #Signature: Bob (received $message + $sig) + my $pub = Crypt::PK::DSA->new('Alice_pub_dsa1.der'); + $pub->verify_message($sig, $message) or die "ERROR"; + + #Key generation + my $pk = Crypt::PK::DSA->new(); + $pk->generate_key(30, 256); + my $private_der = $pk->export_key_der('private'); + my $public_der = $pk->export_key_der('public'); + my $private_pem = $pk->export_key_pem('private'); + my $public_pem = $pk->export_key_pem('public'); + + ### Functional interface + + #Encryption: Alice + my $ct = dsa_encrypt('Bob_pub_dsa1.der', "secret message"); + #Encryption: Bob (received ciphertext $ct) + my $pt = dsa_decrypt('Bob_priv_dsa1.der', $ct); + + #Signature: Alice + my $sig = dsa_sign_message('Alice_priv_dsa1.der', $message); + #Signature: Bob (received $message + $sig) + dsa_verify_message('Alice_pub_dsa1.der', $sig, $message) or die "ERROR"; + +=head1 METHODS + +=head2 new + + my $pk = Crypt::PK::DSA->new(); + #or + my $pk = Crypt::PK::DSA->new($priv_or_pub_key_filename); + #or + my $pk = Crypt::PK::DSA->new(\$buffer_containing_priv_or_pub_key); + +Support for password protected PEM keys + + my $pk = Crypt::PK::DSA->new($priv_pem_key_filename, $password); + #or + my $pk = Crypt::PK::DSA->new(\$buffer_containing_priv_pem_key, $password); + +=head2 generate_key + +Uses Yarrow-based cryptographically strong random number generator seeded with +random data taken from C (UNIX) or C (Win32). + + $pk->generate_key($group_size, $modulus_size); + # $group_size ... in bytes .. 15 < $group_size < 1024 + # $modulus_size .. in bytes .. ($modulus_size - $group_size) < 512 + + ### Bits of Security according to libtomcrypt documentation + # 80 bits => generate_key(20, 128) + # 120 bits => generate_key(30, 256) + # 140 bits => generate_key(35, 384) + # 160 bits => generate_key(40, 512) + + ### Sizes according section 4.2 of FIPS 186-4 + # (L and N are the bit lengths of p and q respectively) + # L = 1024, N = 160 => generate_key(20, 128) + # L = 2048, N = 224 => generate_key(28, 256) + # L = 2048, N = 256 => generate_key(32, 256) + # L = 3072, N = 256 => generate_key(32, 384) + +=head2 import_key + +Loads private or public key in DER or PEM format. + + $pk->import_key($filename); + #or + $pk->import_key(\$buffer_containing_key); + +Support for password protected PEM keys + + $pk->import_key($pem_filename, $password); + #or + $pk->import_key(\$buffer_containing_pem_key, $password); + +Loading private or public keys form perl hash: + + $pk->import_key($hashref); + + # where $hashref is a key exported via key2hash + $pk->import_key({ + p => "AAF839A764E04D80824B79FA1F0496C093...", #prime modulus + q => "D05C4CB45F29D353442F1FEC43A6BE2BE8...", #prime divisor + g => "847E8896D12C9BF18FE283AE7AD58ED7F3...", #generator of a subgroup of order q in GF(p) + x => "6C801901AC74E2DC714D75A9F6969483CF...", #private key, random 0 < x < q + y => "8F7604D77FA62C7539562458A63C7611B7...", #public key, where y = g^x mod p + }); + +Supported key formats: + +=over + +=item * DSA public keys + + -----BEGIN PUBLIC KEY----- + MIIBtjCCASsGByqGSM44BAEwggEeAoGBAJKyu+puNMGLpGIhbD1IatnwlI79ePr4 + YHe2KBhRkheKxWUZRpN1Vd/+usS2IHSJ9op5cSWETiP05d7PMtJaitklw7jhudq3 + GxNvV/GRdCQm3H6d76FHP88dms4vcDYc6ry6wKERGfNEtZ+4BAKrMZK+gDYsF4Aw + U6WVR969kYZhAhUA6w25FgSRmJ8W4XkvC60n8Wv3DpMCgYA4ZFE+3tLOM24PZj9Z + rxuqUzZZdR+kIzrsIYpWN9ustbmdKLKwsqIaUIxc5zxHEhbAjAIf8toPD+VEQIpY + 7vgJgDhXuPq45BgN19iLTzOJwIhAFXPZvnAdIo9D/AnMw688gT6g6U8QCZwX2XYg + ICiVcriYVNcjVKHSFY/X0Oi7CgOBhAACgYB4ZTn4OYT/pjUd6tNhGPtOS3CE1oaj + 5ScbetXg4ZDpceEyQi8VG+/ZTbs8var8X77JdEdeQA686cAxpOaVgW8V4odvcmfA + BfueiGnPXjqGfppiHAyL1Ngyd+EsXKmKVXZYAVFVI0WuJKiZBSVURU7+ByxOfpGa + fZhibr0SggWixQ== + -----END PUBLIC KEY----- + +=item * DSA private keys + + -----BEGIN DSA PRIVATE KEY----- + MIIBuwIBAAKBgQCSsrvqbjTBi6RiIWw9SGrZ8JSO/Xj6+GB3tigYUZIXisVlGUaT + dVXf/rrEtiB0ifaKeXElhE4j9OXezzLSWorZJcO44bnatxsTb1fxkXQkJtx+ne+h + Rz/PHZrOL3A2HOq8usChERnzRLWfuAQCqzGSvoA2LBeAMFOllUfevZGGYQIVAOsN + uRYEkZifFuF5LwutJ/Fr9w6TAoGAOGRRPt7SzjNuD2Y/Wa8bqlM2WXUfpCM67CGK + VjfbrLW5nSiysLKiGlCMXOc8RxIWwIwCH/LaDw/lRECKWO74CYA4V7j6uOQYDdfY + i08zicCIQBVz2b5wHSKPQ/wJzMOvPIE+oOlPEAmcF9l2ICAolXK4mFTXI1Sh0hWP + 19DouwoCgYB4ZTn4OYT/pjUd6tNhGPtOS3CE1oaj5ScbetXg4ZDpceEyQi8VG+/Z + Tbs8var8X77JdEdeQA686cAxpOaVgW8V4odvcmfABfueiGnPXjqGfppiHAyL1Ngy + d+EsXKmKVXZYAVFVI0WuJKiZBSVURU7+ByxOfpGafZhibr0SggWixQIVAL7Sia03 + 8bvANjjL9Sitk8slrM6P + -----END DSA PRIVATE KEY----- + +=item * DSA private keys in password protected PEM format: + + -----BEGIN DSA PRIVATE KEY----- + Proc-Type: 4,ENCRYPTED + DEK-Info: DES-CBC,227ADC3AA0299491 + + UISxBYAxPQMl2eK9LMAeHsssF6IxO+4G2ta2Jn8VE+boJrrH3iSTKeMXGjGaXl0z + DwcLGV+KMR70y+cxtTb34rFy+uSpBy10dOQJhxALDbe1XfCDQIUfaXRfMNA3um2I + JdZixUD/zcxBOUzao+MCr0V9XlJDgqBhJ5EEr53XHH07Eo5fhiBfbbR9NzdUPFrQ + p2ASyZtFh7RXoIBUCQgg21oeLddcNWV7gd/Y46kghO9s0JbJ8C+IsuWEPRSq502h + tSoDN6B0sxbVvOUICLLbQaxt7yduTAhRxVIJZ1PWATTVD7CZBVz9uIDZ7LOv+er2 + 1q3vkwb8E9spPsA240+BnfD571XEop4jrawxC0VKQZ+3cPVLc6jhIsxvzzFQUt67 + g66v8GUgt7KF3KhVV7qEtntybQWDWb+K/uTIH9Ra8nP820d3Rnl61pPXDPlluteT + WSLOvEMN2zRmkaxQNv/tLdT0SYpQtdjw74G3A6T7+KnvinKrjtp1a/AXkCF9hNEx + DGbxOYo1UOmk8qdxWCrab34nO+Q8oQc9wjXHG+ZtRYIMoGMKREK8DeL4H1RPNkMf + rwXWk8scd8QFmJAb8De1VQ== + -----END DSA PRIVATE KEY----- + +=item * SSH public DSA keys + + ssh-dss AAAAB3NzaC1kc3MAAACBAKU8/avmk...4XOwuEssAVhmwA== + +=item * SSH public DSA keys (RFC-4716 format) + + ---- BEGIN SSH2 PUBLIC KEY ---- + Comment: "1024-bit DSA, converted from OpenSSH" + AAAAB3NzaC1kc3MAAACBAKU8/avmkFeGnSqwYG7dZnQlG+01QNaxu3F5v0NcL/SRUW7Idp + Uq8t14siK0mA6yjphLhOf5t8gugTEVBllP86ANSbFigH7WN3v6ydJWqm60pNhNHN//50cn + NtIsXbxeq3VtsI64pkH1OJqeZDHLmu73k4T0EKOzsylSfF/wtVBJAAAAFQChpubLHViwPB + +jSvUb8e4THS7PBQAAAIAJD1PMCiTCQa1xyD/NCWOajCufTOIzKAhm6l+nlBVPiKI+262X + pYt127Ke4mPL8XJBizoTjSQN08uHMg/8L6W/cdO2aZ+mhkBnS1xAm83DAwqLrDraR1w/4Q + RFxr5Vbyy8qnejrPjTJobBN1BGsv84wHkjmoCn6pFIfkGYeATlJgAAAIAHYPU1zMVBTDWr + u7SNC4G2UyWGWYYLjLytBVHfQmBa51CmqrSs2kCfGLGA1ynfYENsxcJq9nsXrb4i17H5BH + JFkH0g7BUDpeBeLr8gsK3WgfqWwtZsDkltObw9chUD/siK6q/dk/fSIB2Ho0inev7k68Z5 + ZkNI4XOwuEssAVhmwA== + ---- END SSH2 PUBLIC KEY ---- + +=back + +=head2 export_key_der + + my $private_der = $pk->export_key_der('private'); + #or + my $public_der = $pk->export_key_der('public'); + +=head2 export_key_pem + + my $private_pem = $pk->export_key_pem('private'); + #or + my $public_pem = $pk->export_key_pem('public'); + #or + my $public_pem = $pk->export_key_pem('public_x509'); + +With parameter C<'public'> uses header and footer lines: + + -----BEGIN DSA PUBLIC KEY------ + -----END DSA PUBLIC KEY------ + +With parameter C<'public_x509'> uses header and footer lines: + + -----BEGIN PUBLIC KEY------ + -----END PUBLIC KEY------ + +Support for password protected PEM keys + + my $private_pem = $pk->export_key_pem('private', $password); + #or + my $private_pem = $pk->export_key_pem('private', $password, $cipher); + + # supported ciphers: 'DES-CBC' + # 'DES-EDE3-CBC' + # 'SEED-CBC' + # 'CAMELLIA-128-CBC' + # 'CAMELLIA-192-CBC' + # 'CAMELLIA-256-CBC' + # 'AES-128-CBC' + # 'AES-192-CBC' + # 'AES-256-CBC' (DEFAULT) + +=head2 encrypt + + my $pk = Crypt::PK::DSA->new($pub_key_filename); + my $ct = $pk->encrypt($message); + #or + my $ct = $pk->encrypt($message, $hash_name); + + #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + +=head2 decrypt + + my $pk = Crypt::PK::DSA->new($priv_key_filename); + my $pt = $pk->decrypt($ciphertext); + +=head2 sign_message + + my $pk = Crypt::PK::DSA->new($priv_key_filename); + my $signature = $priv->sign_message($message); + #or + my $signature = $priv->sign_message($message, $hash_name); + + #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + +=head2 verify_message + + my $pk = Crypt::PK::DSA->new($pub_key_filename); + my $valid = $pub->verify_message($signature, $message) + #or + my $valid = $pub->verify_message($signature, $message, $hash_name); + + #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + +=head2 sign_hash + + my $pk = Crypt::PK::DSA->new($priv_key_filename); + my $signature = $priv->sign_hash($message_hash); + +=head2 verify_hash + + my $pk = Crypt::PK::DSA->new($pub_key_filename); + my $valid = $pub->verify_hash($signature, $message_hash); + +=head2 is_private + + my $rv = $pk->is_private; + # 1 .. private key loaded + # 0 .. public key loaded + # undef .. no key loaded + +=head2 size + + my $size = $pk->size; + # returns key size in bytes or undef if no key loaded + +=head2 key2hash + + my $hash = $pk->key2hash; + + # returns hash like this (or undef if no key loaded): + { + type => 1, # integer: 1 .. private, 0 .. public + size => 256, # integer: key size in bytes + # all the rest are hex strings + p => "AAF839A764E04D80824B79FA1F0496C093...", #prime modulus + q => "D05C4CB45F29D353442F1FEC43A6BE2BE8...", #prime divisor + g => "847E8896D12C9BF18FE283AE7AD58ED7F3...", #generator of a subgroup of order q in GF(p) + x => "6C801901AC74E2DC714D75A9F6969483CF...", #private key, random 0 < x < q + y => "8F7604D77FA62C7539562458A63C7611B7...", #public key, where y = g^x mod p + } + +=head1 FUNCTIONS + +=head2 dsa_encrypt + +DSA based encryption as implemented by libtomcrypt. See method L below. + + my $ct = dsa_encrypt($pub_key_filename, $message); + #or + my $ct = dsa_encrypt(\$buffer_containing_pub_key, $message); + #or + my $ct = dsa_encrypt($pub_key_filename, $message, $hash_name); + + #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + +Encryption works similar to the L encryption whereas shared DSA key is computed, and +the hash of the shared key XOR'ed against the plaintext forms the ciphertext. + +=head2 dsa_decrypt + +DSA based decryption as implemented by libtomcrypt. See method L below. + + my $pt = dsa_decrypt($priv_key_filename, $ciphertext); + #or + my $pt = dsa_decrypt(\$buffer_containing_priv_key, $ciphertext); + +=head2 dsa_sign_message + +Generate DSA signature. See method L below. + + my $sig = dsa_sign_message($priv_key_filename, $message); + #or + my $sig = dsa_sign_message(\$buffer_containing_priv_key, $message); + #or + my $sig = dsa_sign_message($priv_key, $message, $hash_name); + +=head2 dsa_verify_message + +Verify DSA signature. See method L below. + + dsa_verify_message($pub_key_filename, $signature, $message) or die "ERROR"; + #or + dsa_verify_message(\$buffer_containing_pub_key, $signature, $message) or die "ERROR"; + #or + dsa_verify_message($pub_key, $signature, $message, $hash_name) or die "ERROR"; + +=head2 dsa_sign_hash + +Generate DSA signature. See method L below. + + my $sig = dsa_sign_hash($priv_key_filename, $message_hash); + #or + my $sig = dsa_sign_hash(\$buffer_containing_priv_key, $message_hash); + +=head2 dsa_verify_hash + +Verify DSA signature. See method L below. + + dsa_verify_hash($pub_key_filename, $signature, $message_hash) or die "ERROR"; + #or + dsa_verify_hash(\$buffer_containing_pub_key, $signature, $message_hash) or die "ERROR"; + +=head1 OpenSSL interoperability + + ### let's have: + # DSA private key in PEM format - dsakey.priv.pem + # DSA public key in PEM format - dsakey.pub.pem + # data file to be signed - input.data + +=head2 Sign by OpenSSL, verify by Crypt::PK::DSA + +Create signature (from commandline): + + openssl dgst -sha1 -sign dsakey.priv.pem -out input.sha1-dsa.sig input.data + +Verify signature (Perl code): + + use Crypt::PK::DSA; + use Crypt::Digest 'digest_file'; + use File::Slurp 'read_file'; + + my $pkdsa = Crypt::PK::DSA->new("dsakey.pub.pem"); + my $signature = read_file("input.sha1-dsa.sig", binmode=>':raw'); + my $valid = $pkdsa->verify_hash($signature, digest_file("SHA1", "input.data"), "SHA1", "v1.5"); + print $valid ? "SUCCESS" : "FAILURE"; + +=head2 Sign by Crypt::PK::DSA, verify by OpenSSL + +Create signature (Perl code): + + use Crypt::PK::DSA; + use Crypt::Digest 'digest_file'; + use File::Slurp 'write_file'; + + my $pkdsa = Crypt::PK::DSA->new("dsakey.priv.pem"); + my $signature = $pkdsa->sign_hash(digest_file("SHA1", "input.data"), "SHA1", "v1.5"); + write_file("input.sha1-dsa.sig", {binmode=>':raw'}, $signature); + +Verify signature (from commandline): + + openssl dgst -sha1 -verify dsakey.pub.pem -signature input.sha1-dsa.sig input.data + +=head2 Keys generated by Crypt::PK::DSA + +Generate keys (Perl code): + + use Crypt::PK::DSA; + use File::Slurp 'write_file'; + + my $pkdsa = Crypt::PK::DSA->new; + $pkdsa->generate_key(20, 128); + write_file("dsakey.pub.der", {binmode=>':raw'}, $pkdsa->export_key_der('public')); + write_file("dsakey.priv.der", {binmode=>':raw'}, $pkdsa->export_key_der('private')); + write_file("dsakey.pub.pem", $pkdsa->export_key_pem('public_x509')); + write_file("dsakey.priv.pem", $pkdsa->export_key_pem('private')); + write_file("dsakey-passwd.priv.pem", $pkdsa->export_key_pem('private', 'secret')); + +Use keys by OpenSSL: + + openssl dsa -in dsakey.priv.der -text -inform der + openssl dsa -in dsakey.priv.pem -text + openssl dsa -in dsakey-passwd.priv.pem -text -inform pem -passin pass:secret + openssl dsa -in dsakey.pub.der -pubin -text -inform der + openssl dsa -in dsakey.pub.pem -pubin -text + +=head2 Keys generated by OpenSSL + +Generate keys: + + openssl dsaparam -genkey -out dsakey.priv.pem 1024 + openssl dsa -in dsakey.priv.pem -out dsakey.priv.der -outform der + openssl dsa -in dsakey.priv.pem -out dsakey.pub.pem -pubout + openssl dsa -in dsakey.priv.pem -out dsakey.pub.der -outform der -pubout + openssl dsa -in dsakey.priv.pem -passout pass:secret -des3 -out dsakey-passwd.priv.pem + +Load keys (Perl code): + + use Crypt::PK::DSA; + use File::Slurp 'write_file'; + + my $pkdsa = Crypt::PK::DSA->new; + $pkdsa->import_key("dsakey.pub.der"); + $pkdsa->import_key("dsakey.priv.der"); + $pkdsa->import_key("dsakey.pub.pem"); + $pkdsa->import_key("dsakey.priv.pem"); + $pkdsa->import_key("dsakey-passwd.priv.pem", "secret"); + +=head1 SEE ALSO + +=over + +=item * L + +=back diff --git a/lib/Crypt/PK/ECC.pm b/lib/Crypt/PK/ECC.pm new file mode 100644 index 0000000..58f1d7a --- /dev/null +++ b/lib/Crypt/PK/ECC.pm @@ -0,0 +1,1398 @@ +package Crypt::PK::ECC; + +use strict; +use warnings; +our $VERSION = '0.048'; + +require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; +our %EXPORT_TAGS = ( all => [qw( ecc_encrypt ecc_decrypt ecc_sign_message ecc_verify_message ecc_sign_hash ecc_verify_hash ecc_shared_secret )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +use CryptX qw(_encode_json _decode_json); +use Crypt::Digest qw(digest_data digest_data_b64u); +use Crypt::Misc qw(read_rawfile encode_b64u decode_b64u encode_b64 decode_b64 pem_to_der der_to_pem); +use Crypt::PK; + +our %curve = ( + ### http://www.ecc-brainpool.org/download/Domain-parameters.pdf (v1.0 19.10.2005) + brainpoolp160r1 => { + oid => '1.3.36.3.3.2.8.1.1.1', + prime => "E95E4A5F737059DC60DFC7AD95B3D8139515620F", + A => "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", + B => "1E589A8595423412134FAA2DBDEC95C8D8675E58", + Gx => "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3", + Gy => "1667CB477A1A8EC338F94741669C976316DA6321", + order => "E95E4A5F737059DC60DF5991D45029409E60FC09", + cofactor => 1, + }, + brainpoolp192r1 => { + oid => '1.3.36.3.3.2.8.1.1.3', + prime => "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", + A => "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", + B => "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", + Gx => "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6", + Gy => "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", + order => "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", + cofactor => 1, + }, + brainpoolp224r1 => { + oid => '1.3.36.3.3.2.8.1.1.5', + prime => "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", + A => "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", + B => "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", + Gx => "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D", + Gy => "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", + order => "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", + cofactor => 1, + }, + brainpoolp256r1 => { + oid => '1.3.36.3.3.2.8.1.1.7', + prime => "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", + A => "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", + B => "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", + Gx => "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", + Gy => "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", + order => "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", + cofactor => 1, + }, + brainpoolp320r1 => { + oid => '1.3.36.3.3.2.8.1.1.9', + prime => "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", + A => "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", + B => "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", + Gx => "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611", + Gy => "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", + order => "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", + cofactor => 1, + }, + brainpoolp384r1 => { + oid => '1.3.36.3.3.2.8.1.1.11', + prime => "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", + A => "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", + B => "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", + Gx => "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", + Gy => "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", + order => "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", + cofactor => 1, + }, + brainpoolp512r1 => { + oid => '1.3.36.3.3.2.8.1.1.13', + prime => "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", + A => "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", + B => "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", + Gx => "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", + Gy => "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", + order => "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", + cofactor => 1, + }, + ### http://www.secg.org/collateral/sec2_final.pdf (September 20, 2000 - Version 1.0) + secp112r1 => { + oid => '1.3.132.0.6', + prime => "DB7C2ABF62E35E668076BEAD208B", + A => "DB7C2ABF62E35E668076BEAD2088", + B => "659EF8BA043916EEDE8911702B22", + Gx => "09487239995A5EE76B55F9C2F098", + Gy => "A89CE5AF8724C0A23E0E0FF77500", + order => "DB7C2ABF62E35E7628DFAC6561C5", + cofactor => 1, + }, + secp112r2 => { + oid => '1.3.132.0.7', + prime => "DB7C2ABF62E35E668076BEAD208B", + A => "6127C24C05F38A0AAAF65C0EF02C", + B => "51DEF1815DB5ED74FCC34C85D709", + Gx => "4BA30AB5E892B4E1649DD0928643", + Gy => "ADCD46F5882E3747DEF36E956E97", + order => "36DF0AAFD8B8D7597CA10520D04B", + cofactor => 4, + }, + secp128r1 => { + oid => '1.3.132.0.28', + prime => "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", + A => "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", + B => "E87579C11079F43DD824993C2CEE5ED3", + Gx => "161FF7528B899B2D0C28607CA52C5B86", + Gy => "CF5AC8395BAFEB13C02DA292DDED7A83", + order => "FFFFFFFE0000000075A30D1B9038A115", + cofactor => 1, + }, + secp128r2 => { + oid => '1.3.132.0.29', + prime => "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", + A => "D6031998D1B3BBFEBF59CC9BBFF9AEE1", + B => "5EEEFCA380D02919DC2C6558BB6D8A5D", + Gx => "7B6AA5D85E572983E6FB32A7CDEBC140", + Gy => "27B6916A894D3AEE7106FE805FC34B44", + order => "3FFFFFFF7FFFFFFFBE0024720613B5A3", + cofactor => 4, + }, + secp160k1 => { + oid => '1.3.132.0.9', + prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", + A => "0000000000000000000000000000000000000000", + B => "0000000000000000000000000000000000000007", + Gx => "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", + Gy => "938CF935318FDCED6BC28286531733C3F03C4FEE", + order => "0100000000000000000001B8FA16DFAB9ACA16B6B3", + cofactor => 1, + }, + secp160r1 => { + oid => '1.3.132.0.8', + prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", + A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", + B => "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", + Gx => "4A96B5688EF573284664698968C38BB913CBFC82", + Gy => "23A628553168947D59DCC912042351377AC5FB32", + order => "0100000000000000000001F4C8F927AED3CA752257", + cofactor => 1, + }, + secp160r2 => { + oid => '1.3.132.0.30', + prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", + A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", + B => "B4E134D3FB59EB8BAB57274904664D5AF50388BA", + Gx => "52DCB034293A117E1F4FF11B30F7199D3144CE6D", + Gy => "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", + order => "0100000000000000000000351EE786A818F3A1A16B", + cofactor => 1, + }, + secp192k1 => { + oid => '1.3.132.0.31', + prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", + A => "000000000000000000000000000000000000000000000000", + B => "000000000000000000000000000000000000000000000003", + Gx => "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", + Gy => "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", + order => "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", + cofactor => 1, + }, + secp192r1 => { # == NIST P-192, X9.62 prime192v1 + oid => '1.2.840.10045.3.1.1', + prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", + A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", + B => "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", + Gx => "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", + Gy => "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811", + order => "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", + cofactor => 1, + }, + secp224k1 => { + oid => '1.3.132.0.32', + prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", + A => "00000000000000000000000000000000000000000000000000000000", + B => "00000000000000000000000000000000000000000000000000000005", + Gx => "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", + Gy => "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", + order => "010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7", + cofactor => 1, + }, + secp224r1 => { # == NIST P-224 + oid => '1.3.132.0.33', + prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", + A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", + B => "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", + Gx => "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", + Gy => "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", + order => "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", + cofactor => 1, + }, + secp256k1 => { + oid => '1.3.132.0.10', + prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", + A => "0000000000000000000000000000000000000000000000000000000000000000", + B => "0000000000000000000000000000000000000000000000000000000000000007", + Gx => "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", + Gy => "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", + order => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", + cofactor => 1, + }, + secp256r1 => { # == NIST P-256, X9.62 prime256v1 + oid => '1.2.840.10045.3.1.7', + prime => "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", + A => "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", + B => "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", + Gx => "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", + Gy => "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", + order => "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", + cofactor => 1, + }, + secp384r1 => { # == NIST P-384 + oid => '1.3.132.0.34', + prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", + A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", + B => "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", + Gx => "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", + Gy => "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", + order => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", + cofactor => 1, + }, + secp521r1 => { # == NIST P-521 + oid => '1.3.132.0.35', + prime => "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + A => "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", + B => "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", + Gx => "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", + Gy => "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", + order => "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", + cofactor => 1 + }, + ### http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf (July 2013) + nistp192 => { # == secp192r1, X9.62 prime192v1 + oid => '1.2.840.10045.3.1.1', + prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', + A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', + B => '64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1', + Gx => '188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012', + Gy => '07192B95FFC8DA78631011ED6B24CDD573F977A11E794811', + order => 'FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831', + cofactor => 1, + }, + nistp224 => { # == secp224r1 + oid => '1.3.132.0.33', + prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001', + A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE', + B => 'B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4', + Gx => 'B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21', + Gy => 'BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34', + order => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D', + cofactor => 1, + }, + nistp256 => { # == secp256r1, X9.62 prime256v1 + oid => '1.2.840.10045.3.1.7', + prime => 'FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF', + A => 'FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC', + B => '5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B', + Gx => '6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296', + Gy => '4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5', + order => 'FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551', + cofactor => 1, + }, + nistp384 => { # == secp384r1 + oid => '1.3.132.0.34', + prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF', + A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC', + B => 'B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF', + Gx => 'AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7', + Gy => '3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F', + order => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973', + cofactor => 1, + }, + nistp521 => { # == secp521r1 + oid => '1.3.132.0.35', + prime => '1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', + A => '1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC', + B => '051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00', + Gx => '0C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66', + Gy => '11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650', + order => '1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409', + cofactor => 1, + }, + ### ANS X9.62 elliptic curves - http://www.flexiprovider.de/CurvesGfpX962.html + prime192v1 => { # == secp192r1, NIST P-192 + oid => '1.2.840.10045.3.1.1', + prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', + A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', + B => '64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1', + Gx => '188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012', + Gy => '07192B95FFC8DA78631011ED6B24CDD573F977A11E794811', + order => 'FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831', + cofactor => 1, + }, + prime192v2 => { + oid => '1.2.840.10045.3.1.2', + prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', + A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', + B => 'CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953', + Gx => 'EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A', + Gy => '6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15', + order => 'FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31', + cofactor => 1 + }, + prime192v3 => { + oid => '1.2.840.10045.3.1.3', + prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', + A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', + B => '22123DC2395A05CAA7423DAECCC94760A7D462256BD56916', + Gx => '7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896', + Gy => '38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0', + order => 'FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13', + cofactor => 1, + }, + prime239v1 => { + oid => '1.2.840.10045.3.1.4', + prime => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', + A => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', + B => '6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A', + Gx => '0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF', + Gy => '7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE', + order => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B', + cofactor => 1, + }, + prime239v2 => { + oid => '1.2.840.10045.3.1.5', + prime => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', + A => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', + B => '617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C', + Gx => '38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7', + Gy => '5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA', + order => '7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063', + cofactor => 1, + }, + prime239v3 => { + oid => '1.2.840.10045.3.1.6', + prime => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', + A => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', + B => '255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E', + Gx => '6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A', + Gy => '1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3', + order => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551', + cofactor => 1, + }, + prime256v1 => { # == secp256r1, NIST P-256 + oid => '1.2.840.10045.3.1.7', + prime => 'FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF', + A => 'FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC', + B => '5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B', + Gx => '6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296', + Gy => '4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5', + order => 'FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551', + cofactor => 1, + }, +); + +my %jwkcrv = ( + 'P-192' => 'secp192r1', + 'P-224' => 'secp224r1', + 'P-256' => 'secp256r1', + 'P-384' => 'secp384r1', + 'P-521' => 'secp521r1', +); + +sub _import_hex { + my ($self, $x, $y, $k, $crv) = @_; + my $p = $curve{$crv}{prime}; + croak "FATAL: invalid or unknown curve" if !$p; + $p =~ s/^0+//; + my $hex_size = length($p) % 2 ? length($p) + 1 : length($p); + if ($k) { + $k =~ /^0+/; + croak "FATAL: too long private key (k)" if length($k) > $hex_size; + my $priv_hex = "0" x ($hex_size - length($k)) . $k; + return $self->import_key_raw(pack("H*", $priv_hex), $crv); + } + elsif ($x && $y) { + $x =~ /^0+/; + $y =~ /^0+/; + croak "FATAL: too long public key (x)" if length($x) > $hex_size; + croak "FATAL: too long public key (y)" if length($y) > $hex_size; + my $pub_hex = "04" . ("0" x ($hex_size - length($x))) . $x . ("0" x ($hex_size - length($y))) . $y; + return $self->import_key_raw(pack("H*", $pub_hex), $crv); + } +} + +sub _curve_name_lookup { + my ($self, $key) = @_; + + return $key->{curve_name} if $key->{curve_name} && exists $curve{$key->{curve_name}}; + + defined(my $A = $key->{curve_A}) or return; + defined(my $B = $key->{curve_B}) or return; + defined(my $Gx = $key->{curve_Gx}) or return; + defined(my $Gy = $key->{curve_Gy}) or return; + defined(my $order = $key->{curve_order}) or return; + defined(my $prime = $key->{curve_prime}) or return; + defined(my $cofactor = $key->{curve_cofactor}) or return; + $A =~ s/^0+//; + $B =~ s/^0+//; + $Gx =~ s/^0+//; + $Gy =~ s/^0+//; + $order =~ s/^0+//; + $prime =~ s/^0+//; + + for my $k (sort keys %curve) { + (my $c_A = $curve{$k}{A} ) =~ s/^0+//; + (my $c_B = $curve{$k}{B} ) =~ s/^0+//; + (my $c_Gx = $curve{$k}{Gx} ) =~ s/^0+//; + (my $c_Gy = $curve{$k}{Gy} ) =~ s/^0+//; + (my $c_order = $curve{$k}{order} ) =~ s/^0+//; + (my $c_prime = $curve{$k}{prime} ) =~ s/^0+//; + my $c_cofactor = $curve{$k}{cofactor}; + return $k if $A eq $c_A && $B eq $c_B && $Gx eq $c_Gx && $Gy eq $c_Gy && + $order eq $c_order && $prime eq $c_prime && $cofactor == $c_cofactor; + } +} + +sub new { + my ($class, $f, $p) = @_; + my $self = _new(); + $self->import_key($f, $p) if $f; + return $self; +} + +sub export_key_pem { + my ($self, $type, $password, $cipher) = @_; + my $key = $self->export_key_der($type||''); + return unless $key; + return der_to_pem($key, "EC PRIVATE KEY", $password, $cipher) if substr($type, 0, 7) eq 'private'; + return der_to_pem($key, "PUBLIC KEY") if substr($type,0, 6) eq 'public'; +} + +sub export_key_jwk { + my ($self, $type, $wanthash) = @_; + my $kh = $self->key2hash; + my $curve = $self->_curve_name_lookup($kh); + $curve = 'P-192' if $curve =~ /(secp192r1|nistp192|prime192v1)/; + $curve = 'P-224' if $curve =~ /(secp224r1|nistp224)/; + $curve = 'P-256' if $curve =~ /(secp256r1|nistp256|prime256v1)/; + $curve = 'P-384' if $curve =~ /(secp384r1|nistp384)/; + $curve = 'P-521' if $curve =~ /(secp521r1|nistp521)/; + if ($type && $type eq 'private') { + return unless $kh->{pub_x} && $kh->{pub_y} && $kh->{k}; + for (qw/pub_x pub_y k/) { + $kh->{$_} = "0$kh->{$_}" if length($kh->{$_}) % 2; + } + # NOTE: x + y are not necessary in privkey + # but they are used in https://tools.ietf.org/html/rfc7517#appendix-A.2 + my $hash = { + kty => "EC", crv=>$curve, + x => encode_b64u(pack("H*", $kh->{pub_x})), + y => encode_b64u(pack("H*", $kh->{pub_y})), + d => encode_b64u(pack("H*", $kh->{k})), + }; + return $wanthash ? $hash : _encode_json($hash); + } + elsif ($type && $type eq 'public') { + return unless $kh->{pub_x} && $kh->{pub_y}; + for (qw/pub_x pub_y/) { + $kh->{$_} = "0$kh->{$_}" if length($kh->{$_}) % 2; + } + my $hash = { + kty => "EC", crv=>$curve, + x => encode_b64u(pack("H*", $kh->{pub_x})), + y => encode_b64u(pack("H*", $kh->{pub_y})), + }; + return $wanthash ? $hash : _encode_json($hash); + } +} + +sub export_key_jwk_thumbprint { + my ($self, $hash_name) = @_; + $hash_name ||= 'SHA256'; + my $h = $self->export_key_jwk('public', 1); + my $json = _encode_json({crv=>$h->{crv}, kty=>$h->{kty}, x=>$h->{x}, y=>$h->{y}}); + return digest_data_b64u($hash_name, $json); +} + +sub import_key { + my ($self, $key, $password) = @_; + croak "FATAL: undefined key" unless $key; + + # special case + if (ref($key) eq 'HASH') { + if (($key->{pub_x} && $key->{pub_y}) || $key->{k}) { + # hash exported via key2hash + my $curve = $self->_curve_name_lookup($key); + croak "FATAL: invalid or unknown curve" if !$curve; + return $self->_import_hex($key->{pub_x}, $key->{pub_y}, $key->{k}, $curve); + } + if ($key->{crv} && $key->{kty} && $key->{kty} eq "EC" && ($key->{d} || ($key->{x} && $key->{y}))) { + # hash with items corresponding to JSON Web Key (JWK) + $key = {%$key}; # make a copy as we will modify it + for (qw/x y d/) { + $key->{$_} = eval { unpack("H*", decode_b64u($key->{$_})) } if exists $key->{$_}; + } + if (my $curve = $jwkcrv{$key->{crv}}) { + return $self->_import_hex($key->{x}, $key->{y}, $key->{d}, $curve); + } + # curve is not JWK compliant e.g. P-192 P-224 P-256 P-384 P-521 (we'll try to import anyway) + return $self->_import_hex($key->{x}, $key->{y}, $key->{d}, lc($key->{crv})); + } + croak "FATAL: unexpected ECC key hash"; + } + + my $data; + if (ref($key) eq 'SCALAR') { + $data = $$key; + } + elsif (-f $key) { + $data = read_rawfile($key); + } + else { + croak "FATAL: non-existing file '$key'"; + } + croak "FATAL: invalid key data" unless $data; + + if ($data =~ /-----BEGIN (EC PRIVATE|EC PUBLIC|PUBLIC) KEY-----(.*?)-----END/sg) { + $data = pem_to_der($data, $password); + return $self->_import($data); + } + elsif ($data =~ /-----BEGIN PRIVATE KEY-----(.*?)-----END/sg) { + $data = pem_to_der($data, $password); + return $self->_import_pkcs8($data); + } + elsif ($data =~ /-----BEGIN ENCRYPTED PRIVATE KEY-----(.*?)-----END/sg) { + # XXX-TODO: pkcs#8 encrypted private key + croak "FATAL: encrypted pkcs8 EC private keys are not supported"; + } + elsif ($data =~ /^\s*(\{.*?\})\s*$/s) { + # JSON Web Key (JWK) - http://tools.ietf.org/html/draft-ietf-jose-json-web-key + my $json = "$1"; + my $h = _decode_json($json); + if ($h && $h->{kty} eq "EC") { + for (qw/x y d/) { + $h->{$_} = eval { unpack("H*", decode_b64u($h->{$_})) } if exists $h->{$_}; + } + if (my $curve = $jwkcrv{$h->{crv}}) { + return $self->_import_hex($h->{x}, $h->{y}, $h->{d}, $curve); + } + # curve is not JWK compliant e.g. P-192 P-224 P-256 P-384 P-521 (we'll try to import anyway) + return $self->_import_hex($h->{x}, $h->{y}, $h->{d}, lc($h->{crv})); + } + } + elsif ($data =~ /---- BEGIN SSH2 PUBLIC KEY ----(.*?)---- END SSH2 PUBLIC KEY ----/sg) { + $data = pem_to_der($data); + my ($typ, $skip, $pubkey) = Crypt::PK::_ssh_parse($data); + return $self->import_key_raw($pubkey, "$2") if $pubkey && $typ =~ /^ecdsa-(.+?)-(.*)$/; + } + elsif ($data =~ /(ecdsa-\S+)\s+(\S+)/) { + $data = decode_b64("$2"); + my ($typ, $skip, $pubkey) = Crypt::PK::_ssh_parse($data); + return $self->import_key_raw($pubkey, "$2") if $pubkey && $typ =~ /^ecdsa-(.+?)-(.*)$/; + } + else { + my $rv = eval { $self->_import($data) } || eval { $self->_import_pkcs8($data) }; + return $rv if $rv; + } + croak "FATAL: invalid or unsupported EC key format"; +} + +sub encrypt { + my ($self, $data, $hash_name) = @_; + $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); + return $self->_encrypt($data, $hash_name); +} + +sub decrypt { + my ($self, $data) = @_; + return $self->_decrypt($data); +} + +sub sign_message { + my ($self, $data, $hash_name) = @_; + $hash_name ||= 'SHA1'; + my $data_hash = digest_data($hash_name, $data); + return $self->_sign($data_hash); +} + +sub sign_message_rfc7518 { + my ($self, $data, $hash_name) = @_; + $hash_name ||= 'SHA1'; + my $data_hash = digest_data($hash_name, $data); + return $self->_sign_rfc7518($data_hash); +} + +sub verify_message { + my ($self, $sig, $data, $hash_name) = @_; + $hash_name ||= 'SHA1'; + my $data_hash = digest_data($hash_name, $data); + return $self->_verify($sig, $data_hash); +} + +sub verify_message_rfc7518 { + my ($self, $sig, $data, $hash_name) = @_; + $hash_name ||= 'SHA1'; + my $data_hash = digest_data($hash_name, $data); + return $self->_verify_rfc7518($sig, $data_hash); +} + +sub sign_hash { + my ($self, $data_hash) = @_; + return $self->_sign($data_hash); +} + +sub verify_hash { + my ($self, $sig, $data_hash) = @_; + return $self->_verify($sig, $data_hash); +} + +sub curve2hash { + my $self = shift; + my $kh = $self->key2hash; + return { + prime => $kh->{curve_prime}, + A => $kh->{curve_A}, + B => $kh->{curve_B}, + Gx => $kh->{curve_Gx}, + Gy => $kh->{curve_Gy}, + cofactor => $kh->{curve_cofactor}, + order => $kh->{curve_order} + }; +} + +### FUNCTIONS + +sub ecc_encrypt { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->encrypt(@_); +} + +sub ecc_decrypt { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->decrypt(@_); +} + +sub ecc_sign_message { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->sign_message(@_); +} + +sub ecc_verify_message { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->verify_message(@_); +} + +sub ecc_sign_hash { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->sign_hash(@_); +} + +sub ecc_verify_hash { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->verify_hash(@_); +} + +sub ecc_shared_secret { + my ($privkey, $pubkey) = @_; + $privkey = __PACKAGE__->new($privkey) unless ref $privkey; + $pubkey = __PACKAGE__->new($pubkey) unless ref $pubkey; + carp "FATAL: invalid 'privkey' param" unless ref($privkey) eq __PACKAGE__ && $privkey->is_private; + carp "FATAL: invalid 'pubkey' param" unless ref($pubkey) eq __PACKAGE__; + return $privkey->shared_secret($pubkey); +} + +sub CLONE_SKIP { 1 } # prevent cloning + +1; + +=pod + +=head1 NAME + +Crypt::PK::ECC - Public key cryptography based on EC + +=head1 SYNOPSIS + + ### OO interface + + #Encryption: Alice + my $pub = Crypt::PK::ECC->new('Bob_pub_ecc1.der'); + my $ct = $pub->encrypt("secret message"); + # + #Encryption: Bob (received ciphertext $ct) + my $priv = Crypt::PK::ECC->new('Bob_priv_ecc1.der'); + my $pt = $priv->decrypt($ct); + + #Signature: Alice + my $priv = Crypt::PK::ECC->new('Alice_priv_ecc1.der'); + my $sig = $priv->sign_message($message); + # + #Signature: Bob (received $message + $sig) + my $pub = Crypt::PK::ECC->new('Alice_pub_ecc1.der'); + $pub->verify_message($sig, $message) or die "ERROR"; + + #Shared secret + my $priv = Crypt::PK::ECC->new('Alice_priv_ecc1.der'); + my $pub = Crypt::PK::ECC->new('Bob_pub_ecc1.der'); + my $shared_secret = $priv->shared_secret($pub); + + #Key generation + my $pk = Crypt::PK::ECC->new(); + $pk->generate_key('secp160r1'); + my $private_der = $pk->export_key_der('private'); + my $public_der = $pk->export_key_der('public'); + my $private_pem = $pk->export_key_pem('private'); + my $public_pem = $pk->export_key_pem('public'); + my $public_raw = $pk->export_key_raw('public'); + + ### Functional interface + + #Encryption: Alice + my $ct = ecc_encrypt('Bob_pub_ecc1.der', "secret message"); + #Encryption: Bob (received ciphertext $ct) + my $pt = ecc_decrypt('Bob_priv_ecc1.der', $ct); + + #Signature: Alice + my $sig = ecc_sign_message('Alice_priv_ecc1.der', $message); + #Signature: Bob (received $message + $sig) + ecc_verify_message('Alice_pub_ecc1.der', $sig, $message) or die "ERROR"; + + #Shared secret + my $shared_secret = ecc_shared_secret('Alice_priv_ecc1.der', 'Bob_pub_ecc1.der'); + +=head1 DESCRIPTION + +The module provides a set of core ECC functions as well as implementation of ECDSA and ECDH. + +Supports elliptic curves C over prime fields C (binary fields not supported). + +=head1 METHODS + +=head2 new + + my $pk = Crypt::PK::ECC->new(); + #or + my $pk = Crypt::PK::ECC->new($priv_or_pub_key_filename); + #or + my $pk = Crypt::PK::ECC->new(\$buffer_containing_priv_or_pub_key); + +Support for password protected PEM keys + + my $pk = Crypt::PK::ECC->new($priv_pem_key_filename, $password); + #or + my $pk = Crypt::PK::ECC->new(\$buffer_containing_priv_pem_key, $password); + +=head2 generate_key + +Uses Yarrow-based cryptographically strong random number generator seeded with +random data taken from C (UNIX) or C (Win32). + + $pk->generate_key($curve_name); + #or + $pk->generate_key($hashref_with_curve_params); + +The following pre-defined C<$curve_name> values are supported: + + # curves from http://www.ecc-brainpool.org/download/Domain-parameters.pdf + 'brainpoolp160r1' + 'brainpoolp192r1' + 'brainpoolp224r1' + 'brainpoolp256r1' + 'brainpoolp320r1' + 'brainpoolp384r1' + 'brainpoolp512r1' + # curves from http://www.secg.org/collateral/sec2_final.pdf + 'secp112r1' + 'secp112r2' + 'secp128r1' + 'secp128r2' + 'secp160k1' + 'secp160r1' + 'secp160r2' + 'secp192k1' + 'secp192r1' ... same as nistp192, prime192v1 + 'secp224k1' + 'secp224r1' ... same as nistp224 + 'secp256k1' ... used by Bitcoin + 'secp256r1' ... same as nistp256, prime256v1 + 'secp384r1' ... same as nistp384 + 'secp521r1' ... same as nistp521 + #curves from http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf + 'nistp192' ... same as secp192r1, prime192v1 + 'nistp224' ... same as secp224r1 + 'nistp256' ... same as secp256r1, prime256v1 + 'nistp384' ... same as secp384r1 + 'nistp521' ... same as secp521r1 + # curves from ANS X9.62 + 'prime192v1' ... same as nistp192, secp192r1 + 'prime192v2' + 'prime192v3' + 'prime239v1' + 'prime239v2' + 'prime239v3' + 'prime256v1' ... same as nistp256, secp256r1 + +Using custom curve parameters: + + $pk->generate_key({ prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', + A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', + B => '22123DC2395A05CAA7423DAECCC94760A7D462256BD56916', + Gx => '7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896', + Gy => '38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0', + order => 'FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13', + cofactor => 1 }); + +See L, L, L + +=head2 import_key + +Loads private or public key in DER or PEM format. + + $pk->import_key($filename); + #or + $pk->import_key(\$buffer_containing_key); + +Support for password protected PEM keys: + + $pk->import_key($filename, $password); + #or + $pk->import_key(\$buffer_containing_key, $password); + +Loading private or public keys form perl hash: + + $pk->import_key($hashref); + + # the $hashref is either a key exported via key2hash + $pk->import_key({ + curve_A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", + curve_B => "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", + curve_bits => 160, + curve_bytes => 20, + curve_cofactor => 1, + curve_Gx => "4A96B5688EF573284664698968C38BB913CBFC82", + curve_Gy => "23A628553168947D59DCC912042351377AC5FB32", + curve_order => "0100000000000000000001F4C8F927AED3CA752257", + curve_prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", + k => "B0EE84A749FE95DF997E33B8F333E12101E824C3", + pub_x => "5AE1ACE3ED0AEA9707CE5C0BCE014F6A2F15023A", + pub_y => "895D57E992D0A15F88D6680B27B701F615FCDC0F", + }); + + # or with the curve defined just by name + $pk->import_key({ + curve_name => "secp160r1", + k => "B0EE84A749FE95DF997E33B8F333E12101E824C3", + pub_x => "5AE1ACE3ED0AEA9707CE5C0BCE014F6A2F15023A", + pub_y => "895D57E992D0A15F88D6680B27B701F615FCDC0F", + }); + + # or a hash with items corresponding to JWK (JSON Web Key) + $pk->import_key({ + kty => "EC", + crv => "P-256", + x => "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4", + y => "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM", + d => "870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE", + }); + +Supported key formats: + + # all formats can be loaded from a file + my $pk = Crypt::PK::ECC->new($filename); + + # or from a buffer containing the key + my $pk = Crypt::PK::ECC->new(\$buffer_with_key); + +=over + +=item * EC private keys with with all curve parameters + + -----BEGIN EC PRIVATE KEY----- + MIIB+gIBAQQwCKEAcA6cIt6CGfyLKm57LyXWv2PgTjydrHSbvhDJTOl+7bzUW8DS + rgSdtSPONPq1oIIBWzCCAVcCAQEwPAYHKoZIzj0BAQIxAP////////////////// + ///////////////////////+/////wAAAAAAAAAA/////zB7BDD///////////// + /////////////////////////////v////8AAAAAAAAAAP////wEMLMxL6fiPufk + mI4Fa+P4LRkYHZxu/oFBEgMUCI9QE4daxlY5jYou0Z0qhcjt0+wq7wMVAKM1kmqj + GaJ6HQCJamdzpIJ6zaxzBGEEqofKIr6LBTeOscce8yCtdG4dO2KLp5uYWfdB4IJU + KjhVAvJdv1UpbDpUXjhydgq3NhfeSpYmLG9dnpi/kpLcKfj0Hb0omhR86doxE7Xw + uMAKYLHOHX6BnXpDHXyQ6g5fAjEA////////////////////////////////x2NN + gfQ3Ld9YGg2ySLCneuzsGWrMxSlzAgEBoWQDYgAEeGyHPLmHcszPQ9MIIYnznpzi + QbvuJtYSjCqtIGxDfzgcLcc3nCc5tBxo+qX6OJEzcWdDAC0bwplY+9Z9jHR3ylNy + ovlHoK4ItdWkVO8NH89SLSRyVuOF8N5t3CHIo93B + -----END EC PRIVATE KEY----- + +=item * EC private keys with curve defined by OID (short form) + + -----BEGIN EC PRIVATE KEY----- + MHcCAQEEIBG1c3z52T8XwMsahGVdOZWgKCQJfv+l7djuJjgetdbDoAoGCCqGSM49 + AwEHoUQDQgAEoBUyo8CQAFPeYPvv78ylh5MwFZjTCLQeb042TjiMJxG+9DLFmRSM + lBQ9T/RsLLc+PmpB1+7yPAR+oR5gZn3kJQ== + -----END EC PRIVATE KEY----- + +=item * EC private keys in password protected PEM format + + -----BEGIN EC PRIVATE KEY----- + Proc-Type: 4,ENCRYPTED + DEK-Info: AES-128-CBC,98245C830C9282F7937E13D1D5BA11EC + + 0Y85oZ2+BKXYwrkBjsZdj6gnhOAfS5yDVmEsxFCDug+R3+Kw3QvyIfO4MVo9iWoA + D7wtoRfbt2OlBaLVl553+6QrUoa2DyKf8kLHQs1x1/J7tJOMM4SCXjlrOaToQ0dT + o7fOnjQjHne16pjgBVqGilY/I79Ab85AnE4uw7vgEucBEiU0d3nrhwuS2Opnhzyx + 009q9VLDPwY2+q7tXjTqnk9mCmQgsiaDJqY09wlauSukYPgVuOJFmi1VdkRSDKYZ + rUUsQvz6Q6Q+QirSlfHna+NhUgQ2eyhGszwcP6NU8iqIxI+NCwfFVuAzw539yYwS + 8SICczoC/YRlaclayXuomQ== + -----END EC PRIVATE KEY----- + +=item * EC public keys with all curve parameters + + -----BEGIN PUBLIC KEY----- + MIH1MIGuBgcqhkjOPQIBMIGiAgEBMCwGByqGSM49AQECIQD///////////////// + ///////////////////+///8LzAGBAEABAEHBEEEeb5mfvncu6xVoGKVzocLBwKb + /NstzijZWfKBWxb4F5hIOtp3JqPEZV2k+/wOEQio/Re0SKaFVBmcR9CP+xDUuAIh + AP////////////////////66rtzmr0igO7/SXozQNkFBAgEBA0IABITjF/nKK3jg + pjmBRXKWAv7ekR1Ko/Nb5FFPHXjH0sDrpS7qRxFALwJHv7ylGnekgfKU3vzcewNs + lvjpBYt0Yg4= + -----END PUBLIC KEY----- + +=item * EC public keys with curve defined by OID (short form) + + -----BEGIN PUBLIC KEY----- + MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEoBUyo8CQAFPeYPvv78ylh5MwFZjT + CLQeb042TjiMJxG+9DLFmRSMlBQ9T/RsLLc+PmpB1+7yPAR+oR5gZn3kJQ== + -----END PUBLIC KEY----- + +=item * PKCS#8 private keys with all curve parameters + + -----BEGIN PRIVATE KEY----- + MIIBMAIBADCB0wYHKoZIzj0CATCBxwIBATAkBgcqhkjOPQEBAhkA//////////// + /////////v//////////MEsEGP////////////////////7//////////AQYIhI9 + wjlaBcqnQj2uzMlHYKfUYiVr1WkWAxUAxGloRDXes3jEtlypWR4qV2MFmi4EMQR9 + KXeBAMZaHaF4NxZYjc4ri0rujiKPGJY4qQ8iY3M3M0tJ3LZqbcj5l4rKdkipQ7AC + GQD///////////////96YtAxyD9ClPZA7BMCAQEEVTBTAgEBBBiKolTGIsTgOCtl + 6dpdos0LvuaExCDFyT6hNAMyAAREwaCX0VY1LZxLW3G75tmft4p9uhc0J7/+NGaP + DN3Tr7SXkT9+co2a+8KPJhQy10k= + -----END PRIVATE KEY----- + +=item * PKCS#8 private keys with curve defined by OID (short form) + + -----BEGIN PRIVATE KEY----- + MG8CAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQMEVTBTAgEBBBjFP/caeQV4WO3fnWWS + f917PGzwtypd/t+hNAMyAATSg6pBT7RO6l/p+aKcrFsGuthUdfwJWS5V3NGcVt1b + lEHQYjWya2YnHaPq/iMFa7A= + -----END PRIVATE KEY----- + +=item * PKCS#8 encrypted private keys ARE NOT SUPPORTED YET! + + -----BEGIN ENCRYPTED PRIVATE KEY----- + MIGYMBwGCiqGSIb3DQEMAQMwDgQINApjTa6oFl0CAggABHi+59l4d4e6KtG9yci2 + BSC65LEsQSnrnFAExfKptNU1zMFsDLCRvDeDQDbxc6HlfoxyqFL4SmH1g3RvC/Vv + NfckdL5O2L8MRnM+ljkFtV2Te4fszWcJFdd7KiNOkPpn+7sWLfzQdvhHChLKUzmz + 4INKZyMv/G7VpZ0= + -----END ENCRYPTED PRIVATE KEY----- + +=item * SSH public EC keys + + ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNT...T3xYfJIs= + +=item * SSH public EC keys (RFC-4716 format) + + ---- BEGIN SSH2 PUBLIC KEY ---- + Comment: "521-bit ECDSA, converted from OpenSSH" + AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAFk35srteP9twCwYK + vU9ovMBi77Dd6lEBPrFaMEb0CZdZ5MC3nSqflGHRWkSbUpjdPdO7cYQNpK9YXHbNSO5hbU + 1gFZgyiGFxwJYYz8NAjedBXMgyH4JWplK5FQm5P5cvaglItC9qkKioUXhCc67YMYBtivXl + Ue0PgIq6kbHTqbX6+5Nw== + ---- END SSH2 PUBLIC KEY ---- + +=item * EC private keys in JSON Web Key (JWK) format + +See L + + { + "kty":"EC", + "crv":"P-256", + "x":"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4", + "y":"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM", + "d":"870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE", + } + +B For JWK support you need to have L, L or L module. + +=item * EC public keys in JSON Web Key (JWK) format + + { + "kty":"EC", + "crv":"P-256", + "x":"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4", + "y":"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM", + } + +B For JWK support you need to have L, L or L module. + +=back + +=head2 import_key_raw + +Import raw public/private key - can load data exported by L. + + $pk->import_key_raw($key, $curve); + # $key .... data exported by export_key_raw() + # $curve .. curve name or hashref with curve parameters - same as by generate_key() + +=head2 export_key_der + + my $private_der = $pk->export_key_der('private'); + #or + my $public_der = $pk->export_key_der('public'); + +Since CryptX-0.36 C can also export keys in a format +that does not explicitely contain curve parameters but only curve OID. + + my $private_der = $pk->export_key_der('private_short'); + #or + my $public_der = $pk->export_key_der('public_short'); + +=head2 export_key_pem + + my $private_pem = $pk->export_key_pem('private'); + #or + my $public_pem = $pk->export_key_pem('public'); + +Since CryptX-0.36 C can also export keys in a format +that does not explicitely contain curve parameters but only curve OID. + + my $private_pem = $pk->export_key_pem('private_short'); + #or + my $public_pem = $pk->export_key_pem('public_short'); + +Support for password protected PEM keys + + my $private_pem = $pk->export_key_pem('private', $password); + #or + my $private_pem = $pk->export_key_pem('private', $password, $cipher); + + # supported ciphers: 'DES-CBC' + # 'DES-EDE3-CBC' + # 'SEED-CBC' + # 'CAMELLIA-128-CBC' + # 'CAMELLIA-192-CBC' + # 'CAMELLIA-256-CBC' + # 'AES-128-CBC' + # 'AES-192-CBC' + # 'AES-256-CBC' (DEFAULT) + +=head2 export_key_jwk + +I + +Exports public/private keys as a JSON Web Key (JWK). + + my $private_json_text = $pk->export_key_jwk('private'); + #or + my $public_json_text = $pk->export_key_jwk('public'); + +Also exports public/private keys as a perl HASH with JWK structure. + + my $jwk_hash = $pk->export_key_jwk('private', 1); + #or + my $jwk_hash = $pk->export_key_jwk('public', 1); + +B For JWK support you need to have L, L or L module. + +=head2 export_key_jwk_thumbprint + +I + +Exports the key's JSON Web Key Thumbprint as a string. + +If you don't know what this is, see RFC 7638 (C). + + my $thumbprint = $pk->export_key_jwk_thumbprint('SHA256'); + +=head2 export_key_raw + +Export raw public/private key. Public key is exported in ANS X9.63 format (compressed or uncompressed), +private key is exported as raw bytes (padded with leading zeros to have the same size as the ECC curve). + + my $pubkey_octets = $pk->export_key_raw('public'); + #or + my $pubckey_octets = $pk->export_key_raw('public_compressed'); + #or + my $privkey_octets = $pk->export_key_raw('private'); + +=head2 encrypt + + my $pk = Crypt::PK::ECC->new($pub_key_filename); + my $ct = $pk->encrypt($message); + #or + my $ct = $pk->encrypt($message, $hash_name); + + #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + +=head2 decrypt + + my $pk = Crypt::PK::ECC->new($priv_key_filename); + my $pt = $pk->decrypt($ciphertext); + +=head2 sign_message + + my $pk = Crypt::PK::ECC->new($priv_key_filename); + my $signature = $priv->sign_message($message); + #or + my $signature = $priv->sign_message($message, $hash_name); + + #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + +=head2 sign_message_rfc7518 + +I + +Same as L only the signature format is as defined by L +(JWA - JSON Web Algorithms). + +=head2 verify_message + + my $pk = Crypt::PK::ECC->new($pub_key_filename); + my $valid = $pub->verify_message($signature, $message) + #or + my $valid = $pub->verify_message($signature, $message, $hash_name); + + #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + +=head2 verify_message_rfc7518 + +I + +Same as L only the signature format is as defined by L +(JWA - JSON Web Algorithms). + +=head2 sign_hash + + my $pk = Crypt::PK::ECC->new($priv_key_filename); + my $signature = $priv->sign_hash($message_hash); + +=head2 verify_hash + + my $pk = Crypt::PK::ECC->new($pub_key_filename); + my $valid = $pub->verify_hash($signature, $message_hash); + +=head2 shared_secret + + # Alice having her priv key $pk and Bob's public key $pkb + my $pk = Crypt::PK::ECC->new($priv_key_filename); + my $pkb = Crypt::PK::ECC->new($pub_key_filename); + my $shared_secret = $pk->shared_secret($pkb); + + # Bob having his priv key $pk and Alice's public key $pka + my $pk = Crypt::PK::ECC->new($priv_key_filename); + my $pka = Crypt::PK::ECC->new($pub_key_filename); + my $shared_secret = $pk->shared_secret($pka); # same value as computed by Alice + +=head2 is_private + + my $rv = $pk->is_private; + # 1 .. private key loaded + # 0 .. public key loaded + # undef .. no key loaded + +=head2 size + + my $size = $pk->size; + # returns key size in bytes or undef if no key loaded + +=head2 key2hash + + my $hash = $pk->key2hash; + + # returns hash like this (or undef if no key loaded): + { + size => 20, # integer: key (curve) size in bytes + type => 1, # integer: 1 .. private, 0 .. public + #curve parameters + curve_A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", + curve_B => "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", + curve_bits => 160, + curve_bytes => 20, + curve_cofactor => 1, + curve_Gx => "4A96B5688EF573284664698968C38BB913CBFC82", + curve_Gy => "23A628553168947D59DCC912042351377AC5FB32", + curve_name => "secp160r1", + curve_order => "0100000000000000000001F4C8F927AED3CA752257", + curve_prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", + #private key + k => "B0EE84A749FE95DF997E33B8F333E12101E824C3", + #public key point coordinates + pub_x => "5AE1ACE3ED0AEA9707CE5C0BCE014F6A2F15023A", + pub_y => "895D57E992D0A15F88D6680B27B701F615FCDC0F", + } + +=head2 curve2hash + +I + + my $crv = $pk->curve2hash; + + # returns a hash that can be passed to: $pk->generate_key($crv) + { + A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", + B => "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", + cofactor => 1, + Gx => "4A96B5688EF573284664698968C38BB913CBFC82", + Gy => "23A628553168947D59DCC912042351377AC5FB32", + order => "0100000000000000000001F4C8F927AED3CA752257", + prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", + } + +=head1 FUNCTIONS + +=head2 ecc_encrypt + +Elliptic Curve Diffie-Hellman (ECDH) encryption as implemented by libtomcrypt. See method L below. + + my $ct = ecc_encrypt($pub_key_filename, $message); + #or + my $ct = ecc_encrypt(\$buffer_containing_pub_key, $message); + #or + my $ct = ecc_encrypt($pub_key_filename, $message, $hash_name); + + #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + +ECCDH Encryption is performed by producing a random key, hashing it, and XOR'ing the digest against the plaintext. + +=head2 ecc_decrypt + +Elliptic Curve Diffie-Hellman (ECDH) decryption as implemented by libtomcrypt. See method L below. + + my $pt = ecc_decrypt($priv_key_filename, $ciphertext); + #or + my $pt = ecc_decrypt(\$buffer_containing_priv_key, $ciphertext); + +=head2 ecc_sign_message + +Elliptic Curve Digital Signature Algorithm (ECDSA) - signature generation. See method L below. + + my $sig = ecc_sign_message($priv_key_filename, $message); + #or + my $sig = ecc_sign_message(\$buffer_containing_priv_key, $message); + #or + my $sig = ecc_sign_message($priv_key, $message, $hash_name); + +=head2 ecc_verify_message + +Elliptic Curve Digital Signature Algorithm (ECDSA) - signature verification. See method L below. + + ecc_verify_message($pub_key_filename, $signature, $message) or die "ERROR"; + #or + ecc_verify_message(\$buffer_containing_pub_key, $signature, $message) or die "ERROR"; + #or + ecc_verify_message($pub_key, $signature, $message, $hash_name) or die "ERROR"; + +=head2 ecc_sign_hash + +Elliptic Curve Digital Signature Algorithm (ECDSA) - signature generation. See method L below. + + my $sig = ecc_sign_hash($priv_key_filename, $message_hash); + #or + my $sig = ecc_sign_hash(\$buffer_containing_priv_key, $message_hash); + +=head2 ecc_verify_hash + +Elliptic Curve Digital Signature Algorithm (ECDSA) - signature verification. See method L below. + + ecc_verify_hash($pub_key_filename, $signature, $message_hash) or die "ERROR"; + #or + ecc_verify_hash(\$buffer_containing_pub_key, $signature, $message_hash) or die "ERROR"; + +=head2 ecc_shared_secret + +Elliptic curve Diffie-Hellman (ECDH) - construct a Diffie-Hellman shared secret with a private and public ECC key. See method L below. + + #on Alice side + my $shared_secret = ecc_shared_secret('Alice_priv_ecc1.der', 'Bob_pub_ecc1.der'); + + #on Bob side + my $shared_secret = ecc_shared_secret('Bob_priv_ecc1.der', 'Alice_pub_ecc1.der'); + +=head1 OpenSSL interoperability + + ### let's have: + # ECC private key in PEM format - eckey.priv.pem + # ECC public key in PEM format - eckey.pub.pem + # data file to be signed - input.data + +=head2 Sign by OpenSSL, verify by Crypt::PK::ECC + +Create signature (from commandline): + + openssl dgst -sha1 -sign eckey.priv.pem -out input.sha1-ec.sig input.data + +Verify signature (Perl code): + + use Crypt::PK::ECC; + use Crypt::Digest 'digest_file'; + use File::Slurp 'read_file'; + + my $pkec = Crypt::PK::ECC->new("eckey.pub.pem"); + my $signature = read_file("input.sha1-ec.sig", binmode=>':raw'); + my $valid = $pkec->verify_hash($signature, digest_file("SHA1", "input.data"), "SHA1", "v1.5"); + print $valid ? "SUCCESS" : "FAILURE"; + +=head2 Sign by Crypt::PK::ECC, verify by OpenSSL + +Create signature (Perl code): + + use Crypt::PK::ECC; + use Crypt::Digest 'digest_file'; + use File::Slurp 'write_file'; + + my $pkec = Crypt::PK::ECC->new("eckey.priv.pem"); + my $signature = $pkec->sign_hash(digest_file("SHA1", "input.data"), "SHA1", "v1.5"); + write_file("input.sha1-ec.sig", {binmode=>':raw'}, $signature); + +Verify signature (from commandline): + + openssl dgst -sha1 -verify eckey.pub.pem -signature input.sha1-ec.sig input.data + +=head2 Keys generated by Crypt::PK::ECC + +Generate keys (Perl code): + + use Crypt::PK::ECC; + use File::Slurp 'write_file'; + + my $pkec = Crypt::PK::ECC->new; + $pkec->generate_key('secp160k1'); + write_file("eckey.pub.der", {binmode=>':raw'}, $pkec->export_key_der('public')); + write_file("eckey.priv.der", {binmode=>':raw'}, $pkec->export_key_der('private')); + write_file("eckey.pub.pem", $pkec->export_key_pem('public')); + write_file("eckey.priv.pem", $pkec->export_key_pem('private')); + write_file("eckey-passwd.priv.pem", $pkec->export_key_pem('private', 'secret')); + +Use keys by OpenSSL: + + openssl ec -in eckey.priv.der -text -inform der + openssl ec -in eckey.priv.pem -text + openssl ec -in eckey-passwd.priv.pem -text -inform pem -passin pass:secret + openssl ec -in eckey.pub.der -pubin -text -inform der + openssl ec -in eckey.pub.pem -pubin -text + +=head2 Keys generated by OpenSSL + +Generate keys: + + openssl ecparam -param_enc explicit -name prime192v3 -genkey -out eckey.priv.pem + openssl ec -param_enc explicit -in eckey.priv.pem -out eckey.pub.pem -pubout + openssl ec -param_enc explicit -in eckey.priv.pem -out eckey.priv.der -outform der + openssl ec -param_enc explicit -in eckey.priv.pem -out eckey.pub.der -outform der -pubout + openssl ec -param_enc explicit -in eckey.priv.pem -out eckey.privc.der -outform der -conv_form compressed + openssl ec -param_enc explicit -in eckey.priv.pem -out eckey.pubc.der -outform der -pubout -conv_form compressed + openssl ec -param_enc explicit -in eckey.priv.pem -passout pass:secret -des3 -out eckey-passwd.priv.pem + +Load keys (Perl code): + + use Crypt::PK::ECC; + use File::Slurp 'write_file'; + + my $pkec = Crypt::PK::ECC->new; + $pkec->import_key("eckey.pub.der"); + $pkec->import_key("eckey.pubc.der"); + $pkec->import_key("eckey.priv.der"); + $pkec->import_key("eckey.privc.der"); + $pkec->import_key("eckey.pub.pem"); + $pkec->import_key("eckey.priv.pem"); + $pkec->import_key("eckey-passwd.priv.pem", "secret"); + +=head1 SEE ALSO + +=over + +=item * L + +=item * L + +=item * L + +=back diff --git a/lib/Crypt/PK/RSA.pm b/lib/Crypt/PK/RSA.pm new file mode 100644 index 0000000..2fe541a --- /dev/null +++ b/lib/Crypt/PK/RSA.pm @@ -0,0 +1,939 @@ +package Crypt::PK::RSA; + +use strict; +use warnings; +our $VERSION = '0.048'; + +require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; +our %EXPORT_TAGS = ( all => [qw(rsa_encrypt rsa_decrypt rsa_sign_message rsa_verify_message rsa_sign_hash rsa_verify_hash)] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +use CryptX qw(_encode_json _decode_json); +use Crypt::Digest qw(digest_data digest_data_b64u); +use Crypt::Misc qw(read_rawfile encode_b64u decode_b64u encode_b64 decode_b64 pem_to_der der_to_pem); +use Crypt::PK; + +sub new { + my ($class, $f, $p) = @_; + my $self = _new(); + $self->import_key($f, $p) if $f; + return $self; +} + +sub export_key_pem { + my ($self, $type, $password, $cipher) = @_; + my $key = $self->export_key_der($type||''); + return unless $key; + + # PKCS#1 RSAPrivateKey** (PEM header: BEGIN RSA PRIVATE KEY) + # PKCS#8 PrivateKeyInfo* (PEM header: BEGIN PRIVATE KEY) + # PKCS#8 EncryptedPrivateKeyInfo** (PEM header: BEGIN ENCRYPTED PRIVATE KEY) + return der_to_pem($key, "RSA PRIVATE KEY", $password, $cipher) if $type eq 'private'; + + # PKCS#1 RSAPublicKey* (PEM header: BEGIN RSA PUBLIC KEY) + return der_to_pem($key, "RSA PUBLIC KEY") if $type eq 'public'; + # X.509 SubjectPublicKeyInfo** (PEM header: BEGIN PUBLIC KEY) + return der_to_pem($key, "PUBLIC KEY") if $type eq 'public_x509'; +} + +sub export_key_jwk { + my ($self, $type, $wanthash) = @_; + my $kh = $self->key2hash; + if ($type eq 'private') { + return unless $kh->{N} && $kh->{e} && $kh->{d} && $kh->{p} && $kh->{q} && $kh->{dP} && $kh->{dQ} && $kh->{qP}; + for (qw/N e d p q dP dQ qP/) { + $kh->{$_} = "0$kh->{$_}" if length($kh->{$_}) % 2; + } + my $hash = { + kty => "RSA", + n => encode_b64u(pack("H*", $kh->{N})), + e => encode_b64u(pack("H*", $kh->{e})), + d => encode_b64u(pack("H*", $kh->{d})), + p => encode_b64u(pack("H*", $kh->{p})), + q => encode_b64u(pack("H*", $kh->{q})), + dp => encode_b64u(pack("H*", $kh->{dP})), + dq => encode_b64u(pack("H*", $kh->{dQ})), + qi => encode_b64u(pack("H*", $kh->{qP})), + }; + return $wanthash ? $hash : _encode_json($hash); + } + elsif ($type eq 'public') { + return unless $kh->{N} && $kh->{e}; + for (qw/N e/) { + $kh->{$_} = "0$kh->{$_}" if length($kh->{$_}) % 2; + } + my $hash = { + kty => "RSA", + n => encode_b64u(pack("H*", $kh->{N})), + e => encode_b64u(pack("H*", $kh->{e})), + }; + return $wanthash ? $hash : _encode_json($hash); + } +} + +sub export_key_jwk_thumbprint { + my ($self, $hash_name) = @_; + $hash_name ||= 'SHA256'; + my $h = $self->export_key_jwk('public', 1); + my $json = _encode_json({kty=>$h->{kty}, n=>$h->{n}, e=>$h->{e}}); + return digest_data_b64u($hash_name, $json); +} + +sub import_key { + my ($self, $key, $password) = @_; + croak "FATAL: undefined key" unless $key; + + # special case + if (ref($key) eq 'HASH') { + if ($key->{N} && $key->{e}) { + # hash exported via key2hash + return $self->_import_hex($key->{N}, $key->{e}, $key->{d}, $key->{p}, $key->{q}, $key->{dP}, $key->{dQ}, $key->{qP}); + } + if ($key->{n} && $key->{e} && $key->{kty} && $key->{kty} eq "RSA") { + $key = {%$key}; #make a copy so that the modifications below stay local + + # hash with items corresponding to JSON Web Key (JWK) + for (qw/n e d p q dp dq qi/) { + $key->{$_} = eval { unpack("H*", decode_b64u($key->{$_})) } if exists $key->{$_}; + } + return $self->_import_hex($key->{n}, $key->{e}, $key->{d}, $key->{p}, $key->{q}, $key->{dp}, $key->{dq}, $key->{qi}); + } + croak "FATAL: unexpected RSA key hash"; + } + + my $data; + if (ref($key) eq 'SCALAR') { + $data = $$key; + } + elsif (-f $key) { + $data = read_rawfile($key); + } + else { + croak "FATAL: non-existing file '$key'"; + } + croak "FATAL: invalid key data" unless $data; + + if ($data =~ /-----BEGIN (RSA PRIVATE|RSA PUBLIC|PUBLIC) KEY-----(.*?)-----END/sg) { + # PKCS#1 RSAPublicKey (PEM header: BEGIN RSA PUBLIC KEY) + # PKCS#1 RSAPrivateKey (PEM header: BEGIN RSA PRIVATE KEY) + # X.509 SubjectPublicKeyInfo (PEM header: BEGIN PUBLIC KEY) + $data = pem_to_der($data, $password); + return $self->_import($data) if $data; + } + elsif ($data =~ /-----BEGIN PRIVATE KEY-----(.*?)-----END/sg) { + # PKCS#8 PrivateKeyInfo (PEM header: BEGIN PRIVATE KEY) + $data = pem_to_der($data, $password); + return $self->_import_pkcs8($data) if $data; + } + elsif ($data =~ /-----BEGIN ENCRYPTED PRIVATE KEY-----(.*?)-----END/sg) { + # XXX-TODO: PKCS#8 EncryptedPrivateKeyInfo (PEM header: BEGIN ENCRYPTED PRIVATE KEY) + croak "FATAL: encrypted pkcs8 RSA private keys are not supported"; + } + elsif ($data =~ /^\s*(\{.*?\})\s*$/s) { + # JSON Web Key (JWK) - http://tools.ietf.org/html/draft-ietf-jose-json-web-key + my $json = "$1"; + my $h = _decode_json($json); + if ($h && $h->{kty} eq "RSA") { + for (qw/n e d p q dp dq qi/) { + $h->{$_} = eval { unpack("H*", decode_b64u($h->{$_})) } if exists $h->{$_}; + } + return $self->_import_hex($h->{n}, $h->{e}, $h->{d}, $h->{p}, $h->{q}, $h->{dp}, $h->{dq}, $h->{qi}) if $h->{n} && $h->{e}; + } + } + elsif ($data =~ /---- BEGIN SSH2 PUBLIC KEY ----(.*?)---- END SSH2 PUBLIC KEY ----/sg) { + $data = pem_to_der($data); + my ($typ, $N, $e) = Crypt::PK::_ssh_parse($data); + return $self->_import_hex(unpack("H*", $e), unpack("H*", $N)) if $typ && $e && $N && $typ eq 'ssh-rsa'; + } + elsif ($data =~ /ssh-rsa\s+(\S+)/) { + $data = decode_b64("$1"); + my ($typ, $N, $e) = Crypt::PK::_ssh_parse($data); + return $self->_import_hex(unpack("H*", $e), unpack("H*", $N)) if $typ && $e && $N && $typ eq 'ssh-rsa'; + } + else { + # DER format + my $rv = eval { $self->_import($data) } || eval { $self->_import_pkcs8($data) }; + return $rv if $rv; + } + + croak "FATAL: invalid or unsupported RSA key format"; +} + +sub encrypt { + my ($self, $data, $padding, $hash_name, $lparam) = @_; + $lparam ||= ''; + $padding ||= 'oaep'; + $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); + + return $self->_encrypt($data, $padding, $hash_name, $lparam); +} + +sub decrypt { + my ($self, $data, $padding, $hash_name, $lparam) = @_; + $lparam ||= ''; + $padding ||= 'oaep'; + $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); + + return $self->_decrypt($data, $padding, $hash_name, $lparam); +} + +sub sign_hash { + my ($self, $data, $hash_name, $padding, $saltlen) = @_; + $saltlen ||= 12; + $padding ||= 'pss'; + $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); + + return $self->_sign($data, $padding, $hash_name, $saltlen); +} + +sub sign_message { + my ($self, $data, $hash_name, $padding, $saltlen) = @_; + $saltlen ||= 12; + $padding ||= 'pss'; + $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); + + return $self->_sign(digest_data($hash_name, $data), $padding, $hash_name, $saltlen); +} + +sub verify_hash { + my ($self, $sig, $data, $hash_name, $padding, $saltlen) = @_; + $saltlen ||= 12; + $padding ||= 'pss'; + $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); + + return $self->_verify($sig, $data, $padding, $hash_name, $saltlen); +} + +sub verify_message { + my ($self, $sig, $data, $hash_name, $padding, $saltlen) = @_; + $saltlen ||= 12; + $padding ||= 'pss'; + $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); + + return $self->_verify($sig, digest_data($hash_name, $data), $padding, $hash_name, $saltlen); +} + +### FUNCTIONS + +sub rsa_encrypt { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->encrypt(@_); +} + +sub rsa_decrypt { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->decrypt(@_); +} + +sub rsa_sign_hash { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->sign_hash(@_); +} + +sub rsa_verify_hash { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->verify_hash(@_); +} + +sub rsa_sign_message { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->sign_message(@_); +} + +sub rsa_verify_message { + my $key = shift; + $key = __PACKAGE__->new($key) unless ref $key; + carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; + return $key->verify_message(@_); +} + +sub CLONE_SKIP { 1 } # prevent cloning + +1; + +=pod + +=head1 NAME + +Crypt::PK::RSA - Public key cryptography based on RSA + +=head1 SYNOPSIS + + ### OO interface + + #Encryption: Alice + my $pub = Crypt::PK::RSA->new('Bob_pub_rsa1.der'); + my $ct = $pub->encrypt("secret message"); + # + #Encryption: Bob (received ciphertext $ct) + my $priv = Crypt::PK::RSA->new('Bob_priv_rsa1.der'); + my $pt = $priv->decrypt($ct); + + #Signature: Alice + my $priv = Crypt::PK::RSA->new('Alice_priv_rsa1.der'); + my $sig = $priv->sign_message($message); + # + #Signature: Bob (received $message + $sig) + my $pub = Crypt::PK::RSA->new('Alice_pub_rsa1.der'); + $pub->verify_message($sig, $message) or die "ERROR"; + + #Key generation + my $pk = Crypt::PK::RSA->new(); + $pk->generate_key(256, 65537); + my $private_der = $pk->export_key_der('private'); + my $public_der = $pk->export_key_der('public'); + my $private_pem = $pk->export_key_pem('private'); + my $public_pem = $pk->export_key_pem('public'); + + ### Functional interface + + #Encryption: Alice + my $ct = rsa_encrypt('Bob_pub_rsa1.der', "secret message"); + #Encryption: Bob (received ciphertext $ct) + my $pt = rsa_decrypt('Bob_priv_rsa1.der', $ct); + + #Signature: Alice + my $sig = rsa_sign_message('Alice_priv_rsa1.der', $message); + #Signature: Bob (received $message + $sig) + rsa_verify_message('Alice_pub_rsa1.der', $sig, $message) or die "ERROR"; + +=head1 DESCRIPTION + +The module provides a full featured RSA implementation. + +=head1 METHODS + +=head2 new + + my $pk = Crypt::PK::RSA->new(); + #or + my $pk = Crypt::PK::RSA->new($priv_or_pub_key_filename); + #or + my $pk = Crypt::PK::RSA->new(\$buffer_containing_priv_or_pub_key); + +Support for password protected PEM keys + + my $pk = Crypt::PK::RSA->new($priv_pem_key_filename, $password); + #or + my $pk = Crypt::PK::RSA->new(\$buffer_containing_priv_pem_key, $password); + +=head2 generate_key + +Uses Yarrow-based cryptographically strong random number generator seeded with +random data taken from C (UNIX) or C (Win32). + + $pk->generate_key($size, $e); + # $size .. key size: 128-512 bytes (DEFAULT is 256) + # $e ..... exponent: 3, 17, 257 or 65537 (DEFAULT is 65537) + +=head2 import_key + +Loads private or public key in DER or PEM format. + + $pk->import_key($priv_or_pub_key_filename); + #or + $pk->import_key(\$buffer_containing_priv_or_pub_key); + +Support for password protected PEM keys + + $pk->import_key($pem_filename, $password); + #or + $pk->import_key(\$buffer_containing_pem_key, $password); + +Loading private or public keys form perl hash: + + $pk->import_key($hashref); + + # the $hashref is either a key exported via key2hash + $pk->import_key({ + e => "10001", #public exponent + d => "9ED5C3D3F866E06957CA0E9478A273C39BBDA4EEAC5B...", #private exponent + N => "D0A5CCCAE03DF9C2F5C4C8C0CE840D62CDE279990DC6...", #modulus + p => "D3EF0028FFAB508E2773C659E428A80FB0E9211346B4...", #p factor of N + q => "FC07E46B163CAB6A83B8E467D169534B2077DCDEECAE...", #q factor of N + qP => "88C6D406F833DF73C8B734548E0385261AD51F4187CF...", #1/q mod p CRT param + dP => "486F142FEF0A1F53269AC43D2EE4D263E2841B60DA36...", #d mod (p - 1) CRT param + dQ => "4597284B2968B72C4212DB7E8F24360B987B80514DA9...", #d mod (q - 1) CRT param + }); + + # or a hash with items corresponding to JWK (JSON Web Key) + $pk->import_key({ + { + kty => "RSA", + n => "0vx7agoebGcQSuuPiLJXZpt...eZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw", + e => "AQAB", + d => "X4cTteJY_gn4FYPsXB8rdXi...FLN5EEaG6RoVH-HLKD9Mdx5ooGURknhnrRwUkC7h5fJLMWbFAKLWY2v7B6NqSzUvx0_YSf", + p => "83i-7IvMGXoMXCskv73TKr8...Z27zvoj6pbUQyLPBQxtPnwD20-60eTmD2ujMt5PoMrm8RmNhVWtjjMmMjOpSicFHjXOuVI", + q => "3dfOR9cuYq-0S-mkFLzgItg...q3hWeMuG0ouqnb3obLyuqjVZQ1dIrdgTnCdYzBcOW5r37AFXjift_NGiovonzhKpoVVS78", + dp => "G4sPXkc6Ya9y8oJW9_ILj4...zi_H7TkS8x5SdX3oE0oiYwxIiemTAu0UOa5pgFGyJ4c8t2VF40XRugKTP8akhFo5tA77Qe", + dq => "s9lAH9fggBsoFR8Oac2R_E...T2kGOhvIllTE1efA6huUvMfBcpn8lqW6vzzYY5SSF7pMd_agI3G8IbpBUb0JiraRNUfLhc", + qi => "GyM_p6JrXySiz1toFgKbWV...4ypu9bMWx3QJBfm0FoYzUIZEVEcOqwmRN81oDAaaBk0KWGDjJHDdDmFW3AN7I-pux_mHZG", + }); + +Supported key formats: + + # all formats can be loaded from a file + my $pk = Crypt::PK::RSA->new($filename); + + # or from a buffer containing the key + my $pk = Crypt::PK::RSA->new(\$buffer_with_key); + +=over + +=item * RSA public keys + + -----BEGIN PUBLIC KEY----- + MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHlYKg9DeHB3/dY1D9WCyJTnl5 + vEzAXpUOL9tDtdPUl96brIbbdMLooO1hKjsq98kLs1q4vOn/pxvzk0BRwhiu7Vvb + VUjAn/2HHDDL0U1utqqlMJhaffeLI3HEq5o/lSMFY7sSkZU/E4YX1yqAN0SE7xfK + B2uzcNq60sMIfp6siQIDAQAB + -----END PUBLIC KEY----- + +=item * RSA private keys + + -----BEGIN RSA PRIVATE KEY----- + MIICXQIBAAKBgQDHlYKg9DeHB3/dY1D9WCyJTnl5vEzAXpUOL9tDtdPUl96brIbb + dMLooO1hKjsq98kLs1q4vOn/pxvzk0BRwhiu7VvbVUjAn/2HHDDL0U1utqqlMJha + ffeLI3HEq5o/lSMFY7sSkZU/E4YX1yqAN0SE7xfKB2uzcNq60sMIfp6siQIDAQAB + AoGBAI5+GgNcGQDYw9uF+t7FwxZM5sGZRJrbbEPyuvL+sDxKKW6voKCyHi4EJzaF + 9jRZMDqgVJcsmUwjPPuMGBHHJ+MI5Zb3L0jbZkyx8u+U5gf88oy9eZmfGOjmHcMB + oCgzyoLmJETuyADg2onLanuY3jggFb3tq/jimKjO8xM2R6zhAkEA7uXWWyJI9cCN + zrVt5R5v6oosjZ4r5VILGMqBRLrzfTvH+WDMK6Rl/2MHE+YDeLajzunaM8qY2456 + GTYEXQsIdQJBANXfMEtXocSdPtoVj3ME8Do/0r+ApgTdcDPCwXOzkmkEJW/UFMSn + b8CYF5G6sZQN9L5z3s2nvi55PaFV8Q0LMUUCQBh9GvIQm6YFbQPpeTBpZFOIgnSp + 6BoDxPtvlryy5U7LF/6qO4OlwIbjYdBaXbS8FCKbujBg7jZjboSzEtNu1BkCQDGT + w0Yz0jQZn3A+fzpScr2N/fSWheWqz0+wXdfMUKw3YdZCe236wlUK7KvDc1a2xX1A + ru1NbTCoujikC3TSm2ECQQDKQshchJlZJmFv9vCFQlGCA/EX+4406xvOOiixbPYC + pIB4Ee2cmvEdAqSaOjrvgs5zvaCCFBO0MecPStCAxUX6 + -----END RSA PRIVATE KEY----- + +=item * RSA private keys in password protected PEM format + + -----BEGIN RSA PRIVATE KEY----- + Proc-Type: 4,ENCRYPTED + DEK-Info: DES-EDE3-CBC,4D697440FF5AEF18 + + C09H49Gn99o8b8O2r4+Hqao4r3udvC+QSSfsk20sXatyuZSEmbhyqKAB+13NRj+3 + KIsRTqnL9VkeibIGgLHuekOFKAqeSVZ0PmR4bGWEFxUPAYUvg9N9pIa6hGtNZG+y + TEpOAfFITb1pbHQhp3j8y7qmKc5kY5LrZSFE8WwA24NTG773E07wJgRxKDkXNGOl + kki6oYArNEps0DdtHFxzgdRg0+yaotXuFJRuC5V4YzKGG/oSRcgYyXKTwCndb3xt + aHgI2WprQAPg+qOpLABzoi7bEjCqbHWrwkvnAngylbim2Uyvw1e1xKnzlgIHU7pv + e/J+s00pTItfqW1IpY2mh4C9nkfkfVKBKaAv7jO0s6aPySATqsdlrzv2kpF6Ub4J + kgaZDOfZ4K3qkyAYVLWcQeDqg4glv9Ah2J05bTm4qrIMmthYnThyQlGvcjUfCMXs + 0t+mEQbsRY7xKt0o6HzzvQlJ+JsFlLORoslAubJX9iLqpEdnlrj1lD9bo6uIClZ5 + 5+aoLcAyz1D4OsauuP5i8VFu+Is+QG4SN/vHVuArjkqi3VpLwSAjNDY+KWbq042l + CqlM2mwm6FIGUZQFxiLHJD7WDmk1xmae++m+XG9CEDTfrUQ5v+l0O6BTrl80XUfU + w3gzAWbSjz3UK0FpKeABVFPE9fjNP9fTcS6qL5YJWBPflwxCAbVgsBOW4bOMpDGK + BJDQTeShWn4BlYCe/vgThI9ERdgZhRz4NcFeDgVA/CqQzVqptvz4PSqH46fqUN2n + 4PtJgKE5cASYUBuAjlD71FecSVVM/OTzL1uxYzXBilzvVn2vSHgo9g== + -----END RSA PRIVATE KEY----- + +=item * PKCS#8 encoded private keys + + -----BEGIN PRIVATE KEY----- + MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBANPN17xW4EkH5PXG + 1i/i3rE1EXFcCHyxmz95VRBDs1p3MuYf9mxntbfYAmuzS3KrRWh3IyX/Eh80N/v9 + OXPlwZbVqSTX+L3pCEJtRtsWn0zmswGThjMZiwle0oWuap63L35F1QN8EDaSPSBC + yGELNRr6rwVYq0w5b+LOcaCZ+/H1AgMBAAECgYEApfu3aGpww+rC3HUhX0+ckyTy + cXLdV9LbxidwqRlVEb0+DyfXNucjelp2sy5EHy3na9GJovo8mmWSxhCRGKliRkQ6 + XgrEMZdCSaWI2AazuHAGlUJRFEVkvdla3AuBAn6y0YdDp/3kbg0yahmKyD8Gq74z + nUYbDL3R5JtR2Ad/KlUCQQDvSEICTHbO/BF7hVmlKRYZSNHKEPrv8X/OlppS14Kv + QRwc+CZ5+l6T1Y+l5cHJQUXrXZoWS1K741TXdUhjjUd7AkEA4pod804Ex8sttdWi + pHMfeyj+IbPAk5XnBc91jT7AYIeL8ccjtfl99xhMsGFaxrh3wA/4SGEvwzWkbxcq + H8G5TwJAKNG+0P2SVwURRm0dOdukdXPCtiHnbP9Zujhe4zr4hEUrMpXymmRntfh8 + pORpBpgoAVraams3Fe5WDttnGfSD+QJAOOC6V9HjfUrQhG3FT0XeRwm5EDiQQ/tC + a8DxHqz7mL8tL1ju68ReC+G7jiJBqNOwqzLW/UP3uyYByiikWChGHQJAHUau7jIM + 45ErO096n94Vh95p76ANxOroWszOt39TyvJOykIfoPwFagLrBWV9Jjos2/D54KE+ + fyoy4t3yHT+/nw== + -----END PRIVATE KEY----- + +=item * PKCS#8 encrypted private keys ARE NOT SUPPORTED YET! + + -----BEGIN ENCRYPTED PRIVATE KEY----- + MIICojAcBgoqhkiG9w0BDAEDMA4ECCQk+Rr1yzzcAgIIAASCAoD/mgpUFjxxM/Ty + Yt+NeT0Fo4echgoGksqs6+rYhO16oshG664emZfkuNoFGGzJ38X6GVuqIXhlPnYQ + biKvL37dN/KnoGytFHq9Wnk8dDwjGHPtwajhW5WuIV3NuhW/AO1PF/cRZKFjWrPt + NWY5CrpfH6t6zojoe+5uyXpH29lQy4OqvSRdPIt/12UcB+tzV7XzSWEuXh8HAi8a + sYUu6tuCFnq4GrD2ffM4KWFmL5GqBAwN6m0KkyrNni9XT+RaA6zEhv/lVcwg2esa + 4/EzRs0ixzzZDKaml8oCMl9RHtFAbQmdlfV7Ip4rGK9BwY6UFiDMIVru6HynOVQK + vvZ+j//bgO+3ubrv7psX+vC9Fy/MoH2Tc7MIwDN/QVTciPZlzjWBnBNxMfeFKtEn + d7NFiapgfLuRQIiDTMrW/clcqvO54NphxhrcgUEoxos4twKZARntqPZHtf8nEM2x + 2sEF5kI65aEF/5Yy16qvP0vZAA2B1kcIdXZ8XLZCp4c3olhkIrmgUpo1gyFXdCoC + 7dT5Cz7/YLkq5hkcFrtp4V9BZMR24fSttc4p24N5xuZ+JneGnGkLX6B+nJAtm9vw + bZA6P+23GI0qeMzL3HJXwCOTSsWfm/H9W5+2Zmw851aAmE+pZLni/pk3e3iNSWgs + 946x/doA5O0uCFsU7oxme+WAIp2SjhxGoe808Lf1CCFMPboFi1O/E0NsX8SIEX+i + U+UHi4kxZqVkr3Q5SB/9kiSv8K1bE787yueQOT/dsTYYaMsjAbkEZo0o/47F32T6 + A2ioXHOV/pr5zNHqE5tL+qKEcLYbAUF1O+WvmdqYz+vHQjRQBatAqTmncvLDYr/j + 1HPwZX2d + -----END ENCRYPTED PRIVATE KEY----- + +=item * SSH public RSA keys + + ssh-rsa AAAAB3NzaC1yc2EAAAADAQA...6mdYs5iJNGu/ltUdc= + +=item * SSH public RSA keys (RFC-4716 format) + + ---- BEGIN SSH2 PUBLIC KEY ---- + Comment: "768-bit RSA, converted from OpenSSH" + AAAAB3NzaC1yc2EAAAADAQABAAAAYQDYebeGQFCnlQiNRE7r9UEbjr+DQMTdw1ZHGB2w6x + D/DzKem8761GdCpqsLrGaw2D7aSIoP1B5Sz870YoVWHn6Ao7Hvm17V3Kxfn4B01GNQTM5+ + L26mdYs5iJNGu/ltUdc= + ---- END SSH2 PUBLIC KEY ---- + +=item * RSA private keys in JSON Web Key (JWK) format + +See L + + { + "kty":"RSA", + "n":"0vx7agoebGcQSuuPiLJXZpt...eZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw", + "e":"AQAB", + "d":"X4cTteJY_gn4FYPsXB8rdXi...FLN5EEaG6RoVH-HLKD9Mdx5ooGURknhnrRwUkC7h5fJLMWbFAKLWY2v7B6NqSzUvx0_YSf", + "p":"83i-7IvMGXoMXCskv73TKr8...Z27zvoj6pbUQyLPBQxtPnwD20-60eTmD2ujMt5PoMrm8RmNhVWtjjMmMjOpSicFHjXOuVI", + "q":"3dfOR9cuYq-0S-mkFLzgItg...q3hWeMuG0ouqnb3obLyuqjVZQ1dIrdgTnCdYzBcOW5r37AFXjift_NGiovonzhKpoVVS78", + "dp":"G4sPXkc6Ya9y8oJW9_ILj4...zi_H7TkS8x5SdX3oE0oiYwxIiemTAu0UOa5pgFGyJ4c8t2VF40XRugKTP8akhFo5tA77Qe", + "dq":"s9lAH9fggBsoFR8Oac2R_E...T2kGOhvIllTE1efA6huUvMfBcpn8lqW6vzzYY5SSF7pMd_agI3G8IbpBUb0JiraRNUfLhc", + "qi":"GyM_p6JrXySiz1toFgKbWV...4ypu9bMWx3QJBfm0FoYzUIZEVEcOqwmRN81oDAaaBk0KWGDjJHDdDmFW3AN7I-pux_mHZG", + } + +B For JWK support you need to have L, L or L module. + +=item * RSA public keys in JSON Web Key (JWK) format + + { + "kty":"RSA", + "n": "0vx7agoebGcQSuuPiLJXZp...tN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECP", + "e":"AQAB", + } + +B For JWK support you need to have L, L or L module. + +=back + +=head2 export_key_der + + my $private_der = $pk->export_key_der('private'); + #or + my $public_der = $pk->export_key_der('public'); + +=head2 export_key_pem + + my $private_pem = $pk->export_key_pem('private'); + #or + my $public_pem = $pk->export_key_pem('public'); + #or + my $public_pem = $pk->export_key_pem('public_x509'); + +With parameter C<'public'> uses header and footer lines: + + -----BEGIN RSA PUBLIC KEY------ + -----END RSA PUBLIC KEY------ + +With parameter C<'public_x509'> uses header and footer lines: + + -----BEGIN PUBLIC KEY------ + -----END PUBLIC KEY------ + +Support for password protected PEM keys + + my $private_pem = $pk->export_key_pem('private', $password); + #or + my $private_pem = $pk->export_key_pem('private', $password, $cipher); + + # supported ciphers: 'DES-CBC' + # 'DES-EDE3-CBC' + # 'SEED-CBC' + # 'CAMELLIA-128-CBC' + # 'CAMELLIA-192-CBC' + # 'CAMELLIA-256-CBC' + # 'AES-128-CBC' + # 'AES-192-CBC' + # 'AES-256-CBC' (DEFAULT) + +=head2 export_key_jwk + +I + +Exports public/private keys as a JSON Web Key (JWK). + + my $private_json_text = $pk->export_key_jwk('private'); + #or + my $public_json_text = $pk->export_key_jwk('public'); + +Also exports public/private keys as a perl HASH with JWK structure. + + my $jwk_hash = $pk->export_key_jwk('private', 1); + #or + my $jwk_hash = $pk->export_key_jwk('public', 1); + +B For JWK support you need to have L, L or L module. + +=head2 export_key_jwk_thumbprint + +I + +Exports the key's JSON Web Key Thumbprint as a string. + +If you don't know what this is, see RFC 7638 (C). + + my $thumbprint = $pk->export_key_jwk_thumbprint('SHA256'); + +=head2 encrypt + + my $pk = Crypt::PK::RSA->new($pub_key_filename); + my $ct = $pk->encrypt($message); + #or + my $ct = $pk->encrypt($message, $padding); + #or + my $ct = $pk->encrypt($message, 'oaep', $hash_name, $lparam); + + # $padding .................... 'oaep' (DEFAULT), 'v1.5' or 'none' (INSECURE) + # $hash_name (only for oaep) .. 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + # $lparam (only for oaep) ..... DEFAULT is empty string + +=head2 decrypt + + my $pk = Crypt::PK::RSA->new($priv_key_filename); + my $pt = $pk->decrypt($ciphertext); + #or + my $pt = $pk->decrypt($ciphertext, $padding); + #or + my $pt = $pk->decrypt($ciphertext, 'oaep', $hash_name, $lparam); + + # $padding .................... 'oaep' (DEFAULT), 'v1.5' or 'none' (INSECURE) + # $hash_name (only for oaep) .. 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + # $lparam (only for oaep) ..... DEFAULT is empty string + +=head2 sign_message + + my $pk = Crypt::PK::RSA->new($priv_key_filename); + my $signature = $priv->sign_message($message); + #or + my $signature = $priv->sign_message($message, $hash_name); + #or + my $signature = $priv->sign_message($message, $hash_name, $padding); + #or + my $signature = $priv->sign_message($message, $hash_name, 'pss', $saltlen); + + # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + # $padding ................. 'pss' (DEFAULT) or 'v1.5' or 'none' (INSECURE) + # $saltlen (only for pss) .. DEFAULT is 12 + +=head2 verify_message + + my $pk = Crypt::PK::RSA->new($pub_key_filename); + my $valid = $pub->verify_message($signature, $message); + #or + my $valid = $pub->verify_message($signature, $message, $hash_name); + #or + my $valid = $pub->verify_message($signature, $message, $hash_name, $padding); + #or + my $valid = $pub->verify_message($signature, $message, $hash_name, 'pss', $saltlen); + + # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + # $padding ................. 'pss' (DEFAULT) or 'v1.5' or 'none' (INSECURE) + # $saltlen (only for pss) .. DEFAULT is 12 + +=head2 sign_hash + + my $pk = Crypt::PK::RSA->new($priv_key_filename); + my $signature = $priv->sign_hash($message_hash); + #or + my $signature = $priv->sign_hash($message_hash, $hash_name); + #or + my $signature = $priv->sign_hash($message_hash, $hash_name, $padding); + #or + my $signature = $priv->sign_hash($message_hash, $hash_name, 'pss', $saltlen); + + # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + # $padding ................. 'pss' (DEFAULT) or 'v1.5' or 'none' (INSECURE) + # $saltlen (only for pss) .. DEFAULT is 12 + +=head2 verify_hash + + my $pk = Crypt::PK::RSA->new($pub_key_filename); + my $valid = $pub->verify_hash($signature, $message_hash); + #or + my $valid = $pub->verify_hash($signature, $message_hash, $hash_name); + #or + my $valid = $pub->verify_hash($signature, $message_hash, $hash_name, $padding); + #or + my $valid = $pub->verify_hash($signature, $message_hash, $hash_name, 'pss', $saltlen); + + # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + # $padding ................. 'pss' (DEFAULT) or 'v1.5' or 'none' (INSECURE) + # $saltlen (only for pss) .. DEFAULT is 12 + +=head2 is_private + + my $rv = $pk->is_private; + # 1 .. private key loaded + # 0 .. public key loaded + # undef .. no key loaded + +=head2 size + + my $size = $pk->size; + # returns key size in bytes or undef if no key loaded + +=head2 key2hash + + my $hash = $pk->key2hash; + + # returns hash like this (or undef if no key loaded): + { + type => 1, # integer: 1 .. private, 0 .. public + size => 256, # integer: key size in bytes + # all the rest are hex strings + e => "10001", #public exponent + d => "9ED5C3D3F866E06957CA0E9478A273C39BBDA4EEAC5B...", #private exponent + N => "D0A5CCCAE03DF9C2F5C4C8C0CE840D62CDE279990DC6...", #modulus + p => "D3EF0028FFAB508E2773C659E428A80FB0E9211346B4...", #p factor of N + q => "FC07E46B163CAB6A83B8E467D169534B2077DCDEECAE...", #q factor of N + qP => "88C6D406F833DF73C8B734548E0385261AD51F4187CF...", #1/q mod p CRT param + dP => "486F142FEF0A1F53269AC43D2EE4D263E2841B60DA36...", #d mod (p - 1) CRT param + dQ => "4597284B2968B72C4212DB7E8F24360B987B80514DA9...", #d mod (q - 1) CRT param + } + +=head1 FUNCTIONS + +=head2 rsa_encrypt + +RSA based encryption. See method L below. + + my $ct = rsa_encrypt($pub_key_filename, $message); + #or + my $ct = rsa_encrypt(\$buffer_containing_pub_key, $message); + #or + my $ct = rsa_encrypt($pub_key, $message, $padding); + #or + my $ct = rsa_encrypt($pub_key, $message, 'oaep', $hash_name, $lparam); + + # $padding .................... 'oaep' (DEFAULT), 'v1.5' or 'none' (INSECURE) + # $hash_name (only for oaep) .. 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + # $lparam (only for oaep) ..... DEFAULT is empty string + +=head2 rsa_decrypt + +RSA based decryption. See method L below. + + my $pt = rsa_decrypt($priv_key_filename, $ciphertext); + #or + my $pt = rsa_decrypt(\$buffer_containing_priv_key, $ciphertext); + #or + my $pt = rsa_decrypt($priv_key, $ciphertext, $padding); + #or + my $pt = rsa_decrypt($priv_key, $ciphertext, 'oaep', $hash_name, $lparam); + + # $padding .................... 'oaep' (DEFAULT), 'v1.5' or 'none' (INSECURE) + # $hash_name (only for oaep) .. 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + # $lparam (only for oaep) ..... DEFAULT is empty string + +=head2 rsa_sign_message + +Generate RSA signature. See method L below. + + my $sig = rsa_sign_message($priv_key_filename, $message); + #or + my $sig = rsa_sign_message(\$buffer_containing_priv_key, $message); + #or + my $sig = rsa_sign_message($priv_key, $message, $hash_name); + #or + my $sig = rsa_sign_message($priv_key, $message, $hash_name, $padding); + #or + my $sig = rsa_sign_message($priv_key, $message, $hash_name, 'pss', $saltlen); + + # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + # $padding ................. 'pss' (DEFAULT) or 'v1.5' or 'none' (INSECURE) + # $saltlen (only for pss) .. DEFAULT is 12 + +=head2 rsa_verify_message + +Verify RSA signature. See method L below. + + rsa_verify_message($pub_key_filename, $signature, $message) or die "ERROR"; + #or + rsa_verify_message(\$buffer_containing_pub_key, $signature, $message) or die "ERROR"; + #or + rsa_verify_message($pub_key, $signature, $message, $hash_name) or die "ERROR"; + #or + rsa_verify_message($pub_key, $signature, $message, $hash_name, $padding) or die "ERROR"; + #or + rsa_verify_message($pub_key, $signature, $message, $hash_name, 'pss', $saltlen) or die "ERROR"; + + # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + # $padding ................. 'pss' (DEFAULT) or 'v1.5' or 'none' (INSECURE) + # $saltlen (only for pss) .. DEFAULT is 12 + +=head2 rsa_sign_hash + +Generate RSA signature. See method L below. + + my $sig = rsa_sign_hash($priv_key_filename, $message_hash); + #or + my $sig = rsa_sign_hash(\$buffer_containing_priv_key, $message_hash); + #or + my $sig = rsa_sign_hash($priv_key, $message_hash, $hash_name); + #or + my $sig = rsa_sign_hash($priv_key, $message_hash, $hash_name, $padding); + #or + my $sig = rsa_sign_hash($priv_key, $message_hash, $hash_name, 'pss', $saltlen); + + # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + # $padding ................. 'pss' (DEFAULT) or 'v1.5' or 'none' (INSECURE) + # $saltlen (only for pss) .. DEFAULT is 12 + +=head2 rsa_verify_hash + +Verify RSA signature. See method L below. + + rsa_verify_hash($pub_key_filename, $signature, $message_hash) or die "ERROR"; + #or + rsa_verify_hash(\$buffer_containing_pub_key, $signature, $message_hash) or die "ERROR"; + #or + rsa_verify_hash($pub_key, $signature, $message_hash, $hash_name) or die "ERROR"; + #or + rsa_verify_hash($pub_key, $signature, $message_hash, $hash_name, $padding) or die "ERROR"; + #or + rsa_verify_hash($pub_key, $signature, $message_hash, $hash_name, 'pss', $saltlen) or die "ERROR"; + + # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest + # $padding ................. 'pss' (DEFAULT) or 'v1.5' or 'none' (INSECURE) + # $saltlen (only for pss) .. DEFAULT is 12 + +=head1 OpenSSL interoperability + + ### let's have: + # RSA private key in PEM format - rsakey.priv.pem + # RSA public key in PEM format - rsakey.pub.pem + # data file to be signed or encrypted - input.data + +=head2 Encrypt by OpenSSL, decrypt by Crypt::PK::RSA + +Create encrypted file (from commandline): + + openssl rsautl -encrypt -inkey rsakey.pub.pem -pubin -out input.encrypted.rsa -in input.data + +Decrypt file (Perl code): + + use Crypt::PK::RSA; + use File::Slurp 'read_file'; + + my $pkrsa = Crypt::PK::RSA->new("rsakey.priv.pem"); + my $encfile = read_file("input.encrypted.rsa", binmode=>':raw'); + my $plaintext = $pkrsa->decrypt($encfile, 'v1.5'); + print $plaintext; + +=head2 Encrypt by Crypt::PK::RSA, decrypt by OpenSSL + +Create encrypted file (Perl code): + + use Crypt::PK::RSA; + use File::Slurp 'write_file'; + + my $plaintext = 'secret message'; + my $pkrsa = Crypt::PK::RSA->new("rsakey.pub.pem"); + my $encrypted = $pkrsa->encrypt($plaintext, 'v1.5'); + write_file("input.encrypted.rsa", {binmode=>':raw'}, $encrypted); + +Decrypt file (from commandline): + + openssl rsautl -decrypt -inkey rsakey.priv.pem -in input.encrypted.rsa + +=head2 Sign by OpenSSL, verify by Crypt::PK::RSA + +Create signature (from commandline): + + openssl dgst -sha1 -sign rsakey.priv.pem -out input.sha1-rsa.sig input.data + +Verify signature (Perl code): + + use Crypt::PK::RSA; + use Crypt::Digest 'digest_file'; + use File::Slurp 'read_file'; + + my $pkrsa = Crypt::PK::RSA->new("rsakey.pub.pem"); + my $signature = read_file("input.sha1-rsa.sig", binmode=>':raw'); + my $valid = $pkrsa->verify_hash($signature, digest_file("SHA1", "input.data"), "SHA1", "v1.5"); + print $valid ? "SUCCESS" : "FAILURE"; + +=head2 Sign by Crypt::PK::RSA, verify by OpenSSL + +Create signature (Perl code): + + use Crypt::PK::RSA; + use Crypt::Digest 'digest_file'; + use File::Slurp 'write_file'; + + my $pkrsa = Crypt::PK::RSA->new("rsakey.priv.pem"); + my $signature = $pkrsa->sign_hash(digest_file("SHA1", "input.data"), "SHA1", "v1.5"); + write_file("input.sha1-rsa.sig", {binmode=>':raw'}, $signature); + +Verify signature (from commandline): + + openssl dgst -sha1 -verify rsakey.pub.pem -signature input.sha1-rsa.sig input.data + +=head2 Keys generated by Crypt::PK::RSA + +Generate keys (Perl code): + + use Crypt::PK::RSA; + use File::Slurp 'write_file'; + + my $pkrsa = Crypt::PK::RSA->new; + $pkrsa->generate_key(256, 65537); + write_file("rsakey.pub.der", {binmode=>':raw'}, $pkrsa->export_key_der('public')); + write_file("rsakey.priv.der", {binmode=>':raw'}, $pkrsa->export_key_der('private')); + write_file("rsakey.pub.pem", $pkrsa->export_key_pem('public_x509')); + write_file("rsakey.priv.pem", $pkrsa->export_key_pem('private')); + write_file("rsakey-passwd.priv.pem", $pkrsa->export_key_pem('private', 'secret')); + +Use keys by OpenSSL: + + openssl rsa -in rsakey.priv.der -text -inform der + openssl rsa -in rsakey.priv.pem -text + openssl rsa -in rsakey-passwd.priv.pem -text -inform pem -passin pass:secret + openssl rsa -in rsakey.pub.der -pubin -text -inform der + openssl rsa -in rsakey.pub.pem -pubin -text + +=head2 Keys generated by OpenSSL + +Generate keys: + + openssl genrsa -out rsakey.priv.pem 1024 + openssl rsa -in rsakey.priv.pem -out rsakey.priv.der -outform der + openssl rsa -in rsakey.priv.pem -out rsakey.pub.pem -pubout + openssl rsa -in rsakey.priv.pem -out rsakey.pub.der -outform der -pubout + openssl rsa -in rsakey.priv.pem -passout pass:secret -des3 -out rsakey-passwd.priv.pem + +Load keys (Perl code): + + use Crypt::PK::RSA; + use File::Slurp 'write_file'; + + my $pkrsa = Crypt::PK::RSA->new; + $pkrsa->import_key("rsakey.pub.der"); + $pkrsa->import_key("rsakey.priv.der"); + $pkrsa->import_key("rsakey.pub.pem"); + $pkrsa->import_key("rsakey.priv.pem"); + $pkrsa->import_key("rsakey-passwd.priv.pem", "secret"); + +=head1 SEE ALSO + +=over + +=item * L + +=back diff --git a/lib/Crypt/PRNG.pm b/lib/Crypt/PRNG.pm new file mode 100644 index 0000000..ae14afa --- /dev/null +++ b/lib/Crypt/PRNG.pm @@ -0,0 +1,283 @@ +package Crypt::PRNG; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Exporter); +our %EXPORT_TAGS = ( all => [qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand)] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +#BEWARE: cannot use Crypt::Misc qw(encode_b64 encode_b64u); +use CryptX; + +sub _trans_prng_name { + my $name = shift; + $name =~ s/^Crypt::PRNG:://; + return lc($name); +} + +### METHODS + +sub new { + my $pkg = shift; + my $prng_name = $pkg eq __PACKAGE__ ? _trans_prng_name(shift||'ChaCha20') : _trans_prng_name($pkg); + return _new($$, $prng_name, @_); +} + +sub bytes { return shift->_bytes($$, shift) } + +sub int32 { return shift->_int32($$) } + +sub double { return shift->_double($$, shift) } + +sub bytes_hex { return unpack("H*", shift->bytes(shift)) } + +sub bytes_b64 { return CryptX::_encode_base64(shift->bytes(shift)) } + +sub bytes_b64u { return CryptX::_encode_base64url(shift->bytes(shift)) } + +sub string { + my ($self, $len) = @_; + return $self->string_from("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", $len); +} + +sub string_from { + my ($self, $chars, $len) = @_; + + $len = 20 unless defined $len; + return unless $len > 0; + return unless length($chars) > 0; + + my @ch = split(//, $chars); + my $max_index = $#ch; + return if $max_index > 65535; + + my $mask; + for my $n (1..31) { + $mask = (1<<$n) - 1; + last if $mask >= $max_index; + } + + my $upck = ($max_index > 255) ? "n*" : "C*"; + my $l = $len * 2; + + my $rv = ''; + my @r; + while (length $rv < $len) { + @r = unpack($upck, $self->bytes($l)) if scalar @r == 0; + my $i = (shift @r) & $mask; + next if $i > $max_index; + $rv .= $ch[$i]; + } + return $rv; +} + +sub CLONE_SKIP { 1 } # prevent cloning + +### FUNCTIONS + +{ + ### stolen from Bytes::Random::Secure + # + # Instantiate our random number generator(s) inside of a lexical closure, + # limiting the scope of the RNG object so it can't be tampered with. + my $RNG_object = undef; + my $fetch_RNG = sub { # Lazily, instantiate the RNG object, but only once. + $RNG_object = Crypt::PRNG->new unless defined $RNG_object && ref($RNG_object) ne 'SCALAR'; + return $RNG_object; + }; + sub rand(;$) { return $fetch_RNG->()->double(@_) } + sub irand() { return $fetch_RNG->()->int32() } + sub random_bytes($) { return $fetch_RNG->()->bytes(@_) } + sub random_bytes_hex($) { return $fetch_RNG->()->bytes_hex(@_) } + sub random_bytes_b64($) { return $fetch_RNG->()->bytes_b64(@_) } + sub random_bytes_b64u($) { return $fetch_RNG->()->bytes_b64u(@_) } + sub random_string_from($;$) { return $fetch_RNG->()->string_from(@_) } + sub random_string(;$) { return $fetch_RNG->()->string(@_) } +} + +1; + +=pod + +=head1 NAME + +Crypt::PRNG - Cryptographically secure random number generator + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::PRNG qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u + random_string random_string_from rand irand); + + $octets = random_bytes(45); + $hex_string = random_bytes_hex(45); + $base64_string = random_bytes_b64(45); + $base64url_string = random_bytes_b64u(45); + $alphanumeric_string = random_string(30); + $string = random_string_from('ACGT', 64); + $floating_point_number_0_to_1 = rand; + $floating_point_number_0_to_88 = rand(88); + $unsigned_32bit_int = irand; + + ### OO interface: + use Crypt::PRNG; + + $prng = Crypt::PRNG->new; + #or + $prng = Crypt::PRNG->new("RC4"); + #or + $prng = Crypt::PRNG->new("RC4", "some data used for seeding PRNG"); + + $octets = $prng->bytes(45); + $hex_string = $prng->bytes_hex(45); + $base64_string = $prng->bytes_b64(45); + $base64url_string = $prng->bytes_b64u(45); + $alphanumeric_string = $prng->string(30); + $string = $prng->string_from('ACGT', 64); + $floating_point_number_0_to_1 = $prng->double; + $floating_point_number_0_to_88 = $prng->double(88); + $unsigned_32bit_int = $prng->int32; + +=head1 DESCRIPTION + +Provides an interface to the ChaCha20 based pseudo random number generator (thread-safe and fork-safe). + +=head1 FUNCTIONS + +=head2 random_bytes + + $octets = random_bytes($length); + +Returns C<$length> random octects. + +=head2 random_bytes_hex + + $hex_string = random_bytes_hex($length); + +Returns C<$length> random octects encoded as hexadecimal string. + +=head2 random_bytes_b64 + + $base64_string = random_bytes_b64($length); + +Returns C<$length> random octects Base64 encoded. + +=head2 random_bytes_b64u + + $base64url_string = random_bytes_b64u($length); + +Returns C<$length> random octects Base64 URL Safe (RFC 4648 section 5) encoded. + +=head2 random_string_from + + $string = random_string_from($range, $length); + #e.g. + $string = random_string_from("ABCD", 10); + +Returns a random string made of C<$length> chars randomly chosen from C<$range> string. + +=head2 random_string + + $alphanumeric_string = random_string($length); + #or + $alphanumeric_string = random_string; # default length = 20 + +Similar to random_string_from, only C<$range> is fixed to C<'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'>. + +=head2 rand + + $n = rand; + #or + $n = rand($limit); + +Returns a random floating point number from range C<[0,1)> (if called without param) or C<[0,$limit)>. + +=head2 irand + + $i = irand; + +Returns a random unsigned 32bit integer - range 0 .. 0xFFFFFFFF. + +=head1 METHODS + +=head2 new + + $prng = Crypt::PRNG->new; + #or + $prng = Crypt::PRNG->new($alg); + #or + $prng = Crypt::PRNG->new($alg, $seed); + + # $alg ... algorithm name 'Frotuna' (DEFAULT), 'RC4', 'Sober128' or 'Yarrow' + # $seed ... will be used as an initial entropy for seeding PRNG + +If C<$seed> is not specified the PRNG is automatically seeded with 32bytes random data taken from C (UNIX) or C (Win32) + +=head2 add_entropy + + $prng->add_entropy($random_data); + #or + $prng->add_entropy(); + +If called without parameter it uses 32bytes random data taken from C (UNIX) or C (Win32). + +B you probably do not need this function at all as the module does automatic seeding on initialization as well as reseeding after fork and thread creation. + +=head2 bytes + + $octets = $prng->bytes($length); + +See L + +=head2 bytes_hex + + $hex_string = $prng->bytes_hex($length); + +See L + +=head2 bytes_b64 + + $base64_string = $prng->bytes_b64($length); + +See L + +=head2 bytes_b64u + + $base64url_string = $prng->bytes_b64u($length); + +See L + +=head2 string + + $alphanumeric_string = $prng->string($length); + #or + $alphanumeric_string = $prng->string; + +See L + +=head2 string_from + + $string = $prng->string_from($range, $length); + +See L + +=head2 double + + $n = $prng->double; + #or + $n = $prng->double($limit); + +See L + +=head2 int32 + + $i = $prng->int32; + +See L + +=head1 SEE ALSO + +L, L, L, L \ No newline at end of file diff --git a/lib/Crypt/PRNG/ChaCha20.pm b/lib/Crypt/PRNG/ChaCha20.pm new file mode 100644 index 0000000..b9ef777 --- /dev/null +++ b/lib/Crypt/PRNG/ChaCha20.pm @@ -0,0 +1,159 @@ +package Crypt::PRNG::ChaCha20; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::PRNG Exporter); +our %EXPORT_TAGS = ( all => [qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand)] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +use base 'Crypt::PRNG'; + +{ + ### stolen from Bytes::Random::Secure + my $RNG_object = undef; + my $fetch_RNG = sub { # Lazily, instantiate the RNG object, but only once. + $RNG_object = Crypt::PRNG::ChaCha20->new unless defined $RNG_object && ref($RNG_object) ne 'SCALAR'; + return $RNG_object; + }; + sub rand { return $fetch_RNG->()->double(@_) } + sub irand { return $fetch_RNG->()->int32(@_) } + sub random_bytes { return $fetch_RNG->()->bytes(@_) } + sub random_bytes_hex { return $fetch_RNG->()->bytes_hex(@_) } + sub random_bytes_b64 { return $fetch_RNG->()->bytes_b64(@_) } + sub random_bytes_b64u { return $fetch_RNG->()->bytes_b64u(@_) } + sub random_string_from { return $fetch_RNG->()->string_from(@_) } + sub random_string { return $fetch_RNG->()->string(@_) } +} + + +1; + +=pod + +=head1 NAME + +Crypt::PRNG::ChaCha20 - Cryptographically secure PRNG based on ChaCha20 (stream cipher) algorithm + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::PRNG::ChaCha20 qw(random_bytes random_bytes_hex random_bytes_b64 random_string random_string_from rand irand); + + $octets = random_bytes(45); + $hex_string = random_bytes_hex(45); + $base64_string = random_bytes_b64(45); + $base64url_string = random_bytes_b64u(45); + $alphanumeric_string = random_string(30); + $string = random_string_from('ACGT', 64); + $floating_point_number_0_to_1 = rand; + $floating_point_number_0_to_88 = rand(88); + $unsigned_32bit_int = irand; + + ### OO interface: + use Crypt::PRNG::ChaCha20; + + $prng = Crypt::PRNG::ChaCha20->new; + #or + $prng = Crypt::PRNG::ChaCha20->new("some data used for seeding PRNG"); + + $octets = $prng->bytes(45); + $hex_string = $prng->bytes_hex(45); + $base64_string = $prng->bytes_b64(45); + $base64url_string = $prng->bytes_b64u(45); + $alphanumeric_string = $prng->string(30); + $string = $prng->string_from('ACGT', 64); + $floating_point_number_0_to_1 = rand; + $floating_point_number_0_to_88 = rand(88); + $unsigned_32bit_int = irand; + +=head1 DESCRIPTION + +Provides an interface to the ChaCha20 based pseudo random number generator + +All methods and functions are the same as for L. + +=head1 FUNCTIONS + +=head2 random_bytes + +See L. + +=head2 random_bytes_hex + +See L. + +=head2 random_bytes_b64 + +See L. + +=head2 random_bytes_b64u + +See L. + +=head2 random_string + +See L. + +=head2 random_string_from + +See L. + +=head2 rand + +See L. + +=head2 irand + +See L. + +=head1 METHODS + +=head2 new + +See L. + +=head2 bytes + +See L. + +=head2 bytes_hex + +See L. + +=head2 bytes_b64 + +See L. + +=head2 bytes_b64u + +See L. + +=head2 string + +See L. + +=head2 string_from + +See L. + +=head2 double + +See L. + +=head2 int32 + +See L. + +=head1 SEE ALSO + +=over + +=item * L + +=item * L + +=back diff --git a/lib/Crypt/PRNG/Fortuna.pm b/lib/Crypt/PRNG/Fortuna.pm new file mode 100644 index 0000000..5ef5029 --- /dev/null +++ b/lib/Crypt/PRNG/Fortuna.pm @@ -0,0 +1,160 @@ +package Crypt::PRNG::Fortuna; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::PRNG Exporter); +our %EXPORT_TAGS = ( all => [qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand)] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +use base 'Crypt::PRNG'; + +{ + ### stolen from Bytes::Random::Secure + my $RNG_object = undef; + my $fetch_RNG = sub { # Lazily, instantiate the RNG object, but only once. + $RNG_object = Crypt::PRNG::Fortuna->new unless defined $RNG_object && ref($RNG_object) ne 'SCALAR'; + return $RNG_object; + }; + sub rand { return $fetch_RNG->()->double(@_) } + sub irand { return $fetch_RNG->()->int32(@_) } + sub random_bytes { return $fetch_RNG->()->bytes(@_) } + sub random_bytes_hex { return $fetch_RNG->()->bytes_hex(@_) } + sub random_bytes_b64 { return $fetch_RNG->()->bytes_b64(@_) } + sub random_bytes_b64u { return $fetch_RNG->()->bytes_b64u(@_) } + sub random_string_from { return $fetch_RNG->()->string_from(@_) } + sub random_string { return $fetch_RNG->()->string(@_) } +} + + +1; + +=pod + +=head1 NAME + +Crypt::PRNG::Fortuna - Cryptographically secure PRNG based on Fortuna algorithm + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::PRNG::Fortuna qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u + random_string random_string_from rand irand); + + $octets = random_bytes(45); + $hex_string = random_bytes_hex(45); + $base64_string = random_bytes_b64(45); + $base64url_string = random_bytes_b64u(45); + $alphanumeric_string = random_string(30); + $string = random_string_from('ACGT', 64); + $floating_point_number_0_to_1 = rand; + $floating_point_number_0_to_88 = rand(88); + $unsigned_32bit_int = irand; + + ### OO interface: + use Crypt::PRNG::Fortuna; + + $prng = Crypt::PRNG::Fortuna->new; + #or + $prng = Crypt::PRNG::Fortuna->new("some data used for seeding PRNG"); + + $octets = $prng->bytes(45); + $hex_string = $prng->bytes_hex(45); + $base64_string = $prng->bytes_b64(45); + $base64url_string = $prng->bytes_b64u(45); + $alphanumeric_string = $prng->string(30); + $string = $prng->string_from('ACGT', 64); + $floating_point_number_0_to_1 = rand; + $floating_point_number_0_to_88 = rand(88); + $unsigned_32bit_int = irand; + +=head1 DESCRIPTION + +Provides an interface to the Fortuna based pseudo random number generator + +All methods and functions are the same as for L. + +=head1 FUNCTIONS + +=head2 random_bytes + +See L. + +=head2 random_bytes_hex + +See L. + +=head2 random_bytes_b64 + +See L. + +=head2 random_bytes_b64u + +See L. + +=head2 random_string + +See L. + +=head2 random_string_from + +See L. + +=head2 rand + +See L. + +=head2 irand + +See L. + +=head1 METHODS + +=head2 new + +See L. + +=head2 bytes + +See L. + +=head2 bytes_hex + +See L. + +=head2 bytes_b64 + +See L. + +=head2 bytes_b64u + +See L. + +=head2 string + +See L. + +=head2 string_from + +See L. + +=head2 double + +See L. + +=head2 int32 + +See L. + +=head1 SEE ALSO + +=over + +=item * L + +=item * L + +=back diff --git a/lib/Crypt/PRNG/RC4.pm b/lib/Crypt/PRNG/RC4.pm new file mode 100644 index 0000000..fa5d622 --- /dev/null +++ b/lib/Crypt/PRNG/RC4.pm @@ -0,0 +1,159 @@ +package Crypt::PRNG::RC4; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::PRNG Exporter); +our %EXPORT_TAGS = ( all => [qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand)] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +use base 'Crypt::PRNG'; + +{ + ### stolen from Bytes::Random::Secure + my $RNG_object = undef; + my $fetch_RNG = sub { # Lazily, instantiate the RNG object, but only once. + $RNG_object = Crypt::PRNG::RC4->new unless defined $RNG_object && ref($RNG_object) ne 'SCALAR'; + return $RNG_object; + }; + sub rand { return $fetch_RNG->()->double(@_) } + sub irand { return $fetch_RNG->()->int32(@_) } + sub random_bytes { return $fetch_RNG->()->bytes(@_) } + sub random_bytes_hex { return $fetch_RNG->()->bytes_hex(@_) } + sub random_bytes_b64 { return $fetch_RNG->()->bytes_b64(@_) } + sub random_bytes_b64u { return $fetch_RNG->()->bytes_b64u(@_) } + sub random_string_from { return $fetch_RNG->()->string_from(@_) } + sub random_string { return $fetch_RNG->()->string(@_) } +} + + +1; + +=pod + +=head1 NAME + +Crypt::PRNG::RC4 - Cryptographically secure PRNG based on RC4 (stream cipher) algorithm + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::PRNG::RC4 qw(random_bytes random_bytes_hex random_bytes_b64 random_string random_string_from rand irand); + + $octets = random_bytes(45); + $hex_string = random_bytes_hex(45); + $base64_string = random_bytes_b64(45); + $base64url_string = random_bytes_b64u(45); + $alphanumeric_string = random_string(30); + $string = random_string_from('ACGT', 64); + $floating_point_number_0_to_1 = rand; + $floating_point_number_0_to_88 = rand(88); + $unsigned_32bit_int = irand; + + ### OO interface: + use Crypt::PRNG::RC4; + + $prng = Crypt::PRNG::RC4->new; + #or + $prng = Crypt::PRNG::RC4->new("some data used for seeding PRNG"); + + $octets = $prng->bytes(45); + $hex_string = $prng->bytes_hex(45); + $base64_string = $prng->bytes_b64(45); + $base64url_string = $prng->bytes_b64u(45); + $alphanumeric_string = $prng->string(30); + $string = $prng->string_from('ACGT', 64); + $floating_point_number_0_to_1 = rand; + $floating_point_number_0_to_88 = rand(88); + $unsigned_32bit_int = irand; + +=head1 DESCRIPTION + +Provides an interface to the RC4 based pseudo random number generator + +All methods and functions are the same as for L. + +=head1 FUNCTIONS + +=head2 random_bytes + +See L. + +=head2 random_bytes_hex + +See L. + +=head2 random_bytes_b64 + +See L. + +=head2 random_bytes_b64u + +See L. + +=head2 random_string + +See L. + +=head2 random_string_from + +See L. + +=head2 rand + +See L. + +=head2 irand + +See L. + +=head1 METHODS + +=head2 new + +See L. + +=head2 bytes + +See L. + +=head2 bytes_hex + +See L. + +=head2 bytes_b64 + +See L. + +=head2 bytes_b64u + +See L. + +=head2 string + +See L. + +=head2 string_from + +See L. + +=head2 double + +See L. + +=head2 int32 + +See L. + +=head1 SEE ALSO + +=over + +=item * L + +=item * L + +=back diff --git a/lib/Crypt/PRNG/Sober128.pm b/lib/Crypt/PRNG/Sober128.pm new file mode 100644 index 0000000..b27230f --- /dev/null +++ b/lib/Crypt/PRNG/Sober128.pm @@ -0,0 +1,159 @@ +package Crypt::PRNG::Sober128; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::PRNG Exporter); +our %EXPORT_TAGS = ( all => [qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand)] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; +use base 'Crypt::PRNG'; + +{ + ### stolen from Bytes::Random::Secure + my $RNG_object = undef; + my $fetch_RNG = sub { # Lazily, instantiate the RNG object, but only once. + $RNG_object = Crypt::PRNG::Sober128->new unless defined $RNG_object && ref($RNG_object) ne 'SCALAR'; + return $RNG_object; + }; + sub rand { return $fetch_RNG->()->double(@_) } + sub irand { return $fetch_RNG->()->int32(@_) } + sub random_bytes { return $fetch_RNG->()->bytes(@_) } + sub random_bytes_hex { return $fetch_RNG->()->bytes_hex(@_) } + sub random_bytes_b64 { return $fetch_RNG->()->bytes_b64(@_) } + sub random_bytes_b64u { return $fetch_RNG->()->bytes_b64u(@_) } + sub random_string_from { return $fetch_RNG->()->string_from(@_) } + sub random_string { return $fetch_RNG->()->string(@_) } +} + + +1; + +=pod + +=head1 NAME + +Crypt::PRNG::Sober128 - Cryptographically secure PRNG based on Sober128 (stream cipher) algorithm + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::PRNG::Sober128 qw(random_bytes random_bytes_hex random_bytes_b64 random_string random_string_from rand irand); + + $octets = random_bytes(45); + $hex_string = random_bytes_hex(45); + $base64_string = random_bytes_b64(45); + $base64url_string = random_bytes_b64u(45); + $alphanumeric_string = random_string(30); + $string = random_string_from('ACGT', 64); + $floating_point_number_0_to_1 = rand; + $floating_point_number_0_to_88 = rand(88); + $unsigned_32bit_int = irand; + + ### OO interface: + use Crypt::PRNG::Sober128; + + $prng = Crypt::PRNG::Sober128->new; + #or + $prng = Crypt::PRNG::Sober128->new("some data used for seeding PRNG"); + + $octets = $prng->bytes(45); + $hex_string = $prng->bytes_hex(45); + $base64_string = $prng->bytes_b64(45); + $base64url_string = $prng->bytes_b64u(45); + $alphanumeric_string = $prng->string(30); + $string = $prng->string_from('ACGT', 64); + $floating_point_number_0_to_1 = rand; + $floating_point_number_0_to_88 = rand(88); + $unsigned_32bit_int = irand; + +=head1 DESCRIPTION + +Provides an interface to the Sober128 based pseudo random number generator + +All methods and functions are the same as for L. + +=head1 FUNCTIONS + +=head2 random_bytes + +See L. + +=head2 random_bytes_hex + +See L. + +=head2 random_bytes_b64 + +See L. + +=head2 random_bytes_b64u + +See L. + +=head2 random_string + +See L. + +=head2 random_string_from + +See L. + +=head2 rand + +See L. + +=head2 irand + +See L. + +=head1 METHODS + +=head2 new + +See L. + +=head2 bytes + +See L. + +=head2 bytes_hex + +See L. + +=head2 bytes_b64 + +See L. + +=head2 bytes_b64u + +See L. + +=head2 string + +See L. + +=head2 string_from + +See L. + +=head2 double + +See L. + +=head2 int32 + +See L. + +=head1 SEE ALSO + +=over + +=item * L + +=item * L + +=back diff --git a/lib/Crypt/PRNG/Yarrow.pm b/lib/Crypt/PRNG/Yarrow.pm new file mode 100644 index 0000000..3a04bef --- /dev/null +++ b/lib/Crypt/PRNG/Yarrow.pm @@ -0,0 +1,158 @@ +package Crypt::PRNG::Yarrow; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use base qw(Crypt::PRNG Exporter); +our %EXPORT_TAGS = ( all => [qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand)] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use CryptX; + +{ + ### stolen from Bytes::Random::Secure + my $RNG_object = undef; + my $fetch_RNG = sub { # Lazily, instantiate the RNG object, but only once. + $RNG_object = Crypt::PRNG::Yarrow->new unless defined $RNG_object && ref($RNG_object) ne 'SCALAR'; + return $RNG_object; + }; + sub rand { return $fetch_RNG->()->double(@_) } + sub irand { return $fetch_RNG->()->int32(@_) } + sub random_bytes { return $fetch_RNG->()->bytes(@_) } + sub random_bytes_hex { return $fetch_RNG->()->bytes_hex(@_) } + sub random_bytes_b64 { return $fetch_RNG->()->bytes_b64(@_) } + sub random_bytes_b64u { return $fetch_RNG->()->bytes_b64u(@_) } + sub random_string_from { return $fetch_RNG->()->string_from(@_) } + sub random_string { return $fetch_RNG->()->string(@_) } +} + + +1; + +=pod + +=head1 NAME + +Crypt::PRNG::Yarrow - Cryptographically secure PRNG based on Yarrow algorithm + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::PRNG::Yarrow qw(random_bytes random_bytes_hex random_bytes_b64 random_string random_string_from rand irand); + + $octets = random_bytes(45); + $hex_string = random_bytes_hex(45); + $base64_string = random_bytes_b64(45); + $base64url_string = random_bytes_b64u(45); + $alphanumeric_string = random_string(30); + $string = random_string_from('ACGT', 64); + $floating_point_number_0_to_1 = rand; + $floating_point_number_0_to_88 = rand(88); + $unsigned_32bit_int = irand; + + ### OO interface: + use Crypt::PRNG::Yarrow; + + $prng = Crypt::PRNG::Yarrow->new; + #or + $prng = Crypt::PRNG::Yarrow->new("some data used for seeding PRNG"); + + $octets = $prng->bytes(45); + $hex_string = $prng->bytes_hex(45); + $base64_string = $prng->bytes_b64(45); + $base64url_string = $prng->bytes_b64u(45); + $alphanumeric_string = $prng->string(30); + $string = $prng->string_from('ACGT', 64); + $floating_point_number_0_to_1 = rand; + $floating_point_number_0_to_88 = rand(88); + $unsigned_32bit_int = irand; + +=head1 DESCRIPTION + +Provides an interface to the Yarrow based pseudo random number generator + +All methods and functions are the same as for L. + +=head1 FUNCTIONS + +=head2 random_bytes + +See L. + +=head2 random_bytes_hex + +See L. + +=head2 random_bytes_b64 + +See L. + +=head2 random_bytes_b64u + +See L. + +=head2 random_string + +See L. + +=head2 random_string_from + +See L. + +=head2 rand + +See L. + +=head2 irand + +See L. + +=head1 METHODS + +=head2 new + +See L. + +=head2 bytes + +See L. + +=head2 bytes_hex + +See L. + +=head2 bytes_b64 + +See L. + +=head2 bytes_b64u + +See L. + +=head2 string + +See L. + +=head2 string_from + +See L. + +=head2 double + +See L. + +=head2 int32 + +See L. + +=head1 SEE ALSO + +=over + +=item * L + +=item * L + +=back diff --git a/lib/Crypt/Stream/ChaCha.pm b/lib/Crypt/Stream/ChaCha.pm new file mode 100644 index 0000000..bbdc7dd --- /dev/null +++ b/lib/Crypt/Stream/ChaCha.pm @@ -0,0 +1,76 @@ +package Crypt::Stream::ChaCha; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; + +sub new { my $class = shift; _new(@_) } + +1; + +=pod + +=head1 NAME + +Crypt::Stream::ChaCha - Stream cipher ChaCha + +=head1 SYNOPSIS + + use Crypt::Stream::ChaCha; + + # encrypt + $key = "1234567890123456"; + $iv = "123456789012"; + $stream = Crypt::Stream::ChaCha->new($key, $iv); + $ct = $stream->crypt("plain message"); + + # decrypt + $key = "1234567890123456"; + $iv = "123456789012"; + $stream = Crypt::Stream::ChaCha->new($key, $iv); + $pt = $stream->crypt($ct); + +=head1 DESCRIPTION + +Provides an interface to the ChaCha stream cipher. + +=head1 METHODS + +=head2 new + + $stream = Crypt::Stream::ChaCha->new($key, $iv); + #or + $stream = Crypt::Stream::ChaCha->new($key, $iv, $counter, $rounds); + + # $key .. 32 or 16 bytes + # $iv .. 8 or 12 bytes + # $counter .. initial counter value (DEFAULT: 0) + # $rounds .. rounds (DEFAULT: 20) + +=head2 crypt + + $ciphertext = $stream->crypt($plaintext); + #or + $plaintext = $stream->crypt($ciphertext); + +=head2 keystream + + $random_key = $stream->keystream($length); + +=head2 clone + + $stream->clone(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut diff --git a/lib/Crypt/Stream/RC4.pm b/lib/Crypt/Stream/RC4.pm new file mode 100644 index 0000000..c915686 --- /dev/null +++ b/lib/Crypt/Stream/RC4.pm @@ -0,0 +1,68 @@ +package Crypt::Stream::RC4; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; + +sub new { my $class = shift; _new(@_) } + +1; + +=pod + +=head1 NAME + +Crypt::Stream::RC4 - Stream cipher RC4 + +=head1 SYNOPSIS + + use Crypt::Stream::RC4; + + # encrypt + $key = "1234567890123456"; + $stream = Crypt::Stream::RC4->new($key); + $ct = $stream->crypt("plain message"); + + # decrypt + $key = "1234567890123456"; + $stream = Crypt::Stream::RC4->new($key); + $pt = $stream->crypt($ct); + +=head1 DESCRIPTION + +Provides an interface to the RC4 stream cipher. + +=head1 METHODS + +=head2 new + + $stream = Crypt::Stream::RC4->new($key); + # $key .. length 5-256 bytes (40 - 2048 bits) + +=head2 crypt + + $ciphertext = $stream->crypt($plaintext); + #or + $plaintext = $stream->crypt($ciphertext); + +=head2 keystream + + $random_key = $stream->keystream($length); + +=head2 clone + + $stream->clone(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut diff --git a/lib/Crypt/Stream/Sober128.pm b/lib/Crypt/Stream/Sober128.pm new file mode 100644 index 0000000..55366af --- /dev/null +++ b/lib/Crypt/Stream/Sober128.pm @@ -0,0 +1,71 @@ +package Crypt::Stream::Sober128; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; + +sub new { my $class = shift; _new(@_) } + +1; + +=pod + +=head1 NAME + +Crypt::Stream::Sober128 - Stream cipher Sober128 + +=head1 SYNOPSIS + + use Crypt::Stream::Sober128; + + # encrypt + $key = "1234567890123456"; + $iv = "123456789012"; + $stream = Crypt::Stream::Sober128->new($key, $iv); + $ct = $stream->crypt("plain message"); + + # decrypt + $key = "1234567890123456"; + $iv = "123456789012"; + $stream = Crypt::Stream::Sober128->new($key, $iv); + $pt = $stream->crypt($ct); + +=head1 DESCRIPTION + +Provides an interface to the Sober128 stream cipher. + +=head1 METHODS + +=head2 new + + $stream = Crypt::Stream::Sober128->new($key, $iv); + # $key .. keylen must be multiple of 4 bytes + # $iv .. ivlen must be multiple of 4 bytes + +=head2 crypt + + $ciphertext = $stream->crypt($plaintext); + #or + $plaintext = $stream->crypt($ciphertext); + +=head2 keystream + + $random_key = $stream->keystream($length); + +=head2 clone + + $stream->clone(); + +=head1 SEE ALSO + +=over + +=item * L, L + +=item * L + +=back + +=cut diff --git a/lib/CryptX.pm b/lib/CryptX.pm new file mode 100644 index 0000000..a0b8fa4 --- /dev/null +++ b/lib/CryptX.pm @@ -0,0 +1,114 @@ +package CryptX; + +use strict; +use warnings ; +our $VERSION = '0.048'; + +use base qw(Exporter); +our @EXPORT_OK = qw( _decode_json _encode_json); + +require XSLoader; +XSLoader::load('CryptX', $VERSION); + +use Carp; +my $has_json; + +BEGIN { + if (eval { require Cpanel::JSON::XS }) { + Cpanel::JSON::XS->import(qw(encode_json decode_json)); + $has_json = 1; + } + elsif (eval { require JSON::XS }) { + JSON::XS->import(qw(encode_json decode_json)); + $has_json = 2; + } + elsif (eval { require JSON::PP }) { + JSON::PP->import(qw(encode_json decode_json)); + $has_json = 3; + } + else { + $has_json = 0; + } +} + +sub _decode_json { + croak "FATAL: cannot find JSON::PP or JSON::XS or Cpanel::JSON::XS" if !$has_json; + decode_json(shift); +} + +sub _encode_json { + croak "FATAL: cannot find JSON::PP or JSON::XS or Cpanel::JSON::XS" if !$has_json; + my $data = shift; + my $rv = encode_json($data); # non-canonical fallback + return(eval { Cpanel::JSON::XS->new->canonical->encode($data) } || $rv) if $has_json == 1; + return(eval { JSON::XS->new->canonical->encode($data) } || $rv) if $has_json == 2; + return(eval { JSON::PP->new->canonical->encode($data) } || $rv) if $has_json == 3; + return($rv); +} + +1; +__END__ + +=head1 NAME + +CryptX - Crypto toolkit (self-contained no external libraries needed) + +=head1 DESCRIPTION + +Cryptography in CryptX is based on L + +Currently available modules: + +=over + +=item * Ciphers - see L and related modules + +L, L, L, L, L, L, +L, L, L, L, L, L, +L, L, L, L, L, L, +L, L, L, L, L + +=item * Block cipher modes + +L, L, L, L, L + +=item * Stream ciphers + +L, L, L + +=item * Authenticated encryption modes + +L, L, L, L, L + +=item * Hash Functions - see L and related modules + +L, L, L, L, L, L, +L, L, L, L, L, L, +L, L, L, L, L, +L, L, L, L, L + +=item * Message Authentication Codes + +L, L, L, L, L, L, L + +=item * Public key cryptography + +L, L, L, L + +=item * Cryptographically secure random number generators + +L, L, L, L, L, L + +=item * Key derivation functions - PBKDF1, PBKFD2 and HKDF + +L + +=back + +=head1 LICENSE + +This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. + +=head1 COPYRIGHT + +Copyright (c) 2013+ DCIT, a.s. L / Karel Miko \ No newline at end of file diff --git a/lib/Math/BigInt/LTM.pm b/lib/Math/BigInt/LTM.pm new file mode 100644 index 0000000..8a0caf1 --- /dev/null +++ b/lib/Math/BigInt/LTM.pm @@ -0,0 +1,463 @@ +package Math::BigInt::LTM; + +use strict; +use warnings; +our $VERSION = '0.048'; + +use CryptX; + +sub api_version() { 2 } + +sub CLONE_SKIP { 1 } # prevent cloning + +### same as overloading in Math::BigInt::Lib +use overload + # overload key: with_assign + + '+' => sub { + my $class = ref $_[0]; + my $x = $class -> _copy($_[0]); + my $y = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + return $class -> _add($x, $y); + }, + + '-' => sub { + my $class = ref $_[0]; + my ($x, $y); + if ($_[2]) { # if swapped + $y = $_[0]; + $x = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + } else { + $x = $class -> _copy($_[0]); + $y = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + } + return $class -> _sub($x, $y); + }, + + '*' => sub { + my $class = ref $_[0]; + my $x = $class -> _copy($_[0]); + my $y = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + return $class -> _mul($x, $y); + }, + + '/' => sub { + my $class = ref $_[0]; + my ($x, $y); + if ($_[2]) { # if swapped + $y = $_[0]; + $x = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + } else { + $x = $class -> _copy($_[0]); + $y = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + } + return $class -> _div($x, $y); + }, + + '%' => sub { + my $class = ref $_[0]; + my ($x, $y); + if ($_[2]) { # if swapped + $y = $_[0]; + $x = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + } else { + $x = $class -> _copy($_[0]); + $y = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + } + return $class -> _mod($x, $y); + }, + + '**' => sub { + my $class = ref $_[0]; + my ($x, $y); + if ($_[2]) { # if swapped + $y = $_[0]; + $x = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + } else { + $x = $class -> _copy($_[0]); + $y = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + } + return $class -> _pow($x, $y); + }, + + '<<' => sub { + my $class = ref $_[0]; + my ($x, $y); + if ($_[2]) { # if swapped + $y = $class -> _num($_[0]); + $x = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + } else { + $x = $_[0]; + $y = ref($_[1]) ? $class -> _num($_[1]) : $_[1]; + } + return $class -> _blsft($x, $y); + }, + + '>>' => sub { + my $class = ref $_[0]; + my ($x, $y); + if ($_[2]) { # if swapped + $y = $_[0]; + $x = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + } else { + $x = $class -> _copy($_[0]); + $y = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + } + return $class -> _brsft($x, $y); + }, + + # overload key: num_comparison + + '<' => sub { + my $class = ref $_[0]; + my ($x, $y); + if ($_[2]) { # if swapped + $y = $_[0]; + $x = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + } else { + $x = $class -> _copy($_[0]); + $y = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + } + return $class -> _acmp($x, $y) < 0; + }, + + '<=' => sub { + my $class = ref $_[0]; + my ($x, $y); + if ($_[2]) { # if swapped + $y = $_[0]; + $x = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + } else { + $x = $class -> _copy($_[0]); + $y = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + } + return $class -> _acmp($x, $y) <= 0; + }, + + '>' => sub { + my $class = ref $_[0]; + my ($x, $y); + if ($_[2]) { # if swapped + $y = $_[0]; + $x = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + } else { + $x = $class -> _copy($_[0]); + $y = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + } + return $class -> _acmp($x, $y) > 0; + }, + + '>=' => sub { + my $class = ref $_[0]; + my ($x, $y); + if ($_[2]) { # if swapped + $y = $_[0]; + $x = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + } else { + $x = $class -> _copy($_[0]); + $y = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + } + return $class -> _acmp($x, $y) >= 0; + }, + + '==' => sub { + my $class = ref $_[0]; + my $x = $class -> _copy($_[0]); + my $y = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + return $class -> _acmp($x, $y) == 0; + }, + + '!=' => sub { + my $class = ref $_[0]; + my $x = $class -> _copy($_[0]); + my $y = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + return $class -> _acmp($x, $y) != 0; + }, + + # overload key: 3way_comparison + + '<=>' => sub { + my $class = ref $_[0]; + my ($x, $y); + if ($_[2]) { # if swapped + $y = $_[0]; + $x = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + } else { + $x = $class -> _copy($_[0]); + $y = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + } + return $class -> _acmp($x, $y); + }, + + # overload key: binary + + '&' => sub { + my $class = ref $_[0]; + my ($x, $y); + if ($_[2]) { # if swapped + $y = $_[0]; + $x = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + } else { + $x = $class -> _copy($_[0]); + $y = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + } + return $class -> _and($x, $y); + }, + + '|' => sub { + my $class = ref $_[0]; + my ($x, $y); + if ($_[2]) { # if swapped + $y = $_[0]; + $x = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + } else { + $x = $class -> _copy($_[0]); + $y = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + } + return $class -> _or($x, $y); + }, + + '^' => sub { + my $class = ref $_[0]; + my ($x, $y); + if ($_[2]) { # if swapped + $y = $_[0]; + $x = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + } else { + $x = $class -> _copy($_[0]); + $y = ref($_[1]) ? $_[1] : $class -> _new($_[1]); + } + return $class -> _xor($x, $y); + }, + + # overload key: func + + 'abs' => sub { $_[0] }, + + 'sqrt' => sub { + my $class = ref $_[0]; + return $class -> _sqrt($class -> _copy($_[0])); + }, + + 'int' => sub { $_[0] -> copy() -> bint(); }, + + # overload key: conversion + + 'bool' => sub { ref($_[0]) -> _is_zero($_[0]) ? '' : 1; }, + + '""' => sub { ref($_[0]) -> _str($_[0]); }, + + '0+' => sub { ref($_[0]) -> _num($_[0]); }, + + '=' => sub { ref($_[0]) -> _copy($_[0]); }, + + ; + +### same as import() in Math::BigInt::Lib +sub import { } + +### same as _check() in Math::BigInt::Lib +sub _check { + # used by the test suite + my ($class, $x) = @_; + return "Input is undefined" unless defined $x; + return "$x is not a reference" unless ref($x); + return 0; +} + +### same as _digit() in Math::BigInt::Lib +sub _digit { + my ($class, $x, $n) = @_; + substr($class ->_str($x), -($n+1), 1); +} + +### same as _num() in Math::BigInt::Lib +sub _num { + my ($class, $x) = @_; + 0 + $class -> _str($x); +} + +### BEWARE!!! NOT THE SAME as _fac() in Math::BigInt::Lib +sub _fac { + # factorial + my ($class, $x) = @_; + + my $two = $class -> _two(); + + if ($class -> _acmp($x, $two) < 0) { + $class->_set($x, 1); + return $x; + } + + my $i = $class -> _copy($x); + while ($class -> _acmp($i, $two) > 0) { + $i = $class -> _dec($i); + $x = $class -> _mul($x, $i); + } + + return $x; +} + +### same as _nok() in Math::BigInt::Lib +sub _nok { + # Return binomial coefficient (n over k). + # Given refs to arrays, return ref to array. + # First input argument is modified. + + my ($class, $n, $k) = @_; + + # If k > n/2, or, equivalently, 2*k > n, compute nok(n, k) as + # nok(n, n-k), to minimize the number if iterations in the loop. + + { + my $twok = $class -> _mul($class -> _two(), $class -> _copy($k)); + if ($class -> _acmp($twok, $n) > 0) { + $k = $class -> _sub($class -> _copy($n), $k); + } + } + + # Example: + # + # / 7 \ 7! 1*2*3*4 * 5*6*7 5 * 6 * 7 6 7 + # | | = --------- = --------------- = --------- = 5 * - * - + # \ 3 / (7-3)! 3! 1*2*3*4 * 1*2*3 1 * 2 * 3 2 3 + + if ($class -> _is_zero($k)) { + return $class -> _one(); + } + + # Make a copy of the original n, since we'll be modifying n in-place. + + my $n_orig = $class -> _copy($n); + + # n = 5, f = 6, d = 2 (cf. example above) + + $n = $class -> _sub($n, $k); + $n = $class -> _inc($n); + + my $f = $class -> _copy($n); + $class -> _inc($f); + + my $d = $class -> _two(); + + # while f <= n (the original n, that is) ... + + while ($class -> _acmp($f, $n_orig) <= 0) { + + # n = (n * f / d) == 5 * 6 / 2 (cf. example above) + + $n = $class -> _mul($n, $f); + $n = $class -> _div($n, $d); + + # f = 7, d = 3 (cf. example above) + + $f = $class -> _inc($f); + $d = $class -> _inc($d); + } + + return $n; +} + +### same as _log_int() in Math::BigInt::Lib +sub _log_int { + # calculate integer log of $x to base $base + # ref to array, ref to array - return ref to array + my ($class, $x, $base) = @_; + + # X == 0 => NaN + return if $class -> _is_zero($x); + + $base = $class -> _new(2) unless defined($base); + $base = $class -> _new($base) unless ref($base); + + # BASE 0 or 1 => NaN + return if $class -> _is_zero($base) || $class -> _is_one($base); + + # X == 1 => 0 (is exact) + if ($class -> _is_one($x)) { + return $class -> _zero(), 1; + } + + my $cmp = $class -> _acmp($x, $base); + + # X == BASE => 1 (is exact) + if ($cmp == 0) { + return $class -> _one(), 1; + } + + # 1 < X < BASE => 0 (is truncated) + if ($cmp < 0) { + return $class -> _zero(), 0; + } + + my $y; + + # log(x) / log(b) = log(xm * 10^xe) / log(bm * 10^be) + # = (log(xm) + xe*(log(10))) / (log(bm) + be*log(10)) + + { + my $x_str = $class -> _str($x); + my $b_str = $class -> _str($base); + my $xm = "." . $x_str; + my $bm = "." . $b_str; + my $xe = length($x_str); + my $be = length($b_str); + my $log10 = log(10); + my $guess = int((log($xm) + $xe * $log10) / (log($bm) + $be * $log10)); + $y = $class -> _new($guess); + } + + my $trial = $class -> _pow($class -> _copy($base), $y); + my $acmp = $class -> _acmp($trial, $x); + + # Did we get the exact result? + + return $y, 1 if $acmp == 0; + + # Too small? + + while ($acmp < 0) { + $trial = $class -> _mul($trial, $base); + $y = $class -> _inc($y); + $acmp = $class -> _acmp($trial, $x); + } + + # Too big? + + while ($acmp > 0) { + $trial = $class -> _div($trial, $base); + $y = $class -> _dec($y); + $acmp = $class -> _acmp($trial, $x); + } + + return $y, 1 if $acmp == 0; # result is exact + return $y, 0; # result is too small +} + +1; + +__END__ + +=pod + +=head1 NAME + +Math::BigInt::LTM - Use the libtommath library for Math::BigInt routines + +=head1 SYNOPSIS + + use Math::BigInt lib => 'LTM'; + + ## See Math::BigInt docs for usage. + +=head1 DESCRIPTION + +Provides support for big integer calculations by means of the libtommath c-library. + +I + +=head1 SEE ALSO + +L, L + +=cut diff --git a/ppport.h b/ppport.h new file mode 100644 index 0000000..27f9aa7 --- /dev/null +++ b/ppport.h @@ -0,0 +1,7748 @@ +#if 0 +<<'SKIP'; +#endif +/* +---------------------------------------------------------------------- + + ppport.h -- Perl/Pollution/Portability Version 3.31 + + Automatically created by Devel::PPPort running under perl 5.018002. + + Do NOT edit this file directly! -- Edit PPPort_pm.PL and the + includes in parts/inc/ instead. + + Use 'perldoc ppport.h' to view the documentation below. + +---------------------------------------------------------------------- + +SKIP + +=pod + +=head1 NAME + +ppport.h - Perl/Pollution/Portability version 3.31 + +=head1 SYNOPSIS + + perl ppport.h [options] [source files] + + Searches current directory for files if no [source files] are given + + --help show short help + + --version show version + + --patch=file write one patch file with changes + --copy=suffix write changed copies with suffix + --diff=program use diff program and options + + --compat-version=version provide compatibility with Perl version + --cplusplus accept C++ comments + + --quiet don't output anything except fatal errors + --nodiag don't show diagnostics + --nohints don't show hints + --nochanges don't suggest changes + --nofilter don't filter input files + + --strip strip all script and doc functionality from + ppport.h + + --list-provided list provided API + --list-unsupported list unsupported API + --api-info=name show Perl API portability information + +=head1 COMPATIBILITY + +This version of F is designed to support operation with Perl +installations back to 5.003, and has been tested up to 5.20. + +=head1 OPTIONS + +=head2 --help + +Display a brief usage summary. + +=head2 --version + +Display the version of F. + +=head2 --patch=I + +If this option is given, a single patch file will be created if +any changes are suggested. This requires a working diff program +to be installed on your system. + +=head2 --copy=I + +If this option is given, a copy of each file will be saved with +the given suffix that contains the suggested changes. This does +not require any external programs. Note that this does not +automagically add a dot between the original filename and the +suffix. If you want the dot, you have to include it in the option +argument. + +If neither C<--patch> or C<--copy> are given, the default is to +simply print the diffs for each file. This requires either +C or a C program to be installed. + +=head2 --diff=I + +Manually set the diff program and options to use. The default +is to use C, when installed, and output unified +context diffs. + +=head2 --compat-version=I + +Tell F to check for compatibility with the given +Perl version. The default is to check for compatibility with Perl +version 5.003. You can use this option to reduce the output +of F if you intend to be backward compatible only +down to a certain Perl version. + +=head2 --cplusplus + +Usually, F will detect C++ style comments and +replace them with C style comments for portability reasons. +Using this option instructs F to leave C++ +comments untouched. + +=head2 --quiet + +Be quiet. Don't print anything except fatal errors. + +=head2 --nodiag + +Don't output any diagnostic messages. Only portability +alerts will be printed. + +=head2 --nohints + +Don't output any hints. Hints often contain useful portability +notes. Warnings will still be displayed. + +=head2 --nochanges + +Don't suggest any changes. Only give diagnostic output and hints +unless these are also deactivated. + +=head2 --nofilter + +Don't filter the list of input files. By default, files not looking +like source code (i.e. not *.xs, *.c, *.cc, *.cpp or *.h) are skipped. + +=head2 --strip + +Strip all script and documentation functionality from F. +This reduces the size of F dramatically and may be useful +if you want to include F in smaller modules without +increasing their distribution size too much. + +The stripped F will have a C<--unstrip> option that allows +you to undo the stripping, but only if an appropriate C +module is installed. + +=head2 --list-provided + +Lists the API elements for which compatibility is provided by +F. Also lists if it must be explicitly requested, +if it has dependencies, and if there are hints or warnings for it. + +=head2 --list-unsupported + +Lists the API elements that are known not to be supported by +F and below which version of Perl they probably +won't be available or work. + +=head2 --api-info=I + +Show portability information for API elements matching I. +If I is surrounded by slashes, it is interpreted as a regular +expression. + +=head1 DESCRIPTION + +In order for a Perl extension (XS) module to be as portable as possible +across differing versions of Perl itself, certain steps need to be taken. + +=over 4 + +=item * + +Including this header is the first major one. This alone will give you +access to a large part of the Perl API that hasn't been available in +earlier Perl releases. Use + + perl ppport.h --list-provided + +to see which API elements are provided by ppport.h. + +=item * + +You should avoid using deprecated parts of the API. For example, using +global Perl variables without the C prefix is deprecated. Also, +some API functions used to have a C prefix. Using this form is +also deprecated. You can safely use the supported API, as F +will provide wrappers for older Perl versions. + +=item * + +If you use one of a few functions or variables that were not present in +earlier versions of Perl, and that can't be provided using a macro, you +have to explicitly request support for these functions by adding one or +more C<#define>s in your source code before the inclusion of F. + +These functions or variables will be marked C in the list shown +by C<--list-provided>. + +Depending on whether you module has a single or multiple files that +use such functions or variables, you want either C or global +variants. + +For a C function or variable (used only in a single source +file), use: + + #define NEED_function + #define NEED_variable + +For a global function or variable (used in multiple source files), +use: + + #define NEED_function_GLOBAL + #define NEED_variable_GLOBAL + +Note that you mustn't have more than one global request for the +same function or variable in your project. + + Function / Variable Static Request Global Request + ----------------------------------------------------------------------------------------- + PL_parser NEED_PL_parser NEED_PL_parser_GLOBAL + PL_signals NEED_PL_signals NEED_PL_signals_GLOBAL + caller_cx() NEED_caller_cx NEED_caller_cx_GLOBAL + eval_pv() NEED_eval_pv NEED_eval_pv_GLOBAL + grok_bin() NEED_grok_bin NEED_grok_bin_GLOBAL + grok_hex() NEED_grok_hex NEED_grok_hex_GLOBAL + grok_number() NEED_grok_number NEED_grok_number_GLOBAL + grok_numeric_radix() NEED_grok_numeric_radix NEED_grok_numeric_radix_GLOBAL + grok_oct() NEED_grok_oct NEED_grok_oct_GLOBAL + load_module() NEED_load_module NEED_load_module_GLOBAL + mg_findext() NEED_mg_findext NEED_mg_findext_GLOBAL + my_snprintf() NEED_my_snprintf NEED_my_snprintf_GLOBAL + my_sprintf() NEED_my_sprintf NEED_my_sprintf_GLOBAL + my_strlcat() NEED_my_strlcat NEED_my_strlcat_GLOBAL + my_strlcpy() NEED_my_strlcpy NEED_my_strlcpy_GLOBAL + newCONSTSUB() NEED_newCONSTSUB NEED_newCONSTSUB_GLOBAL + newRV_noinc() NEED_newRV_noinc NEED_newRV_noinc_GLOBAL + newSV_type() NEED_newSV_type NEED_newSV_type_GLOBAL + newSVpvn_flags() NEED_newSVpvn_flags NEED_newSVpvn_flags_GLOBAL + newSVpvn_share() NEED_newSVpvn_share NEED_newSVpvn_share_GLOBAL + pv_display() NEED_pv_display NEED_pv_display_GLOBAL + pv_escape() NEED_pv_escape NEED_pv_escape_GLOBAL + pv_pretty() NEED_pv_pretty NEED_pv_pretty_GLOBAL + sv_2pv_flags() NEED_sv_2pv_flags NEED_sv_2pv_flags_GLOBAL + sv_2pvbyte() NEED_sv_2pvbyte NEED_sv_2pvbyte_GLOBAL + sv_catpvf_mg() NEED_sv_catpvf_mg NEED_sv_catpvf_mg_GLOBAL + sv_catpvf_mg_nocontext() NEED_sv_catpvf_mg_nocontext NEED_sv_catpvf_mg_nocontext_GLOBAL + sv_pvn_force_flags() NEED_sv_pvn_force_flags NEED_sv_pvn_force_flags_GLOBAL + sv_setpvf_mg() NEED_sv_setpvf_mg NEED_sv_setpvf_mg_GLOBAL + sv_setpvf_mg_nocontext() NEED_sv_setpvf_mg_nocontext NEED_sv_setpvf_mg_nocontext_GLOBAL + sv_unmagicext() NEED_sv_unmagicext NEED_sv_unmagicext_GLOBAL + vload_module() NEED_vload_module NEED_vload_module_GLOBAL + vnewSVpvf() NEED_vnewSVpvf NEED_vnewSVpvf_GLOBAL + warner() NEED_warner NEED_warner_GLOBAL + +To avoid namespace conflicts, you can change the namespace of the +explicitly exported functions / variables using the C +macro. Just C<#define> the macro before including C: + + #define DPPP_NAMESPACE MyOwnNamespace_ + #include "ppport.h" + +The default namespace is C. + +=back + +The good thing is that most of the above can be checked by running +F on your source code. See the next section for +details. + +=head1 EXAMPLES + +To verify whether F is needed for your module, whether you +should make any changes to your code, and whether any special defines +should be used, F can be run as a Perl script to check your +source code. Simply say: + + perl ppport.h + +The result will usually be a list of patches suggesting changes +that should at least be acceptable, if not necessarily the most +efficient solution, or a fix for all possible problems. + +If you know that your XS module uses features only available in +newer Perl releases, if you're aware that it uses C++ comments, +and if you want all suggestions as a single patch file, you could +use something like this: + + perl ppport.h --compat-version=5.6.0 --cplusplus --patch=test.diff + +If you only want your code to be scanned without any suggestions +for changes, use: + + perl ppport.h --nochanges + +You can specify a different C program or options, using +the C<--diff> option: + + perl ppport.h --diff='diff -C 10' + +This would output context diffs with 10 lines of context. + +If you want to create patched copies of your files instead, use: + + perl ppport.h --copy=.new + +To display portability information for the C function, +use: + + perl ppport.h --api-info=newSVpvn + +Since the argument to C<--api-info> can be a regular expression, +you can use + + perl ppport.h --api-info=/_nomg$/ + +to display portability information for all C<_nomg> functions or + + perl ppport.h --api-info=/./ + +to display information for all known API elements. + +=head1 BUGS + +If this version of F is causing failure during +the compilation of this module, please check if newer versions +of either this module or C are available on CPAN +before sending a bug report. + +If F was generated using the latest version of +C and is causing failure of this module, please +file a bug report here: L + +Please include the following information: + +=over 4 + +=item 1. + +The complete output from running "perl -V" + +=item 2. + +This file. + +=item 3. + +The name and version of the module you were trying to build. + +=item 4. + +A full log of the build that failed. + +=item 5. + +Any other information that you think could be relevant. + +=back + +For the latest version of this code, please get the C +module from CPAN. + +=head1 COPYRIGHT + +Version 3.x, Copyright (c) 2004-2013, Marcus Holland-Moritz. + +Version 2.x, Copyright (C) 2001, Paul Marquess. + +Version 1.x, Copyright (C) 1999, Kenneth Albanowski. + +This program is free software; you can redistribute it and/or +modify it under the same terms as Perl itself. + +=head1 SEE ALSO + +See L. + +=cut + +use strict; + +# Disable broken TRIE-optimization +BEGIN { eval '${^RE_TRIE_MAXBUF} = -1' if $] >= 5.009004 && $] <= 5.009005 } + +my $VERSION = 3.31; + +my %opt = ( + quiet => 0, + diag => 1, + hints => 1, + changes => 1, + cplusplus => 0, + filter => 1, + strip => 0, + version => 0, +); + +my($ppport) = $0 =~ /([\w.]+)$/; +my $LF = '(?:\r\n|[\r\n])'; # line feed +my $HS = "[ \t]"; # horizontal whitespace + +# Never use C comments in this file! +my $ccs = '/'.'*'; +my $cce = '*'.'/'; +my $rccs = quotemeta $ccs; +my $rcce = quotemeta $cce; + +eval { + require Getopt::Long; + Getopt::Long::GetOptions(\%opt, qw( + help quiet diag! filter! hints! changes! cplusplus strip version + patch=s copy=s diff=s compat-version=s + list-provided list-unsupported api-info=s + )) or usage(); +}; + +if ($@ and grep /^-/, @ARGV) { + usage() if "@ARGV" =~ /^--?h(?:elp)?$/; + die "Getopt::Long not found. Please don't use any options.\n"; +} + +if ($opt{version}) { + print "This is $0 $VERSION.\n"; + exit 0; +} + +usage() if $opt{help}; +strip() if $opt{strip}; + +if (exists $opt{'compat-version'}) { + my($r,$v,$s) = eval { parse_version($opt{'compat-version'}) }; + if ($@) { + die "Invalid version number format: '$opt{'compat-version'}'\n"; + } + die "Only Perl 5 is supported\n" if $r != 5; + die "Invalid version number: $opt{'compat-version'}\n" if $v >= 1000 || $s >= 1000; + $opt{'compat-version'} = sprintf "%d.%03d%03d", $r, $v, $s; +} +else { + $opt{'compat-version'} = 5; +} + +my %API = map { /^(\w+)\|([^|]*)\|([^|]*)\|(\w*)$/ + ? ( $1 => { + ($2 ? ( base => $2 ) : ()), + ($3 ? ( todo => $3 ) : ()), + (index($4, 'v') >= 0 ? ( varargs => 1 ) : ()), + (index($4, 'p') >= 0 ? ( provided => 1 ) : ()), + (index($4, 'n') >= 0 ? ( nothxarg => 1 ) : ()), + } ) + : die "invalid spec: $_" } qw( +ASCII_TO_NEED||5.007001|n +AvFILLp|5.004050||p +AvFILL||| +BhkDISABLE||5.021008| +BhkENABLE||5.021008| +BhkENTRY_set||5.021008| +BhkENTRY||| +BhkFLAGS||| +CALL_BLOCK_HOOKS||| +CLASS|||n +CPERLscope|5.005000||p +CX_CURPAD_SAVE||| +CX_CURPAD_SV||| +CopFILEAV|5.006000||p +CopFILEGV_set|5.006000||p +CopFILEGV|5.006000||p +CopFILESV|5.006000||p +CopFILE_set|5.006000||p +CopFILE|5.006000||p +CopSTASHPV_set|5.006000||p +CopSTASHPV|5.006000||p +CopSTASH_eq|5.006000||p +CopSTASH_set|5.006000||p +CopSTASH|5.006000||p +CopyD|5.009002|5.004050|p +Copy||| +CvPADLIST||5.008001| +CvSTASH||| +CvWEAKOUTSIDE||| +DEFSV_set|5.010001||p +DEFSV|5.004050||p +END_EXTERN_C|5.005000||p +ENTER||| +ERRSV|5.004050||p +EXTEND||| +EXTERN_C|5.005000||p +F0convert|||n +FREETMPS||| +GIMME_V||5.004000|n +GIMME|||n +GROK_NUMERIC_RADIX|5.007002||p +G_ARRAY||| +G_DISCARD||| +G_EVAL||| +G_METHOD|5.006001||p +G_NOARGS||| +G_SCALAR||| +G_VOID||5.004000| +GetVars||| +GvAV||| +GvCV||| +GvHV||| +GvSVn|5.009003||p +GvSV||| +Gv_AMupdate||5.011000| +HEf_SVKEY|5.003070||p +HeHASH||5.003070| +HeKEY||5.003070| +HeKLEN||5.003070| +HePV||5.004000| +HeSVKEY_force||5.003070| +HeSVKEY_set||5.004000| +HeSVKEY||5.003070| +HeUTF8|5.010001|5.008000|p +HeVAL||5.003070| +HvENAMELEN||5.015004| +HvENAMEUTF8||5.015004| +HvENAME||5.013007| +HvNAMELEN_get|5.009003||p +HvNAMELEN||5.015004| +HvNAMEUTF8||5.015004| +HvNAME_get|5.009003||p +HvNAME||| +INT2PTR|5.006000||p +IN_LOCALE_COMPILETIME|5.007002||p +IN_LOCALE_RUNTIME|5.007002||p +IN_LOCALE|5.007002||p +IN_PERL_COMPILETIME|5.008001||p +IS_NUMBER_GREATER_THAN_UV_MAX|5.007002||p +IS_NUMBER_INFINITY|5.007002||p +IS_NUMBER_IN_UV|5.007002||p +IS_NUMBER_NAN|5.007003||p +IS_NUMBER_NEG|5.007002||p +IS_NUMBER_NOT_INT|5.007002||p +IVSIZE|5.006000||p +IVTYPE|5.006000||p +IVdf|5.006000||p +LEAVE||| +LINKLIST||5.013006| +LVRET||| +MARK||| +MULTICALL||5.021008| +MUTABLE_PTR|5.010001||p +MUTABLE_SV|5.010001||p +MY_CXT_CLONE|5.009002||p +MY_CXT_INIT|5.007003||p +MY_CXT|5.007003||p +MoveD|5.009002|5.004050|p +Move||| +NATIVE_TO_NEED||5.007001|n +NOOP|5.005000||p +NUM2PTR|5.006000||p +NVTYPE|5.006000||p +NVef|5.006001||p +NVff|5.006001||p +NVgf|5.006001||p +Newxc|5.009003||p +Newxz|5.009003||p +Newx|5.009003||p +Nullav||| +Nullch||| +Nullcv||| +Nullhv||| +Nullsv||| +OP_CLASS||5.013007| +OP_DESC||5.007003| +OP_NAME||5.007003| +OP_TYPE_IS_OR_WAS||5.019010| +OP_TYPE_IS||5.019007| +ORIGMARK||| +OpHAS_SIBLING||5.021007| +OpSIBLING_set||5.021007| +OpSIBLING||5.021007| +PAD_BASE_SV||| +PAD_CLONE_VARS||| +PAD_COMPNAME_FLAGS||| +PAD_COMPNAME_GEN_set||| +PAD_COMPNAME_GEN||| +PAD_COMPNAME_OURSTASH||| +PAD_COMPNAME_PV||| +PAD_COMPNAME_TYPE||| +PAD_RESTORE_LOCAL||| +PAD_SAVE_LOCAL||| +PAD_SAVE_SETNULLPAD||| +PAD_SETSV||| +PAD_SET_CUR_NOSAVE||| +PAD_SET_CUR||| +PAD_SVl||| +PAD_SV||| +PERLIO_FUNCS_CAST|5.009003||p +PERLIO_FUNCS_DECL|5.009003||p +PERL_ABS|5.008001||p +PERL_BCDVERSION|5.021008||p +PERL_GCC_BRACE_GROUPS_FORBIDDEN|5.008001||p +PERL_HASH|5.003070||p +PERL_INT_MAX|5.003070||p +PERL_INT_MIN|5.003070||p +PERL_LONG_MAX|5.003070||p +PERL_LONG_MIN|5.003070||p +PERL_MAGIC_arylen|5.007002||p +PERL_MAGIC_backref|5.007002||p +PERL_MAGIC_bm|5.007002||p +PERL_MAGIC_collxfrm|5.007002||p +PERL_MAGIC_dbfile|5.007002||p +PERL_MAGIC_dbline|5.007002||p +PERL_MAGIC_defelem|5.007002||p +PERL_MAGIC_envelem|5.007002||p +PERL_MAGIC_env|5.007002||p +PERL_MAGIC_ext|5.007002||p +PERL_MAGIC_fm|5.007002||p +PERL_MAGIC_glob|5.021008||p +PERL_MAGIC_isaelem|5.007002||p +PERL_MAGIC_isa|5.007002||p +PERL_MAGIC_mutex|5.021008||p +PERL_MAGIC_nkeys|5.007002||p +PERL_MAGIC_overload_elem|5.021008||p +PERL_MAGIC_overload_table|5.007002||p +PERL_MAGIC_overload|5.021008||p +PERL_MAGIC_pos|5.007002||p +PERL_MAGIC_qr|5.007002||p +PERL_MAGIC_regdata|5.007002||p +PERL_MAGIC_regdatum|5.007002||p +PERL_MAGIC_regex_global|5.007002||p +PERL_MAGIC_shared_scalar|5.007003||p +PERL_MAGIC_shared|5.007003||p +PERL_MAGIC_sigelem|5.007002||p +PERL_MAGIC_sig|5.007002||p +PERL_MAGIC_substr|5.007002||p +PERL_MAGIC_sv|5.007002||p +PERL_MAGIC_taint|5.007002||p +PERL_MAGIC_tiedelem|5.007002||p +PERL_MAGIC_tiedscalar|5.007002||p +PERL_MAGIC_tied|5.007002||p +PERL_MAGIC_utf8|5.008001||p +PERL_MAGIC_uvar_elem|5.007003||p +PERL_MAGIC_uvar|5.007002||p +PERL_MAGIC_vec|5.007002||p +PERL_MAGIC_vstring|5.008001||p +PERL_PV_ESCAPE_ALL|5.009004||p +PERL_PV_ESCAPE_FIRSTCHAR|5.009004||p +PERL_PV_ESCAPE_NOBACKSLASH|5.009004||p +PERL_PV_ESCAPE_NOCLEAR|5.009004||p +PERL_PV_ESCAPE_QUOTE|5.009004||p +PERL_PV_ESCAPE_RE|5.009005||p +PERL_PV_ESCAPE_UNI_DETECT|5.009004||p +PERL_PV_ESCAPE_UNI|5.009004||p +PERL_PV_PRETTY_DUMP|5.009004||p +PERL_PV_PRETTY_ELLIPSES|5.010000||p +PERL_PV_PRETTY_LTGT|5.009004||p +PERL_PV_PRETTY_NOCLEAR|5.010000||p +PERL_PV_PRETTY_QUOTE|5.009004||p +PERL_PV_PRETTY_REGPROP|5.009004||p +PERL_QUAD_MAX|5.003070||p +PERL_QUAD_MIN|5.003070||p +PERL_REVISION|5.006000||p +PERL_SCAN_ALLOW_UNDERSCORES|5.007003||p +PERL_SCAN_DISALLOW_PREFIX|5.007003||p +PERL_SCAN_GREATER_THAN_UV_MAX|5.007003||p +PERL_SCAN_SILENT_ILLDIGIT|5.008001||p +PERL_SHORT_MAX|5.003070||p +PERL_SHORT_MIN|5.003070||p +PERL_SIGNALS_UNSAFE_FLAG|5.008001||p +PERL_SUBVERSION|5.006000||p +PERL_SYS_INIT3||5.006000| +PERL_SYS_INIT||| +PERL_SYS_TERM||5.021008| +PERL_UCHAR_MAX|5.003070||p +PERL_UCHAR_MIN|5.003070||p +PERL_UINT_MAX|5.003070||p +PERL_UINT_MIN|5.003070||p +PERL_ULONG_MAX|5.003070||p +PERL_ULONG_MIN|5.003070||p +PERL_UNUSED_ARG|5.009003||p +PERL_UNUSED_CONTEXT|5.009004||p +PERL_UNUSED_DECL|5.007002||p +PERL_UNUSED_VAR|5.007002||p +PERL_UQUAD_MAX|5.003070||p +PERL_UQUAD_MIN|5.003070||p +PERL_USE_GCC_BRACE_GROUPS|5.009004||p +PERL_USHORT_MAX|5.003070||p +PERL_USHORT_MIN|5.003070||p +PERL_VERSION|5.006000||p +PL_DBsignal|5.005000||p +PL_DBsingle|||pn +PL_DBsub|||pn +PL_DBtrace|||pn +PL_Sv|5.005000||p +PL_bufend|5.021008||p +PL_bufptr|5.021008||p +PL_check||5.006000| +PL_compiling|5.004050||p +PL_comppad_name||5.017004| +PL_comppad||5.008001| +PL_copline|5.021008||p +PL_curcop|5.004050||p +PL_curpad||5.005000| +PL_curstash|5.004050||p +PL_debstash|5.004050||p +PL_defgv|5.004050||p +PL_diehook|5.004050||p +PL_dirty|5.004050||p +PL_dowarn|||pn +PL_errgv|5.004050||p +PL_error_count|5.021008||p +PL_expect|5.021008||p +PL_hexdigit|5.005000||p +PL_hints|5.005000||p +PL_in_my_stash|5.021008||p +PL_in_my|5.021008||p +PL_keyword_plugin||5.011002| +PL_last_in_gv|||n +PL_laststatval|5.005000||p +PL_lex_state|5.021008||p +PL_lex_stuff|5.021008||p +PL_linestr|5.021008||p +PL_modglobal||5.005000|n +PL_na|5.004050||pn +PL_no_modify|5.006000||p +PL_ofsgv|||n +PL_opfreehook||5.011000|n +PL_parser|5.009005||p +PL_peepp||5.007003|n +PL_perl_destruct_level|5.004050||p +PL_perldb|5.004050||p +PL_ppaddr|5.006000||p +PL_rpeepp||5.013005|n +PL_rsfp_filters|5.021008||p +PL_rsfp|5.021008||p +PL_rs|||n +PL_signals|5.008001||p +PL_stack_base|5.004050||p +PL_stack_sp|5.004050||p +PL_statcache|5.005000||p +PL_stdingv|5.004050||p +PL_sv_arenaroot|5.004050||p +PL_sv_no|5.004050||pn +PL_sv_undef|5.004050||pn +PL_sv_yes|5.004050||pn +PL_tainted|5.004050||p +PL_tainting|5.004050||p +PL_tokenbuf|5.021008||p +POP_MULTICALL||5.021008| +POPi|||n +POPl|||n +POPn|||n +POPpbytex||5.007001|n +POPpx||5.005030|n +POPp|||n +POPs|||n +PTR2IV|5.006000||p +PTR2NV|5.006000||p +PTR2UV|5.006000||p +PTR2nat|5.009003||p +PTR2ul|5.007001||p +PTRV|5.006000||p +PUSHMARK||| +PUSH_MULTICALL||5.021008| +PUSHi||| +PUSHmortal|5.009002||p +PUSHn||| +PUSHp||| +PUSHs||| +PUSHu|5.004000||p +PUTBACK||| +PadARRAY||5.021008| +PadMAX||5.021008| +PadlistARRAY||5.021008| +PadlistMAX||5.021008| +PadlistNAMESARRAY||5.021008| +PadlistNAMESMAX||5.021008| +PadlistNAMES||5.021008| +PadlistREFCNT||5.017004| +PadnameIsOUR||| +PadnameIsSTATE||| +PadnameLEN||5.021008| +PadnameOURSTASH||| +PadnameOUTER||| +PadnamePV||5.021008| +PadnameREFCNT_dec||5.021008| +PadnameREFCNT||5.021008| +PadnameSV||5.021008| +PadnameTYPE||| +PadnameUTF8||5.021007| +PadnamelistARRAY||5.021008| +PadnamelistMAX||5.021008| +PadnamelistREFCNT_dec||5.021008| +PadnamelistREFCNT||5.021008| +PerlIO_clearerr||5.007003| +PerlIO_close||5.007003| +PerlIO_context_layers||5.009004| +PerlIO_eof||5.007003| +PerlIO_error||5.007003| +PerlIO_fileno||5.007003| +PerlIO_fill||5.007003| +PerlIO_flush||5.007003| +PerlIO_get_base||5.007003| +PerlIO_get_bufsiz||5.007003| +PerlIO_get_cnt||5.007003| +PerlIO_get_ptr||5.007003| +PerlIO_read||5.007003| +PerlIO_restore_errno||| +PerlIO_save_errno||| +PerlIO_seek||5.007003| +PerlIO_set_cnt||5.007003| +PerlIO_set_ptrcnt||5.007003| +PerlIO_setlinebuf||5.007003| +PerlIO_stderr||5.007003| +PerlIO_stdin||5.007003| +PerlIO_stdout||5.007003| +PerlIO_tell||5.007003| +PerlIO_unread||5.007003| +PerlIO_write||5.007003| +Perl_signbit||5.009005|n +PoisonFree|5.009004||p +PoisonNew|5.009004||p +PoisonWith|5.009004||p +Poison|5.008000||p +READ_XDIGIT||5.017006| +RETVAL|||n +Renewc||| +Renew||| +SAVECLEARSV||| +SAVECOMPPAD||| +SAVEPADSV||| +SAVETMPS||| +SAVE_DEFSV|5.004050||p +SPAGAIN||| +SP||| +START_EXTERN_C|5.005000||p +START_MY_CXT|5.007003||p +STMT_END|||p +STMT_START|||p +STR_WITH_LEN|5.009003||p +ST||| +SV_CONST_RETURN|5.009003||p +SV_COW_DROP_PV|5.008001||p +SV_COW_SHARED_HASH_KEYS|5.009005||p +SV_GMAGIC|5.007002||p +SV_HAS_TRAILING_NUL|5.009004||p +SV_IMMEDIATE_UNREF|5.007001||p +SV_MUTABLE_RETURN|5.009003||p +SV_NOSTEAL|5.009002||p +SV_SMAGIC|5.009003||p +SV_UTF8_NO_ENCODING|5.008001||p +SVfARG|5.009005||p +SVf_UTF8|5.006000||p +SVf|5.006000||p +SVt_INVLIST||5.019002| +SVt_IV||| +SVt_NULL||| +SVt_NV||| +SVt_PVAV||| +SVt_PVCV||| +SVt_PVFM||| +SVt_PVGV||| +SVt_PVHV||| +SVt_PVIO||| +SVt_PVIV||| +SVt_PVLV||| +SVt_PVMG||| +SVt_PVNV||| +SVt_PV||| +SVt_REGEXP||5.011000| +Safefree||| +Slab_Alloc||| +Slab_Free||| +Slab_to_ro||| +Slab_to_rw||| +StructCopy||| +SvCUR_set||| +SvCUR||| +SvEND||| +SvGAMAGIC||5.006001| +SvGETMAGIC|5.004050||p +SvGROW||| +SvIOK_UV||5.006000| +SvIOK_notUV||5.006000| +SvIOK_off||| +SvIOK_only_UV||5.006000| +SvIOK_only||| +SvIOK_on||| +SvIOKp||| +SvIOK||| +SvIVX||| +SvIV_nomg|5.009001||p +SvIV_set||| +SvIVx||| +SvIV||| +SvIsCOW_shared_hash||5.008003| +SvIsCOW||5.008003| +SvLEN_set||| +SvLEN||| +SvLOCK||5.007003| +SvMAGIC_set|5.009003||p +SvNIOK_off||| +SvNIOKp||| +SvNIOK||| +SvNOK_off||| +SvNOK_only||| +SvNOK_on||| +SvNOKp||| +SvNOK||| +SvNVX||| +SvNV_nomg||5.013002| +SvNV_set||| +SvNVx||| +SvNV||| +SvOK||| +SvOOK_offset||5.011000| +SvOOK||| +SvPOK_off||| +SvPOK_only_UTF8||5.006000| +SvPOK_only||| +SvPOK_on||| +SvPOKp||| +SvPOK||| +SvPVX_const|5.009003||p +SvPVX_mutable|5.009003||p +SvPVX||| +SvPV_const|5.009003||p +SvPV_flags_const_nolen|5.009003||p +SvPV_flags_const|5.009003||p +SvPV_flags_mutable|5.009003||p +SvPV_flags|5.007002||p +SvPV_force_flags_mutable|5.009003||p +SvPV_force_flags_nolen|5.009003||p +SvPV_force_flags|5.007002||p +SvPV_force_mutable|5.009003||p +SvPV_force_nolen|5.009003||p +SvPV_force_nomg_nolen|5.009003||p +SvPV_force_nomg|5.007002||p +SvPV_force|||p +SvPV_mutable|5.009003||p +SvPV_nolen_const|5.009003||p +SvPV_nolen|5.006000||p +SvPV_nomg_const_nolen|5.009003||p +SvPV_nomg_const|5.009003||p +SvPV_nomg_nolen|5.013007||p +SvPV_nomg|5.007002||p +SvPV_renew|5.009003||p +SvPV_set||| +SvPVbyte_force||5.009002| +SvPVbyte_nolen||5.006000| +SvPVbytex_force||5.006000| +SvPVbytex||5.006000| +SvPVbyte|5.006000||p +SvPVutf8_force||5.006000| +SvPVutf8_nolen||5.006000| +SvPVutf8x_force||5.006000| +SvPVutf8x||5.006000| +SvPVutf8||5.006000| +SvPVx||| +SvPV||| +SvREFCNT_dec_NN||5.017007| +SvREFCNT_dec||| +SvREFCNT_inc_NN|5.009004||p +SvREFCNT_inc_simple_NN|5.009004||p +SvREFCNT_inc_simple_void_NN|5.009004||p +SvREFCNT_inc_simple_void|5.009004||p +SvREFCNT_inc_simple|5.009004||p +SvREFCNT_inc_void_NN|5.009004||p +SvREFCNT_inc_void|5.009004||p +SvREFCNT_inc|||p +SvREFCNT||| +SvROK_off||| +SvROK_on||| +SvROK||| +SvRV_set|5.009003||p +SvRV||| +SvRXOK||5.009005| +SvRX||5.009005| +SvSETMAGIC||| +SvSHARED_HASH|5.009003||p +SvSHARE||5.007003| +SvSTASH_set|5.009003||p +SvSTASH||| +SvSetMagicSV_nosteal||5.004000| +SvSetMagicSV||5.004000| +SvSetSV_nosteal||5.004000| +SvSetSV||| +SvTAINTED_off||5.004000| +SvTAINTED_on||5.004000| +SvTAINTED||5.004000| +SvTAINT||| +SvTHINKFIRST||| +SvTRUE_nomg||5.013006| +SvTRUE||| +SvTYPE||| +SvUNLOCK||5.007003| +SvUOK|5.007001|5.006000|p +SvUPGRADE||| +SvUTF8_off||5.006000| +SvUTF8_on||5.006000| +SvUTF8||5.006000| +SvUVXx|5.004000||p +SvUVX|5.004000||p +SvUV_nomg|5.009001||p +SvUV_set|5.009003||p +SvUVx|5.004000||p +SvUV|5.004000||p +SvVOK||5.008001| +SvVSTRING_mg|5.009004||p +THIS|||n +UNDERBAR|5.009002||p +UTF8_MAXBYTES|5.009002||p +UVSIZE|5.006000||p +UVTYPE|5.006000||p +UVXf|5.007001||p +UVof|5.006000||p +UVuf|5.006000||p +UVxf|5.006000||p +WARN_ALL|5.006000||p +WARN_AMBIGUOUS|5.006000||p +WARN_ASSERTIONS|5.021008||p +WARN_BAREWORD|5.006000||p +WARN_CLOSED|5.006000||p +WARN_CLOSURE|5.006000||p +WARN_DEBUGGING|5.006000||p +WARN_DEPRECATED|5.006000||p +WARN_DIGIT|5.006000||p +WARN_EXEC|5.006000||p +WARN_EXITING|5.006000||p +WARN_GLOB|5.006000||p +WARN_INPLACE|5.006000||p +WARN_INTERNAL|5.006000||p +WARN_IO|5.006000||p +WARN_LAYER|5.008000||p +WARN_MALLOC|5.006000||p +WARN_MISC|5.006000||p +WARN_NEWLINE|5.006000||p +WARN_NUMERIC|5.006000||p +WARN_ONCE|5.006000||p +WARN_OVERFLOW|5.006000||p +WARN_PACK|5.006000||p +WARN_PARENTHESIS|5.006000||p +WARN_PIPE|5.006000||p +WARN_PORTABLE|5.006000||p +WARN_PRECEDENCE|5.006000||p +WARN_PRINTF|5.006000||p +WARN_PROTOTYPE|5.006000||p +WARN_QW|5.006000||p +WARN_RECURSION|5.006000||p +WARN_REDEFINE|5.006000||p +WARN_REGEXP|5.006000||p +WARN_RESERVED|5.006000||p +WARN_SEMICOLON|5.006000||p +WARN_SEVERE|5.006000||p +WARN_SIGNAL|5.006000||p +WARN_SUBSTR|5.006000||p +WARN_SYNTAX|5.006000||p +WARN_TAINT|5.006000||p +WARN_THREADS|5.008000||p +WARN_UNINITIALIZED|5.006000||p +WARN_UNOPENED|5.006000||p +WARN_UNPACK|5.006000||p +WARN_UNTIE|5.006000||p +WARN_UTF8|5.006000||p +WARN_VOID|5.006000||p +WIDEST_UTYPE|5.015004||p +XCPT_CATCH|5.009002||p +XCPT_RETHROW|5.009002||p +XCPT_TRY_END|5.009002||p +XCPT_TRY_START|5.009002||p +XPUSHi||| +XPUSHmortal|5.009002||p +XPUSHn||| +XPUSHp||| +XPUSHs||| +XPUSHu|5.004000||p +XSPROTO|5.010000||p +XSRETURN_EMPTY||| +XSRETURN_IV||| +XSRETURN_NO||| +XSRETURN_NV||| +XSRETURN_PV||| +XSRETURN_UNDEF||| +XSRETURN_UV|5.008001||p +XSRETURN_YES||| +XSRETURN|||p +XST_mIV||| +XST_mNO||| +XST_mNV||| +XST_mPV||| +XST_mUNDEF||| +XST_mUV|5.008001||p +XST_mYES||| +XS_APIVERSION_BOOTCHECK||5.021008| +XS_EXTERNAL||5.021008| +XS_INTERNAL||5.021008| +XS_VERSION_BOOTCHECK||5.021008| +XS_VERSION||| +XSprePUSH|5.006000||p +XS||| +XopDISABLE||5.021008| +XopENABLE||5.021008| +XopENTRYCUSTOM||5.021008| +XopENTRY_set||5.021008| +XopENTRY||5.021008| +XopFLAGS||5.013007| +ZeroD|5.009002||p +Zero||| +_aMY_CXT|5.007003||p +_add_range_to_invlist||| +_append_range_to_invlist||| +_core_swash_init||| +_get_encoding||| +_get_regclass_nonbitmap_data||| +_get_swash_invlist||| +_invlist_array_init|||n +_invlist_contains_cp|||n +_invlist_contents||| +_invlist_dump||| +_invlist_intersection_maybe_complement_2nd||| +_invlist_intersection||| +_invlist_invert||| +_invlist_len|||n +_invlist_populate_swatch|||n +_invlist_search|||n +_invlist_subtract||| +_invlist_union_maybe_complement_2nd||| +_invlist_union||| +_is_cur_LC_category_utf8||| +_is_in_locale_category||5.021001| +_is_uni_FOO||5.017008| +_is_uni_perl_idcont||5.017008| +_is_uni_perl_idstart||5.017007| +_is_utf8_FOO||5.017008| +_is_utf8_char_slow||5.021001|n +_is_utf8_idcont||5.021001| +_is_utf8_idstart||5.021001| +_is_utf8_mark||5.017008| +_is_utf8_perl_idcont||5.017008| +_is_utf8_perl_idstart||5.017007| +_is_utf8_xidcont||5.021001| +_is_utf8_xidstart||5.021001| +_load_PL_utf8_foldclosures||| +_make_exactf_invlist||| +_new_invlist_C_array||| +_new_invlist||| +_pMY_CXT|5.007003||p +_setup_canned_invlist||| +_swash_inversion_hash||| +_swash_to_invlist||| +_to_fold_latin1||| +_to_uni_fold_flags||5.014000| +_to_upper_title_latin1||| +_to_utf8_fold_flags||5.019009| +_to_utf8_lower_flags||5.019009| +_to_utf8_title_flags||5.019009| +_to_utf8_upper_flags||5.019009| +_warn_problematic_locale|||n +aMY_CXT_|5.007003||p +aMY_CXT|5.007003||p +aTHXR_|5.021008||p +aTHXR|5.021008||p +aTHX_|5.006000||p +aTHX|5.006000||p +aassign_common_vars||| +add_above_Latin1_folds||| +add_cp_to_invlist||| +add_data|||n +add_multi_match||| +add_utf16_textfilter||| +adjust_size_and_find_bucket|||n +advance_one_SB||| +advance_one_WB||| +alloc_maybe_populate_EXACT||| +alloccopstash||| +allocmy||| +amagic_call||| +amagic_cmp_locale||| +amagic_cmp||| +amagic_deref_call||5.013007| +amagic_i_ncmp||| +amagic_is_enabled||| +amagic_ncmp||| +anonymise_cv_maybe||| +any_dup||| +ao||| +append_utf8_from_native_byte||5.019004|n +apply_attrs_my||| +apply_attrs_string||5.006001| +apply_attrs||| +apply||| +assert_uft8_cache_coherent||| +assignment_type||| +atfork_lock||5.007003|n +atfork_unlock||5.007003|n +av_arylen_p||5.009003| +av_clear||| +av_create_and_push||5.009005| +av_create_and_unshift_one||5.009005| +av_delete||5.006000| +av_exists||5.006000| +av_extend_guts||| +av_extend||| +av_fetch||| +av_fill||| +av_iter_p||5.011000| +av_len||| +av_make||| +av_pop||| +av_push||| +av_reify||| +av_shift||| +av_store||| +av_tindex||5.017009| +av_top_index||5.017009| +av_undef||| +av_unshift||| +ax|||n +backup_one_SB||| +backup_one_WB||| +bad_type_gv||| +bad_type_pv||| +bind_match||| +block_end||5.004000| +block_gimme||5.004000| +block_start||5.004000| +blockhook_register||5.013003| +boolSV|5.004000||p +boot_core_PerlIO||| +boot_core_UNIVERSAL||| +boot_core_mro||| +bytes_cmp_utf8||5.013007| +bytes_from_utf8||5.007001| +bytes_to_utf8||5.006001| +call_argv|5.006000||p +call_atexit||5.006000| +call_list||5.004000| +call_method|5.006000||p +call_pv|5.006000||p +call_sv|5.006000||p +caller_cx|5.013005|5.006000|p +calloc||5.007002|n +cando||| +cast_i32||5.006000|n +cast_iv||5.006000|n +cast_ulong||5.006000|n +cast_uv||5.006000|n +check_locale_boundary_crossing||| +check_type_and_open||| +check_uni||| +check_utf8_print||| +checkcomma||| +ckWARN|5.006000||p +ck_entersub_args_core||| +ck_entersub_args_list||5.013006| +ck_entersub_args_proto_or_list||5.013006| +ck_entersub_args_proto||5.013006| +ck_warner_d||5.011001|v +ck_warner||5.011001|v +ckwarn_common||| +ckwarn_d||5.009003| +ckwarn||5.009003| +clear_placeholders||| +clear_special_blocks||| +clone_params_del|||n +clone_params_new|||n +closest_cop||| +cntrl_to_mnemonic|||n +compute_EXACTish|||n +construct_ahocorasick_from_trie||| +cop_fetch_label||5.015001| +cop_free||| +cop_hints_2hv||5.013007| +cop_hints_fetch_pvn||5.013007| +cop_hints_fetch_pvs||5.013007| +cop_hints_fetch_pv||5.013007| +cop_hints_fetch_sv||5.013007| +cop_store_label||5.015001| +cophh_2hv||5.013007| +cophh_copy||5.013007| +cophh_delete_pvn||5.013007| +cophh_delete_pvs||5.013007| +cophh_delete_pv||5.013007| +cophh_delete_sv||5.013007| +cophh_fetch_pvn||5.013007| +cophh_fetch_pvs||5.013007| +cophh_fetch_pv||5.013007| +cophh_fetch_sv||5.013007| +cophh_free||5.013007| +cophh_new_empty||5.021008| +cophh_store_pvn||5.013007| +cophh_store_pvs||5.013007| +cophh_store_pv||5.013007| +cophh_store_sv||5.013007| +core_prototype||| +coresub_op||| +could_it_be_a_POSIX_class|||n +cr_textfilter||| +create_eval_scope||| +croak_memory_wrap||5.019003|n +croak_no_mem|||n +croak_no_modify||5.013003|n +croak_nocontext|||vn +croak_popstack|||n +croak_sv||5.013001| +croak_xs_usage||5.010001|n +croak|||v +csighandler||5.009003|n +current_re_engine||| +curse||| +custom_op_desc||5.007003| +custom_op_get_field||| +custom_op_name||5.007003| +custom_op_register||5.013007| +custom_op_xop||5.013007| +cv_ckproto_len_flags||| +cv_clone_into||| +cv_clone||| +cv_const_sv_or_av|||n +cv_const_sv||5.003070|n +cv_dump||| +cv_forget_slab||| +cv_get_call_checker||5.013006| +cv_name||5.021005| +cv_set_call_checker_flags||5.021004| +cv_set_call_checker||5.013006| +cv_undef_flags||| +cv_undef||| +cvgv_from_hek||| +cvgv_set||| +cvstash_set||| +cx_dump||5.005000| +cx_dup||| +cxinc||| +dAXMARK|5.009003||p +dAX|5.007002||p +dITEMS|5.007002||p +dMARK||| +dMULTICALL||5.009003| +dMY_CXT_SV|5.007003||p +dMY_CXT|5.007003||p +dNOOP|5.006000||p +dORIGMARK||| +dSP||| +dTHR|5.004050||p +dTHXR|5.021008||p +dTHXa|5.006000||p +dTHXoa|5.006000||p +dTHX|5.006000||p +dUNDERBAR|5.009002||p +dVAR|5.009003||p +dXCPT|5.009002||p +dXSARGS||| +dXSI32||| +dXSTARG|5.006000||p +deb_curcv||| +deb_nocontext|||vn +deb_stack_all||| +deb_stack_n||| +debop||5.005000| +debprofdump||5.005000| +debprof||| +debstackptrs||5.007003| +debstack||5.007003| +debug_start_match||| +deb||5.007003|v +defelem_target||| +del_sv||| +delete_eval_scope||| +delimcpy||5.004000|n +deprecate_commaless_var_list||| +despatch_signals||5.007001| +destroy_matcher||| +die_nocontext|||vn +die_sv||5.013001| +die_unwind||| +die|||v +dirp_dup||| +div128||| +djSP||| +do_aexec5||| +do_aexec||| +do_aspawn||| +do_binmode||5.004050| +do_chomp||| +do_close||| +do_delete_local||| +do_dump_pad||| +do_eof||| +do_exec3||| +do_execfree||| +do_exec||| +do_gv_dump||5.006000| +do_gvgv_dump||5.006000| +do_hv_dump||5.006000| +do_ipcctl||| +do_ipcget||| +do_join||| +do_magic_dump||5.006000| +do_msgrcv||| +do_msgsnd||| +do_ncmp||| +do_oddball||| +do_op_dump||5.006000| +do_open6||| +do_open9||5.006000| +do_open_raw||| +do_openn||5.007001| +do_open||5.003070| +do_pmop_dump||5.006000| +do_print||| +do_readline||| +do_seek||| +do_semop||| +do_shmio||| +do_smartmatch||| +do_spawn_nowait||| +do_spawn||| +do_sprintf||| +do_sv_dump||5.006000| +do_sysseek||| +do_tell||| +do_trans_complex_utf8||| +do_trans_complex||| +do_trans_count_utf8||| +do_trans_count||| +do_trans_simple_utf8||| +do_trans_simple||| +do_trans||| +do_vecget||| +do_vecset||| +do_vop||| +docatch||| +doeval||| +dofile||| +dofindlabel||| +doform||| +doing_taint||5.008001|n +dooneliner||| +doopen_pm||| +doparseform||| +dopoptoeval||| +dopoptogiven||| +dopoptolabel||| +dopoptoloop||| +dopoptosub_at||| +dopoptowhen||| +doref||5.009003| +dounwind||| +dowantarray||| +drand48_init_r|||n +drand48_r|||n +dump_all_perl||| +dump_all||5.006000| +dump_c_backtrace||| +dump_eval||5.006000| +dump_exec_pos||| +dump_form||5.006000| +dump_indent||5.006000|v +dump_mstats||| +dump_packsubs_perl||| +dump_packsubs||5.006000| +dump_sub_perl||| +dump_sub||5.006000| +dump_sv_child||| +dump_trie_interim_list||| +dump_trie_interim_table||| +dump_trie||| +dump_vindent||5.006000| +dumpuntil||| +dup_attrlist||| +emulate_cop_io||| +eval_pv|5.006000||p +eval_sv|5.006000||p +exec_failed||| +expect_number||| +fbm_compile||5.005000| +fbm_instr||5.005000| +feature_is_enabled||| +filter_add||| +filter_del||| +filter_gets||| +filter_read||| +finalize_optree||| +finalize_op||| +find_and_forget_pmops||| +find_array_subscript||| +find_beginning||| +find_byclass||| +find_default_stash||| +find_hash_subscript||| +find_in_my_stash||| +find_lexical_cv||| +find_runcv_where||| +find_runcv||5.008001| +find_rundefsv2||| +find_rundefsvoffset||5.009002| +find_rundefsv||5.013002| +find_script||| +find_uninit_var||| +first_symbol|||n +fixup_errno_string||| +foldEQ_latin1||5.013008|n +foldEQ_locale||5.013002|n +foldEQ_utf8_flags||5.013010| +foldEQ_utf8||5.013002| +foldEQ||5.013002|n +fold_constants||| +forbid_setid||| +force_ident_maybe_lex||| +force_ident||| +force_list||| +force_next||| +force_strict_version||| +force_version||| +force_word||| +forget_pmop||| +form_nocontext|||vn +form_short_octal_warning||| +form||5.004000|v +fp_dup||| +fprintf_nocontext|||vn +free_c_backtrace||| +free_global_struct||| +free_tied_hv_pool||| +free_tmps||| +gen_constant_list||| +get_ANYOF_cp_list_for_ssc||| +get_and_check_backslash_N_name||| +get_aux_mg||| +get_av|5.006000||p +get_c_backtrace_dump||| +get_c_backtrace||| +get_context||5.006000|n +get_cvn_flags|5.009005||p +get_cvs|5.011000||p +get_cv|5.006000||p +get_db_sub||| +get_debug_opts||| +get_hash_seed||| +get_hv|5.006000||p +get_invlist_iter_addr|||n +get_invlist_offset_addr|||n +get_invlist_previous_index_addr|||n +get_mstats||| +get_no_modify||| +get_num||| +get_op_descs||5.005000| +get_op_names||5.005000| +get_opargs||| +get_ppaddr||5.006000| +get_re_arg||| +get_sv|5.006000||p +get_vtbl||5.005030| +getcwd_sv||5.007002| +getenv_len||| +glob_2number||| +glob_assign_glob||| +gp_dup||| +gp_free||| +gp_ref||| +grok_atoUV|||n +grok_bin|5.007003||p +grok_bslash_N||| +grok_bslash_c||| +grok_bslash_o||| +grok_bslash_x||| +grok_hex|5.007003||p +grok_infnan||5.021004| +grok_number_flags||5.021002| +grok_number|5.007002||p +grok_numeric_radix|5.007002||p +grok_oct|5.007003||p +group_end||| +gv_AVadd||| +gv_HVadd||| +gv_IOadd||| +gv_SVadd||| +gv_add_by_type||5.011000| +gv_autoload4||5.004000| +gv_autoload_pvn||5.015004| +gv_autoload_pv||5.015004| +gv_autoload_sv||5.015004| +gv_check||| +gv_const_sv||5.009003| +gv_dump||5.006000| +gv_efullname3||5.003070| +gv_efullname4||5.006001| +gv_efullname||| +gv_fetchfile_flags||5.009005| +gv_fetchfile||| +gv_fetchmeth_autoload||5.007003| +gv_fetchmeth_internal||| +gv_fetchmeth_pv_autoload||5.015004| +gv_fetchmeth_pvn_autoload||5.015004| +gv_fetchmeth_pvn||5.015004| +gv_fetchmeth_pv||5.015004| +gv_fetchmeth_sv_autoload||5.015004| +gv_fetchmeth_sv||5.015004| +gv_fetchmethod_autoload||5.004000| +gv_fetchmethod_pv_flags||5.015004| +gv_fetchmethod_pvn_flags||5.015004| +gv_fetchmethod_sv_flags||5.015004| +gv_fetchmethod||| +gv_fetchmeth||| +gv_fetchpvn_flags|5.009002||p +gv_fetchpvs|5.009004||p +gv_fetchpv||| +gv_fetchsv|5.009002||p +gv_fullname3||5.003070| +gv_fullname4||5.006001| +gv_fullname||| +gv_handler||5.007001| +gv_init_pvn||5.015004| +gv_init_pv||5.015004| +gv_init_svtype||| +gv_init_sv||5.015004| +gv_init||| +gv_is_in_main||| +gv_magicalize_isa||| +gv_magicalize||| +gv_name_set||5.009004| +gv_override||| +gv_setref||| +gv_stashpvn_internal||| +gv_stashpvn|5.003070||p +gv_stashpvs|5.009003||p +gv_stashpv||| +gv_stashsvpvn_cached||| +gv_stashsv||| +gv_try_downgrade||| +handle_regex_sets||| +he_dup||| +hek_dup||| +hfree_next_entry||| +hfreeentries||| +hsplit||| +hv_assert||| +hv_auxinit_internal|||n +hv_auxinit||| +hv_backreferences_p||| +hv_clear_placeholders||5.009001| +hv_clear||| +hv_common_key_len||5.010000| +hv_common||5.010000| +hv_copy_hints_hv||5.009004| +hv_delayfree_ent||5.004000| +hv_delete_common||| +hv_delete_ent||5.003070| +hv_delete||| +hv_eiter_p||5.009003| +hv_eiter_set||5.009003| +hv_ename_add||| +hv_ename_delete||| +hv_exists_ent||5.003070| +hv_exists||| +hv_fetch_ent||5.003070| +hv_fetchs|5.009003||p +hv_fetch||| +hv_fill||5.013002| +hv_free_ent_ret||| +hv_free_ent||5.004000| +hv_iterinit||| +hv_iterkeysv||5.003070| +hv_iterkey||| +hv_iternext_flags||5.008000| +hv_iternextsv||| +hv_iternext||| +hv_iterval||| +hv_kill_backrefs||| +hv_ksplit||5.003070| +hv_magic_check|||n +hv_magic||| +hv_name_set||5.009003| +hv_notallowed||| +hv_placeholders_get||5.009003| +hv_placeholders_p||| +hv_placeholders_set||5.009003| +hv_rand_set||5.018000| +hv_riter_p||5.009003| +hv_riter_set||5.009003| +hv_scalar||5.009001| +hv_store_ent||5.003070| +hv_store_flags||5.008000| +hv_stores|5.009004||p +hv_store||| +hv_undef_flags||| +hv_undef||| +ibcmp_locale||5.004000| +ibcmp_utf8||5.007003| +ibcmp||| +incline||| +incpush_if_exists||| +incpush_use_sep||| +incpush||| +ingroup||| +init_argv_symbols||| +init_constants||| +init_dbargs||| +init_debugger||| +init_global_struct||| +init_i18nl10n||5.006000| +init_i18nl14n||5.006000| +init_ids||| +init_interp||| +init_main_stash||| +init_perllib||| +init_postdump_symbols||| +init_predump_symbols||| +init_stacks||5.005000| +init_tm||5.007002| +inplace_aassign||| +instr|||n +intro_my||5.004000| +intuit_method||| +intuit_more||| +invert||| +invlist_array|||n +invlist_clone||| +invlist_extend||| +invlist_highest|||n +invlist_is_iterating|||n +invlist_iterfinish|||n +invlist_iterinit|||n +invlist_iternext|||n +invlist_max|||n +invlist_previous_index|||n +invlist_set_len||| +invlist_set_previous_index|||n +invlist_trim|||n +invoke_exception_hook||| +io_close||| +isALNUMC|5.006000||p +isALNUM_lazy||5.021001| +isALPHANUMERIC||5.017008| +isALPHA||| +isASCII|5.006000||p +isBLANK|5.006001||p +isCNTRL|5.006000||p +isDIGIT||| +isFOO_lc||| +isFOO_utf8_lc||| +isGCB|||n +isGRAPH|5.006000||p +isGV_with_GP|5.009004||p +isIDCONT||5.017008| +isIDFIRST_lazy||5.021001| +isIDFIRST||| +isLOWER||| +isOCTAL||5.013005| +isPRINT|5.004000||p +isPSXSPC|5.006001||p +isPUNCT|5.006000||p +isSB||| +isSPACE||| +isUPPER||| +isUTF8_CHAR||5.021001| +isWB||| +isWORDCHAR||5.013006| +isXDIGIT|5.006000||p +is_an_int||| +is_ascii_string||5.011000| +is_handle_constructor|||n +is_invariant_string||5.021007|n +is_lvalue_sub||5.007001| +is_safe_syscall||5.019004| +is_ssc_worth_it|||n +is_uni_alnum_lc||5.006000| +is_uni_alnumc_lc||5.017007| +is_uni_alnumc||5.017007| +is_uni_alnum||5.006000| +is_uni_alpha_lc||5.006000| +is_uni_alpha||5.006000| +is_uni_ascii_lc||5.006000| +is_uni_ascii||5.006000| +is_uni_blank_lc||5.017002| +is_uni_blank||5.017002| +is_uni_cntrl_lc||5.006000| +is_uni_cntrl||5.006000| +is_uni_digit_lc||5.006000| +is_uni_digit||5.006000| +is_uni_graph_lc||5.006000| +is_uni_graph||5.006000| +is_uni_idfirst_lc||5.006000| +is_uni_idfirst||5.006000| +is_uni_lower_lc||5.006000| +is_uni_lower||5.006000| +is_uni_print_lc||5.006000| +is_uni_print||5.006000| +is_uni_punct_lc||5.006000| +is_uni_punct||5.006000| +is_uni_space_lc||5.006000| +is_uni_space||5.006000| +is_uni_upper_lc||5.006000| +is_uni_upper||5.006000| +is_uni_xdigit_lc||5.006000| +is_uni_xdigit||5.006000| +is_utf8_alnumc||5.017007| +is_utf8_alnum||5.006000| +is_utf8_alpha||5.006000| +is_utf8_ascii||5.006000| +is_utf8_blank||5.017002| +is_utf8_char_buf||5.015008|n +is_utf8_char||5.006000|n +is_utf8_cntrl||5.006000| +is_utf8_common||| +is_utf8_digit||5.006000| +is_utf8_graph||5.006000| +is_utf8_idcont||5.008000| +is_utf8_idfirst||5.006000| +is_utf8_lower||5.006000| +is_utf8_mark||5.006000| +is_utf8_perl_space||5.011001| +is_utf8_perl_word||5.011001| +is_utf8_posix_digit||5.011001| +is_utf8_print||5.006000| +is_utf8_punct||5.006000| +is_utf8_space||5.006000| +is_utf8_string_loclen||5.009003|n +is_utf8_string_loc||5.008001|n +is_utf8_string||5.006001|n +is_utf8_upper||5.006000| +is_utf8_xdigit||5.006000| +is_utf8_xidcont||5.013010| +is_utf8_xidfirst||5.013010| +isa_lookup||| +isinfnansv||| +isinfnan||5.021004|n +items|||n +ix|||n +jmaybe||| +join_exact||| +keyword_plugin_standard||| +keyword||| +leave_common||| +leave_scope||| +lex_bufutf8||5.011002| +lex_discard_to||5.011002| +lex_grow_linestr||5.011002| +lex_next_chunk||5.011002| +lex_peek_unichar||5.011002| +lex_read_space||5.011002| +lex_read_to||5.011002| +lex_read_unichar||5.011002| +lex_start||5.009005| +lex_stuff_pvn||5.011002| +lex_stuff_pvs||5.013005| +lex_stuff_pv||5.013006| +lex_stuff_sv||5.011002| +lex_unstuff||5.011002| +listkids||| +list||| +load_module_nocontext|||vn +load_module|5.006000||pv +localize||| +looks_like_bool||| +looks_like_number||| +lop||| +mPUSHi|5.009002||p +mPUSHn|5.009002||p +mPUSHp|5.009002||p +mPUSHs|5.010001||p +mPUSHu|5.009002||p +mXPUSHi|5.009002||p +mXPUSHn|5.009002||p +mXPUSHp|5.009002||p +mXPUSHs|5.010001||p +mXPUSHu|5.009002||p +magic_clear_all_env||| +magic_cleararylen_p||| +magic_clearenv||| +magic_clearhints||| +magic_clearhint||| +magic_clearisa||| +magic_clearpack||| +magic_clearsig||| +magic_copycallchecker||| +magic_dump||5.006000| +magic_existspack||| +magic_freearylen_p||| +magic_freeovrld||| +magic_getarylen||| +magic_getdebugvar||| +magic_getdefelem||| +magic_getnkeys||| +magic_getpack||| +magic_getpos||| +magic_getsig||| +magic_getsubstr||| +magic_gettaint||| +magic_getuvar||| +magic_getvec||| +magic_get||| +magic_killbackrefs||| +magic_methcall1||| +magic_methcall|||v +magic_methpack||| +magic_nextpack||| +magic_regdata_cnt||| +magic_regdatum_get||| +magic_regdatum_set||| +magic_scalarpack||| +magic_set_all_env||| +magic_setarylen||| +magic_setcollxfrm||| +magic_setdbline||| +magic_setdebugvar||| +magic_setdefelem||| +magic_setenv||| +magic_sethint||| +magic_setisa||| +magic_setlvref||| +magic_setmglob||| +magic_setnkeys||| +magic_setpack||| +magic_setpos||| +magic_setregexp||| +magic_setsig||| +magic_setsubstr||| +magic_settaint||| +magic_setutf8||| +magic_setuvar||| +magic_setvec||| +magic_set||| +magic_sizepack||| +magic_wipepack||| +make_matcher||| +make_trie||| +malloc_good_size|||n +malloced_size|||n +malloc||5.007002|n +markstack_grow||5.021001| +matcher_matches_sv||| +maybe_multimagic_gv||| +mayberelocate||| +measure_struct||| +memEQs|5.009005||p +memEQ|5.004000||p +memNEs|5.009005||p +memNE|5.004000||p +mem_collxfrm||| +mem_log_common|||n +mess_alloc||| +mess_nocontext|||vn +mess_sv||5.013001| +mess||5.006000|v +mfree||5.007002|n +mg_clear||| +mg_copy||| +mg_dup||| +mg_find_mglob||| +mg_findext|5.013008||pn +mg_find|||n +mg_free_type||5.013006| +mg_free||| +mg_get||| +mg_length||5.005000| +mg_localize||| +mg_magical|||n +mg_set||| +mg_size||5.005000| +mini_mktime||5.007002|n +minus_v||| +missingterm||| +mode_from_discipline||| +modkids||| +more_bodies||| +more_sv||| +moreswitches||| +move_proto_attr||| +mro_clean_isarev||| +mro_gather_and_rename||| +mro_get_from_name||5.010001| +mro_get_linear_isa_dfs||| +mro_get_linear_isa||5.009005| +mro_get_private_data||5.010001| +mro_isa_changed_in||| +mro_meta_dup||| +mro_meta_init||| +mro_method_changed_in||5.009005| +mro_package_moved||| +mro_register||5.010001| +mro_set_mro||5.010001| +mro_set_private_data||5.010001| +mul128||| +mulexp10|||n +multideref_stringify||| +my_atof2||5.007002| +my_atof||5.006000| +my_attrs||| +my_bcopy|||n +my_bytes_to_utf8|||n +my_bzero|||n +my_chsize||| +my_clearenv||| +my_cxt_index||| +my_cxt_init||| +my_dirfd||5.009005|n +my_exit_jump||| +my_exit||| +my_failure_exit||5.004000| +my_fflush_all||5.006000| +my_fork||5.007003|n +my_kid||| +my_lstat_flags||| +my_lstat||5.021008| +my_memcmp|||n +my_memset|||n +my_pclose||5.003070| +my_popen_list||5.007001| +my_popen||5.003070| +my_setenv||| +my_setlocale||| +my_snprintf|5.009004||pvn +my_socketpair||5.007003|n +my_sprintf|5.009003||pvn +my_stat_flags||| +my_stat||5.021008| +my_strerror||5.021001| +my_strftime||5.007002| +my_strlcat|5.009004||pn +my_strlcpy|5.009004||pn +my_unexec||| +my_vsnprintf||5.009004|n +need_utf8|||n +newANONATTRSUB||5.006000| +newANONHASH||| +newANONLIST||| +newANONSUB||| +newASSIGNOP||| +newATTRSUB_x||| +newATTRSUB||5.006000| +newAVREF||| +newAV||| +newBINOP||| +newCONDOP||| +newCONSTSUB_flags||5.015006| +newCONSTSUB|5.004050||p +newCVREF||| +newDEFSVOP||5.021006| +newFORM||| +newFOROP||5.013007| +newGIVENOP||5.009003| +newGIVWHENOP||| +newGP||| +newGVOP||| +newGVREF||| +newGVgen_flags||5.015004| +newGVgen||| +newHVREF||| +newHVhv||5.005000| +newHV||| +newIO||| +newLISTOP||| +newLOGOP||| +newLOOPEX||| +newLOOPOP||| +newMETHOP_internal||| +newMETHOP_named||5.021005| +newMETHOP||5.021005| +newMYSUB||5.017004| +newNULLLIST||| +newOP||| +newPADNAMELIST||5.021007|n +newPADNAMEouter||5.021007|n +newPADNAMEpvn||5.021007|n +newPADOP||| +newPMOP||| +newPROG||| +newPVOP||| +newRANGE||| +newRV_inc|5.004000||p +newRV_noinc|5.004000||p +newRV||| +newSLICEOP||| +newSTATEOP||| +newSTUB||| +newSUB||| +newSVOP||| +newSVREF||| +newSV_type|5.009005||p +newSVavdefelem||| +newSVhek||5.009003| +newSViv||| +newSVnv||| +newSVpadname||5.017004| +newSVpv_share||5.013006| +newSVpvf_nocontext|||vn +newSVpvf||5.004000|v +newSVpvn_flags|5.010001||p +newSVpvn_share|5.007001||p +newSVpvn_utf8|5.010001||p +newSVpvn|5.004050||p +newSVpvs_flags|5.010001||p +newSVpvs_share|5.009003||p +newSVpvs|5.009003||p +newSVpv||| +newSVrv||| +newSVsv||| +newSVuv|5.006000||p +newSV||| +newUNOP_AUX||5.021007| +newUNOP||| +newWHENOP||5.009003| +newWHILEOP||5.013007| +newXS_deffile||| +newXS_flags||5.009004| +newXS_len_flags||| +newXSproto||5.006000| +newXS||5.006000| +new_collate||5.006000| +new_constant||| +new_ctype||5.006000| +new_he||| +new_logop||| +new_numeric||5.006000| +new_stackinfo||5.005000| +new_version||5.009000| +new_warnings_bitfield||| +next_symbol||| +nextargv||| +nextchar||| +ninstr|||n +no_bareword_allowed||| +no_fh_allowed||| +no_op||| +noperl_die|||vn +not_a_number||| +not_incrementable||| +nothreadhook||5.008000| +nuke_stacks||| +num_overflow|||n +oopsAV||| +oopsHV||| +op_append_elem||5.013006| +op_append_list||5.013006| +op_clear||| +op_contextualize||5.013006| +op_convert_list||5.021006| +op_dump||5.006000| +op_free||| +op_integerize||| +op_linklist||5.013006| +op_lvalue_flags||| +op_lvalue||5.013007| +op_null||5.007002| +op_parent||5.021002|n +op_prepend_elem||5.013006| +op_refcnt_dec||| +op_refcnt_inc||| +op_refcnt_lock||5.009002| +op_refcnt_unlock||5.009002| +op_relocate_sv||| +op_scope||5.013007| +op_sibling_splice||5.021002|n +op_std_init||| +op_unscope||| +open_script||| +openn_cleanup||| +openn_setup||| +opmethod_stash||| +opslab_force_free||| +opslab_free_nopad||| +opslab_free||| +pMY_CXT_|5.007003||p +pMY_CXT|5.007003||p +pTHX_|5.006000||p +pTHX|5.006000||p +packWARN|5.007003||p +pack_cat||5.007003| +pack_rec||| +package_version||| +package||| +packlist||5.008001| +pad_add_anon||5.008001| +pad_add_name_pvn||5.015001| +pad_add_name_pvs||5.015001| +pad_add_name_pv||5.015001| +pad_add_name_sv||5.015001| +pad_add_weakref||| +pad_alloc_name||| +pad_alloc||| +pad_block_start||| +pad_check_dup||| +pad_compname_type||5.009003| +pad_findlex||| +pad_findmy_pvn||5.015001| +pad_findmy_pvs||5.015001| +pad_findmy_pv||5.015001| +pad_findmy_sv||5.015001| +pad_fixup_inner_anons||| +pad_free||| +pad_leavemy||| +pad_new||5.008001| +pad_push||| +pad_reset||| +pad_setsv||| +pad_sv||| +pad_swipe||| +pad_tidy||5.008001| +padlist_dup||| +padlist_store||| +padname_dup||| +padname_free||| +padnamelist_dup||| +padnamelist_fetch||5.021007|n +padnamelist_free||| +padnamelist_store||5.021007| +parse_arithexpr||5.013008| +parse_barestmt||5.013007| +parse_block||5.013007| +parse_body||| +parse_fullexpr||5.013008| +parse_fullstmt||5.013005| +parse_gv_stash_name||| +parse_ident||| +parse_label||5.013007| +parse_listexpr||5.013008| +parse_lparen_question_flags||| +parse_stmtseq||5.013006| +parse_subsignature||| +parse_termexpr||5.013008| +parse_unicode_opts||| +parser_dup||| +parser_free_nexttoke_ops||| +parser_free||| +path_is_searchable|||n +peep||| +pending_ident||| +perl_alloc_using|||n +perl_alloc|||n +perl_clone_using|||n +perl_clone|||n +perl_construct|||n +perl_destruct||5.007003|n +perl_free|||n +perl_parse||5.006000|n +perl_run|||n +pidgone||| +pm_description||| +pmop_dump||5.006000| +pmruntime||| +pmtrans||| +pop_scope||| +populate_ANYOF_from_invlist||| +populate_isa|||v +pregcomp||5.009005| +pregexec||| +pregfree2||5.011000| +pregfree||| +prescan_version||5.011004| +printbuf||| +printf_nocontext|||vn +process_special_blocks||| +ptr_hash|||n +ptr_table_clear||5.009005| +ptr_table_fetch||5.009005| +ptr_table_find|||n +ptr_table_free||5.009005| +ptr_table_new||5.009005| +ptr_table_split||5.009005| +ptr_table_store||5.009005| +push_scope||| +put_charclass_bitmap_innards||| +put_code_point||| +put_range||| +pv_display|5.006000||p +pv_escape|5.009004||p +pv_pretty|5.009004||p +pv_uni_display||5.007003| +qerror||| +qsortsvu||| +quadmath_format_needed|||n +quadmath_format_single|||n +re_compile||5.009005| +re_croak2||| +re_dup_guts||| +re_intuit_start||5.019001| +re_intuit_string||5.006000| +re_op_compile||| +realloc||5.007002|n +reentrant_free||5.021008| +reentrant_init||5.021008| +reentrant_retry||5.021008|vn +reentrant_size||5.021008| +ref_array_or_hash||| +refcounted_he_chain_2hv||| +refcounted_he_fetch_pvn||| +refcounted_he_fetch_pvs||| +refcounted_he_fetch_pv||| +refcounted_he_fetch_sv||| +refcounted_he_free||| +refcounted_he_inc||| +refcounted_he_new_pvn||| +refcounted_he_new_pvs||| +refcounted_he_new_pv||| +refcounted_he_new_sv||| +refcounted_he_value||| +refkids||| +refto||| +ref||5.021008| +reg2Lanode||| +reg_check_named_buff_matched|||n +reg_named_buff_all||5.009005| +reg_named_buff_exists||5.009005| +reg_named_buff_fetch||5.009005| +reg_named_buff_firstkey||5.009005| +reg_named_buff_iter||| +reg_named_buff_nextkey||5.009005| +reg_named_buff_scalar||5.009005| +reg_named_buff||| +reg_node||| +reg_numbered_buff_fetch||| +reg_numbered_buff_length||| +reg_numbered_buff_store||| +reg_qr_package||| +reg_recode||| +reg_scan_name||| +reg_skipcomment|||n +reg_temp_copy||| +reganode||| +regatom||| +regbranch||| +regclass_swash||5.009004| +regclass||| +regcppop||| +regcppush||| +regcurly|||n +regdump_extflags||| +regdump_intflags||| +regdump||5.005000| +regdupe_internal||| +regexec_flags||5.005000| +regfree_internal||5.009005| +reghop3|||n +reghop4|||n +reghopmaybe3|||n +reginclass||| +reginitcolors||5.006000| +reginsert||| +regmatch||| +regnext||5.005000| +regnode_guts||| +regpatws|||n +regpiece||| +regpposixcc||| +regprop||| +regrepeat||| +regtail_study||| +regtail||| +regtry||| +reg||| +repeatcpy|||n +report_evil_fh||| +report_redefined_cv||| +report_uninit||| +report_wrongway_fh||| +require_pv||5.006000| +require_tie_mod||| +restore_magic||| +rninstr|||n +rpeep||| +rsignal_restore||| +rsignal_save||| +rsignal_state||5.004000| +rsignal||5.004000| +run_body||| +run_user_filter||| +runops_debug||5.005000| +runops_standard||5.005000| +rv2cv_op_cv||5.013006| +rvpv_dup||| +rxres_free||| +rxres_restore||| +rxres_save||| +safesyscalloc||5.006000|n +safesysfree||5.006000|n +safesysmalloc||5.006000|n +safesysrealloc||5.006000|n +same_dirent||| +save_I16||5.004000| +save_I32||| +save_I8||5.006000| +save_adelete||5.011000| +save_aelem_flags||5.011000| +save_aelem||5.004050| +save_aliased_sv||| +save_alloc||5.006000| +save_aptr||| +save_ary||| +save_bool||5.008001| +save_clearsv||| +save_delete||| +save_destructor_x||5.006000| +save_destructor||5.006000| +save_freeop||| +save_freepv||| +save_freesv||| +save_generic_pvref||5.006001| +save_generic_svref||5.005030| +save_gp||5.004000| +save_hash||| +save_hdelete||5.011000| +save_hek_flags|||n +save_helem_flags||5.011000| +save_helem||5.004050| +save_hints||5.010001| +save_hptr||| +save_int||| +save_item||| +save_iv||5.005000| +save_lines||| +save_list||| +save_long||| +save_magic_flags||| +save_mortalizesv||5.007001| +save_nogv||| +save_op||5.005000| +save_padsv_and_mortalize||5.010001| +save_pptr||| +save_pushi32ptr||5.010001| +save_pushptri32ptr||| +save_pushptrptr||5.010001| +save_pushptr||5.010001| +save_re_context||5.006000| +save_scalar_at||| +save_scalar||| +save_set_svflags||5.009000| +save_shared_pvref||5.007003| +save_sptr||| +save_strlen||| +save_svref||| +save_vptr||5.006000| +savepvn||| +savepvs||5.009003| +savepv||| +savesharedpvn||5.009005| +savesharedpvs||5.013006| +savesharedpv||5.007003| +savesharedsvpv||5.013006| +savestack_grow_cnt||5.008001| +savestack_grow||| +savesvpv||5.009002| +sawparens||| +scalar_mod_type|||n +scalarboolean||| +scalarkids||| +scalarseq||| +scalarvoid||| +scalar||| +scan_bin||5.006000| +scan_commit||| +scan_const||| +scan_formline||| +scan_heredoc||| +scan_hex||| +scan_ident||| +scan_inputsymbol||| +scan_num||5.007001| +scan_oct||| +scan_pat||| +scan_str||| +scan_subst||| +scan_trans||| +scan_version||5.009001| +scan_vstring||5.009005| +scan_word||| +search_const||| +seed||5.008001| +sequence_num||| +set_ANYOF_arg||| +set_caret_X||| +set_context||5.006000|n +set_numeric_local||5.006000| +set_numeric_radix||5.006000| +set_numeric_standard||5.006000| +set_padlist|||n +setdefout||| +share_hek_flags||| +share_hek||5.004000| +should_warn_nl|||n +si_dup||| +sighandler|||n +simplify_sort||| +skipspace_flags||| +softref2xv||| +sortcv_stacked||| +sortcv_xsub||| +sortcv||| +sortsv_flags||5.009003| +sortsv||5.007003| +space_join_names_mortal||| +ss_dup||| +ssc_add_range||| +ssc_and||| +ssc_anything||| +ssc_clear_locale|||n +ssc_cp_and||| +ssc_finalize||| +ssc_init||| +ssc_intersection||| +ssc_is_anything|||n +ssc_is_cp_posixl_init|||n +ssc_or||| +ssc_union||| +stack_grow||| +start_glob||| +start_subparse||5.004000| +stdize_locale||| +strEQ||| +strGE||| +strGT||| +strLE||| +strLT||| +strNE||| +str_to_version||5.006000| +strip_return||| +strnEQ||| +strnNE||| +study_chunk||| +sub_crush_depth||| +sublex_done||| +sublex_push||| +sublex_start||| +sv_2bool_flags||5.013006| +sv_2bool||| +sv_2cv||| +sv_2io||| +sv_2iuv_common||| +sv_2iuv_non_preserve||| +sv_2iv_flags||5.009001| +sv_2iv||| +sv_2mortal||| +sv_2num||| +sv_2nv_flags||5.013001| +sv_2pv_flags|5.007002||p +sv_2pv_nolen|5.006000||p +sv_2pvbyte_nolen|5.006000||p +sv_2pvbyte|5.006000||p +sv_2pvutf8_nolen||5.006000| +sv_2pvutf8||5.006000| +sv_2pv||| +sv_2uv_flags||5.009001| +sv_2uv|5.004000||p +sv_add_arena||| +sv_add_backref||| +sv_backoff|||n +sv_bless||| +sv_buf_to_ro||| +sv_buf_to_rw||| +sv_cat_decode||5.008001| +sv_catpv_flags||5.013006| +sv_catpv_mg|5.004050||p +sv_catpv_nomg||5.013006| +sv_catpvf_mg_nocontext|||pvn +sv_catpvf_mg|5.006000|5.004000|pv +sv_catpvf_nocontext|||vn +sv_catpvf||5.004000|v +sv_catpvn_flags||5.007002| +sv_catpvn_mg|5.004050||p +sv_catpvn_nomg|5.007002||p +sv_catpvn||| +sv_catpvs_flags||5.013006| +sv_catpvs_mg||5.013006| +sv_catpvs_nomg||5.013006| +sv_catpvs|5.009003||p +sv_catpv||| +sv_catsv_flags||5.007002| +sv_catsv_mg|5.004050||p +sv_catsv_nomg|5.007002||p +sv_catsv||| +sv_chop||| +sv_clean_all||| +sv_clean_objs||| +sv_clear||| +sv_cmp_flags||5.013006| +sv_cmp_locale_flags||5.013006| +sv_cmp_locale||5.004000| +sv_cmp||| +sv_collxfrm_flags||5.013006| +sv_collxfrm||| +sv_copypv_flags||5.017002| +sv_copypv_nomg||5.017002| +sv_copypv||| +sv_dec_nomg||5.013002| +sv_dec||| +sv_del_backref||| +sv_derived_from_pvn||5.015004| +sv_derived_from_pv||5.015004| +sv_derived_from_sv||5.015004| +sv_derived_from||5.004000| +sv_destroyable||5.010000| +sv_display||| +sv_does_pvn||5.015004| +sv_does_pv||5.015004| +sv_does_sv||5.015004| +sv_does||5.009004| +sv_dump||| +sv_dup_common||| +sv_dup_inc_multiple||| +sv_dup_inc||| +sv_dup||| +sv_eq_flags||5.013006| +sv_eq||| +sv_exp_grow||| +sv_force_normal_flags||5.007001| +sv_force_normal||5.006000| +sv_free2||| +sv_free_arenas||| +sv_free||| +sv_get_backrefs||5.021008|n +sv_gets||5.003070| +sv_grow||| +sv_i_ncmp||| +sv_inc_nomg||5.013002| +sv_inc||| +sv_insert_flags||5.010001| +sv_insert||| +sv_isa||| +sv_isobject||| +sv_iv||5.005000| +sv_kill_backrefs||| +sv_len_utf8_nomg||| +sv_len_utf8||5.006000| +sv_len||| +sv_magic_portable|5.021008|5.004000|p +sv_magicext_mglob||| +sv_magicext||5.007003| +sv_magic||| +sv_mortalcopy_flags||| +sv_mortalcopy||| +sv_ncmp||| +sv_newmortal||| +sv_newref||| +sv_nolocking||5.007003| +sv_nosharing||5.007003| +sv_nounlocking||| +sv_nv||5.005000| +sv_only_taint_gmagic|||n +sv_or_pv_pos_u2b||| +sv_peek||5.005000| +sv_pos_b2u_flags||5.019003| +sv_pos_b2u_midway||| +sv_pos_b2u||5.006000| +sv_pos_u2b_cached||| +sv_pos_u2b_flags||5.011005| +sv_pos_u2b_forwards|||n +sv_pos_u2b_midway|||n +sv_pos_u2b||5.006000| +sv_pvbyten_force||5.006000| +sv_pvbyten||5.006000| +sv_pvbyte||5.006000| +sv_pvn_force_flags|5.007002||p +sv_pvn_force||| +sv_pvn_nomg|5.007003|5.005000|p +sv_pvn||5.005000| +sv_pvutf8n_force||5.006000| +sv_pvutf8n||5.006000| +sv_pvutf8||5.006000| +sv_pv||5.006000| +sv_recode_to_utf8||5.007003| +sv_reftype||| +sv_ref||| +sv_release_COW||| +sv_replace||| +sv_report_used||| +sv_resetpvn||| +sv_reset||| +sv_rvweaken||5.006000| +sv_sethek||| +sv_setiv_mg|5.004050||p +sv_setiv||| +sv_setnv_mg|5.006000||p +sv_setnv||| +sv_setpv_mg|5.004050||p +sv_setpvf_mg_nocontext|||pvn +sv_setpvf_mg|5.006000|5.004000|pv +sv_setpvf_nocontext|||vn +sv_setpvf||5.004000|v +sv_setpviv_mg||5.008001| +sv_setpviv||5.008001| +sv_setpvn_mg|5.004050||p +sv_setpvn||| +sv_setpvs_mg||5.013006| +sv_setpvs|5.009004||p +sv_setpv||| +sv_setref_iv||| +sv_setref_nv||| +sv_setref_pvn||| +sv_setref_pvs||5.021008| +sv_setref_pv||| +sv_setref_uv||5.007001| +sv_setsv_cow||| +sv_setsv_flags||5.007002| +sv_setsv_mg|5.004050||p +sv_setsv_nomg|5.007002||p +sv_setsv||| +sv_setuv_mg|5.004050||p +sv_setuv|5.004000||p +sv_tainted||5.004000| +sv_taint||5.004000| +sv_true||5.005000| +sv_unglob||| +sv_uni_display||5.007003| +sv_unmagicext|5.013008||p +sv_unmagic||| +sv_unref_flags||5.007001| +sv_unref||| +sv_untaint||5.004000| +sv_upgrade||| +sv_usepvn_flags||5.009004| +sv_usepvn_mg|5.004050||p +sv_usepvn||| +sv_utf8_decode||5.006000| +sv_utf8_downgrade||5.006000| +sv_utf8_encode||5.006000| +sv_utf8_upgrade_flags_grow||5.011000| +sv_utf8_upgrade_flags||5.007002| +sv_utf8_upgrade_nomg||5.007002| +sv_utf8_upgrade||5.007001| +sv_uv|5.005000||p +sv_vcatpvf_mg|5.006000|5.004000|p +sv_vcatpvfn_flags||5.017002| +sv_vcatpvfn||5.004000| +sv_vcatpvf|5.006000|5.004000|p +sv_vsetpvf_mg|5.006000|5.004000|p +sv_vsetpvfn||5.004000| +sv_vsetpvf|5.006000|5.004000|p +svtype||| +swallow_bom||| +swash_fetch||5.007002| +swash_init||5.006000| +swash_scan_list_line||| +swatch_get||| +sync_locale||5.021004| +sys_init3||5.010000|n +sys_init||5.010000|n +sys_intern_clear||| +sys_intern_dup||| +sys_intern_init||| +sys_term||5.010000|n +taint_env||| +taint_proper||| +tied_method|||v +tmps_grow_p||| +toFOLD_uni||5.007003| +toFOLD_utf8||5.019001| +toFOLD||5.019001| +toLOWER_L1||5.019001| +toLOWER_LC||5.004000| +toLOWER_uni||5.007003| +toLOWER_utf8||5.015007| +toLOWER||| +toTITLE_uni||5.007003| +toTITLE_utf8||5.015007| +toTITLE||5.019001| +toUPPER_uni||5.007003| +toUPPER_utf8||5.015007| +toUPPER||| +to_byte_substr||| +to_lower_latin1|||n +to_uni_fold||5.007003| +to_uni_lower_lc||5.006000| +to_uni_lower||5.007003| +to_uni_title_lc||5.006000| +to_uni_title||5.007003| +to_uni_upper_lc||5.006000| +to_uni_upper||5.007003| +to_utf8_case||5.007003| +to_utf8_fold||5.015007| +to_utf8_lower||5.015007| +to_utf8_substr||| +to_utf8_title||5.015007| +to_utf8_upper||5.015007| +tokenize_use||| +tokeq||| +tokereport||| +too_few_arguments_pv||| +too_many_arguments_pv||| +translate_substr_offsets|||n +try_amagic_bin||| +try_amagic_un||| +uiv_2buf|||n +unlnk||| +unpack_rec||| +unpack_str||5.007003| +unpackstring||5.008001| +unreferenced_to_tmp_stack||| +unshare_hek_or_pvn||| +unshare_hek||| +unsharepvn||5.003070| +unwind_handler_stack||| +update_debugger_info||| +upg_version||5.009005| +usage||| +utf16_textfilter||| +utf16_to_utf8_reversed||5.006001| +utf16_to_utf8||5.006001| +utf8_distance||5.006000| +utf8_hop||5.006000|n +utf8_length||5.007001| +utf8_mg_len_cache_update||| +utf8_mg_pos_cache_update||| +utf8_to_bytes||5.006001| +utf8_to_uvchr_buf||5.015009| +utf8_to_uvchr||5.007001| +utf8_to_uvuni_buf||5.015009| +utf8_to_uvuni||5.007001| +utf8n_to_uvchr||5.007001| +utf8n_to_uvuni||5.007001| +utilize||| +uvchr_to_utf8_flags||5.007003| +uvchr_to_utf8||5.007001| +uvoffuni_to_utf8_flags||5.019004| +uvuni_to_utf8_flags||5.007003| +uvuni_to_utf8||5.007001| +valid_utf8_to_uvchr||5.015009| +valid_utf8_to_uvuni||5.015009| +validate_proto||| +validate_suid||| +varname||| +vcmp||5.009000| +vcroak||5.006000| +vdeb||5.007003| +vform||5.006000| +visit||| +vivify_defelem||| +vivify_ref||| +vload_module|5.006000||p +vmess||5.006000| +vnewSVpvf|5.006000|5.004000|p +vnormal||5.009002| +vnumify||5.009000| +vstringify||5.009000| +vverify||5.009003| +vwarner||5.006000| +vwarn||5.006000| +wait4pid||| +warn_nocontext|||vn +warn_sv||5.013001| +warner_nocontext|||vn +warner|5.006000|5.004000|pv +warn|||v +was_lvalue_sub||| +watch||| +whichsig_pvn||5.015004| +whichsig_pv||5.015004| +whichsig_sv||5.015004| +whichsig||| +win32_croak_not_implemented|||n +with_queued_errors||| +wrap_op_checker||5.015008| +write_to_stderr||| +xs_boot_epilog||| +xs_handshake|||vn +xs_version_bootcheck||| +yyerror_pvn||| +yyerror_pv||| +yyerror||| +yylex||| +yyparse||| +yyunlex||| +yywarn||| +); + +if (exists $opt{'list-unsupported'}) { + my $f; + for $f (sort { lc $a cmp lc $b } keys %API) { + next unless $API{$f}{todo}; + print "$f ", '.'x(40-length($f)), " ", format_version($API{$f}{todo}), "\n"; + } + exit 0; +} + +# Scan for possible replacement candidates + +my(%replace, %need, %hints, %warnings, %depends); +my $replace = 0; +my($hint, $define, $function); + +sub find_api +{ + my $code = shift; + $code =~ s{ + / (?: \*[^*]*\*+(?:[^$ccs][^*]*\*+)* / | /[^\r\n]*) + | "[^"\\]*(?:\\.[^"\\]*)*" + | '[^'\\]*(?:\\.[^'\\]*)*' }{}egsx; + grep { exists $API{$_} } $code =~ /(\w+)/mg; +} + +while () { + if ($hint) { + my $h = $hint->[0] eq 'Hint' ? \%hints : \%warnings; + if (m{^\s*\*\s(.*?)\s*$}) { + for (@{$hint->[1]}) { + $h->{$_} ||= ''; # suppress warning with older perls + $h->{$_} .= "$1\n"; + } + } + else { undef $hint } + } + + $hint = [$1, [split /,?\s+/, $2]] + if m{^\s*$rccs\s+(Hint|Warning):\s+(\w+(?:,?\s+\w+)*)\s*$}; + + if ($define) { + if ($define->[1] =~ /\\$/) { + $define->[1] .= $_; + } + else { + if (exists $API{$define->[0]} && $define->[1] !~ /^DPPP_\(/) { + my @n = find_api($define->[1]); + push @{$depends{$define->[0]}}, @n if @n + } + undef $define; + } + } + + $define = [$1, $2] if m{^\s*#\s*define\s+(\w+)(?:\([^)]*\))?\s+(.*)}; + + if ($function) { + if (/^}/) { + if (exists $API{$function->[0]}) { + my @n = find_api($function->[1]); + push @{$depends{$function->[0]}}, @n if @n + } + undef $function; + } + else { + $function->[1] .= $_; + } + } + + $function = [$1, ''] if m{^DPPP_\(my_(\w+)\)}; + + $replace = $1 if m{^\s*$rccs\s+Replace:\s+(\d+)\s+$rcce\s*$}; + $replace{$2} = $1 if $replace and m{^\s*#\s*define\s+(\w+)(?:\([^)]*\))?\s+(\w+)}; + $replace{$2} = $1 if m{^\s*#\s*define\s+(\w+)(?:\([^)]*\))?\s+(\w+).*$rccs\s+Replace\s+$rcce}; + $replace{$1} = $2 if m{^\s*$rccs\s+Replace (\w+) with (\w+)\s+$rcce\s*$}; + + if (m{^\s*$rccs\s+(\w+(\s*,\s*\w+)*)\s+depends\s+on\s+(\w+(\s*,\s*\w+)*)\s+$rcce\s*$}) { + my @deps = map { s/\s+//g; $_ } split /,/, $3; + my $d; + for $d (map { s/\s+//g; $_ } split /,/, $1) { + push @{$depends{$d}}, @deps; + } + } + + $need{$1} = 1 if m{^#if\s+defined\(NEED_(\w+)(?:_GLOBAL)?\)}; +} + +for (values %depends) { + my %s; + $_ = [sort grep !$s{$_}++, @$_]; +} + +if (exists $opt{'api-info'}) { + my $f; + my $count = 0; + my $match = $opt{'api-info'} =~ m!^/(.*)/$! ? $1 : "^\Q$opt{'api-info'}\E\$"; + for $f (sort { lc $a cmp lc $b } keys %API) { + next unless $f =~ /$match/; + print "\n=== $f ===\n\n"; + my $info = 0; + if ($API{$f}{base} || $API{$f}{todo}) { + my $base = format_version($API{$f}{base} || $API{$f}{todo}); + print "Supported at least starting from perl-$base.\n"; + $info++; + } + if ($API{$f}{provided}) { + my $todo = $API{$f}{todo} ? format_version($API{$f}{todo}) : "5.003"; + print "Support by $ppport provided back to perl-$todo.\n"; + print "Support needs to be explicitly requested by NEED_$f.\n" if exists $need{$f}; + print "Depends on: ", join(', ', @{$depends{$f}}), ".\n" if exists $depends{$f}; + print "\n$hints{$f}" if exists $hints{$f}; + print "\nWARNING:\n$warnings{$f}" if exists $warnings{$f}; + $info++; + } + print "No portability information available.\n" unless $info; + $count++; + } + $count or print "Found no API matching '$opt{'api-info'}'."; + print "\n"; + exit 0; +} + +if (exists $opt{'list-provided'}) { + my $f; + for $f (sort { lc $a cmp lc $b } keys %API) { + next unless $API{$f}{provided}; + my @flags; + push @flags, 'explicit' if exists $need{$f}; + push @flags, 'depend' if exists $depends{$f}; + push @flags, 'hint' if exists $hints{$f}; + push @flags, 'warning' if exists $warnings{$f}; + my $flags = @flags ? ' ['.join(', ', @flags).']' : ''; + print "$f$flags\n"; + } + exit 0; +} + +my @files; +my @srcext = qw( .xs .c .h .cc .cpp -c.inc -xs.inc ); +my $srcext = join '|', map { quotemeta $_ } @srcext; + +if (@ARGV) { + my %seen; + for (@ARGV) { + if (-e) { + if (-f) { + push @files, $_ unless $seen{$_}++; + } + else { warn "'$_' is not a file.\n" } + } + else { + my @new = grep { -f } glob $_ + or warn "'$_' does not exist.\n"; + push @files, grep { !$seen{$_}++ } @new; + } + } +} +else { + eval { + require File::Find; + File::Find::find(sub { + $File::Find::name =~ /($srcext)$/i + and push @files, $File::Find::name; + }, '.'); + }; + if ($@) { + @files = map { glob "*$_" } @srcext; + } +} + +if (!@ARGV || $opt{filter}) { + my(@in, @out); + my %xsc = map { /(.*)\.xs$/ ? ("$1.c" => 1, "$1.cc" => 1) : () } @files; + for (@files) { + my $out = exists $xsc{$_} || /\b\Q$ppport\E$/i || !/($srcext)$/i; + push @{ $out ? \@out : \@in }, $_; + } + if (@ARGV && @out) { + warning("Skipping the following files (use --nofilter to avoid this):\n| ", join "\n| ", @out); + } + @files = @in; +} + +die "No input files given!\n" unless @files; + +my(%files, %global, %revreplace); +%revreplace = reverse %replace; +my $filename; +my $patch_opened = 0; + +for $filename (@files) { + unless (open IN, "<$filename") { + warn "Unable to read from $filename: $!\n"; + next; + } + + info("Scanning $filename ..."); + + my $c = do { local $/; }; + close IN; + + my %file = (orig => $c, changes => 0); + + # Temporarily remove C/XS comments and strings from the code + my @ccom; + + $c =~ s{ + ( ^$HS*\#$HS*include\b[^\r\n]+\b(?:\Q$ppport\E|XSUB\.h)\b[^\r\n]* + | ^$HS*\#$HS*(?:define|elif|if(?:def)?)\b[^\r\n]* ) + | ( ^$HS*\#[^\r\n]* + | "[^"\\]*(?:\\.[^"\\]*)*" + | '[^'\\]*(?:\\.[^'\\]*)*' + | / (?: \*[^*]*\*+(?:[^$ccs][^*]*\*+)* / | /[^\r\n]* ) ) + }{ defined $2 and push @ccom, $2; + defined $1 ? $1 : "$ccs$#ccom$cce" }mgsex; + + $file{ccom} = \@ccom; + $file{code} = $c; + $file{has_inc_ppport} = $c =~ /^$HS*#$HS*include[^\r\n]+\b\Q$ppport\E\b/m; + + my $func; + + for $func (keys %API) { + my $match = $func; + $match .= "|$revreplace{$func}" if exists $revreplace{$func}; + if ($c =~ /\b(?:Perl_)?($match)\b/) { + $file{uses_replace}{$1}++ if exists $revreplace{$func} && $1 eq $revreplace{$func}; + $file{uses_Perl}{$func}++ if $c =~ /\bPerl_$func\b/; + if (exists $API{$func}{provided}) { + $file{uses_provided}{$func}++; + if (!exists $API{$func}{base} || $API{$func}{base} > $opt{'compat-version'}) { + $file{uses}{$func}++; + my @deps = rec_depend($func); + if (@deps) { + $file{uses_deps}{$func} = \@deps; + for (@deps) { + $file{uses}{$_} = 0 unless exists $file{uses}{$_}; + } + } + for ($func, @deps) { + $file{needs}{$_} = 'static' if exists $need{$_}; + } + } + } + if (exists $API{$func}{todo} && $API{$func}{todo} > $opt{'compat-version'}) { + if ($c =~ /\b$func\b/) { + $file{uses_todo}{$func}++; + } + } + } + } + + while ($c =~ /^$HS*#$HS*define$HS+(NEED_(\w+?)(_GLOBAL)?)\b/mg) { + if (exists $need{$2}) { + $file{defined $3 ? 'needed_global' : 'needed_static'}{$2}++; + } + else { warning("Possibly wrong #define $1 in $filename") } + } + + for (qw(uses needs uses_todo needed_global needed_static)) { + for $func (keys %{$file{$_}}) { + push @{$global{$_}{$func}}, $filename; + } + } + + $files{$filename} = \%file; +} + +# Globally resolve NEED_'s +my $need; +for $need (keys %{$global{needs}}) { + if (@{$global{needs}{$need}} > 1) { + my @targets = @{$global{needs}{$need}}; + my @t = grep $files{$_}{needed_global}{$need}, @targets; + @targets = @t if @t; + @t = grep /\.xs$/i, @targets; + @targets = @t if @t; + my $target = shift @targets; + $files{$target}{needs}{$need} = 'global'; + for (@{$global{needs}{$need}}) { + $files{$_}{needs}{$need} = 'extern' if $_ ne $target; + } + } +} + +for $filename (@files) { + exists $files{$filename} or next; + + info("=== Analyzing $filename ==="); + + my %file = %{$files{$filename}}; + my $func; + my $c = $file{code}; + my $warnings = 0; + + for $func (sort keys %{$file{uses_Perl}}) { + if ($API{$func}{varargs}) { + unless ($API{$func}{nothxarg}) { + my $changes = ($c =~ s{\b(Perl_$func\s*\(\s*)(?!aTHX_?)(\)|[^\s)]*\))} + { $1 . ($2 eq ')' ? 'aTHX' : 'aTHX_ ') . $2 }ge); + if ($changes) { + warning("Doesn't pass interpreter argument aTHX to Perl_$func"); + $file{changes} += $changes; + } + } + } + else { + warning("Uses Perl_$func instead of $func"); + $file{changes} += ($c =~ s{\bPerl_$func(\s*)\((\s*aTHX_?)?\s*} + {$func$1(}g); + } + } + + for $func (sort keys %{$file{uses_replace}}) { + warning("Uses $func instead of $replace{$func}"); + $file{changes} += ($c =~ s/\b$func\b/$replace{$func}/g); + } + + for $func (sort keys %{$file{uses_provided}}) { + if ($file{uses}{$func}) { + if (exists $file{uses_deps}{$func}) { + diag("Uses $func, which depends on ", join(', ', @{$file{uses_deps}{$func}})); + } + else { + diag("Uses $func"); + } + } + $warnings += hint($func); + } + + unless ($opt{quiet}) { + for $func (sort keys %{$file{uses_todo}}) { + print "*** WARNING: Uses $func, which may not be portable below perl ", + format_version($API{$func}{todo}), ", even with '$ppport'\n"; + $warnings++; + } + } + + for $func (sort keys %{$file{needed_static}}) { + my $message = ''; + if (not exists $file{uses}{$func}) { + $message = "No need to define NEED_$func if $func is never used"; + } + elsif (exists $file{needs}{$func} && $file{needs}{$func} ne 'static') { + $message = "No need to define NEED_$func when already needed globally"; + } + if ($message) { + diag($message); + $file{changes} += ($c =~ s/^$HS*#$HS*define$HS+NEED_$func\b.*$LF//mg); + } + } + + for $func (sort keys %{$file{needed_global}}) { + my $message = ''; + if (not exists $global{uses}{$func}) { + $message = "No need to define NEED_${func}_GLOBAL if $func is never used"; + } + elsif (exists $file{needs}{$func}) { + if ($file{needs}{$func} eq 'extern') { + $message = "No need to define NEED_${func}_GLOBAL when already needed globally"; + } + elsif ($file{needs}{$func} eq 'static') { + $message = "No need to define NEED_${func}_GLOBAL when only used in this file"; + } + } + if ($message) { + diag($message); + $file{changes} += ($c =~ s/^$HS*#$HS*define$HS+NEED_${func}_GLOBAL\b.*$LF//mg); + } + } + + $file{needs_inc_ppport} = keys %{$file{uses}}; + + if ($file{needs_inc_ppport}) { + my $pp = ''; + + for $func (sort keys %{$file{needs}}) { + my $type = $file{needs}{$func}; + next if $type eq 'extern'; + my $suffix = $type eq 'global' ? '_GLOBAL' : ''; + unless (exists $file{"needed_$type"}{$func}) { + if ($type eq 'global') { + diag("Files [@{$global{needs}{$func}}] need $func, adding global request"); + } + else { + diag("File needs $func, adding static request"); + } + $pp .= "#define NEED_$func$suffix\n"; + } + } + + if ($pp && ($c =~ s/^(?=$HS*#$HS*define$HS+NEED_\w+)/$pp/m)) { + $pp = ''; + $file{changes}++; + } + + unless ($file{has_inc_ppport}) { + diag("Needs to include '$ppport'"); + $pp .= qq(#include "$ppport"\n) + } + + if ($pp) { + $file{changes} += ($c =~ s/^($HS*#$HS*define$HS+NEED_\w+.*?)^/$1$pp/ms) + || ($c =~ s/^(?=$HS*#$HS*include.*\Q$ppport\E)/$pp/m) + || ($c =~ s/^($HS*#$HS*include.*XSUB.*\s*?)^/$1$pp/m) + || ($c =~ s/^/$pp/); + } + } + else { + if ($file{has_inc_ppport}) { + diag("No need to include '$ppport'"); + $file{changes} += ($c =~ s/^$HS*?#$HS*include.*\Q$ppport\E.*?$LF//m); + } + } + + # put back in our C comments + my $ix; + my $cppc = 0; + my @ccom = @{$file{ccom}}; + for $ix (0 .. $#ccom) { + if (!$opt{cplusplus} && $ccom[$ix] =~ s!^//!!) { + $cppc++; + $file{changes} += $c =~ s/$rccs$ix$rcce/$ccs$ccom[$ix] $cce/; + } + else { + $c =~ s/$rccs$ix$rcce/$ccom[$ix]/; + } + } + + if ($cppc) { + my $s = $cppc != 1 ? 's' : ''; + warning("Uses $cppc C++ style comment$s, which is not portable"); + } + + my $s = $warnings != 1 ? 's' : ''; + my $warn = $warnings ? " ($warnings warning$s)" : ''; + info("Analysis completed$warn"); + + if ($file{changes}) { + if (exists $opt{copy}) { + my $newfile = "$filename$opt{copy}"; + if (-e $newfile) { + error("'$newfile' already exists, refusing to write copy of '$filename'"); + } + else { + local *F; + if (open F, ">$newfile") { + info("Writing copy of '$filename' with changes to '$newfile'"); + print F $c; + close F; + } + else { + error("Cannot open '$newfile' for writing: $!"); + } + } + } + elsif (exists $opt{patch} || $opt{changes}) { + if (exists $opt{patch}) { + unless ($patch_opened) { + if (open PATCH, ">$opt{patch}") { + $patch_opened = 1; + } + else { + error("Cannot open '$opt{patch}' for writing: $!"); + delete $opt{patch}; + $opt{changes} = 1; + goto fallback; + } + } + mydiff(\*PATCH, $filename, $c); + } + else { +fallback: + info("Suggested changes:"); + mydiff(\*STDOUT, $filename, $c); + } + } + else { + my $s = $file{changes} == 1 ? '' : 's'; + info("$file{changes} potentially required change$s detected"); + } + } + else { + info("Looks good"); + } +} + +close PATCH if $patch_opened; + +exit 0; + + +sub try_use { eval "use @_;"; return $@ eq '' } + +sub mydiff +{ + local *F = shift; + my($file, $str) = @_; + my $diff; + + if (exists $opt{diff}) { + $diff = run_diff($opt{diff}, $file, $str); + } + + if (!defined $diff and try_use('Text::Diff')) { + $diff = Text::Diff::diff($file, \$str, { STYLE => 'Unified' }); + $diff = <
$tmp") { + print F $str; + close F; + + if (open F, "$prog $file $tmp |") { + while () { + s/\Q$tmp\E/$file.patched/; + $diff .= $_; + } + close F; + unlink $tmp; + return $diff; + } + + unlink $tmp; + } + else { + error("Cannot open '$tmp' for writing: $!"); + } + + return undef; +} + +sub rec_depend +{ + my($func, $seen) = @_; + return () unless exists $depends{$func}; + $seen = {%{$seen||{}}}; + return () if $seen->{$func}++; + my %s; + grep !$s{$_}++, map { ($_, rec_depend($_, $seen)) } @{$depends{$func}}; +} + +sub parse_version +{ + my $ver = shift; + + if ($ver =~ /^(\d+)\.(\d+)\.(\d+)$/) { + return ($1, $2, $3); + } + elsif ($ver !~ /^\d+\.[\d_]+$/) { + die "cannot parse version '$ver'\n"; + } + + $ver =~ s/_//g; + $ver =~ s/$/000000/; + + my($r,$v,$s) = $ver =~ /(\d+)\.(\d{3})(\d{3})/; + + $v = int $v; + $s = int $s; + + if ($r < 5 || ($r == 5 && $v < 6)) { + if ($s % 10) { + die "cannot parse version '$ver'\n"; + } + } + + return ($r, $v, $s); +} + +sub format_version +{ + my $ver = shift; + + $ver =~ s/$/000000/; + my($r,$v,$s) = $ver =~ /(\d+)\.(\d{3})(\d{3})/; + + $v = int $v; + $s = int $s; + + if ($r < 5 || ($r == 5 && $v < 6)) { + if ($s % 10) { + die "invalid version '$ver'\n"; + } + $s /= 10; + + $ver = sprintf "%d.%03d", $r, $v; + $s > 0 and $ver .= sprintf "_%02d", $s; + + return $ver; + } + + return sprintf "%d.%d.%d", $r, $v, $s; +} + +sub info +{ + $opt{quiet} and return; + print @_, "\n"; +} + +sub diag +{ + $opt{quiet} and return; + $opt{diag} and print @_, "\n"; +} + +sub warning +{ + $opt{quiet} and return; + print "*** ", @_, "\n"; +} + +sub error +{ + print "*** ERROR: ", @_, "\n"; +} + +my %given_hints; +my %given_warnings; +sub hint +{ + $opt{quiet} and return; + my $func = shift; + my $rv = 0; + if (exists $warnings{$func} && !$given_warnings{$func}++) { + my $warn = $warnings{$func}; + $warn =~ s!^!*** !mg; + print "*** WARNING: $func\n", $warn; + $rv++; + } + if ($opt{hints} && exists $hints{$func} && !$given_hints{$func}++) { + my $hint = $hints{$func}; + $hint =~ s/^/ /mg; + print " --- hint for $func ---\n", $hint; + } + $rv; +} + +sub usage +{ + my($usage) = do { local(@ARGV,$/)=($0); <> } =~ /^=head\d$HS+SYNOPSIS\s*^(.*?)\s*^=/ms; + my %M = ( 'I' => '*' ); + $usage =~ s/^\s*perl\s+\S+/$^X $0/; + $usage =~ s/([A-Z])<([^>]+)>/$M{$1}$2$M{$1}/g; + + print < }; + my($copy) = $self =~ /^=head\d\s+COPYRIGHT\s*^(.*?)^=\w+/ms; + $copy =~ s/^(?=\S+)/ /gms; + $self =~ s/^$HS+Do NOT edit.*?(?=^-)/$copy/ms; + $self =~ s/^SKIP.*(?=^__DATA__)/SKIP +if (\@ARGV && \$ARGV[0] eq '--unstrip') { + eval { require Devel::PPPort }; + \$@ and die "Cannot require Devel::PPPort, please install.\\n"; + if (eval \$Devel::PPPort::VERSION < $VERSION) { + die "$0 was originally generated with Devel::PPPort $VERSION.\\n" + . "Your Devel::PPPort is only version \$Devel::PPPort::VERSION.\\n" + . "Please install a newer version, or --unstrip will not work.\\n"; + } + Devel::PPPort::WriteFile(\$0); + exit 0; +} +print <$0" or die "cannot strip $0: $!\n"; + print OUT "$pl$c\n"; + + exit 0; +} + +__DATA__ +*/ + +#ifndef _P_P_PORTABILITY_H_ +#define _P_P_PORTABILITY_H_ + +#ifndef DPPP_NAMESPACE +# define DPPP_NAMESPACE DPPP_ +#endif + +#define DPPP_CAT2(x,y) CAT2(x,y) +#define DPPP_(name) DPPP_CAT2(DPPP_NAMESPACE, name) + +#ifndef PERL_REVISION +# if !defined(__PATCHLEVEL_H_INCLUDED__) && !(defined(PATCHLEVEL) && defined(SUBVERSION)) +# define PERL_PATCHLEVEL_H_IMPLICIT +# include +# endif +# if !(defined(PERL_VERSION) || (defined(SUBVERSION) && defined(PATCHLEVEL))) +# include +# endif +# ifndef PERL_REVISION +# define PERL_REVISION (5) + /* Replace: 1 */ +# define PERL_VERSION PATCHLEVEL +# define PERL_SUBVERSION SUBVERSION + /* Replace PERL_PATCHLEVEL with PERL_VERSION */ + /* Replace: 0 */ +# endif +#endif + +#define _dpppDEC2BCD(dec) ((((dec)/100)<<8)|((((dec)%100)/10)<<4)|((dec)%10)) +#define PERL_BCDVERSION ((_dpppDEC2BCD(PERL_REVISION)<<24)|(_dpppDEC2BCD(PERL_VERSION)<<12)|_dpppDEC2BCD(PERL_SUBVERSION)) + +/* It is very unlikely that anyone will try to use this with Perl 6 + (or greater), but who knows. + */ +#if PERL_REVISION != 5 +# error ppport.h only works with Perl version 5 +#endif /* PERL_REVISION != 5 */ +#ifndef dTHR +# define dTHR dNOOP +#endif +#ifndef dTHX +# define dTHX dNOOP +#endif + +#ifndef dTHXa +# define dTHXa(x) dNOOP +#endif +#ifndef pTHX +# define pTHX void +#endif + +#ifndef pTHX_ +# define pTHX_ +#endif + +#ifndef aTHX +# define aTHX +#endif + +#ifndef aTHX_ +# define aTHX_ +#endif + +#if (PERL_BCDVERSION < 0x5006000) +# ifdef USE_THREADS +# define aTHXR thr +# define aTHXR_ thr, +# else +# define aTHXR +# define aTHXR_ +# endif +# define dTHXR dTHR +#else +# define aTHXR aTHX +# define aTHXR_ aTHX_ +# define dTHXR dTHX +#endif +#ifndef dTHXoa +# define dTHXoa(x) dTHXa(x) +#endif + +#ifdef I_LIMITS +# include +#endif + +#ifndef PERL_UCHAR_MIN +# define PERL_UCHAR_MIN ((unsigned char)0) +#endif + +#ifndef PERL_UCHAR_MAX +# ifdef UCHAR_MAX +# define PERL_UCHAR_MAX ((unsigned char)UCHAR_MAX) +# else +# ifdef MAXUCHAR +# define PERL_UCHAR_MAX ((unsigned char)MAXUCHAR) +# else +# define PERL_UCHAR_MAX ((unsigned char)~(unsigned)0) +# endif +# endif +#endif + +#ifndef PERL_USHORT_MIN +# define PERL_USHORT_MIN ((unsigned short)0) +#endif + +#ifndef PERL_USHORT_MAX +# ifdef USHORT_MAX +# define PERL_USHORT_MAX ((unsigned short)USHORT_MAX) +# else +# ifdef MAXUSHORT +# define PERL_USHORT_MAX ((unsigned short)MAXUSHORT) +# else +# ifdef USHRT_MAX +# define PERL_USHORT_MAX ((unsigned short)USHRT_MAX) +# else +# define PERL_USHORT_MAX ((unsigned short)~(unsigned)0) +# endif +# endif +# endif +#endif + +#ifndef PERL_SHORT_MAX +# ifdef SHORT_MAX +# define PERL_SHORT_MAX ((short)SHORT_MAX) +# else +# ifdef MAXSHORT /* Often used in */ +# define PERL_SHORT_MAX ((short)MAXSHORT) +# else +# ifdef SHRT_MAX +# define PERL_SHORT_MAX ((short)SHRT_MAX) +# else +# define PERL_SHORT_MAX ((short) (PERL_USHORT_MAX >> 1)) +# endif +# endif +# endif +#endif + +#ifndef PERL_SHORT_MIN +# ifdef SHORT_MIN +# define PERL_SHORT_MIN ((short)SHORT_MIN) +# else +# ifdef MINSHORT +# define PERL_SHORT_MIN ((short)MINSHORT) +# else +# ifdef SHRT_MIN +# define PERL_SHORT_MIN ((short)SHRT_MIN) +# else +# define PERL_SHORT_MIN (-PERL_SHORT_MAX - ((3 & -1) == 3)) +# endif +# endif +# endif +#endif + +#ifndef PERL_UINT_MAX +# ifdef UINT_MAX +# define PERL_UINT_MAX ((unsigned int)UINT_MAX) +# else +# ifdef MAXUINT +# define PERL_UINT_MAX ((unsigned int)MAXUINT) +# else +# define PERL_UINT_MAX (~(unsigned int)0) +# endif +# endif +#endif + +#ifndef PERL_UINT_MIN +# define PERL_UINT_MIN ((unsigned int)0) +#endif + +#ifndef PERL_INT_MAX +# ifdef INT_MAX +# define PERL_INT_MAX ((int)INT_MAX) +# else +# ifdef MAXINT /* Often used in */ +# define PERL_INT_MAX ((int)MAXINT) +# else +# define PERL_INT_MAX ((int)(PERL_UINT_MAX >> 1)) +# endif +# endif +#endif + +#ifndef PERL_INT_MIN +# ifdef INT_MIN +# define PERL_INT_MIN ((int)INT_MIN) +# else +# ifdef MININT +# define PERL_INT_MIN ((int)MININT) +# else +# define PERL_INT_MIN (-PERL_INT_MAX - ((3 & -1) == 3)) +# endif +# endif +#endif + +#ifndef PERL_ULONG_MAX +# ifdef ULONG_MAX +# define PERL_ULONG_MAX ((unsigned long)ULONG_MAX) +# else +# ifdef MAXULONG +# define PERL_ULONG_MAX ((unsigned long)MAXULONG) +# else +# define PERL_ULONG_MAX (~(unsigned long)0) +# endif +# endif +#endif + +#ifndef PERL_ULONG_MIN +# define PERL_ULONG_MIN ((unsigned long)0L) +#endif + +#ifndef PERL_LONG_MAX +# ifdef LONG_MAX +# define PERL_LONG_MAX ((long)LONG_MAX) +# else +# ifdef MAXLONG +# define PERL_LONG_MAX ((long)MAXLONG) +# else +# define PERL_LONG_MAX ((long) (PERL_ULONG_MAX >> 1)) +# endif +# endif +#endif + +#ifndef PERL_LONG_MIN +# ifdef LONG_MIN +# define PERL_LONG_MIN ((long)LONG_MIN) +# else +# ifdef MINLONG +# define PERL_LONG_MIN ((long)MINLONG) +# else +# define PERL_LONG_MIN (-PERL_LONG_MAX - ((3 & -1) == 3)) +# endif +# endif +#endif + +#if defined(HAS_QUAD) && (defined(convex) || defined(uts)) +# ifndef PERL_UQUAD_MAX +# ifdef ULONGLONG_MAX +# define PERL_UQUAD_MAX ((unsigned long long)ULONGLONG_MAX) +# else +# ifdef MAXULONGLONG +# define PERL_UQUAD_MAX ((unsigned long long)MAXULONGLONG) +# else +# define PERL_UQUAD_MAX (~(unsigned long long)0) +# endif +# endif +# endif + +# ifndef PERL_UQUAD_MIN +# define PERL_UQUAD_MIN ((unsigned long long)0L) +# endif + +# ifndef PERL_QUAD_MAX +# ifdef LONGLONG_MAX +# define PERL_QUAD_MAX ((long long)LONGLONG_MAX) +# else +# ifdef MAXLONGLONG +# define PERL_QUAD_MAX ((long long)MAXLONGLONG) +# else +# define PERL_QUAD_MAX ((long long) (PERL_UQUAD_MAX >> 1)) +# endif +# endif +# endif + +# ifndef PERL_QUAD_MIN +# ifdef LONGLONG_MIN +# define PERL_QUAD_MIN ((long long)LONGLONG_MIN) +# else +# ifdef MINLONGLONG +# define PERL_QUAD_MIN ((long long)MINLONGLONG) +# else +# define PERL_QUAD_MIN (-PERL_QUAD_MAX - ((3 & -1) == 3)) +# endif +# endif +# endif +#endif + +/* This is based on code from 5.003 perl.h */ +#ifdef HAS_QUAD +# ifdef cray +#ifndef IVTYPE +# define IVTYPE int +#endif + +#ifndef IV_MIN +# define IV_MIN PERL_INT_MIN +#endif + +#ifndef IV_MAX +# define IV_MAX PERL_INT_MAX +#endif + +#ifndef UV_MIN +# define UV_MIN PERL_UINT_MIN +#endif + +#ifndef UV_MAX +# define UV_MAX PERL_UINT_MAX +#endif + +# ifdef INTSIZE +#ifndef IVSIZE +# define IVSIZE INTSIZE +#endif + +# endif +# else +# if defined(convex) || defined(uts) +#ifndef IVTYPE +# define IVTYPE long long +#endif + +#ifndef IV_MIN +# define IV_MIN PERL_QUAD_MIN +#endif + +#ifndef IV_MAX +# define IV_MAX PERL_QUAD_MAX +#endif + +#ifndef UV_MIN +# define UV_MIN PERL_UQUAD_MIN +#endif + +#ifndef UV_MAX +# define UV_MAX PERL_UQUAD_MAX +#endif + +# ifdef LONGLONGSIZE +#ifndef IVSIZE +# define IVSIZE LONGLONGSIZE +#endif + +# endif +# else +#ifndef IVTYPE +# define IVTYPE long +#endif + +#ifndef IV_MIN +# define IV_MIN PERL_LONG_MIN +#endif + +#ifndef IV_MAX +# define IV_MAX PERL_LONG_MAX +#endif + +#ifndef UV_MIN +# define UV_MIN PERL_ULONG_MIN +#endif + +#ifndef UV_MAX +# define UV_MAX PERL_ULONG_MAX +#endif + +# ifdef LONGSIZE +#ifndef IVSIZE +# define IVSIZE LONGSIZE +#endif + +# endif +# endif +# endif +#ifndef IVSIZE +# define IVSIZE 8 +#endif + +#ifndef LONGSIZE +# define LONGSIZE 8 +#endif + +#ifndef PERL_QUAD_MIN +# define PERL_QUAD_MIN IV_MIN +#endif + +#ifndef PERL_QUAD_MAX +# define PERL_QUAD_MAX IV_MAX +#endif + +#ifndef PERL_UQUAD_MIN +# define PERL_UQUAD_MIN UV_MIN +#endif + +#ifndef PERL_UQUAD_MAX +# define PERL_UQUAD_MAX UV_MAX +#endif + +#else +#ifndef IVTYPE +# define IVTYPE long +#endif + +#ifndef LONGSIZE +# define LONGSIZE 4 +#endif + +#ifndef IV_MIN +# define IV_MIN PERL_LONG_MIN +#endif + +#ifndef IV_MAX +# define IV_MAX PERL_LONG_MAX +#endif + +#ifndef UV_MIN +# define UV_MIN PERL_ULONG_MIN +#endif + +#ifndef UV_MAX +# define UV_MAX PERL_ULONG_MAX +#endif + +#endif + +#ifndef IVSIZE +# ifdef LONGSIZE +# define IVSIZE LONGSIZE +# else +# define IVSIZE 4 /* A bold guess, but the best we can make. */ +# endif +#endif +#ifndef UVTYPE +# define UVTYPE unsigned IVTYPE +#endif + +#ifndef UVSIZE +# define UVSIZE IVSIZE +#endif +#ifndef sv_setuv +# define sv_setuv(sv, uv) \ + STMT_START { \ + UV TeMpUv = uv; \ + if (TeMpUv <= IV_MAX) \ + sv_setiv(sv, TeMpUv); \ + else \ + sv_setnv(sv, (double)TeMpUv); \ + } STMT_END +#endif +#ifndef newSVuv +# define newSVuv(uv) ((uv) <= IV_MAX ? newSViv((IV)uv) : newSVnv((NV)uv)) +#endif +#ifndef sv_2uv +# define sv_2uv(sv) ((PL_Sv = (sv)), (UV) (SvNOK(PL_Sv) ? SvNV(PL_Sv) : sv_2nv(PL_Sv))) +#endif + +#ifndef SvUVX +# define SvUVX(sv) ((UV)SvIVX(sv)) +#endif + +#ifndef SvUVXx +# define SvUVXx(sv) SvUVX(sv) +#endif + +#ifndef SvUV +# define SvUV(sv) (SvIOK(sv) ? SvUVX(sv) : sv_2uv(sv)) +#endif + +#ifndef SvUVx +# define SvUVx(sv) ((PL_Sv = (sv)), SvUV(PL_Sv)) +#endif + +/* Hint: sv_uv + * Always use the SvUVx() macro instead of sv_uv(). + */ +#ifndef sv_uv +# define sv_uv(sv) SvUVx(sv) +#endif + +#if !defined(SvUOK) && defined(SvIOK_UV) +# define SvUOK(sv) SvIOK_UV(sv) +#endif +#ifndef XST_mUV +# define XST_mUV(i,v) (ST(i) = sv_2mortal(newSVuv(v)) ) +#endif + +#ifndef XSRETURN_UV +# define XSRETURN_UV(v) STMT_START { XST_mUV(0,v); XSRETURN(1); } STMT_END +#endif +#ifndef PUSHu +# define PUSHu(u) STMT_START { sv_setuv(TARG, (UV)(u)); PUSHTARG; } STMT_END +#endif + +#ifndef XPUSHu +# define XPUSHu(u) STMT_START { sv_setuv(TARG, (UV)(u)); XPUSHTARG; } STMT_END +#endif + +#ifdef HAS_MEMCMP +#ifndef memNE +# define memNE(s1,s2,l) (memcmp(s1,s2,l)) +#endif + +#ifndef memEQ +# define memEQ(s1,s2,l) (!memcmp(s1,s2,l)) +#endif + +#else +#ifndef memNE +# define memNE(s1,s2,l) (bcmp(s1,s2,l)) +#endif + +#ifndef memEQ +# define memEQ(s1,s2,l) (!bcmp(s1,s2,l)) +#endif + +#endif +#ifndef memEQs +# define memEQs(s1, l, s2) \ + (sizeof(s2)-1 == l && memEQ(s1, (s2 ""), (sizeof(s2)-1))) +#endif + +#ifndef memNEs +# define memNEs(s1, l, s2) !memEQs(s1, l, s2) +#endif +#ifndef MoveD +# define MoveD(s,d,n,t) memmove((char*)(d),(char*)(s), (n) * sizeof(t)) +#endif + +#ifndef CopyD +# define CopyD(s,d,n,t) memcpy((char*)(d),(char*)(s), (n) * sizeof(t)) +#endif + +#ifdef HAS_MEMSET +#ifndef ZeroD +# define ZeroD(d,n,t) memzero((char*)(d), (n) * sizeof(t)) +#endif + +#else +#ifndef ZeroD +# define ZeroD(d,n,t) ((void)memzero((char*)(d), (n) * sizeof(t)), d) +#endif + +#endif +#ifndef PoisonWith +# define PoisonWith(d,n,t,b) (void)memset((char*)(d), (U8)(b), (n) * sizeof(t)) +#endif + +#ifndef PoisonNew +# define PoisonNew(d,n,t) PoisonWith(d,n,t,0xAB) +#endif + +#ifndef PoisonFree +# define PoisonFree(d,n,t) PoisonWith(d,n,t,0xEF) +#endif + +#ifndef Poison +# define Poison(d,n,t) PoisonFree(d,n,t) +#endif +#ifndef Newx +# define Newx(v,n,t) New(0,v,n,t) +#endif + +#ifndef Newxc +# define Newxc(v,n,t,c) Newc(0,v,n,t,c) +#endif + +#ifndef Newxz +# define Newxz(v,n,t) Newz(0,v,n,t) +#endif + +#ifndef PERL_UNUSED_DECL +# ifdef HASATTRIBUTE +# if (defined(__GNUC__) && defined(__cplusplus)) || defined(__INTEL_COMPILER) +# define PERL_UNUSED_DECL +# else +# define PERL_UNUSED_DECL __attribute__((unused)) +# endif +# else +# define PERL_UNUSED_DECL +# endif +#endif + +#ifndef PERL_UNUSED_ARG +# if defined(lint) && defined(S_SPLINT_S) /* www.splint.org */ +# include +# define PERL_UNUSED_ARG(x) NOTE(ARGUNUSED(x)) +# else +# define PERL_UNUSED_ARG(x) ((void)x) +# endif +#endif + +#ifndef PERL_UNUSED_VAR +# define PERL_UNUSED_VAR(x) ((void)x) +#endif + +#ifndef PERL_UNUSED_CONTEXT +# ifdef USE_ITHREADS +# define PERL_UNUSED_CONTEXT PERL_UNUSED_ARG(my_perl) +# else +# define PERL_UNUSED_CONTEXT +# endif +#endif +#ifndef NOOP +# define NOOP /*EMPTY*/(void)0 +#endif + +#ifndef dNOOP +# define dNOOP extern int /*@unused@*/ Perl___notused PERL_UNUSED_DECL +#endif + +#ifndef NVTYPE +# if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE) +# define NVTYPE long double +# else +# define NVTYPE double +# endif +typedef NVTYPE NV; +#endif + +#ifndef INT2PTR +# if (IVSIZE == PTRSIZE) && (UVSIZE == PTRSIZE) +# define PTRV UV +# define INT2PTR(any,d) (any)(d) +# else +# if PTRSIZE == LONGSIZE +# define PTRV unsigned long +# else +# define PTRV unsigned +# endif +# define INT2PTR(any,d) (any)(PTRV)(d) +# endif +#endif + +#ifndef PTR2ul +# if PTRSIZE == LONGSIZE +# define PTR2ul(p) (unsigned long)(p) +# else +# define PTR2ul(p) INT2PTR(unsigned long,p) +# endif +#endif +#ifndef PTR2nat +# define PTR2nat(p) (PTRV)(p) +#endif + +#ifndef NUM2PTR +# define NUM2PTR(any,d) (any)PTR2nat(d) +#endif + +#ifndef PTR2IV +# define PTR2IV(p) INT2PTR(IV,p) +#endif + +#ifndef PTR2UV +# define PTR2UV(p) INT2PTR(UV,p) +#endif + +#ifndef PTR2NV +# define PTR2NV(p) NUM2PTR(NV,p) +#endif + +#undef START_EXTERN_C +#undef END_EXTERN_C +#undef EXTERN_C +#ifdef __cplusplus +# define START_EXTERN_C extern "C" { +# define END_EXTERN_C } +# define EXTERN_C extern "C" +#else +# define START_EXTERN_C +# define END_EXTERN_C +# define EXTERN_C extern +#endif + +#if defined(PERL_GCC_PEDANTIC) +# ifndef PERL_GCC_BRACE_GROUPS_FORBIDDEN +# define PERL_GCC_BRACE_GROUPS_FORBIDDEN +# endif +#endif + +#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) && !defined(__cplusplus) +# ifndef PERL_USE_GCC_BRACE_GROUPS +# define PERL_USE_GCC_BRACE_GROUPS +# endif +#endif + +#undef STMT_START +#undef STMT_END +#ifdef PERL_USE_GCC_BRACE_GROUPS +# define STMT_START (void)( /* gcc supports ``({ STATEMENTS; })'' */ +# define STMT_END ) +#else +# if defined(VOIDFLAGS) && (VOIDFLAGS) && (defined(sun) || defined(__sun__)) && !defined(__GNUC__) +# define STMT_START if (1) +# define STMT_END else (void)0 +# else +# define STMT_START do +# define STMT_END while (0) +# endif +#endif +#ifndef boolSV +# define boolSV(b) ((b) ? &PL_sv_yes : &PL_sv_no) +#endif + +/* DEFSV appears first in 5.004_56 */ +#ifndef DEFSV +# define DEFSV GvSV(PL_defgv) +#endif + +#ifndef SAVE_DEFSV +# define SAVE_DEFSV SAVESPTR(GvSV(PL_defgv)) +#endif + +#ifndef DEFSV_set +# define DEFSV_set(sv) (DEFSV = (sv)) +#endif + +/* Older perls (<=5.003) lack AvFILLp */ +#ifndef AvFILLp +# define AvFILLp AvFILL +#endif +#ifndef ERRSV +# define ERRSV get_sv("@",FALSE) +#endif + +/* Hint: gv_stashpvn + * This function's backport doesn't support the length parameter, but + * rather ignores it. Portability can only be ensured if the length + * parameter is used for speed reasons, but the length can always be + * correctly computed from the string argument. + */ +#ifndef gv_stashpvn +# define gv_stashpvn(str,len,create) gv_stashpv(str,create) +#endif + +/* Replace: 1 */ +#ifndef get_cv +# define get_cv perl_get_cv +#endif + +#ifndef get_sv +# define get_sv perl_get_sv +#endif + +#ifndef get_av +# define get_av perl_get_av +#endif + +#ifndef get_hv +# define get_hv perl_get_hv +#endif + +/* Replace: 0 */ +#ifndef dUNDERBAR +# define dUNDERBAR dNOOP +#endif + +#ifndef UNDERBAR +# define UNDERBAR DEFSV +#endif +#ifndef dAX +# define dAX I32 ax = MARK - PL_stack_base + 1 +#endif + +#ifndef dITEMS +# define dITEMS I32 items = SP - MARK +#endif +#ifndef dXSTARG +# define dXSTARG SV * targ = sv_newmortal() +#endif +#ifndef dAXMARK +# define dAXMARK I32 ax = POPMARK; \ + register SV ** const mark = PL_stack_base + ax++ +#endif +#ifndef XSprePUSH +# define XSprePUSH (sp = PL_stack_base + ax - 1) +#endif + +#if (PERL_BCDVERSION < 0x5005000) +# undef XSRETURN +# define XSRETURN(off) \ + STMT_START { \ + PL_stack_sp = PL_stack_base + ax + ((off) - 1); \ + return; \ + } STMT_END +#endif +#ifndef XSPROTO +# define XSPROTO(name) void name(pTHX_ CV* cv) +#endif + +#ifndef SVfARG +# define SVfARG(p) ((void*)(p)) +#endif +#ifndef PERL_ABS +# define PERL_ABS(x) ((x) < 0 ? -(x) : (x)) +#endif +#ifndef dVAR +# define dVAR dNOOP +#endif +#ifndef SVf +# define SVf "_" +#endif +#ifndef UTF8_MAXBYTES +# define UTF8_MAXBYTES UTF8_MAXLEN +#endif +#ifndef CPERLscope +# define CPERLscope(x) x +#endif +#ifndef PERL_HASH +# define PERL_HASH(hash,str,len) \ + STMT_START { \ + const char *s_PeRlHaSh = str; \ + I32 i_PeRlHaSh = len; \ + U32 hash_PeRlHaSh = 0; \ + while (i_PeRlHaSh--) \ + hash_PeRlHaSh = hash_PeRlHaSh * 33 + *s_PeRlHaSh++; \ + (hash) = hash_PeRlHaSh; \ + } STMT_END +#endif + +#ifndef PERLIO_FUNCS_DECL +# ifdef PERLIO_FUNCS_CONST +# define PERLIO_FUNCS_DECL(funcs) const PerlIO_funcs funcs +# define PERLIO_FUNCS_CAST(funcs) (PerlIO_funcs*)(funcs) +# else +# define PERLIO_FUNCS_DECL(funcs) PerlIO_funcs funcs +# define PERLIO_FUNCS_CAST(funcs) (funcs) +# endif +#endif + +/* provide these typedefs for older perls */ +#if (PERL_BCDVERSION < 0x5009003) + +# ifdef ARGSproto +typedef OP* (CPERLscope(*Perl_ppaddr_t))(ARGSproto); +# else +typedef OP* (CPERLscope(*Perl_ppaddr_t))(pTHX); +# endif + +typedef OP* (CPERLscope(*Perl_check_t)) (pTHX_ OP*); + +#endif +#ifndef isPSXSPC +# define isPSXSPC(c) (isSPACE(c) || (c) == '\v') +#endif + +#ifndef isBLANK +# define isBLANK(c) ((c) == ' ' || (c) == '\t') +#endif + +#ifdef EBCDIC +#ifndef isALNUMC +# define isALNUMC(c) isalnum(c) +#endif + +#ifndef isASCII +# define isASCII(c) isascii(c) +#endif + +#ifndef isCNTRL +# define isCNTRL(c) iscntrl(c) +#endif + +#ifndef isGRAPH +# define isGRAPH(c) isgraph(c) +#endif + +#ifndef isPRINT +# define isPRINT(c) isprint(c) +#endif + +#ifndef isPUNCT +# define isPUNCT(c) ispunct(c) +#endif + +#ifndef isXDIGIT +# define isXDIGIT(c) isxdigit(c) +#endif + +#else +# if (PERL_BCDVERSION < 0x5010000) +/* Hint: isPRINT + * The implementation in older perl versions includes all of the + * isSPACE() characters, which is wrong. The version provided by + * Devel::PPPort always overrides a present buggy version. + */ +# undef isPRINT +# endif + +#ifdef HAS_QUAD +# ifdef U64TYPE +# define WIDEST_UTYPE U64TYPE +# else +# define WIDEST_UTYPE Quad_t +# endif +#else +# define WIDEST_UTYPE U32 +#endif +#ifndef isALNUMC +# define isALNUMC(c) (isALPHA(c) || isDIGIT(c)) +#endif + +#ifndef isASCII +# define isASCII(c) ((WIDEST_UTYPE) (c) <= 127) +#endif + +#ifndef isCNTRL +# define isCNTRL(c) ((WIDEST_UTYPE) (c) < ' ' || (c) == 127) +#endif + +#ifndef isGRAPH +# define isGRAPH(c) (isALNUM(c) || isPUNCT(c)) +#endif + +#ifndef isPRINT +# define isPRINT(c) (((c) >= 32 && (c) < 127)) +#endif + +#ifndef isPUNCT +# define isPUNCT(c) (((c) >= 33 && (c) <= 47) || ((c) >= 58 && (c) <= 64) || ((c) >= 91 && (c) <= 96) || ((c) >= 123 && (c) <= 126)) +#endif + +#ifndef isXDIGIT +# define isXDIGIT(c) (isDIGIT(c) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F')) +#endif + +#endif + +/* Until we figure out how to support this in older perls... */ +#if (PERL_BCDVERSION >= 0x5008000) +#ifndef HeUTF8 +# define HeUTF8(he) ((HeKLEN(he) == HEf_SVKEY) ? \ + SvUTF8(HeKEY_sv(he)) : \ + (U32)HeKUTF8(he)) +#endif + +#endif + +#ifndef PERL_SIGNALS_UNSAFE_FLAG + +#define PERL_SIGNALS_UNSAFE_FLAG 0x0001 + +#if (PERL_BCDVERSION < 0x5008000) +# define D_PPP_PERL_SIGNALS_INIT PERL_SIGNALS_UNSAFE_FLAG +#else +# define D_PPP_PERL_SIGNALS_INIT 0 +#endif + +#if defined(NEED_PL_signals) +static U32 DPPP_(my_PL_signals) = D_PPP_PERL_SIGNALS_INIT; +#elif defined(NEED_PL_signals_GLOBAL) +U32 DPPP_(my_PL_signals) = D_PPP_PERL_SIGNALS_INIT; +#else +extern U32 DPPP_(my_PL_signals); +#endif +#define PL_signals DPPP_(my_PL_signals) + +#endif + +/* Hint: PL_ppaddr + * Calling an op via PL_ppaddr requires passing a context argument + * for threaded builds. Since the context argument is different for + * 5.005 perls, you can use aTHXR (supplied by ppport.h), which will + * automatically be defined as the correct argument. + */ + +#if (PERL_BCDVERSION <= 0x5005005) +/* Replace: 1 */ +# define PL_ppaddr ppaddr +# define PL_no_modify no_modify +/* Replace: 0 */ +#endif + +#if (PERL_BCDVERSION <= 0x5004005) +/* Replace: 1 */ +# define PL_DBsignal DBsignal +# define PL_DBsingle DBsingle +# define PL_DBsub DBsub +# define PL_DBtrace DBtrace +# define PL_Sv Sv +# define PL_bufend bufend +# define PL_bufptr bufptr +# define PL_compiling compiling +# define PL_copline copline +# define PL_curcop curcop +# define PL_curstash curstash +# define PL_debstash debstash +# define PL_defgv defgv +# define PL_diehook diehook +# define PL_dirty dirty +# define PL_dowarn dowarn +# define PL_errgv errgv +# define PL_error_count error_count +# define PL_expect expect +# define PL_hexdigit hexdigit +# define PL_hints hints +# define PL_in_my in_my +# define PL_laststatval laststatval +# define PL_lex_state lex_state +# define PL_lex_stuff lex_stuff +# define PL_linestr linestr +# define PL_na na +# define PL_perl_destruct_level perl_destruct_level +# define PL_perldb perldb +# define PL_rsfp_filters rsfp_filters +# define PL_rsfp rsfp +# define PL_stack_base stack_base +# define PL_stack_sp stack_sp +# define PL_statcache statcache +# define PL_stdingv stdingv +# define PL_sv_arenaroot sv_arenaroot +# define PL_sv_no sv_no +# define PL_sv_undef sv_undef +# define PL_sv_yes sv_yes +# define PL_tainted tainted +# define PL_tainting tainting +# define PL_tokenbuf tokenbuf +/* Replace: 0 */ +#endif + +/* Warning: PL_parser + * For perl versions earlier than 5.9.5, this is an always + * non-NULL dummy. Also, it cannot be dereferenced. Don't + * use it if you can avoid is and unless you absolutely know + * what you're doing. + * If you always check that PL_parser is non-NULL, you can + * define DPPP_PL_parser_NO_DUMMY to avoid the creation of + * a dummy parser structure. + */ + +#if (PERL_BCDVERSION >= 0x5009005) +# ifdef DPPP_PL_parser_NO_DUMMY +# define D_PPP_my_PL_parser_var(var) ((PL_parser ? PL_parser : \ + (croak("panic: PL_parser == NULL in %s:%d", \ + __FILE__, __LINE__), (yy_parser *) NULL))->var) +# else +# ifdef DPPP_PL_parser_NO_DUMMY_WARNING +# define D_PPP_parser_dummy_warning(var) +# else +# define D_PPP_parser_dummy_warning(var) \ + warn("warning: dummy PL_" #var " used in %s:%d", __FILE__, __LINE__), +# endif +# define D_PPP_my_PL_parser_var(var) ((PL_parser ? PL_parser : \ + (D_PPP_parser_dummy_warning(var) &DPPP_(dummy_PL_parser)))->var) +#if defined(NEED_PL_parser) +static yy_parser DPPP_(dummy_PL_parser); +#elif defined(NEED_PL_parser_GLOBAL) +yy_parser DPPP_(dummy_PL_parser); +#else +extern yy_parser DPPP_(dummy_PL_parser); +#endif + +# endif + +/* PL_expect, PL_copline, PL_rsfp, PL_rsfp_filters, PL_linestr, PL_bufptr, PL_bufend, PL_lex_state, PL_lex_stuff, PL_tokenbuf depends on PL_parser */ +/* Warning: PL_expect, PL_copline, PL_rsfp, PL_rsfp_filters, PL_linestr, PL_bufptr, PL_bufend, PL_lex_state, PL_lex_stuff, PL_tokenbuf + * Do not use this variable unless you know exactly what you're + * doint. It is internal to the perl parser and may change or even + * be removed in the future. As of perl 5.9.5, you have to check + * for (PL_parser != NULL) for this variable to have any effect. + * An always non-NULL PL_parser dummy is provided for earlier + * perl versions. + * If PL_parser is NULL when you try to access this variable, a + * dummy is being accessed instead and a warning is issued unless + * you define DPPP_PL_parser_NO_DUMMY_WARNING. + * If DPPP_PL_parser_NO_DUMMY is defined, the code trying to access + * this variable will croak with a panic message. + */ + +# define PL_expect D_PPP_my_PL_parser_var(expect) +# define PL_copline D_PPP_my_PL_parser_var(copline) +# define PL_rsfp D_PPP_my_PL_parser_var(rsfp) +# define PL_rsfp_filters D_PPP_my_PL_parser_var(rsfp_filters) +# define PL_linestr D_PPP_my_PL_parser_var(linestr) +# define PL_bufptr D_PPP_my_PL_parser_var(bufptr) +# define PL_bufend D_PPP_my_PL_parser_var(bufend) +# define PL_lex_state D_PPP_my_PL_parser_var(lex_state) +# define PL_lex_stuff D_PPP_my_PL_parser_var(lex_stuff) +# define PL_tokenbuf D_PPP_my_PL_parser_var(tokenbuf) +# define PL_in_my D_PPP_my_PL_parser_var(in_my) +# define PL_in_my_stash D_PPP_my_PL_parser_var(in_my_stash) +# define PL_error_count D_PPP_my_PL_parser_var(error_count) + + +#else + +/* ensure that PL_parser != NULL and cannot be dereferenced */ +# define PL_parser ((void *) 1) + +#endif +#ifndef mPUSHs +# define mPUSHs(s) PUSHs(sv_2mortal(s)) +#endif + +#ifndef PUSHmortal +# define PUSHmortal PUSHs(sv_newmortal()) +#endif + +#ifndef mPUSHp +# define mPUSHp(p,l) sv_setpvn(PUSHmortal, (p), (l)) +#endif + +#ifndef mPUSHn +# define mPUSHn(n) sv_setnv(PUSHmortal, (NV)(n)) +#endif + +#ifndef mPUSHi +# define mPUSHi(i) sv_setiv(PUSHmortal, (IV)(i)) +#endif + +#ifndef mPUSHu +# define mPUSHu(u) sv_setuv(PUSHmortal, (UV)(u)) +#endif +#ifndef mXPUSHs +# define mXPUSHs(s) XPUSHs(sv_2mortal(s)) +#endif + +#ifndef XPUSHmortal +# define XPUSHmortal XPUSHs(sv_newmortal()) +#endif + +#ifndef mXPUSHp +# define mXPUSHp(p,l) STMT_START { EXTEND(sp,1); sv_setpvn(PUSHmortal, (p), (l)); } STMT_END +#endif + +#ifndef mXPUSHn +# define mXPUSHn(n) STMT_START { EXTEND(sp,1); sv_setnv(PUSHmortal, (NV)(n)); } STMT_END +#endif + +#ifndef mXPUSHi +# define mXPUSHi(i) STMT_START { EXTEND(sp,1); sv_setiv(PUSHmortal, (IV)(i)); } STMT_END +#endif + +#ifndef mXPUSHu +# define mXPUSHu(u) STMT_START { EXTEND(sp,1); sv_setuv(PUSHmortal, (UV)(u)); } STMT_END +#endif + +/* Replace: 1 */ +#ifndef call_sv +# define call_sv perl_call_sv +#endif + +#ifndef call_pv +# define call_pv perl_call_pv +#endif + +#ifndef call_argv +# define call_argv perl_call_argv +#endif + +#ifndef call_method +# define call_method perl_call_method +#endif +#ifndef eval_sv +# define eval_sv perl_eval_sv +#endif + +/* Replace: 0 */ +#ifndef PERL_LOADMOD_DENY +# define PERL_LOADMOD_DENY 0x1 +#endif + +#ifndef PERL_LOADMOD_NOIMPORT +# define PERL_LOADMOD_NOIMPORT 0x2 +#endif + +#ifndef PERL_LOADMOD_IMPORT_OPS +# define PERL_LOADMOD_IMPORT_OPS 0x4 +#endif + +#ifndef G_METHOD +# define G_METHOD 64 +# ifdef call_sv +# undef call_sv +# endif +# if (PERL_BCDVERSION < 0x5006000) +# define call_sv(sv, flags) ((flags) & G_METHOD ? perl_call_method((char *) SvPV_nolen_const(sv), \ + (flags) & ~G_METHOD) : perl_call_sv(sv, flags)) +# else +# define call_sv(sv, flags) ((flags) & G_METHOD ? Perl_call_method(aTHX_ (char *) SvPV_nolen_const(sv), \ + (flags) & ~G_METHOD) : Perl_call_sv(aTHX_ sv, flags)) +# endif +#endif + +/* Replace perl_eval_pv with eval_pv */ + +#ifndef eval_pv +#if defined(NEED_eval_pv) +static SV* DPPP_(my_eval_pv)(char *p, I32 croak_on_error); +static +#else +extern SV* DPPP_(my_eval_pv)(char *p, I32 croak_on_error); +#endif + +#ifdef eval_pv +# undef eval_pv +#endif +#define eval_pv(a,b) DPPP_(my_eval_pv)(aTHX_ a,b) +#define Perl_eval_pv DPPP_(my_eval_pv) + +#if defined(NEED_eval_pv) || defined(NEED_eval_pv_GLOBAL) + +SV* +DPPP_(my_eval_pv)(char *p, I32 croak_on_error) +{ + dSP; + SV* sv = newSVpv(p, 0); + + PUSHMARK(sp); + eval_sv(sv, G_SCALAR); + SvREFCNT_dec(sv); + + SPAGAIN; + sv = POPs; + PUTBACK; + + if (croak_on_error && SvTRUE(GvSV(errgv))) + croak(SvPVx(GvSV(errgv), na)); + + return sv; +} + +#endif +#endif + +#ifndef vload_module +#if defined(NEED_vload_module) +static void DPPP_(my_vload_module)(U32 flags, SV *name, SV *ver, va_list *args); +static +#else +extern void DPPP_(my_vload_module)(U32 flags, SV *name, SV *ver, va_list *args); +#endif + +#ifdef vload_module +# undef vload_module +#endif +#define vload_module(a,b,c,d) DPPP_(my_vload_module)(aTHX_ a,b,c,d) +#define Perl_vload_module DPPP_(my_vload_module) + +#if defined(NEED_vload_module) || defined(NEED_vload_module_GLOBAL) + +void +DPPP_(my_vload_module)(U32 flags, SV *name, SV *ver, va_list *args) +{ + dTHR; + dVAR; + OP *veop, *imop; + + OP * const modname = newSVOP(OP_CONST, 0, name); + /* 5.005 has a somewhat hacky force_normal that doesn't croak on + SvREADONLY() if PL_compling is true. Current perls take care in + ck_require() to correctly turn off SvREADONLY before calling + force_normal_flags(). This seems a better fix than fudging PL_compling + */ + SvREADONLY_off(((SVOP*)modname)->op_sv); + modname->op_private |= OPpCONST_BARE; + if (ver) { + veop = newSVOP(OP_CONST, 0, ver); + } + else + veop = NULL; + if (flags & PERL_LOADMOD_NOIMPORT) { + imop = sawparens(newNULLLIST()); + } + else if (flags & PERL_LOADMOD_IMPORT_OPS) { + imop = va_arg(*args, OP*); + } + else { + SV *sv; + imop = NULL; + sv = va_arg(*args, SV*); + while (sv) { + imop = append_elem(OP_LIST, imop, newSVOP(OP_CONST, 0, sv)); + sv = va_arg(*args, SV*); + } + } + { + const line_t ocopline = PL_copline; + COP * const ocurcop = PL_curcop; + const int oexpect = PL_expect; + +#if (PERL_BCDVERSION >= 0x5004000) + utilize(!(flags & PERL_LOADMOD_DENY), start_subparse(FALSE, 0), + veop, modname, imop); +#elif (PERL_BCDVERSION > 0x5003000) + utilize(!(flags & PERL_LOADMOD_DENY), start_subparse(), + veop, modname, imop); +#else + utilize(!(flags & PERL_LOADMOD_DENY), start_subparse(), + modname, imop); +#endif + PL_expect = oexpect; + PL_copline = ocopline; + PL_curcop = ocurcop; + } +} + +#endif +#endif + +#ifndef load_module +#if defined(NEED_load_module) +static void DPPP_(my_load_module)(U32 flags, SV *name, SV *ver, ...); +static +#else +extern void DPPP_(my_load_module)(U32 flags, SV *name, SV *ver, ...); +#endif + +#ifdef load_module +# undef load_module +#endif +#define load_module DPPP_(my_load_module) +#define Perl_load_module DPPP_(my_load_module) + +#if defined(NEED_load_module) || defined(NEED_load_module_GLOBAL) + +void +DPPP_(my_load_module)(U32 flags, SV *name, SV *ver, ...) +{ + va_list args; + va_start(args, ver); + vload_module(flags, name, ver, &args); + va_end(args); +} + +#endif +#endif +#ifndef newRV_inc +# define newRV_inc(sv) newRV(sv) /* Replace */ +#endif + +#ifndef newRV_noinc +#if defined(NEED_newRV_noinc) +static SV * DPPP_(my_newRV_noinc)(SV *sv); +static +#else +extern SV * DPPP_(my_newRV_noinc)(SV *sv); +#endif + +#ifdef newRV_noinc +# undef newRV_noinc +#endif +#define newRV_noinc(a) DPPP_(my_newRV_noinc)(aTHX_ a) +#define Perl_newRV_noinc DPPP_(my_newRV_noinc) + +#if defined(NEED_newRV_noinc) || defined(NEED_newRV_noinc_GLOBAL) +SV * +DPPP_(my_newRV_noinc)(SV *sv) +{ + SV *rv = (SV *)newRV(sv); + SvREFCNT_dec(sv); + return rv; +} +#endif +#endif + +/* Hint: newCONSTSUB + * Returns a CV* as of perl-5.7.1. This return value is not supported + * by Devel::PPPort. + */ + +/* newCONSTSUB from IO.xs is in the core starting with 5.004_63 */ +#if (PERL_BCDVERSION < 0x5004063) && (PERL_BCDVERSION != 0x5004005) +#if defined(NEED_newCONSTSUB) +static void DPPP_(my_newCONSTSUB)(HV *stash, const char *name, SV *sv); +static +#else +extern void DPPP_(my_newCONSTSUB)(HV *stash, const char *name, SV *sv); +#endif + +#ifdef newCONSTSUB +# undef newCONSTSUB +#endif +#define newCONSTSUB(a,b,c) DPPP_(my_newCONSTSUB)(aTHX_ a,b,c) +#define Perl_newCONSTSUB DPPP_(my_newCONSTSUB) + +#if defined(NEED_newCONSTSUB) || defined(NEED_newCONSTSUB_GLOBAL) + +/* This is just a trick to avoid a dependency of newCONSTSUB on PL_parser */ +/* (There's no PL_parser in perl < 5.005, so this is completely safe) */ +#define D_PPP_PL_copline PL_copline + +void +DPPP_(my_newCONSTSUB)(HV *stash, const char *name, SV *sv) +{ + U32 oldhints = PL_hints; + HV *old_cop_stash = PL_curcop->cop_stash; + HV *old_curstash = PL_curstash; + line_t oldline = PL_curcop->cop_line; + PL_curcop->cop_line = D_PPP_PL_copline; + + PL_hints &= ~HINT_BLOCK_SCOPE; + if (stash) + PL_curstash = PL_curcop->cop_stash = stash; + + newSUB( + +#if (PERL_BCDVERSION < 0x5003022) + start_subparse(), +#elif (PERL_BCDVERSION == 0x5003022) + start_subparse(0), +#else /* 5.003_23 onwards */ + start_subparse(FALSE, 0), +#endif + + newSVOP(OP_CONST, 0, newSVpv((char *) name, 0)), + newSVOP(OP_CONST, 0, &PL_sv_no), /* SvPV(&PL_sv_no) == "" -- GMB */ + newSTATEOP(0, Nullch, newSVOP(OP_CONST, 0, sv)) + ); + + PL_hints = oldhints; + PL_curcop->cop_stash = old_cop_stash; + PL_curstash = old_curstash; + PL_curcop->cop_line = oldline; +} +#endif +#endif + +/* + * Boilerplate macros for initializing and accessing interpreter-local + * data from C. All statics in extensions should be reworked to use + * this, if you want to make the extension thread-safe. See ext/re/re.xs + * for an example of the use of these macros. + * + * Code that uses these macros is responsible for the following: + * 1. #define MY_CXT_KEY to a unique string, e.g. "DynaLoader_guts" + * 2. Declare a typedef named my_cxt_t that is a structure that contains + * all the data that needs to be interpreter-local. + * 3. Use the START_MY_CXT macro after the declaration of my_cxt_t. + * 4. Use the MY_CXT_INIT macro such that it is called exactly once + * (typically put in the BOOT: section). + * 5. Use the members of the my_cxt_t structure everywhere as + * MY_CXT.member. + * 6. Use the dMY_CXT macro (a declaration) in all the functions that + * access MY_CXT. + */ + +#if defined(MULTIPLICITY) || defined(PERL_OBJECT) || \ + defined(PERL_CAPI) || defined(PERL_IMPLICIT_CONTEXT) + +#ifndef START_MY_CXT + +/* This must appear in all extensions that define a my_cxt_t structure, + * right after the definition (i.e. at file scope). The non-threads + * case below uses it to declare the data as static. */ +#define START_MY_CXT + +#if (PERL_BCDVERSION < 0x5004068) +/* Fetches the SV that keeps the per-interpreter data. */ +#define dMY_CXT_SV \ + SV *my_cxt_sv = get_sv(MY_CXT_KEY, FALSE) +#else /* >= perl5.004_68 */ +#define dMY_CXT_SV \ + SV *my_cxt_sv = *hv_fetch(PL_modglobal, MY_CXT_KEY, \ + sizeof(MY_CXT_KEY)-1, TRUE) +#endif /* < perl5.004_68 */ + +/* This declaration should be used within all functions that use the + * interpreter-local data. */ +#define dMY_CXT \ + dMY_CXT_SV; \ + my_cxt_t *my_cxtp = INT2PTR(my_cxt_t*,SvUV(my_cxt_sv)) + +/* Creates and zeroes the per-interpreter data. + * (We allocate my_cxtp in a Perl SV so that it will be released when + * the interpreter goes away.) */ +#define MY_CXT_INIT \ + dMY_CXT_SV; \ + /* newSV() allocates one more than needed */ \ + my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\ + Zero(my_cxtp, 1, my_cxt_t); \ + sv_setuv(my_cxt_sv, PTR2UV(my_cxtp)) + +/* This macro must be used to access members of the my_cxt_t structure. + * e.g. MYCXT.some_data */ +#define MY_CXT (*my_cxtp) + +/* Judicious use of these macros can reduce the number of times dMY_CXT + * is used. Use is similar to pTHX, aTHX etc. */ +#define pMY_CXT my_cxt_t *my_cxtp +#define pMY_CXT_ pMY_CXT, +#define _pMY_CXT ,pMY_CXT +#define aMY_CXT my_cxtp +#define aMY_CXT_ aMY_CXT, +#define _aMY_CXT ,aMY_CXT + +#endif /* START_MY_CXT */ + +#ifndef MY_CXT_CLONE +/* Clones the per-interpreter data. */ +#define MY_CXT_CLONE \ + dMY_CXT_SV; \ + my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\ + Copy(INT2PTR(my_cxt_t*, SvUV(my_cxt_sv)), my_cxtp, 1, my_cxt_t);\ + sv_setuv(my_cxt_sv, PTR2UV(my_cxtp)) +#endif + +#else /* single interpreter */ + +#ifndef START_MY_CXT + +#define START_MY_CXT static my_cxt_t my_cxt; +#define dMY_CXT_SV dNOOP +#define dMY_CXT dNOOP +#define MY_CXT_INIT NOOP +#define MY_CXT my_cxt + +#define pMY_CXT void +#define pMY_CXT_ +#define _pMY_CXT +#define aMY_CXT +#define aMY_CXT_ +#define _aMY_CXT + +#endif /* START_MY_CXT */ + +#ifndef MY_CXT_CLONE +#define MY_CXT_CLONE NOOP +#endif + +#endif + +#ifndef IVdf +# if IVSIZE == LONGSIZE +# define IVdf "ld" +# define UVuf "lu" +# define UVof "lo" +# define UVxf "lx" +# define UVXf "lX" +# elif IVSIZE == INTSIZE +# define IVdf "d" +# define UVuf "u" +# define UVof "o" +# define UVxf "x" +# define UVXf "X" +# else +# error "cannot define IV/UV formats" +# endif +#endif + +#ifndef NVef +# if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE) && \ + defined(PERL_PRIfldbl) && (PERL_BCDVERSION != 0x5006000) + /* Not very likely, but let's try anyway. */ +# define NVef PERL_PRIeldbl +# define NVff PERL_PRIfldbl +# define NVgf PERL_PRIgldbl +# else +# define NVef "e" +# define NVff "f" +# define NVgf "g" +# endif +#endif + +#ifndef SvREFCNT_inc +# ifdef PERL_USE_GCC_BRACE_GROUPS +# define SvREFCNT_inc(sv) \ + ({ \ + SV * const _sv = (SV*)(sv); \ + if (_sv) \ + (SvREFCNT(_sv))++; \ + _sv; \ + }) +# else +# define SvREFCNT_inc(sv) \ + ((PL_Sv=(SV*)(sv)) ? (++(SvREFCNT(PL_Sv)),PL_Sv) : NULL) +# endif +#endif + +#ifndef SvREFCNT_inc_simple +# ifdef PERL_USE_GCC_BRACE_GROUPS +# define SvREFCNT_inc_simple(sv) \ + ({ \ + if (sv) \ + (SvREFCNT(sv))++; \ + (SV *)(sv); \ + }) +# else +# define SvREFCNT_inc_simple(sv) \ + ((sv) ? (SvREFCNT(sv)++,(SV*)(sv)) : NULL) +# endif +#endif + +#ifndef SvREFCNT_inc_NN +# ifdef PERL_USE_GCC_BRACE_GROUPS +# define SvREFCNT_inc_NN(sv) \ + ({ \ + SV * const _sv = (SV*)(sv); \ + SvREFCNT(_sv)++; \ + _sv; \ + }) +# else +# define SvREFCNT_inc_NN(sv) \ + (PL_Sv=(SV*)(sv),++(SvREFCNT(PL_Sv)),PL_Sv) +# endif +#endif + +#ifndef SvREFCNT_inc_void +# ifdef PERL_USE_GCC_BRACE_GROUPS +# define SvREFCNT_inc_void(sv) \ + ({ \ + SV * const _sv = (SV*)(sv); \ + if (_sv) \ + (void)(SvREFCNT(_sv)++); \ + }) +# else +# define SvREFCNT_inc_void(sv) \ + (void)((PL_Sv=(SV*)(sv)) ? ++(SvREFCNT(PL_Sv)) : 0) +# endif +#endif +#ifndef SvREFCNT_inc_simple_void +# define SvREFCNT_inc_simple_void(sv) STMT_START { if (sv) SvREFCNT(sv)++; } STMT_END +#endif + +#ifndef SvREFCNT_inc_simple_NN +# define SvREFCNT_inc_simple_NN(sv) (++SvREFCNT(sv), (SV*)(sv)) +#endif + +#ifndef SvREFCNT_inc_void_NN +# define SvREFCNT_inc_void_NN(sv) (void)(++SvREFCNT((SV*)(sv))) +#endif + +#ifndef SvREFCNT_inc_simple_void_NN +# define SvREFCNT_inc_simple_void_NN(sv) (void)(++SvREFCNT((SV*)(sv))) +#endif + +#ifndef newSV_type + +#if defined(NEED_newSV_type) +static SV* DPPP_(my_newSV_type)(pTHX_ svtype const t); +static +#else +extern SV* DPPP_(my_newSV_type)(pTHX_ svtype const t); +#endif + +#ifdef newSV_type +# undef newSV_type +#endif +#define newSV_type(a) DPPP_(my_newSV_type)(aTHX_ a) +#define Perl_newSV_type DPPP_(my_newSV_type) + +#if defined(NEED_newSV_type) || defined(NEED_newSV_type_GLOBAL) + +SV* +DPPP_(my_newSV_type)(pTHX_ svtype const t) +{ + SV* const sv = newSV(0); + sv_upgrade(sv, t); + return sv; +} + +#endif + +#endif + +#if (PERL_BCDVERSION < 0x5006000) +# define D_PPP_CONSTPV_ARG(x) ((char *) (x)) +#else +# define D_PPP_CONSTPV_ARG(x) (x) +#endif +#ifndef newSVpvn +# define newSVpvn(data,len) ((data) \ + ? ((len) ? newSVpv((data), (len)) : newSVpv("", 0)) \ + : newSV(0)) +#endif +#ifndef newSVpvn_utf8 +# define newSVpvn_utf8(s, len, u) newSVpvn_flags((s), (len), (u) ? SVf_UTF8 : 0) +#endif +#ifndef SVf_UTF8 +# define SVf_UTF8 0 +#endif + +#ifndef newSVpvn_flags + +#if defined(NEED_newSVpvn_flags) +static SV * DPPP_(my_newSVpvn_flags)(pTHX_ const char *s, STRLEN len, U32 flags); +static +#else +extern SV * DPPP_(my_newSVpvn_flags)(pTHX_ const char *s, STRLEN len, U32 flags); +#endif + +#ifdef newSVpvn_flags +# undef newSVpvn_flags +#endif +#define newSVpvn_flags(a,b,c) DPPP_(my_newSVpvn_flags)(aTHX_ a,b,c) +#define Perl_newSVpvn_flags DPPP_(my_newSVpvn_flags) + +#if defined(NEED_newSVpvn_flags) || defined(NEED_newSVpvn_flags_GLOBAL) + +SV * +DPPP_(my_newSVpvn_flags)(pTHX_ const char *s, STRLEN len, U32 flags) +{ + SV *sv = newSVpvn(D_PPP_CONSTPV_ARG(s), len); + SvFLAGS(sv) |= (flags & SVf_UTF8); + return (flags & SVs_TEMP) ? sv_2mortal(sv) : sv; +} + +#endif + +#endif + +/* Backwards compatibility stuff... :-( */ +#if !defined(NEED_sv_2pv_flags) && defined(NEED_sv_2pv_nolen) +# define NEED_sv_2pv_flags +#endif +#if !defined(NEED_sv_2pv_flags_GLOBAL) && defined(NEED_sv_2pv_nolen_GLOBAL) +# define NEED_sv_2pv_flags_GLOBAL +#endif + +/* Hint: sv_2pv_nolen + * Use the SvPV_nolen() or SvPV_nolen_const() macros instead of sv_2pv_nolen(). + */ +#ifndef sv_2pv_nolen +# define sv_2pv_nolen(sv) SvPV_nolen(sv) +#endif + +#ifdef SvPVbyte + +/* Hint: SvPVbyte + * Does not work in perl-5.6.1, ppport.h implements a version + * borrowed from perl-5.7.3. + */ + +#if (PERL_BCDVERSION < 0x5007000) + +#if defined(NEED_sv_2pvbyte) +static char * DPPP_(my_sv_2pvbyte)(pTHX_ SV *sv, STRLEN *lp); +static +#else +extern char * DPPP_(my_sv_2pvbyte)(pTHX_ SV *sv, STRLEN *lp); +#endif + +#ifdef sv_2pvbyte +# undef sv_2pvbyte +#endif +#define sv_2pvbyte(a,b) DPPP_(my_sv_2pvbyte)(aTHX_ a,b) +#define Perl_sv_2pvbyte DPPP_(my_sv_2pvbyte) + +#if defined(NEED_sv_2pvbyte) || defined(NEED_sv_2pvbyte_GLOBAL) + +char * +DPPP_(my_sv_2pvbyte)(pTHX_ SV *sv, STRLEN *lp) +{ + sv_utf8_downgrade(sv,0); + return SvPV(sv,*lp); +} + +#endif + +/* Hint: sv_2pvbyte + * Use the SvPVbyte() macro instead of sv_2pvbyte(). + */ + +#undef SvPVbyte + +#define SvPVbyte(sv, lp) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK) \ + ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pvbyte(sv, &lp)) + +#endif + +#else + +# define SvPVbyte SvPV +# define sv_2pvbyte sv_2pv + +#endif +#ifndef sv_2pvbyte_nolen +# define sv_2pvbyte_nolen(sv) sv_2pv_nolen(sv) +#endif + +/* Hint: sv_pvn + * Always use the SvPV() macro instead of sv_pvn(). + */ + +/* Hint: sv_pvn_force + * Always use the SvPV_force() macro instead of sv_pvn_force(). + */ + +/* If these are undefined, they're not handled by the core anyway */ +#ifndef SV_IMMEDIATE_UNREF +# define SV_IMMEDIATE_UNREF 0 +#endif + +#ifndef SV_GMAGIC +# define SV_GMAGIC 0 +#endif + +#ifndef SV_COW_DROP_PV +# define SV_COW_DROP_PV 0 +#endif + +#ifndef SV_UTF8_NO_ENCODING +# define SV_UTF8_NO_ENCODING 0 +#endif + +#ifndef SV_NOSTEAL +# define SV_NOSTEAL 0 +#endif + +#ifndef SV_CONST_RETURN +# define SV_CONST_RETURN 0 +#endif + +#ifndef SV_MUTABLE_RETURN +# define SV_MUTABLE_RETURN 0 +#endif + +#ifndef SV_SMAGIC +# define SV_SMAGIC 0 +#endif + +#ifndef SV_HAS_TRAILING_NUL +# define SV_HAS_TRAILING_NUL 0 +#endif + +#ifndef SV_COW_SHARED_HASH_KEYS +# define SV_COW_SHARED_HASH_KEYS 0 +#endif + +#if (PERL_BCDVERSION < 0x5007002) + +#if defined(NEED_sv_2pv_flags) +static char * DPPP_(my_sv_2pv_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags); +static +#else +extern char * DPPP_(my_sv_2pv_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags); +#endif + +#ifdef sv_2pv_flags +# undef sv_2pv_flags +#endif +#define sv_2pv_flags(a,b,c) DPPP_(my_sv_2pv_flags)(aTHX_ a,b,c) +#define Perl_sv_2pv_flags DPPP_(my_sv_2pv_flags) + +#if defined(NEED_sv_2pv_flags) || defined(NEED_sv_2pv_flags_GLOBAL) + +char * +DPPP_(my_sv_2pv_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags) +{ + STRLEN n_a = (STRLEN) flags; + return sv_2pv(sv, lp ? lp : &n_a); +} + +#endif + +#if defined(NEED_sv_pvn_force_flags) +static char * DPPP_(my_sv_pvn_force_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags); +static +#else +extern char * DPPP_(my_sv_pvn_force_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags); +#endif + +#ifdef sv_pvn_force_flags +# undef sv_pvn_force_flags +#endif +#define sv_pvn_force_flags(a,b,c) DPPP_(my_sv_pvn_force_flags)(aTHX_ a,b,c) +#define Perl_sv_pvn_force_flags DPPP_(my_sv_pvn_force_flags) + +#if defined(NEED_sv_pvn_force_flags) || defined(NEED_sv_pvn_force_flags_GLOBAL) + +char * +DPPP_(my_sv_pvn_force_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags) +{ + STRLEN n_a = (STRLEN) flags; + return sv_pvn_force(sv, lp ? lp : &n_a); +} + +#endif + +#endif + +#if (PERL_BCDVERSION < 0x5008008) || ( (PERL_BCDVERSION >= 0x5009000) && (PERL_BCDVERSION < 0x5009003) ) +# define DPPP_SVPV_NOLEN_LP_ARG &PL_na +#else +# define DPPP_SVPV_NOLEN_LP_ARG 0 +#endif +#ifndef SvPV_const +# define SvPV_const(sv, lp) SvPV_flags_const(sv, lp, SV_GMAGIC) +#endif + +#ifndef SvPV_mutable +# define SvPV_mutable(sv, lp) SvPV_flags_mutable(sv, lp, SV_GMAGIC) +#endif +#ifndef SvPV_flags +# define SvPV_flags(sv, lp, flags) \ + ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pv_flags(sv, &lp, flags)) +#endif +#ifndef SvPV_flags_const +# define SvPV_flags_const(sv, lp, flags) \ + ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + ? ((lp = SvCUR(sv)), SvPVX_const(sv)) : \ + (const char*) sv_2pv_flags(sv, &lp, flags|SV_CONST_RETURN)) +#endif +#ifndef SvPV_flags_const_nolen +# define SvPV_flags_const_nolen(sv, flags) \ + ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + ? SvPVX_const(sv) : \ + (const char*) sv_2pv_flags(sv, DPPP_SVPV_NOLEN_LP_ARG, flags|SV_CONST_RETURN)) +#endif +#ifndef SvPV_flags_mutable +# define SvPV_flags_mutable(sv, lp, flags) \ + ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + ? ((lp = SvCUR(sv)), SvPVX_mutable(sv)) : \ + sv_2pv_flags(sv, &lp, flags|SV_MUTABLE_RETURN)) +#endif +#ifndef SvPV_force +# define SvPV_force(sv, lp) SvPV_force_flags(sv, lp, SV_GMAGIC) +#endif + +#ifndef SvPV_force_nolen +# define SvPV_force_nolen(sv) SvPV_force_flags_nolen(sv, SV_GMAGIC) +#endif + +#ifndef SvPV_force_mutable +# define SvPV_force_mutable(sv, lp) SvPV_force_flags_mutable(sv, lp, SV_GMAGIC) +#endif + +#ifndef SvPV_force_nomg +# define SvPV_force_nomg(sv, lp) SvPV_force_flags(sv, lp, 0) +#endif + +#ifndef SvPV_force_nomg_nolen +# define SvPV_force_nomg_nolen(sv) SvPV_force_flags_nolen(sv, 0) +#endif +#ifndef SvPV_force_flags +# define SvPV_force_flags(sv, lp, flags) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \ + ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvn_force_flags(sv, &lp, flags)) +#endif +#ifndef SvPV_force_flags_nolen +# define SvPV_force_flags_nolen(sv, flags) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \ + ? SvPVX(sv) : sv_pvn_force_flags(sv, DPPP_SVPV_NOLEN_LP_ARG, flags)) +#endif +#ifndef SvPV_force_flags_mutable +# define SvPV_force_flags_mutable(sv, lp, flags) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \ + ? ((lp = SvCUR(sv)), SvPVX_mutable(sv)) \ + : sv_pvn_force_flags(sv, &lp, flags|SV_MUTABLE_RETURN)) +#endif +#ifndef SvPV_nolen +# define SvPV_nolen(sv) \ + ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + ? SvPVX(sv) : sv_2pv_flags(sv, DPPP_SVPV_NOLEN_LP_ARG, SV_GMAGIC)) +#endif +#ifndef SvPV_nolen_const +# define SvPV_nolen_const(sv) \ + ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + ? SvPVX_const(sv) : sv_2pv_flags(sv, DPPP_SVPV_NOLEN_LP_ARG, SV_GMAGIC|SV_CONST_RETURN)) +#endif +#ifndef SvPV_nomg +# define SvPV_nomg(sv, lp) SvPV_flags(sv, lp, 0) +#endif + +#ifndef SvPV_nomg_const +# define SvPV_nomg_const(sv, lp) SvPV_flags_const(sv, lp, 0) +#endif + +#ifndef SvPV_nomg_const_nolen +# define SvPV_nomg_const_nolen(sv) SvPV_flags_const_nolen(sv, 0) +#endif + +#ifndef SvPV_nomg_nolen +# define SvPV_nomg_nolen(sv) ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + ? SvPVX(sv) : sv_2pv_flags(sv, DPPP_SVPV_NOLEN_LP_ARG, 0)) +#endif +#ifndef SvPV_renew +# define SvPV_renew(sv,n) STMT_START { SvLEN_set(sv, n); \ + SvPV_set((sv), (char *) saferealloc( \ + (Malloc_t)SvPVX(sv), (MEM_SIZE)((n)))); \ + } STMT_END +#endif +#ifndef SvMAGIC_set +# define SvMAGIC_set(sv, val) \ + STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \ + (((XPVMG*) SvANY(sv))->xmg_magic = (val)); } STMT_END +#endif + +#if (PERL_BCDVERSION < 0x5009003) +#ifndef SvPVX_const +# define SvPVX_const(sv) ((const char*) (0 + SvPVX(sv))) +#endif + +#ifndef SvPVX_mutable +# define SvPVX_mutable(sv) (0 + SvPVX(sv)) +#endif +#ifndef SvRV_set +# define SvRV_set(sv, val) \ + STMT_START { assert(SvTYPE(sv) >= SVt_RV); \ + (((XRV*) SvANY(sv))->xrv_rv = (val)); } STMT_END +#endif + +#else +#ifndef SvPVX_const +# define SvPVX_const(sv) ((const char*)((sv)->sv_u.svu_pv)) +#endif + +#ifndef SvPVX_mutable +# define SvPVX_mutable(sv) ((sv)->sv_u.svu_pv) +#endif +#ifndef SvRV_set +# define SvRV_set(sv, val) \ + STMT_START { assert(SvTYPE(sv) >= SVt_RV); \ + ((sv)->sv_u.svu_rv = (val)); } STMT_END +#endif + +#endif +#ifndef SvSTASH_set +# define SvSTASH_set(sv, val) \ + STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \ + (((XPVMG*) SvANY(sv))->xmg_stash = (val)); } STMT_END +#endif + +#if (PERL_BCDVERSION < 0x5004000) +#ifndef SvUV_set +# define SvUV_set(sv, val) \ + STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \ + (((XPVIV*) SvANY(sv))->xiv_iv = (IV) (val)); } STMT_END +#endif + +#else +#ifndef SvUV_set +# define SvUV_set(sv, val) \ + STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \ + (((XPVUV*) SvANY(sv))->xuv_uv = (val)); } STMT_END +#endif + +#endif + +#if (PERL_BCDVERSION >= 0x5004000) && !defined(vnewSVpvf) +#if defined(NEED_vnewSVpvf) +static SV * DPPP_(my_vnewSVpvf)(pTHX_ const char *pat, va_list *args); +static +#else +extern SV * DPPP_(my_vnewSVpvf)(pTHX_ const char *pat, va_list *args); +#endif + +#ifdef vnewSVpvf +# undef vnewSVpvf +#endif +#define vnewSVpvf(a,b) DPPP_(my_vnewSVpvf)(aTHX_ a,b) +#define Perl_vnewSVpvf DPPP_(my_vnewSVpvf) + +#if defined(NEED_vnewSVpvf) || defined(NEED_vnewSVpvf_GLOBAL) + +SV * +DPPP_(my_vnewSVpvf)(pTHX_ const char *pat, va_list *args) +{ + register SV *sv = newSV(0); + sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*)); + return sv; +} + +#endif +#endif + +#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_vcatpvf) +# define sv_vcatpvf(sv, pat, args) sv_vcatpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*)) +#endif + +#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_vsetpvf) +# define sv_vsetpvf(sv, pat, args) sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*)) +#endif + +#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_catpvf_mg) +#if defined(NEED_sv_catpvf_mg) +static void DPPP_(my_sv_catpvf_mg)(pTHX_ SV *sv, const char *pat, ...); +static +#else +extern void DPPP_(my_sv_catpvf_mg)(pTHX_ SV *sv, const char *pat, ...); +#endif + +#define Perl_sv_catpvf_mg DPPP_(my_sv_catpvf_mg) + +#if defined(NEED_sv_catpvf_mg) || defined(NEED_sv_catpvf_mg_GLOBAL) + +void +DPPP_(my_sv_catpvf_mg)(pTHX_ SV *sv, const char *pat, ...) +{ + va_list args; + va_start(args, pat); + sv_vcatpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*)); + SvSETMAGIC(sv); + va_end(args); +} + +#endif +#endif + +#ifdef PERL_IMPLICIT_CONTEXT +#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_catpvf_mg_nocontext) +#if defined(NEED_sv_catpvf_mg_nocontext) +static void DPPP_(my_sv_catpvf_mg_nocontext)(SV *sv, const char *pat, ...); +static +#else +extern void DPPP_(my_sv_catpvf_mg_nocontext)(SV *sv, const char *pat, ...); +#endif + +#define sv_catpvf_mg_nocontext DPPP_(my_sv_catpvf_mg_nocontext) +#define Perl_sv_catpvf_mg_nocontext DPPP_(my_sv_catpvf_mg_nocontext) + +#if defined(NEED_sv_catpvf_mg_nocontext) || defined(NEED_sv_catpvf_mg_nocontext_GLOBAL) + +void +DPPP_(my_sv_catpvf_mg_nocontext)(SV *sv, const char *pat, ...) +{ + dTHX; + va_list args; + va_start(args, pat); + sv_vcatpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*)); + SvSETMAGIC(sv); + va_end(args); +} + +#endif +#endif +#endif + +/* sv_catpvf_mg depends on sv_catpvf_mg_nocontext */ +#ifndef sv_catpvf_mg +# ifdef PERL_IMPLICIT_CONTEXT +# define sv_catpvf_mg Perl_sv_catpvf_mg_nocontext +# else +# define sv_catpvf_mg Perl_sv_catpvf_mg +# endif +#endif + +#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_vcatpvf_mg) +# define sv_vcatpvf_mg(sv, pat, args) \ + STMT_START { \ + sv_vcatpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*)); \ + SvSETMAGIC(sv); \ + } STMT_END +#endif + +#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_setpvf_mg) +#if defined(NEED_sv_setpvf_mg) +static void DPPP_(my_sv_setpvf_mg)(pTHX_ SV *sv, const char *pat, ...); +static +#else +extern void DPPP_(my_sv_setpvf_mg)(pTHX_ SV *sv, const char *pat, ...); +#endif + +#define Perl_sv_setpvf_mg DPPP_(my_sv_setpvf_mg) + +#if defined(NEED_sv_setpvf_mg) || defined(NEED_sv_setpvf_mg_GLOBAL) + +void +DPPP_(my_sv_setpvf_mg)(pTHX_ SV *sv, const char *pat, ...) +{ + va_list args; + va_start(args, pat); + sv_vsetpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*)); + SvSETMAGIC(sv); + va_end(args); +} + +#endif +#endif + +#ifdef PERL_IMPLICIT_CONTEXT +#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_setpvf_mg_nocontext) +#if defined(NEED_sv_setpvf_mg_nocontext) +static void DPPP_(my_sv_setpvf_mg_nocontext)(SV *sv, const char *pat, ...); +static +#else +extern void DPPP_(my_sv_setpvf_mg_nocontext)(SV *sv, const char *pat, ...); +#endif + +#define sv_setpvf_mg_nocontext DPPP_(my_sv_setpvf_mg_nocontext) +#define Perl_sv_setpvf_mg_nocontext DPPP_(my_sv_setpvf_mg_nocontext) + +#if defined(NEED_sv_setpvf_mg_nocontext) || defined(NEED_sv_setpvf_mg_nocontext_GLOBAL) + +void +DPPP_(my_sv_setpvf_mg_nocontext)(SV *sv, const char *pat, ...) +{ + dTHX; + va_list args; + va_start(args, pat); + sv_vsetpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*)); + SvSETMAGIC(sv); + va_end(args); +} + +#endif +#endif +#endif + +/* sv_setpvf_mg depends on sv_setpvf_mg_nocontext */ +#ifndef sv_setpvf_mg +# ifdef PERL_IMPLICIT_CONTEXT +# define sv_setpvf_mg Perl_sv_setpvf_mg_nocontext +# else +# define sv_setpvf_mg Perl_sv_setpvf_mg +# endif +#endif + +#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_vsetpvf_mg) +# define sv_vsetpvf_mg(sv, pat, args) \ + STMT_START { \ + sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*)); \ + SvSETMAGIC(sv); \ + } STMT_END +#endif + +/* Hint: newSVpvn_share + * The SVs created by this function only mimic the behaviour of + * shared PVs without really being shared. Only use if you know + * what you're doing. + */ + +#ifndef newSVpvn_share + +#if defined(NEED_newSVpvn_share) +static SV * DPPP_(my_newSVpvn_share)(pTHX_ const char *src, I32 len, U32 hash); +static +#else +extern SV * DPPP_(my_newSVpvn_share)(pTHX_ const char *src, I32 len, U32 hash); +#endif + +#ifdef newSVpvn_share +# undef newSVpvn_share +#endif +#define newSVpvn_share(a,b,c) DPPP_(my_newSVpvn_share)(aTHX_ a,b,c) +#define Perl_newSVpvn_share DPPP_(my_newSVpvn_share) + +#if defined(NEED_newSVpvn_share) || defined(NEED_newSVpvn_share_GLOBAL) + +SV * +DPPP_(my_newSVpvn_share)(pTHX_ const char *src, I32 len, U32 hash) +{ + SV *sv; + if (len < 0) + len = -len; + if (!hash) + PERL_HASH(hash, (char*) src, len); + sv = newSVpvn((char *) src, len); + sv_upgrade(sv, SVt_PVIV); + SvIVX(sv) = hash; + SvREADONLY_on(sv); + SvPOK_on(sv); + return sv; +} + +#endif + +#endif +#ifndef SvSHARED_HASH +# define SvSHARED_HASH(sv) (0 + SvUVX(sv)) +#endif +#ifndef HvNAME_get +# define HvNAME_get(hv) HvNAME(hv) +#endif +#ifndef HvNAMELEN_get +# define HvNAMELEN_get(hv) (HvNAME_get(hv) ? (I32)strlen(HvNAME_get(hv)) : 0) +#endif +#ifndef GvSVn +# define GvSVn(gv) GvSV(gv) +#endif + +#ifndef isGV_with_GP +# define isGV_with_GP(gv) isGV(gv) +#endif + +#ifndef gv_fetchpvn_flags +# define gv_fetchpvn_flags(name, len, flags, svt) gv_fetchpv(name, flags, svt) +#endif + +#ifndef gv_fetchsv +# define gv_fetchsv(name, flags, svt) gv_fetchpv(SvPV_nolen_const(name), flags, svt) +#endif +#ifndef get_cvn_flags +# define get_cvn_flags(name, namelen, flags) get_cv(name, flags) +#endif +#ifndef WARN_ALL +# define WARN_ALL 0 +#endif + +#ifndef WARN_CLOSURE +# define WARN_CLOSURE 1 +#endif + +#ifndef WARN_DEPRECATED +# define WARN_DEPRECATED 2 +#endif + +#ifndef WARN_EXITING +# define WARN_EXITING 3 +#endif + +#ifndef WARN_GLOB +# define WARN_GLOB 4 +#endif + +#ifndef WARN_IO +# define WARN_IO 5 +#endif + +#ifndef WARN_CLOSED +# define WARN_CLOSED 6 +#endif + +#ifndef WARN_EXEC +# define WARN_EXEC 7 +#endif + +#ifndef WARN_LAYER +# define WARN_LAYER 8 +#endif + +#ifndef WARN_NEWLINE +# define WARN_NEWLINE 9 +#endif + +#ifndef WARN_PIPE +# define WARN_PIPE 10 +#endif + +#ifndef WARN_UNOPENED +# define WARN_UNOPENED 11 +#endif + +#ifndef WARN_MISC +# define WARN_MISC 12 +#endif + +#ifndef WARN_NUMERIC +# define WARN_NUMERIC 13 +#endif + +#ifndef WARN_ONCE +# define WARN_ONCE 14 +#endif + +#ifndef WARN_OVERFLOW +# define WARN_OVERFLOW 15 +#endif + +#ifndef WARN_PACK +# define WARN_PACK 16 +#endif + +#ifndef WARN_PORTABLE +# define WARN_PORTABLE 17 +#endif + +#ifndef WARN_RECURSION +# define WARN_RECURSION 18 +#endif + +#ifndef WARN_REDEFINE +# define WARN_REDEFINE 19 +#endif + +#ifndef WARN_REGEXP +# define WARN_REGEXP 20 +#endif + +#ifndef WARN_SEVERE +# define WARN_SEVERE 21 +#endif + +#ifndef WARN_DEBUGGING +# define WARN_DEBUGGING 22 +#endif + +#ifndef WARN_INPLACE +# define WARN_INPLACE 23 +#endif + +#ifndef WARN_INTERNAL +# define WARN_INTERNAL 24 +#endif + +#ifndef WARN_MALLOC +# define WARN_MALLOC 25 +#endif + +#ifndef WARN_SIGNAL +# define WARN_SIGNAL 26 +#endif + +#ifndef WARN_SUBSTR +# define WARN_SUBSTR 27 +#endif + +#ifndef WARN_SYNTAX +# define WARN_SYNTAX 28 +#endif + +#ifndef WARN_AMBIGUOUS +# define WARN_AMBIGUOUS 29 +#endif + +#ifndef WARN_BAREWORD +# define WARN_BAREWORD 30 +#endif + +#ifndef WARN_DIGIT +# define WARN_DIGIT 31 +#endif + +#ifndef WARN_PARENTHESIS +# define WARN_PARENTHESIS 32 +#endif + +#ifndef WARN_PRECEDENCE +# define WARN_PRECEDENCE 33 +#endif + +#ifndef WARN_PRINTF +# define WARN_PRINTF 34 +#endif + +#ifndef WARN_PROTOTYPE +# define WARN_PROTOTYPE 35 +#endif + +#ifndef WARN_QW +# define WARN_QW 36 +#endif + +#ifndef WARN_RESERVED +# define WARN_RESERVED 37 +#endif + +#ifndef WARN_SEMICOLON +# define WARN_SEMICOLON 38 +#endif + +#ifndef WARN_TAINT +# define WARN_TAINT 39 +#endif + +#ifndef WARN_THREADS +# define WARN_THREADS 40 +#endif + +#ifndef WARN_UNINITIALIZED +# define WARN_UNINITIALIZED 41 +#endif + +#ifndef WARN_UNPACK +# define WARN_UNPACK 42 +#endif + +#ifndef WARN_UNTIE +# define WARN_UNTIE 43 +#endif + +#ifndef WARN_UTF8 +# define WARN_UTF8 44 +#endif + +#ifndef WARN_VOID +# define WARN_VOID 45 +#endif + +#ifndef WARN_ASSERTIONS +# define WARN_ASSERTIONS 46 +#endif +#ifndef packWARN +# define packWARN(a) (a) +#endif + +#ifndef ckWARN +# ifdef G_WARN_ON +# define ckWARN(a) (PL_dowarn & G_WARN_ON) +# else +# define ckWARN(a) PL_dowarn +# endif +#endif + +#if (PERL_BCDVERSION >= 0x5004000) && !defined(warner) +#if defined(NEED_warner) +static void DPPP_(my_warner)(U32 err, const char *pat, ...); +static +#else +extern void DPPP_(my_warner)(U32 err, const char *pat, ...); +#endif + +#define Perl_warner DPPP_(my_warner) + +#if defined(NEED_warner) || defined(NEED_warner_GLOBAL) + +void +DPPP_(my_warner)(U32 err, const char *pat, ...) +{ + SV *sv; + va_list args; + + PERL_UNUSED_ARG(err); + + va_start(args, pat); + sv = vnewSVpvf(pat, &args); + va_end(args); + sv_2mortal(sv); + warn("%s", SvPV_nolen(sv)); +} + +#define warner Perl_warner + +#define Perl_warner_nocontext Perl_warner + +#endif +#endif + +/* concatenating with "" ensures that only literal strings are accepted as argument + * note that STR_WITH_LEN() can't be used as argument to macros or functions that + * under some configurations might be macros + */ +#ifndef STR_WITH_LEN +# define STR_WITH_LEN(s) (s ""), (sizeof(s)-1) +#endif +#ifndef newSVpvs +# define newSVpvs(str) newSVpvn(str "", sizeof(str) - 1) +#endif + +#ifndef newSVpvs_flags +# define newSVpvs_flags(str, flags) newSVpvn_flags(str "", sizeof(str) - 1, flags) +#endif + +#ifndef newSVpvs_share +# define newSVpvs_share(str) newSVpvn_share(str "", sizeof(str) - 1, 0) +#endif + +#ifndef sv_catpvs +# define sv_catpvs(sv, str) sv_catpvn(sv, str "", sizeof(str) - 1) +#endif + +#ifndef sv_setpvs +# define sv_setpvs(sv, str) sv_setpvn(sv, str "", sizeof(str) - 1) +#endif + +#ifndef hv_fetchs +# define hv_fetchs(hv, key, lval) hv_fetch(hv, key "", sizeof(key) - 1, lval) +#endif + +#ifndef hv_stores +# define hv_stores(hv, key, val) hv_store(hv, key "", sizeof(key) - 1, val, 0) +#endif +#ifndef gv_fetchpvs +# define gv_fetchpvs(name, flags, svt) gv_fetchpvn_flags(name "", sizeof(name) - 1, flags, svt) +#endif + +#ifndef gv_stashpvs +# define gv_stashpvs(name, flags) gv_stashpvn(name "", sizeof(name) - 1, flags) +#endif +#ifndef get_cvs +# define get_cvs(name, flags) get_cvn_flags(name "", sizeof(name)-1, flags) +#endif +#ifndef SvGETMAGIC +# define SvGETMAGIC(x) STMT_START { if (SvGMAGICAL(x)) mg_get(x); } STMT_END +#endif + +/* Some random bits for sv_unmagicext. These should probably be pulled in for + real and organized at some point */ +#ifndef HEf_SVKEY +# define HEf_SVKEY -2 +#endif + +#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) +# define MUTABLE_PTR(p) ({ void *_p = (p); _p; }) +#else +# define MUTABLE_PTR(p) ((void *) (p)) +#endif + +#define MUTABLE_SV(p) ((SV *)MUTABLE_PTR(p)) + +/* end of random bits */ +#ifndef PERL_MAGIC_sv +# define PERL_MAGIC_sv '\0' +#endif + +#ifndef PERL_MAGIC_overload +# define PERL_MAGIC_overload 'A' +#endif + +#ifndef PERL_MAGIC_overload_elem +# define PERL_MAGIC_overload_elem 'a' +#endif + +#ifndef PERL_MAGIC_overload_table +# define PERL_MAGIC_overload_table 'c' +#endif + +#ifndef PERL_MAGIC_bm +# define PERL_MAGIC_bm 'B' +#endif + +#ifndef PERL_MAGIC_regdata +# define PERL_MAGIC_regdata 'D' +#endif + +#ifndef PERL_MAGIC_regdatum +# define PERL_MAGIC_regdatum 'd' +#endif + +#ifndef PERL_MAGIC_env +# define PERL_MAGIC_env 'E' +#endif + +#ifndef PERL_MAGIC_envelem +# define PERL_MAGIC_envelem 'e' +#endif + +#ifndef PERL_MAGIC_fm +# define PERL_MAGIC_fm 'f' +#endif + +#ifndef PERL_MAGIC_regex_global +# define PERL_MAGIC_regex_global 'g' +#endif + +#ifndef PERL_MAGIC_isa +# define PERL_MAGIC_isa 'I' +#endif + +#ifndef PERL_MAGIC_isaelem +# define PERL_MAGIC_isaelem 'i' +#endif + +#ifndef PERL_MAGIC_nkeys +# define PERL_MAGIC_nkeys 'k' +#endif + +#ifndef PERL_MAGIC_dbfile +# define PERL_MAGIC_dbfile 'L' +#endif + +#ifndef PERL_MAGIC_dbline +# define PERL_MAGIC_dbline 'l' +#endif + +#ifndef PERL_MAGIC_mutex +# define PERL_MAGIC_mutex 'm' +#endif + +#ifndef PERL_MAGIC_shared +# define PERL_MAGIC_shared 'N' +#endif + +#ifndef PERL_MAGIC_shared_scalar +# define PERL_MAGIC_shared_scalar 'n' +#endif + +#ifndef PERL_MAGIC_collxfrm +# define PERL_MAGIC_collxfrm 'o' +#endif + +#ifndef PERL_MAGIC_tied +# define PERL_MAGIC_tied 'P' +#endif + +#ifndef PERL_MAGIC_tiedelem +# define PERL_MAGIC_tiedelem 'p' +#endif + +#ifndef PERL_MAGIC_tiedscalar +# define PERL_MAGIC_tiedscalar 'q' +#endif + +#ifndef PERL_MAGIC_qr +# define PERL_MAGIC_qr 'r' +#endif + +#ifndef PERL_MAGIC_sig +# define PERL_MAGIC_sig 'S' +#endif + +#ifndef PERL_MAGIC_sigelem +# define PERL_MAGIC_sigelem 's' +#endif + +#ifndef PERL_MAGIC_taint +# define PERL_MAGIC_taint 't' +#endif + +#ifndef PERL_MAGIC_uvar +# define PERL_MAGIC_uvar 'U' +#endif + +#ifndef PERL_MAGIC_uvar_elem +# define PERL_MAGIC_uvar_elem 'u' +#endif + +#ifndef PERL_MAGIC_vstring +# define PERL_MAGIC_vstring 'V' +#endif + +#ifndef PERL_MAGIC_vec +# define PERL_MAGIC_vec 'v' +#endif + +#ifndef PERL_MAGIC_utf8 +# define PERL_MAGIC_utf8 'w' +#endif + +#ifndef PERL_MAGIC_substr +# define PERL_MAGIC_substr 'x' +#endif + +#ifndef PERL_MAGIC_defelem +# define PERL_MAGIC_defelem 'y' +#endif + +#ifndef PERL_MAGIC_glob +# define PERL_MAGIC_glob '*' +#endif + +#ifndef PERL_MAGIC_arylen +# define PERL_MAGIC_arylen '#' +#endif + +#ifndef PERL_MAGIC_pos +# define PERL_MAGIC_pos '.' +#endif + +#ifndef PERL_MAGIC_backref +# define PERL_MAGIC_backref '<' +#endif + +#ifndef PERL_MAGIC_ext +# define PERL_MAGIC_ext '~' +#endif + +/* That's the best we can do... */ +#ifndef sv_catpvn_nomg +# define sv_catpvn_nomg sv_catpvn +#endif + +#ifndef sv_catsv_nomg +# define sv_catsv_nomg sv_catsv +#endif + +#ifndef sv_setsv_nomg +# define sv_setsv_nomg sv_setsv +#endif + +#ifndef sv_pvn_nomg +# define sv_pvn_nomg sv_pvn +#endif + +#ifndef SvIV_nomg +# define SvIV_nomg SvIV +#endif + +#ifndef SvUV_nomg +# define SvUV_nomg SvUV +#endif + +#ifndef sv_catpv_mg +# define sv_catpv_mg(sv, ptr) \ + STMT_START { \ + SV *TeMpSv = sv; \ + sv_catpv(TeMpSv,ptr); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif + +#ifndef sv_catpvn_mg +# define sv_catpvn_mg(sv, ptr, len) \ + STMT_START { \ + SV *TeMpSv = sv; \ + sv_catpvn(TeMpSv,ptr,len); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif + +#ifndef sv_catsv_mg +# define sv_catsv_mg(dsv, ssv) \ + STMT_START { \ + SV *TeMpSv = dsv; \ + sv_catsv(TeMpSv,ssv); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif + +#ifndef sv_setiv_mg +# define sv_setiv_mg(sv, i) \ + STMT_START { \ + SV *TeMpSv = sv; \ + sv_setiv(TeMpSv,i); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif + +#ifndef sv_setnv_mg +# define sv_setnv_mg(sv, num) \ + STMT_START { \ + SV *TeMpSv = sv; \ + sv_setnv(TeMpSv,num); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif + +#ifndef sv_setpv_mg +# define sv_setpv_mg(sv, ptr) \ + STMT_START { \ + SV *TeMpSv = sv; \ + sv_setpv(TeMpSv,ptr); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif + +#ifndef sv_setpvn_mg +# define sv_setpvn_mg(sv, ptr, len) \ + STMT_START { \ + SV *TeMpSv = sv; \ + sv_setpvn(TeMpSv,ptr,len); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif + +#ifndef sv_setsv_mg +# define sv_setsv_mg(dsv, ssv) \ + STMT_START { \ + SV *TeMpSv = dsv; \ + sv_setsv(TeMpSv,ssv); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif + +#ifndef sv_setuv_mg +# define sv_setuv_mg(sv, i) \ + STMT_START { \ + SV *TeMpSv = sv; \ + sv_setuv(TeMpSv,i); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif + +#ifndef sv_usepvn_mg +# define sv_usepvn_mg(sv, ptr, len) \ + STMT_START { \ + SV *TeMpSv = sv; \ + sv_usepvn(TeMpSv,ptr,len); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif +#ifndef SvVSTRING_mg +# define SvVSTRING_mg(sv) (SvMAGICAL(sv) ? mg_find(sv, PERL_MAGIC_vstring) : NULL) +#endif + +/* Hint: sv_magic_portable + * This is a compatibility function that is only available with + * Devel::PPPort. It is NOT in the perl core. + * Its purpose is to mimic the 5.8.0 behaviour of sv_magic() when + * it is being passed a name pointer with namlen == 0. In that + * case, perl 5.8.0 and later store the pointer, not a copy of it. + * The compatibility can be provided back to perl 5.004. With + * earlier versions, the code will not compile. + */ + +#if (PERL_BCDVERSION < 0x5004000) + + /* code that uses sv_magic_portable will not compile */ + +#elif (PERL_BCDVERSION < 0x5008000) + +# define sv_magic_portable(sv, obj, how, name, namlen) \ + STMT_START { \ + SV *SvMp_sv = (sv); \ + char *SvMp_name = (char *) (name); \ + I32 SvMp_namlen = (namlen); \ + if (SvMp_name && SvMp_namlen == 0) \ + { \ + MAGIC *mg; \ + sv_magic(SvMp_sv, obj, how, 0, 0); \ + mg = SvMAGIC(SvMp_sv); \ + mg->mg_len = -42; /* XXX: this is the tricky part */ \ + mg->mg_ptr = SvMp_name; \ + } \ + else \ + { \ + sv_magic(SvMp_sv, obj, how, SvMp_name, SvMp_namlen); \ + } \ + } STMT_END + +#else + +# define sv_magic_portable(a, b, c, d, e) sv_magic(a, b, c, d, e) + +#endif + +#if !defined(mg_findext) +#if defined(NEED_mg_findext) +static MAGIC * DPPP_(my_mg_findext)(SV * sv, int type, const MGVTBL *vtbl); +static +#else +extern MAGIC * DPPP_(my_mg_findext)(SV * sv, int type, const MGVTBL *vtbl); +#endif + +#define mg_findext DPPP_(my_mg_findext) +#define Perl_mg_findext DPPP_(my_mg_findext) + +#if defined(NEED_mg_findext) || defined(NEED_mg_findext_GLOBAL) + +MAGIC * +DPPP_(my_mg_findext)(SV * sv, int type, const MGVTBL *vtbl) { + if (sv) { + MAGIC *mg; + +#ifdef AvPAD_NAMELIST + assert(!(SvTYPE(sv) == SVt_PVAV && AvPAD_NAMELIST(sv))); +#endif + + for (mg = SvMAGIC (sv); mg; mg = mg->mg_moremagic) { + if (mg->mg_type == type && mg->mg_virtual == vtbl) + return mg; + } + } + + return NULL; +} + +#endif +#endif + +#if !defined(sv_unmagicext) +#if defined(NEED_sv_unmagicext) +static int DPPP_(my_sv_unmagicext)(pTHX_ SV * const sv, const int type, MGVTBL * vtbl); +static +#else +extern int DPPP_(my_sv_unmagicext)(pTHX_ SV * const sv, const int type, MGVTBL * vtbl); +#endif + +#ifdef sv_unmagicext +# undef sv_unmagicext +#endif +#define sv_unmagicext(a,b,c) DPPP_(my_sv_unmagicext)(aTHX_ a,b,c) +#define Perl_sv_unmagicext DPPP_(my_sv_unmagicext) + +#if defined(NEED_sv_unmagicext) || defined(NEED_sv_unmagicext_GLOBAL) + +int +DPPP_(my_sv_unmagicext)(pTHX_ SV *const sv, const int type, MGVTBL *vtbl) +{ + MAGIC* mg; + MAGIC** mgp; + + if (SvTYPE(sv) < SVt_PVMG || !SvMAGIC(sv)) + return 0; + mgp = &(SvMAGIC(sv)); + for (mg = *mgp; mg; mg = *mgp) { + const MGVTBL* const virt = mg->mg_virtual; + if (mg->mg_type == type && virt == vtbl) { + *mgp = mg->mg_moremagic; + if (virt && virt->svt_free) + virt->svt_free(aTHX_ sv, mg); + if (mg->mg_ptr && mg->mg_type != PERL_MAGIC_regex_global) { + if (mg->mg_len > 0) + Safefree(mg->mg_ptr); + else if (mg->mg_len == HEf_SVKEY) /* Questionable on older perls... */ + SvREFCNT_dec(MUTABLE_SV(mg->mg_ptr)); + else if (mg->mg_type == PERL_MAGIC_utf8) + Safefree(mg->mg_ptr); + } + if (mg->mg_flags & MGf_REFCOUNTED) + SvREFCNT_dec(mg->mg_obj); + Safefree(mg); + } + else + mgp = &mg->mg_moremagic; + } + if (SvMAGIC(sv)) { + if (SvMAGICAL(sv)) /* if we're under save_magic, wait for restore_magic; */ + mg_magical(sv); /* else fix the flags now */ + } + else { + SvMAGICAL_off(sv); + SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT; + } + return 0; +} + +#endif +#endif + +#ifdef USE_ITHREADS +#ifndef CopFILE +# define CopFILE(c) ((c)->cop_file) +#endif + +#ifndef CopFILEGV +# define CopFILEGV(c) (CopFILE(c) ? gv_fetchfile(CopFILE(c)) : Nullgv) +#endif + +#ifndef CopFILE_set +# define CopFILE_set(c,pv) ((c)->cop_file = savepv(pv)) +#endif + +#ifndef CopFILESV +# define CopFILESV(c) (CopFILE(c) ? GvSV(gv_fetchfile(CopFILE(c))) : Nullsv) +#endif + +#ifndef CopFILEAV +# define CopFILEAV(c) (CopFILE(c) ? GvAV(gv_fetchfile(CopFILE(c))) : Nullav) +#endif + +#ifndef CopSTASHPV +# define CopSTASHPV(c) ((c)->cop_stashpv) +#endif + +#ifndef CopSTASHPV_set +# define CopSTASHPV_set(c,pv) ((c)->cop_stashpv = ((pv) ? savepv(pv) : Nullch)) +#endif + +#ifndef CopSTASH +# define CopSTASH(c) (CopSTASHPV(c) ? gv_stashpv(CopSTASHPV(c),GV_ADD) : Nullhv) +#endif + +#ifndef CopSTASH_set +# define CopSTASH_set(c,hv) CopSTASHPV_set(c, (hv) ? HvNAME(hv) : Nullch) +#endif + +#ifndef CopSTASH_eq +# define CopSTASH_eq(c,hv) ((hv) && (CopSTASHPV(c) == HvNAME(hv) \ + || (CopSTASHPV(c) && HvNAME(hv) \ + && strEQ(CopSTASHPV(c), HvNAME(hv))))) +#endif + +#else +#ifndef CopFILEGV +# define CopFILEGV(c) ((c)->cop_filegv) +#endif + +#ifndef CopFILEGV_set +# define CopFILEGV_set(c,gv) ((c)->cop_filegv = (GV*)SvREFCNT_inc(gv)) +#endif + +#ifndef CopFILE_set +# define CopFILE_set(c,pv) CopFILEGV_set((c), gv_fetchfile(pv)) +#endif + +#ifndef CopFILESV +# define CopFILESV(c) (CopFILEGV(c) ? GvSV(CopFILEGV(c)) : Nullsv) +#endif + +#ifndef CopFILEAV +# define CopFILEAV(c) (CopFILEGV(c) ? GvAV(CopFILEGV(c)) : Nullav) +#endif + +#ifndef CopFILE +# define CopFILE(c) (CopFILESV(c) ? SvPVX(CopFILESV(c)) : Nullch) +#endif + +#ifndef CopSTASH +# define CopSTASH(c) ((c)->cop_stash) +#endif + +#ifndef CopSTASH_set +# define CopSTASH_set(c,hv) ((c)->cop_stash = (hv)) +#endif + +#ifndef CopSTASHPV +# define CopSTASHPV(c) (CopSTASH(c) ? HvNAME(CopSTASH(c)) : Nullch) +#endif + +#ifndef CopSTASHPV_set +# define CopSTASHPV_set(c,pv) CopSTASH_set((c), gv_stashpv(pv,GV_ADD)) +#endif + +#ifndef CopSTASH_eq +# define CopSTASH_eq(c,hv) (CopSTASH(c) == (hv)) +#endif + +#endif /* USE_ITHREADS */ + +#if (PERL_BCDVERSION >= 0x5006000) +#ifndef caller_cx + +# if defined(NEED_caller_cx) || defined(NEED_caller_cx_GLOBAL) +static I32 +DPPP_dopoptosub_at(const PERL_CONTEXT *cxstk, I32 startingblock) +{ + I32 i; + + for (i = startingblock; i >= 0; i--) { + register const PERL_CONTEXT * const cx = &cxstk[i]; + switch (CxTYPE(cx)) { + default: + continue; + case CXt_EVAL: + case CXt_SUB: + case CXt_FORMAT: + return i; + } + } + return i; +} +# endif + +# if defined(NEED_caller_cx) +static const PERL_CONTEXT * DPPP_(my_caller_cx)(pTHX_ I32 count, const PERL_CONTEXT **dbcxp); +static +#else +extern const PERL_CONTEXT * DPPP_(my_caller_cx)(pTHX_ I32 count, const PERL_CONTEXT **dbcxp); +#endif + +#ifdef caller_cx +# undef caller_cx +#endif +#define caller_cx(a,b) DPPP_(my_caller_cx)(aTHX_ a,b) +#define Perl_caller_cx DPPP_(my_caller_cx) + +#if defined(NEED_caller_cx) || defined(NEED_caller_cx_GLOBAL) + +const PERL_CONTEXT * +DPPP_(my_caller_cx)(pTHX_ I32 count, const PERL_CONTEXT **dbcxp) +{ + register I32 cxix = DPPP_dopoptosub_at(cxstack, cxstack_ix); + register const PERL_CONTEXT *cx; + register const PERL_CONTEXT *ccstack = cxstack; + const PERL_SI *top_si = PL_curstackinfo; + + for (;;) { + /* we may be in a higher stacklevel, so dig down deeper */ + while (cxix < 0 && top_si->si_type != PERLSI_MAIN) { + top_si = top_si->si_prev; + ccstack = top_si->si_cxstack; + cxix = DPPP_dopoptosub_at(ccstack, top_si->si_cxix); + } + if (cxix < 0) + return NULL; + /* caller() should not report the automatic calls to &DB::sub */ + if (PL_DBsub && GvCV(PL_DBsub) && cxix >= 0 && + ccstack[cxix].blk_sub.cv == GvCV(PL_DBsub)) + count++; + if (!count--) + break; + cxix = DPPP_dopoptosub_at(ccstack, cxix - 1); + } + + cx = &ccstack[cxix]; + if (dbcxp) *dbcxp = cx; + + if (CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT) { + const I32 dbcxix = DPPP_dopoptosub_at(ccstack, cxix - 1); + /* We expect that ccstack[dbcxix] is CXt_SUB, anyway, the + field below is defined for any cx. */ + /* caller() should not report the automatic calls to &DB::sub */ + if (PL_DBsub && GvCV(PL_DBsub) && dbcxix >= 0 && ccstack[dbcxix].blk_sub.cv == GvCV(PL_DBsub)) + cx = &ccstack[dbcxix]; + } + + return cx; +} + +# endif +#endif /* caller_cx */ +#endif /* 5.6.0 */ +#ifndef IN_PERL_COMPILETIME +# define IN_PERL_COMPILETIME (PL_curcop == &PL_compiling) +#endif + +#ifndef IN_LOCALE_RUNTIME +# define IN_LOCALE_RUNTIME (PL_curcop->op_private & HINT_LOCALE) +#endif + +#ifndef IN_LOCALE_COMPILETIME +# define IN_LOCALE_COMPILETIME (PL_hints & HINT_LOCALE) +#endif + +#ifndef IN_LOCALE +# define IN_LOCALE (IN_PERL_COMPILETIME ? IN_LOCALE_COMPILETIME : IN_LOCALE_RUNTIME) +#endif +#ifndef IS_NUMBER_IN_UV +# define IS_NUMBER_IN_UV 0x01 +#endif + +#ifndef IS_NUMBER_GREATER_THAN_UV_MAX +# define IS_NUMBER_GREATER_THAN_UV_MAX 0x02 +#endif + +#ifndef IS_NUMBER_NOT_INT +# define IS_NUMBER_NOT_INT 0x04 +#endif + +#ifndef IS_NUMBER_NEG +# define IS_NUMBER_NEG 0x08 +#endif + +#ifndef IS_NUMBER_INFINITY +# define IS_NUMBER_INFINITY 0x10 +#endif + +#ifndef IS_NUMBER_NAN +# define IS_NUMBER_NAN 0x20 +#endif +#ifndef GROK_NUMERIC_RADIX +# define GROK_NUMERIC_RADIX(sp, send) grok_numeric_radix(sp, send) +#endif +#ifndef PERL_SCAN_GREATER_THAN_UV_MAX +# define PERL_SCAN_GREATER_THAN_UV_MAX 0x02 +#endif + +#ifndef PERL_SCAN_SILENT_ILLDIGIT +# define PERL_SCAN_SILENT_ILLDIGIT 0x04 +#endif + +#ifndef PERL_SCAN_ALLOW_UNDERSCORES +# define PERL_SCAN_ALLOW_UNDERSCORES 0x01 +#endif + +#ifndef PERL_SCAN_DISALLOW_PREFIX +# define PERL_SCAN_DISALLOW_PREFIX 0x02 +#endif + +#ifndef grok_numeric_radix +#if defined(NEED_grok_numeric_radix) +static bool DPPP_(my_grok_numeric_radix)(pTHX_ const char ** sp, const char * send); +static +#else +extern bool DPPP_(my_grok_numeric_radix)(pTHX_ const char ** sp, const char * send); +#endif + +#ifdef grok_numeric_radix +# undef grok_numeric_radix +#endif +#define grok_numeric_radix(a,b) DPPP_(my_grok_numeric_radix)(aTHX_ a,b) +#define Perl_grok_numeric_radix DPPP_(my_grok_numeric_radix) + +#if defined(NEED_grok_numeric_radix) || defined(NEED_grok_numeric_radix_GLOBAL) +bool +DPPP_(my_grok_numeric_radix)(pTHX_ const char **sp, const char *send) +{ +#ifdef USE_LOCALE_NUMERIC +#ifdef PL_numeric_radix_sv + if (PL_numeric_radix_sv && IN_LOCALE) { + STRLEN len; + char* radix = SvPV(PL_numeric_radix_sv, len); + if (*sp + len <= send && memEQ(*sp, radix, len)) { + *sp += len; + return TRUE; + } + } +#else + /* older perls don't have PL_numeric_radix_sv so the radix + * must manually be requested from locale.h + */ +#include + dTHR; /* needed for older threaded perls */ + struct lconv *lc = localeconv(); + char *radix = lc->decimal_point; + if (radix && IN_LOCALE) { + STRLEN len = strlen(radix); + if (*sp + len <= send && memEQ(*sp, radix, len)) { + *sp += len; + return TRUE; + } + } +#endif +#endif /* USE_LOCALE_NUMERIC */ + /* always try "." if numeric radix didn't match because + * we may have data from different locales mixed */ + if (*sp < send && **sp == '.') { + ++*sp; + return TRUE; + } + return FALSE; +} +#endif +#endif + +#ifndef grok_number +#if defined(NEED_grok_number) +static int DPPP_(my_grok_number)(pTHX_ const char * pv, STRLEN len, UV * valuep); +static +#else +extern int DPPP_(my_grok_number)(pTHX_ const char * pv, STRLEN len, UV * valuep); +#endif + +#ifdef grok_number +# undef grok_number +#endif +#define grok_number(a,b,c) DPPP_(my_grok_number)(aTHX_ a,b,c) +#define Perl_grok_number DPPP_(my_grok_number) + +#if defined(NEED_grok_number) || defined(NEED_grok_number_GLOBAL) +int +DPPP_(my_grok_number)(pTHX_ const char *pv, STRLEN len, UV *valuep) +{ + const char *s = pv; + const char *send = pv + len; + const UV max_div_10 = UV_MAX / 10; + const char max_mod_10 = UV_MAX % 10; + int numtype = 0; + int sawinf = 0; + int sawnan = 0; + + while (s < send && isSPACE(*s)) + s++; + if (s == send) { + return 0; + } else if (*s == '-') { + s++; + numtype = IS_NUMBER_NEG; + } + else if (*s == '+') + s++; + + if (s == send) + return 0; + + /* next must be digit or the radix separator or beginning of infinity */ + if (isDIGIT(*s)) { + /* UVs are at least 32 bits, so the first 9 decimal digits cannot + overflow. */ + UV value = *s - '0'; + /* This construction seems to be more optimiser friendly. + (without it gcc does the isDIGIT test and the *s - '0' separately) + With it gcc on arm is managing 6 instructions (6 cycles) per digit. + In theory the optimiser could deduce how far to unroll the loop + before checking for overflow. */ + if (++s < send) { + int digit = *s - '0'; + if (digit >= 0 && digit <= 9) { + value = value * 10 + digit; + if (++s < send) { + digit = *s - '0'; + if (digit >= 0 && digit <= 9) { + value = value * 10 + digit; + if (++s < send) { + digit = *s - '0'; + if (digit >= 0 && digit <= 9) { + value = value * 10 + digit; + if (++s < send) { + digit = *s - '0'; + if (digit >= 0 && digit <= 9) { + value = value * 10 + digit; + if (++s < send) { + digit = *s - '0'; + if (digit >= 0 && digit <= 9) { + value = value * 10 + digit; + if (++s < send) { + digit = *s - '0'; + if (digit >= 0 && digit <= 9) { + value = value * 10 + digit; + if (++s < send) { + digit = *s - '0'; + if (digit >= 0 && digit <= 9) { + value = value * 10 + digit; + if (++s < send) { + digit = *s - '0'; + if (digit >= 0 && digit <= 9) { + value = value * 10 + digit; + if (++s < send) { + /* Now got 9 digits, so need to check + each time for overflow. */ + digit = *s - '0'; + while (digit >= 0 && digit <= 9 + && (value < max_div_10 + || (value == max_div_10 + && digit <= max_mod_10))) { + value = value * 10 + digit; + if (++s < send) + digit = *s - '0'; + else + break; + } + if (digit >= 0 && digit <= 9 + && (s < send)) { + /* value overflowed. + skip the remaining digits, don't + worry about setting *valuep. */ + do { + s++; + } while (s < send && isDIGIT(*s)); + numtype |= + IS_NUMBER_GREATER_THAN_UV_MAX; + goto skip_value; + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + numtype |= IS_NUMBER_IN_UV; + if (valuep) + *valuep = value; + + skip_value: + if (GROK_NUMERIC_RADIX(&s, send)) { + numtype |= IS_NUMBER_NOT_INT; + while (s < send && isDIGIT(*s)) /* optional digits after the radix */ + s++; + } + } + else if (GROK_NUMERIC_RADIX(&s, send)) { + numtype |= IS_NUMBER_NOT_INT | IS_NUMBER_IN_UV; /* valuep assigned below */ + /* no digits before the radix means we need digits after it */ + if (s < send && isDIGIT(*s)) { + do { + s++; + } while (s < send && isDIGIT(*s)); + if (valuep) { + /* integer approximation is valid - it's 0. */ + *valuep = 0; + } + } + else + return 0; + } else if (*s == 'I' || *s == 'i') { + s++; if (s == send || (*s != 'N' && *s != 'n')) return 0; + s++; if (s == send || (*s != 'F' && *s != 'f')) return 0; + s++; if (s < send && (*s == 'I' || *s == 'i')) { + s++; if (s == send || (*s != 'N' && *s != 'n')) return 0; + s++; if (s == send || (*s != 'I' && *s != 'i')) return 0; + s++; if (s == send || (*s != 'T' && *s != 't')) return 0; + s++; if (s == send || (*s != 'Y' && *s != 'y')) return 0; + s++; + } + sawinf = 1; + } else if (*s == 'N' || *s == 'n') { + /* XXX TODO: There are signaling NaNs and quiet NaNs. */ + s++; if (s == send || (*s != 'A' && *s != 'a')) return 0; + s++; if (s == send || (*s != 'N' && *s != 'n')) return 0; + s++; + sawnan = 1; + } else + return 0; + + if (sawinf) { + numtype &= IS_NUMBER_NEG; /* Keep track of sign */ + numtype |= IS_NUMBER_INFINITY | IS_NUMBER_NOT_INT; + } else if (sawnan) { + numtype &= IS_NUMBER_NEG; /* Keep track of sign */ + numtype |= IS_NUMBER_NAN | IS_NUMBER_NOT_INT; + } else if (s < send) { + /* we can have an optional exponent part */ + if (*s == 'e' || *s == 'E') { + /* The only flag we keep is sign. Blow away any "it's UV" */ + numtype &= IS_NUMBER_NEG; + numtype |= IS_NUMBER_NOT_INT; + s++; + if (s < send && (*s == '-' || *s == '+')) + s++; + if (s < send && isDIGIT(*s)) { + do { + s++; + } while (s < send && isDIGIT(*s)); + } + else + return 0; + } + } + while (s < send && isSPACE(*s)) + s++; + if (s >= send) + return numtype; + if (len == 10 && memEQ(pv, "0 but true", 10)) { + if (valuep) + *valuep = 0; + return IS_NUMBER_IN_UV; + } + return 0; +} +#endif +#endif + +/* + * The grok_* routines have been modified to use warn() instead of + * Perl_warner(). Also, 'hexdigit' was the former name of PL_hexdigit, + * which is why the stack variable has been renamed to 'xdigit'. + */ + +#ifndef grok_bin +#if defined(NEED_grok_bin) +static UV DPPP_(my_grok_bin)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); +static +#else +extern UV DPPP_(my_grok_bin)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); +#endif + +#ifdef grok_bin +# undef grok_bin +#endif +#define grok_bin(a,b,c,d) DPPP_(my_grok_bin)(aTHX_ a,b,c,d) +#define Perl_grok_bin DPPP_(my_grok_bin) + +#if defined(NEED_grok_bin) || defined(NEED_grok_bin_GLOBAL) +UV +DPPP_(my_grok_bin)(pTHX_ const char *start, STRLEN *len_p, I32 *flags, NV *result) +{ + const char *s = start; + STRLEN len = *len_p; + UV value = 0; + NV value_nv = 0; + + const UV max_div_2 = UV_MAX / 2; + bool allow_underscores = *flags & PERL_SCAN_ALLOW_UNDERSCORES; + bool overflowed = FALSE; + + if (!(*flags & PERL_SCAN_DISALLOW_PREFIX)) { + /* strip off leading b or 0b. + for compatibility silently suffer "b" and "0b" as valid binary + numbers. */ + if (len >= 1) { + if (s[0] == 'b') { + s++; + len--; + } + else if (len >= 2 && s[0] == '0' && s[1] == 'b') { + s+=2; + len-=2; + } + } + } + + for (; len-- && *s; s++) { + char bit = *s; + if (bit == '0' || bit == '1') { + /* Write it in this wonky order with a goto to attempt to get the + compiler to make the common case integer-only loop pretty tight. + With gcc seems to be much straighter code than old scan_bin. */ + redo: + if (!overflowed) { + if (value <= max_div_2) { + value = (value << 1) | (bit - '0'); + continue; + } + /* Bah. We're just overflowed. */ + warn("Integer overflow in binary number"); + overflowed = TRUE; + value_nv = (NV) value; + } + value_nv *= 2.0; + /* If an NV has not enough bits in its mantissa to + * represent a UV this summing of small low-order numbers + * is a waste of time (because the NV cannot preserve + * the low-order bits anyway): we could just remember when + * did we overflow and in the end just multiply value_nv by the + * right amount. */ + value_nv += (NV)(bit - '0'); + continue; + } + if (bit == '_' && len && allow_underscores && (bit = s[1]) + && (bit == '0' || bit == '1')) + { + --len; + ++s; + goto redo; + } + if (!(*flags & PERL_SCAN_SILENT_ILLDIGIT)) + warn("Illegal binary digit '%c' ignored", *s); + break; + } + + if ( ( overflowed && value_nv > 4294967295.0) +#if UVSIZE > 4 + || (!overflowed && value > 0xffffffff ) +#endif + ) { + warn("Binary number > 0b11111111111111111111111111111111 non-portable"); + } + *len_p = s - start; + if (!overflowed) { + *flags = 0; + return value; + } + *flags = PERL_SCAN_GREATER_THAN_UV_MAX; + if (result) + *result = value_nv; + return UV_MAX; +} +#endif +#endif + +#ifndef grok_hex +#if defined(NEED_grok_hex) +static UV DPPP_(my_grok_hex)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); +static +#else +extern UV DPPP_(my_grok_hex)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); +#endif + +#ifdef grok_hex +# undef grok_hex +#endif +#define grok_hex(a,b,c,d) DPPP_(my_grok_hex)(aTHX_ a,b,c,d) +#define Perl_grok_hex DPPP_(my_grok_hex) + +#if defined(NEED_grok_hex) || defined(NEED_grok_hex_GLOBAL) +UV +DPPP_(my_grok_hex)(pTHX_ const char *start, STRLEN *len_p, I32 *flags, NV *result) +{ + const char *s = start; + STRLEN len = *len_p; + UV value = 0; + NV value_nv = 0; + + const UV max_div_16 = UV_MAX / 16; + bool allow_underscores = *flags & PERL_SCAN_ALLOW_UNDERSCORES; + bool overflowed = FALSE; + const char *xdigit; + + if (!(*flags & PERL_SCAN_DISALLOW_PREFIX)) { + /* strip off leading x or 0x. + for compatibility silently suffer "x" and "0x" as valid hex numbers. + */ + if (len >= 1) { + if (s[0] == 'x') { + s++; + len--; + } + else if (len >= 2 && s[0] == '0' && s[1] == 'x') { + s+=2; + len-=2; + } + } + } + + for (; len-- && *s; s++) { + xdigit = strchr((char *) PL_hexdigit, *s); + if (xdigit) { + /* Write it in this wonky order with a goto to attempt to get the + compiler to make the common case integer-only loop pretty tight. + With gcc seems to be much straighter code than old scan_hex. */ + redo: + if (!overflowed) { + if (value <= max_div_16) { + value = (value << 4) | ((xdigit - PL_hexdigit) & 15); + continue; + } + warn("Integer overflow in hexadecimal number"); + overflowed = TRUE; + value_nv = (NV) value; + } + value_nv *= 16.0; + /* If an NV has not enough bits in its mantissa to + * represent a UV this summing of small low-order numbers + * is a waste of time (because the NV cannot preserve + * the low-order bits anyway): we could just remember when + * did we overflow and in the end just multiply value_nv by the + * right amount of 16-tuples. */ + value_nv += (NV)((xdigit - PL_hexdigit) & 15); + continue; + } + if (*s == '_' && len && allow_underscores && s[1] + && (xdigit = strchr((char *) PL_hexdigit, s[1]))) + { + --len; + ++s; + goto redo; + } + if (!(*flags & PERL_SCAN_SILENT_ILLDIGIT)) + warn("Illegal hexadecimal digit '%c' ignored", *s); + break; + } + + if ( ( overflowed && value_nv > 4294967295.0) +#if UVSIZE > 4 + || (!overflowed && value > 0xffffffff ) +#endif + ) { + warn("Hexadecimal number > 0xffffffff non-portable"); + } + *len_p = s - start; + if (!overflowed) { + *flags = 0; + return value; + } + *flags = PERL_SCAN_GREATER_THAN_UV_MAX; + if (result) + *result = value_nv; + return UV_MAX; +} +#endif +#endif + +#ifndef grok_oct +#if defined(NEED_grok_oct) +static UV DPPP_(my_grok_oct)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); +static +#else +extern UV DPPP_(my_grok_oct)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); +#endif + +#ifdef grok_oct +# undef grok_oct +#endif +#define grok_oct(a,b,c,d) DPPP_(my_grok_oct)(aTHX_ a,b,c,d) +#define Perl_grok_oct DPPP_(my_grok_oct) + +#if defined(NEED_grok_oct) || defined(NEED_grok_oct_GLOBAL) +UV +DPPP_(my_grok_oct)(pTHX_ const char *start, STRLEN *len_p, I32 *flags, NV *result) +{ + const char *s = start; + STRLEN len = *len_p; + UV value = 0; + NV value_nv = 0; + + const UV max_div_8 = UV_MAX / 8; + bool allow_underscores = *flags & PERL_SCAN_ALLOW_UNDERSCORES; + bool overflowed = FALSE; + + for (; len-- && *s; s++) { + /* gcc 2.95 optimiser not smart enough to figure that this subtraction + out front allows slicker code. */ + int digit = *s - '0'; + if (digit >= 0 && digit <= 7) { + /* Write it in this wonky order with a goto to attempt to get the + compiler to make the common case integer-only loop pretty tight. + */ + redo: + if (!overflowed) { + if (value <= max_div_8) { + value = (value << 3) | digit; + continue; + } + /* Bah. We're just overflowed. */ + warn("Integer overflow in octal number"); + overflowed = TRUE; + value_nv = (NV) value; + } + value_nv *= 8.0; + /* If an NV has not enough bits in its mantissa to + * represent a UV this summing of small low-order numbers + * is a waste of time (because the NV cannot preserve + * the low-order bits anyway): we could just remember when + * did we overflow and in the end just multiply value_nv by the + * right amount of 8-tuples. */ + value_nv += (NV)digit; + continue; + } + if (digit == ('_' - '0') && len && allow_underscores + && (digit = s[1] - '0') && (digit >= 0 && digit <= 7)) + { + --len; + ++s; + goto redo; + } + /* Allow \octal to work the DWIM way (that is, stop scanning + * as soon as non-octal characters are seen, complain only iff + * someone seems to want to use the digits eight and nine). */ + if (digit == 8 || digit == 9) { + if (!(*flags & PERL_SCAN_SILENT_ILLDIGIT)) + warn("Illegal octal digit '%c' ignored", *s); + } + break; + } + + if ( ( overflowed && value_nv > 4294967295.0) +#if UVSIZE > 4 + || (!overflowed && value > 0xffffffff ) +#endif + ) { + warn("Octal number > 037777777777 non-portable"); + } + *len_p = s - start; + if (!overflowed) { + *flags = 0; + return value; + } + *flags = PERL_SCAN_GREATER_THAN_UV_MAX; + if (result) + *result = value_nv; + return UV_MAX; +} +#endif +#endif + +#if !defined(my_snprintf) +#if defined(NEED_my_snprintf) +static int DPPP_(my_my_snprintf)(char * buffer, const Size_t len, const char * format, ...); +static +#else +extern int DPPP_(my_my_snprintf)(char * buffer, const Size_t len, const char * format, ...); +#endif + +#define my_snprintf DPPP_(my_my_snprintf) +#define Perl_my_snprintf DPPP_(my_my_snprintf) + +#if defined(NEED_my_snprintf) || defined(NEED_my_snprintf_GLOBAL) + +int +DPPP_(my_my_snprintf)(char *buffer, const Size_t len, const char *format, ...) +{ + dTHX; + int retval; + va_list ap; + va_start(ap, format); +#ifdef HAS_VSNPRINTF + retval = vsnprintf(buffer, len, format, ap); +#else + retval = vsprintf(buffer, format, ap); +#endif + va_end(ap); + if (retval < 0 || (len > 0 && (Size_t)retval >= len)) + Perl_croak(aTHX_ "panic: my_snprintf buffer overflow"); + return retval; +} + +#endif +#endif + +#if !defined(my_sprintf) +#if defined(NEED_my_sprintf) +static int DPPP_(my_my_sprintf)(char * buffer, const char * pat, ...); +static +#else +extern int DPPP_(my_my_sprintf)(char * buffer, const char * pat, ...); +#endif + +#define my_sprintf DPPP_(my_my_sprintf) +#define Perl_my_sprintf DPPP_(my_my_sprintf) + +#if defined(NEED_my_sprintf) || defined(NEED_my_sprintf_GLOBAL) + +int +DPPP_(my_my_sprintf)(char *buffer, const char* pat, ...) +{ + va_list args; + va_start(args, pat); + vsprintf(buffer, pat, args); + va_end(args); + return strlen(buffer); +} + +#endif +#endif + +#ifdef NO_XSLOCKS +# ifdef dJMPENV +# define dXCPT dJMPENV; int rEtV = 0 +# define XCPT_TRY_START JMPENV_PUSH(rEtV); if (rEtV == 0) +# define XCPT_TRY_END JMPENV_POP; +# define XCPT_CATCH if (rEtV != 0) +# define XCPT_RETHROW JMPENV_JUMP(rEtV) +# else +# define dXCPT Sigjmp_buf oldTOP; int rEtV = 0 +# define XCPT_TRY_START Copy(top_env, oldTOP, 1, Sigjmp_buf); rEtV = Sigsetjmp(top_env, 1); if (rEtV == 0) +# define XCPT_TRY_END Copy(oldTOP, top_env, 1, Sigjmp_buf); +# define XCPT_CATCH if (rEtV != 0) +# define XCPT_RETHROW Siglongjmp(top_env, rEtV) +# endif +#endif + +#if !defined(my_strlcat) +#if defined(NEED_my_strlcat) +static Size_t DPPP_(my_my_strlcat)(char * dst, const char * src, Size_t size); +static +#else +extern Size_t DPPP_(my_my_strlcat)(char * dst, const char * src, Size_t size); +#endif + +#define my_strlcat DPPP_(my_my_strlcat) +#define Perl_my_strlcat DPPP_(my_my_strlcat) + +#if defined(NEED_my_strlcat) || defined(NEED_my_strlcat_GLOBAL) + +Size_t +DPPP_(my_my_strlcat)(char *dst, const char *src, Size_t size) +{ + Size_t used, length, copy; + + used = strlen(dst); + length = strlen(src); + if (size > 0 && used < size - 1) { + copy = (length >= size - used) ? size - used - 1 : length; + memcpy(dst + used, src, copy); + dst[used + copy] = '\0'; + } + return used + length; +} +#endif +#endif + +#if !defined(my_strlcpy) +#if defined(NEED_my_strlcpy) +static Size_t DPPP_(my_my_strlcpy)(char * dst, const char * src, Size_t size); +static +#else +extern Size_t DPPP_(my_my_strlcpy)(char * dst, const char * src, Size_t size); +#endif + +#define my_strlcpy DPPP_(my_my_strlcpy) +#define Perl_my_strlcpy DPPP_(my_my_strlcpy) + +#if defined(NEED_my_strlcpy) || defined(NEED_my_strlcpy_GLOBAL) + +Size_t +DPPP_(my_my_strlcpy)(char *dst, const char *src, Size_t size) +{ + Size_t length, copy; + + length = strlen(src); + if (size > 0) { + copy = (length >= size) ? size - 1 : length; + memcpy(dst, src, copy); + dst[copy] = '\0'; + } + return length; +} + +#endif +#endif +#ifndef PERL_PV_ESCAPE_QUOTE +# define PERL_PV_ESCAPE_QUOTE 0x0001 +#endif + +#ifndef PERL_PV_PRETTY_QUOTE +# define PERL_PV_PRETTY_QUOTE PERL_PV_ESCAPE_QUOTE +#endif + +#ifndef PERL_PV_PRETTY_ELLIPSES +# define PERL_PV_PRETTY_ELLIPSES 0x0002 +#endif + +#ifndef PERL_PV_PRETTY_LTGT +# define PERL_PV_PRETTY_LTGT 0x0004 +#endif + +#ifndef PERL_PV_ESCAPE_FIRSTCHAR +# define PERL_PV_ESCAPE_FIRSTCHAR 0x0008 +#endif + +#ifndef PERL_PV_ESCAPE_UNI +# define PERL_PV_ESCAPE_UNI 0x0100 +#endif + +#ifndef PERL_PV_ESCAPE_UNI_DETECT +# define PERL_PV_ESCAPE_UNI_DETECT 0x0200 +#endif + +#ifndef PERL_PV_ESCAPE_ALL +# define PERL_PV_ESCAPE_ALL 0x1000 +#endif + +#ifndef PERL_PV_ESCAPE_NOBACKSLASH +# define PERL_PV_ESCAPE_NOBACKSLASH 0x2000 +#endif + +#ifndef PERL_PV_ESCAPE_NOCLEAR +# define PERL_PV_ESCAPE_NOCLEAR 0x4000 +#endif + +#ifndef PERL_PV_ESCAPE_RE +# define PERL_PV_ESCAPE_RE 0x8000 +#endif + +#ifndef PERL_PV_PRETTY_NOCLEAR +# define PERL_PV_PRETTY_NOCLEAR PERL_PV_ESCAPE_NOCLEAR +#endif +#ifndef PERL_PV_PRETTY_DUMP +# define PERL_PV_PRETTY_DUMP PERL_PV_PRETTY_ELLIPSES|PERL_PV_PRETTY_QUOTE +#endif + +#ifndef PERL_PV_PRETTY_REGPROP +# define PERL_PV_PRETTY_REGPROP PERL_PV_PRETTY_ELLIPSES|PERL_PV_PRETTY_LTGT|PERL_PV_ESCAPE_RE +#endif + +/* Hint: pv_escape + * Note that unicode functionality is only backported to + * those perl versions that support it. For older perl + * versions, the implementation will fall back to bytes. + */ + +#ifndef pv_escape +#if defined(NEED_pv_escape) +static char * DPPP_(my_pv_escape)(pTHX_ SV * dsv, char const * const str, const STRLEN count, const STRLEN max, STRLEN * const escaped, const U32 flags); +static +#else +extern char * DPPP_(my_pv_escape)(pTHX_ SV * dsv, char const * const str, const STRLEN count, const STRLEN max, STRLEN * const escaped, const U32 flags); +#endif + +#ifdef pv_escape +# undef pv_escape +#endif +#define pv_escape(a,b,c,d,e,f) DPPP_(my_pv_escape)(aTHX_ a,b,c,d,e,f) +#define Perl_pv_escape DPPP_(my_pv_escape) + +#if defined(NEED_pv_escape) || defined(NEED_pv_escape_GLOBAL) + +char * +DPPP_(my_pv_escape)(pTHX_ SV *dsv, char const * const str, + const STRLEN count, const STRLEN max, + STRLEN * const escaped, const U32 flags) +{ + const char esc = flags & PERL_PV_ESCAPE_RE ? '%' : '\\'; + const char dq = flags & PERL_PV_ESCAPE_QUOTE ? '"' : esc; + char octbuf[32] = "%123456789ABCDF"; + STRLEN wrote = 0; + STRLEN chsize = 0; + STRLEN readsize = 1; +#if defined(is_utf8_string) && defined(utf8_to_uvchr) + bool isuni = flags & PERL_PV_ESCAPE_UNI ? 1 : 0; +#endif + const char *pv = str; + const char * const end = pv + count; + octbuf[0] = esc; + + if (!(flags & PERL_PV_ESCAPE_NOCLEAR)) + sv_setpvs(dsv, ""); + +#if defined(is_utf8_string) && defined(utf8_to_uvchr) + if ((flags & PERL_PV_ESCAPE_UNI_DETECT) && is_utf8_string((U8*)pv, count)) + isuni = 1; +#endif + + for (; pv < end && (!max || wrote < max) ; pv += readsize) { + const UV u = +#if defined(is_utf8_string) && defined(utf8_to_uvchr) + isuni ? utf8_to_uvchr((U8*)pv, &readsize) : +#endif + (U8)*pv; + const U8 c = (U8)u & 0xFF; + + if (u > 255 || (flags & PERL_PV_ESCAPE_ALL)) { + if (flags & PERL_PV_ESCAPE_FIRSTCHAR) + chsize = my_snprintf(octbuf, sizeof octbuf, + "%" UVxf, u); + else + chsize = my_snprintf(octbuf, sizeof octbuf, + "%cx{%" UVxf "}", esc, u); + } else if (flags & PERL_PV_ESCAPE_NOBACKSLASH) { + chsize = 1; + } else { + if (c == dq || c == esc || !isPRINT(c)) { + chsize = 2; + switch (c) { + case '\\' : /* fallthrough */ + case '%' : if (c == esc) + octbuf[1] = esc; + else + chsize = 1; + break; + case '\v' : octbuf[1] = 'v'; break; + case '\t' : octbuf[1] = 't'; break; + case '\r' : octbuf[1] = 'r'; break; + case '\n' : octbuf[1] = 'n'; break; + case '\f' : octbuf[1] = 'f'; break; + case '"' : if (dq == '"') + octbuf[1] = '"'; + else + chsize = 1; + break; + default: chsize = my_snprintf(octbuf, sizeof octbuf, + pv < end && isDIGIT((U8)*(pv+readsize)) + ? "%c%03o" : "%c%o", esc, c); + } + } else { + chsize = 1; + } + } + if (max && wrote + chsize > max) { + break; + } else if (chsize > 1) { + sv_catpvn(dsv, octbuf, chsize); + wrote += chsize; + } else { + char tmp[2]; + my_snprintf(tmp, sizeof tmp, "%c", c); + sv_catpvn(dsv, tmp, 1); + wrote++; + } + if (flags & PERL_PV_ESCAPE_FIRSTCHAR) + break; + } + if (escaped != NULL) + *escaped= pv - str; + return SvPVX(dsv); +} + +#endif +#endif + +#ifndef pv_pretty +#if defined(NEED_pv_pretty) +static char * DPPP_(my_pv_pretty)(pTHX_ SV * dsv, char const * const str, const STRLEN count, const STRLEN max, char const * const start_color, char const * const end_color, const U32 flags); +static +#else +extern char * DPPP_(my_pv_pretty)(pTHX_ SV * dsv, char const * const str, const STRLEN count, const STRLEN max, char const * const start_color, char const * const end_color, const U32 flags); +#endif + +#ifdef pv_pretty +# undef pv_pretty +#endif +#define pv_pretty(a,b,c,d,e,f,g) DPPP_(my_pv_pretty)(aTHX_ a,b,c,d,e,f,g) +#define Perl_pv_pretty DPPP_(my_pv_pretty) + +#if defined(NEED_pv_pretty) || defined(NEED_pv_pretty_GLOBAL) + +char * +DPPP_(my_pv_pretty)(pTHX_ SV *dsv, char const * const str, const STRLEN count, + const STRLEN max, char const * const start_color, char const * const end_color, + const U32 flags) +{ + const U8 dq = (flags & PERL_PV_PRETTY_QUOTE) ? '"' : '%'; + STRLEN escaped; + + if (!(flags & PERL_PV_PRETTY_NOCLEAR)) + sv_setpvs(dsv, ""); + + if (dq == '"') + sv_catpvs(dsv, "\""); + else if (flags & PERL_PV_PRETTY_LTGT) + sv_catpvs(dsv, "<"); + + if (start_color != NULL) + sv_catpv(dsv, D_PPP_CONSTPV_ARG(start_color)); + + pv_escape(dsv, str, count, max, &escaped, flags | PERL_PV_ESCAPE_NOCLEAR); + + if (end_color != NULL) + sv_catpv(dsv, D_PPP_CONSTPV_ARG(end_color)); + + if (dq == '"') + sv_catpvs(dsv, "\""); + else if (flags & PERL_PV_PRETTY_LTGT) + sv_catpvs(dsv, ">"); + + if ((flags & PERL_PV_PRETTY_ELLIPSES) && escaped < count) + sv_catpvs(dsv, "..."); + + return SvPVX(dsv); +} + +#endif +#endif + +#ifndef pv_display +#if defined(NEED_pv_display) +static char * DPPP_(my_pv_display)(pTHX_ SV * dsv, const char * pv, STRLEN cur, STRLEN len, STRLEN pvlim); +static +#else +extern char * DPPP_(my_pv_display)(pTHX_ SV * dsv, const char * pv, STRLEN cur, STRLEN len, STRLEN pvlim); +#endif + +#ifdef pv_display +# undef pv_display +#endif +#define pv_display(a,b,c,d,e) DPPP_(my_pv_display)(aTHX_ a,b,c,d,e) +#define Perl_pv_display DPPP_(my_pv_display) + +#if defined(NEED_pv_display) || defined(NEED_pv_display_GLOBAL) + +char * +DPPP_(my_pv_display)(pTHX_ SV *dsv, const char *pv, STRLEN cur, STRLEN len, STRLEN pvlim) +{ + pv_pretty(dsv, pv, cur, pvlim, NULL, NULL, PERL_PV_PRETTY_DUMP); + if (len > cur && pv[cur] == '\0') + sv_catpvs(dsv, "\\0"); + return SvPVX(dsv); +} + +#endif +#endif + +#endif /* _P_P_PORTABILITY_H_ */ + +/* End of File ppport.h */ diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..a4185a5 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,165 @@ +OBJS=ltc/ciphers/anubis.o ltc/ciphers/blowfish.o ltc/ciphers/camellia.o ltc/ciphers/cast5.o \ +ltc/ciphers/des.o ltc/ciphers/kasumi.o ltc/ciphers/khazad.o ltc/ciphers/kseed.o ltc/ciphers/multi2.o \ +ltc/ciphers/noekeon.o ltc/ciphers/rc2.o ltc/ciphers/rc5.o ltc/ciphers/rc6.o ltc/ciphers/skipjack.o \ +ltc/ciphers/xtea.o ltc/ciphers/aes/aes.o ltc/ciphers/safer/safer.o ltc/ciphers/safer/saferp.o \ +ltc/ciphers/twofish/twofish.o ltc/encauth/ccm/ccm_add_aad.o ltc/encauth/ccm/ccm_add_nonce.o \ +ltc/encauth/ccm/ccm_done.o ltc/encauth/ccm/ccm_init.o ltc/encauth/ccm/ccm_memory.o \ +ltc/encauth/ccm/ccm_process.o ltc/encauth/ccm/ccm_reset.o ltc/encauth/chachapoly/chacha20poly1305_add_aad.o \ +ltc/encauth/chachapoly/chacha20poly1305_decrypt.o ltc/encauth/chachapoly/chacha20poly1305_done.o \ +ltc/encauth/chachapoly/chacha20poly1305_encrypt.o ltc/encauth/chachapoly/chacha20poly1305_init.o \ +ltc/encauth/chachapoly/chacha20poly1305_memory.o ltc/encauth/chachapoly/chacha20poly1305_setiv.o \ +ltc/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.o ltc/encauth/eax/eax_addheader.o \ +ltc/encauth/eax/eax_decrypt.o ltc/encauth/eax/eax_decrypt_verify_memory.o ltc/encauth/eax/eax_done.o \ +ltc/encauth/eax/eax_encrypt.o ltc/encauth/eax/eax_encrypt_authenticate_memory.o ltc/encauth/eax/eax_init.o \ +ltc/encauth/gcm/gcm_add_aad.o ltc/encauth/gcm/gcm_add_iv.o ltc/encauth/gcm/gcm_done.o \ +ltc/encauth/gcm/gcm_gf_mult.o ltc/encauth/gcm/gcm_init.o ltc/encauth/gcm/gcm_memory.o \ +ltc/encauth/gcm/gcm_mult_h.o ltc/encauth/gcm/gcm_process.o ltc/encauth/gcm/gcm_reset.o \ +ltc/encauth/ocb3/ocb3_add_aad.o ltc/encauth/ocb3/ocb3_decrypt.o ltc/encauth/ocb3/ocb3_decrypt_last.o \ +ltc/encauth/ocb3/ocb3_decrypt_verify_memory.o ltc/encauth/ocb3/ocb3_done.o ltc/encauth/ocb3/ocb3_encrypt.o \ +ltc/encauth/ocb3/ocb3_encrypt_authenticate_memory.o ltc/encauth/ocb3/ocb3_encrypt_last.o \ +ltc/encauth/ocb3/ocb3_init.o ltc/encauth/ocb3/ocb3_int_aad_add_block.o ltc/encauth/ocb3/ocb3_int_calc_offset_zero.o \ +ltc/encauth/ocb3/ocb3_int_ntz.o ltc/encauth/ocb3/ocb3_int_xor_blocks.o ltc/hashes/blake2b.o \ +ltc/hashes/blake2s.o ltc/hashes/md2.o ltc/hashes/md4.o ltc/hashes/md5.o ltc/hashes/rmd128.o \ +ltc/hashes/rmd160.o ltc/hashes/rmd256.o ltc/hashes/rmd320.o ltc/hashes/sha1.o ltc/hashes/sha3.o \ +ltc/hashes/sha3_test.o ltc/hashes/tiger.o ltc/hashes/chc/chc.o ltc/hashes/helper/hash_file.o \ +ltc/hashes/helper/hash_filehandle.o ltc/hashes/helper/hash_memory.o ltc/hashes/helper/hash_memory_multi.o \ +ltc/hashes/sha2/sha224.o ltc/hashes/sha2/sha256.o ltc/hashes/sha2/sha384.o ltc/hashes/sha2/sha512.o \ +ltc/hashes/sha2/sha512_224.o ltc/hashes/sha2/sha512_256.o ltc/hashes/whirl/whirl.o \ +ltc/mac/blake2/blake2bmac.o ltc/mac/blake2/blake2bmac_file.o ltc/mac/blake2/blake2bmac_memory.o \ +ltc/mac/blake2/blake2bmac_memory_multi.o ltc/mac/blake2/blake2smac.o ltc/mac/blake2/blake2smac_file.o \ +ltc/mac/blake2/blake2smac_memory.o ltc/mac/blake2/blake2smac_memory_multi.o ltc/mac/f9/f9_done.o \ +ltc/mac/f9/f9_file.o ltc/mac/f9/f9_init.o ltc/mac/f9/f9_memory.o ltc/mac/f9/f9_memory_multi.o \ +ltc/mac/f9/f9_process.o ltc/mac/hmac/hmac_done.o ltc/mac/hmac/hmac_file.o ltc/mac/hmac/hmac_init.o \ +ltc/mac/hmac/hmac_memory.o ltc/mac/hmac/hmac_memory_multi.o ltc/mac/hmac/hmac_process.o \ +ltc/mac/omac/omac_done.o ltc/mac/omac/omac_file.o ltc/mac/omac/omac_init.o ltc/mac/omac/omac_memory.o \ +ltc/mac/omac/omac_memory_multi.o ltc/mac/omac/omac_process.o ltc/mac/pelican/pelican.o \ +ltc/mac/pelican/pelican_memory.o ltc/mac/pmac/pmac_done.o ltc/mac/pmac/pmac_file.o \ +ltc/mac/pmac/pmac_init.o ltc/mac/pmac/pmac_memory.o ltc/mac/pmac/pmac_memory_multi.o \ +ltc/mac/pmac/pmac_ntz.o ltc/mac/pmac/pmac_process.o ltc/mac/pmac/pmac_shift_xor.o \ +ltc/mac/poly1305/poly1305.o ltc/mac/poly1305/poly1305_file.o ltc/mac/poly1305/poly1305_memory.o \ +ltc/mac/poly1305/poly1305_memory_multi.o ltc/mac/xcbc/xcbc_done.o ltc/mac/xcbc/xcbc_file.o \ +ltc/mac/xcbc/xcbc_init.o ltc/mac/xcbc/xcbc_memory.o ltc/mac/xcbc/xcbc_memory_multi.o \ +ltc/mac/xcbc/xcbc_process.o ltc/math/ltm_desc.o ltc/math/multi.o ltc/math/rand_bn.o \ +ltc/math/rand_prime.o ltc/math/tfm_desc.o ltc/math/fp/ltc_ecc_fp_mulmod.o ltc/misc/adler32.o \ +ltc/misc/burn_stack.o ltc/misc/crc32.o ltc/misc/error_to_string.o ltc/misc/mem_neq.o \ +ltc/misc/pk_get_oid.o ltc/misc/zeromem.o ltc/misc/base64/base64_decode.o ltc/misc/base64/base64_encode.o \ +ltc/misc/crypt/crypt.o ltc/misc/crypt/crypt_argchk.o ltc/misc/crypt/crypt_cipher_descriptor.o \ +ltc/misc/crypt/crypt_cipher_is_valid.o ltc/misc/crypt/crypt_find_cipher.o ltc/misc/crypt/crypt_find_cipher_any.o \ +ltc/misc/crypt/crypt_find_cipher_id.o ltc/misc/crypt/crypt_find_hash.o ltc/misc/crypt/crypt_find_hash_any.o \ +ltc/misc/crypt/crypt_find_hash_id.o ltc/misc/crypt/crypt_find_hash_oid.o ltc/misc/crypt/crypt_find_prng.o \ +ltc/misc/crypt/crypt_fsa.o ltc/misc/crypt/crypt_hash_descriptor.o ltc/misc/crypt/crypt_hash_is_valid.o \ +ltc/misc/crypt/crypt_inits.o ltc/misc/crypt/crypt_ltc_mp_descriptor.o ltc/misc/crypt/crypt_prng_descriptor.o \ +ltc/misc/crypt/crypt_prng_is_valid.o ltc/misc/crypt/crypt_register_cipher.o ltc/misc/crypt/crypt_register_hash.o \ +ltc/misc/crypt/crypt_register_prng.o ltc/misc/crypt/crypt_unregister_cipher.o ltc/misc/crypt/crypt_unregister_hash.o \ +ltc/misc/crypt/crypt_unregister_prng.o ltc/misc/hkdf/hkdf.o ltc/misc/pkcs5/pkcs_5_1.o \ +ltc/misc/pkcs5/pkcs_5_2.o ltc/modes/cbc/cbc_decrypt.o ltc/modes/cbc/cbc_done.o ltc/modes/cbc/cbc_encrypt.o \ +ltc/modes/cbc/cbc_getiv.o ltc/modes/cbc/cbc_setiv.o ltc/modes/cbc/cbc_start.o ltc/modes/cfb/cfb_decrypt.o \ +ltc/modes/cfb/cfb_done.o ltc/modes/cfb/cfb_encrypt.o ltc/modes/cfb/cfb_getiv.o ltc/modes/cfb/cfb_setiv.o \ +ltc/modes/cfb/cfb_start.o ltc/modes/ctr/ctr_decrypt.o ltc/modes/ctr/ctr_done.o ltc/modes/ctr/ctr_encrypt.o \ +ltc/modes/ctr/ctr_getiv.o ltc/modes/ctr/ctr_setiv.o ltc/modes/ctr/ctr_start.o ltc/modes/ecb/ecb_decrypt.o \ +ltc/modes/ecb/ecb_done.o ltc/modes/ecb/ecb_encrypt.o ltc/modes/ecb/ecb_start.o ltc/modes/ofb/ofb_decrypt.o \ +ltc/modes/ofb/ofb_done.o ltc/modes/ofb/ofb_encrypt.o ltc/modes/ofb/ofb_getiv.o ltc/modes/ofb/ofb_setiv.o \ +ltc/modes/ofb/ofb_start.o ltc/pk/asn1/der/bit/der_decode_bit_string.o ltc/pk/asn1/der/bit/der_decode_raw_bit_string.o \ +ltc/pk/asn1/der/bit/der_encode_bit_string.o ltc/pk/asn1/der/bit/der_encode_raw_bit_string.o \ +ltc/pk/asn1/der/bit/der_length_bit_string.o ltc/pk/asn1/der/boolean/der_decode_boolean.o \ +ltc/pk/asn1/der/boolean/der_encode_boolean.o ltc/pk/asn1/der/boolean/der_length_boolean.o \ +ltc/pk/asn1/der/choice/der_decode_choice.o ltc/pk/asn1/der/generalizedtime/der_decode_generalizedtime.o \ +ltc/pk/asn1/der/generalizedtime/der_encode_generalizedtime.o ltc/pk/asn1/der/generalizedtime/der_length_generalizedtime.o \ +ltc/pk/asn1/der/ia5/der_decode_ia5_string.o ltc/pk/asn1/der/ia5/der_encode_ia5_string.o \ +ltc/pk/asn1/der/ia5/der_length_ia5_string.o ltc/pk/asn1/der/integer/der_decode_integer.o \ +ltc/pk/asn1/der/integer/der_encode_integer.o ltc/pk/asn1/der/integer/der_length_integer.o \ +ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.o ltc/pk/asn1/der/object_identifier/der_encode_object_identifier.o \ +ltc/pk/asn1/der/object_identifier/der_length_object_identifier.o ltc/pk/asn1/der/octet/der_decode_octet_string.o \ +ltc/pk/asn1/der/octet/der_encode_octet_string.o ltc/pk/asn1/der/octet/der_length_octet_string.o \ +ltc/pk/asn1/der/printable_string/der_decode_printable_string.o ltc/pk/asn1/der/printable_string/der_encode_printable_string.o \ +ltc/pk/asn1/der/printable_string/der_length_printable_string.o ltc/pk/asn1/der/sequence/der_decode_sequence_ex.o \ +ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.o ltc/pk/asn1/der/sequence/der_decode_sequence_multi.o \ +ltc/pk/asn1/der/sequence/der_decode_subject_public_key_info.o ltc/pk/asn1/der/sequence/der_encode_sequence_ex.o \ +ltc/pk/asn1/der/sequence/der_encode_sequence_multi.o ltc/pk/asn1/der/sequence/der_encode_subject_public_key_info.o \ +ltc/pk/asn1/der/sequence/der_length_sequence.o ltc/pk/asn1/der/sequence/der_sequence_free.o \ +ltc/pk/asn1/der/set/der_encode_set.o ltc/pk/asn1/der/set/der_encode_setof.o ltc/pk/asn1/der/short_integer/der_decode_short_integer.o \ +ltc/pk/asn1/der/short_integer/der_encode_short_integer.o ltc/pk/asn1/der/short_integer/der_length_short_integer.o \ +ltc/pk/asn1/der/teletex_string/der_decode_teletex_string.o ltc/pk/asn1/der/teletex_string/der_length_teletex_string.o \ +ltc/pk/asn1/der/utctime/der_decode_utctime.o ltc/pk/asn1/der/utctime/der_encode_utctime.o \ +ltc/pk/asn1/der/utctime/der_length_utctime.o ltc/pk/asn1/der/utf8/der_decode_utf8_string.o \ +ltc/pk/asn1/der/utf8/der_encode_utf8_string.o ltc/pk/asn1/der/utf8/der_length_utf8_string.o \ +ltc/pk/dh/dh.o ltc/pk/dh/dh_static.o ltc/pk/dh/dh_sys.o ltc/pk/dsa/dsa_decrypt_key.o \ +ltc/pk/dsa/dsa_encrypt_key.o ltc/pk/dsa/dsa_export.o ltc/pk/dsa/dsa_free.o ltc/pk/dsa/dsa_import.o \ +ltc/pk/dsa/dsa_import_radix.o ltc/pk/dsa/dsa_make_key.o ltc/pk/dsa/dsa_shared_secret.o \ +ltc/pk/dsa/dsa_sign_hash.o ltc/pk/dsa/dsa_verify_hash.o ltc/pk/dsa/dsa_verify_key.o \ +ltc/pk/ecc/ecc.o ltc/pk/ecc/ecc_ansi_x963_export.o ltc/pk/ecc/ecc_ansi_x963_import.o \ +ltc/pk/ecc/ecc_decrypt_key.o ltc/pk/ecc/ecc_dp_clear.o ltc/pk/ecc/ecc_dp_fill_from_sets.o \ +ltc/pk/ecc/ecc_dp_from_oid.o ltc/pk/ecc/ecc_dp_from_params.o ltc/pk/ecc/ecc_dp_init.o \ +ltc/pk/ecc/ecc_dp_set.o ltc/pk/ecc/ecc_encrypt_key.o ltc/pk/ecc/ecc_export.o ltc/pk/ecc/ecc_export_full.o \ +ltc/pk/ecc/ecc_export_raw.o ltc/pk/ecc/ecc_free.o ltc/pk/ecc/ecc_get_size.o ltc/pk/ecc/ecc_import.o \ +ltc/pk/ecc/ecc_import_full.o ltc/pk/ecc/ecc_import_pkcs8.o ltc/pk/ecc/ecc_import_raw.o \ +ltc/pk/ecc/ecc_make_key.o ltc/pk/ecc/ecc_shared_secret.o ltc/pk/ecc/ecc_sign_hash.o \ +ltc/pk/ecc/ecc_sizes.o ltc/pk/ecc/ecc_verify_hash.o ltc/pk/ecc/ecc_verify_key.o ltc/pk/ecc/ltc_ecc_export_point.o \ +ltc/pk/ecc/ltc_ecc_import_point.o ltc/pk/ecc/ltc_ecc_is_point.o ltc/pk/ecc/ltc_ecc_is_point_at_infinity.o \ +ltc/pk/ecc/ltc_ecc_is_valid_idx.o ltc/pk/ecc/ltc_ecc_map.o ltc/pk/ecc/ltc_ecc_mul2add.o \ +ltc/pk/ecc/ltc_ecc_mulmod.o ltc/pk/ecc/ltc_ecc_mulmod_timing.o ltc/pk/ecc/ltc_ecc_points.o \ +ltc/pk/ecc/ltc_ecc_projective_add_point.o ltc/pk/ecc/ltc_ecc_projective_dbl_point.o \ +ltc/pk/pkcs1/pkcs_1_i2osp.o ltc/pk/pkcs1/pkcs_1_mgf1.o ltc/pk/pkcs1/pkcs_1_oaep_decode.o \ +ltc/pk/pkcs1/pkcs_1_oaep_encode.o ltc/pk/pkcs1/pkcs_1_os2ip.o ltc/pk/pkcs1/pkcs_1_pss_decode.o \ +ltc/pk/pkcs1/pkcs_1_pss_encode.o ltc/pk/pkcs1/pkcs_1_v1_5_decode.o ltc/pk/pkcs1/pkcs_1_v1_5_encode.o \ +ltc/pk/rsa/rsa_decrypt_key.o ltc/pk/rsa/rsa_encrypt_key.o ltc/pk/rsa/rsa_export.o \ +ltc/pk/rsa/rsa_exptmod.o ltc/pk/rsa/rsa_free.o ltc/pk/rsa/rsa_get_size.o ltc/pk/rsa/rsa_import.o \ +ltc/pk/rsa/rsa_import_pkcs8.o ltc/pk/rsa/rsa_import_radix.o ltc/pk/rsa/rsa_import_x509.o \ +ltc/pk/rsa/rsa_make_key.o ltc/pk/rsa/rsa_sign_hash.o ltc/pk/rsa/rsa_sign_saltlen_get.o \ +ltc/pk/rsa/rsa_verify_hash.o ltc/prngs/chacha20.o ltc/prngs/fortuna.o ltc/prngs/rc4.o \ +ltc/prngs/rng_get_bytes.o ltc/prngs/rng_make_prng.o ltc/prngs/sober128.o ltc/prngs/sprng.o \ +ltc/prngs/yarrow.o ltc/stream/chacha/chacha_crypt.o ltc/stream/chacha/chacha_done.o \ +ltc/stream/chacha/chacha_ivctr32.o ltc/stream/chacha/chacha_ivctr64.o ltc/stream/chacha/chacha_keystream.o \ +ltc/stream/chacha/chacha_setup.o ltc/stream/rc4/rc4.o ltc/stream/sober128/sober128.o \ +ltm/bncore.o ltm/bn_error.o ltm/bn_fast_mp_invmod.o ltm/bn_fast_mp_montgomery_reduce.o \ +ltm/bn_fast_s_mp_mul_digs.o ltm/bn_fast_s_mp_mul_high_digs.o ltm/bn_fast_s_mp_sqr.o \ +ltm/bn_mp_2expt.o ltm/bn_mp_abs.o ltm/bn_mp_add.o ltm/bn_mp_addmod.o ltm/bn_mp_add_d.o \ +ltm/bn_mp_and.o ltm/bn_mp_clamp.o ltm/bn_mp_clear.o ltm/bn_mp_clear_multi.o ltm/bn_mp_cmp.o \ +ltm/bn_mp_cmp_d.o ltm/bn_mp_cmp_mag.o ltm/bn_mp_cnt_lsb.o ltm/bn_mp_copy.o ltm/bn_mp_count_bits.o \ +ltm/bn_mp_div.o ltm/bn_mp_div_2.o ltm/bn_mp_div_2d.o ltm/bn_mp_div_3.o ltm/bn_mp_div_d.o \ +ltm/bn_mp_dr_is_modulus.o ltm/bn_mp_dr_reduce.o ltm/bn_mp_dr_setup.o ltm/bn_mp_exch.o \ +ltm/bn_mp_export.o ltm/bn_mp_exptmod.o ltm/bn_mp_exptmod_fast.o ltm/bn_mp_expt_d.o \ +ltm/bn_mp_expt_d_ex.o ltm/bn_mp_exteuclid.o ltm/bn_mp_fread.o ltm/bn_mp_fwrite.o \ +ltm/bn_mp_gcd.o ltm/bn_mp_get_int.o ltm/bn_mp_get_long.o ltm/bn_mp_get_long_long.o \ +ltm/bn_mp_grow.o ltm/bn_mp_import.o ltm/bn_mp_init.o ltm/bn_mp_init_copy.o ltm/bn_mp_init_multi.o \ +ltm/bn_mp_init_set.o ltm/bn_mp_init_set_int.o ltm/bn_mp_init_size.o ltm/bn_mp_invmod.o \ +ltm/bn_mp_invmod_slow.o ltm/bn_mp_is_square.o ltm/bn_mp_jacobi.o ltm/bn_mp_karatsuba_mul.o \ +ltm/bn_mp_karatsuba_sqr.o ltm/bn_mp_lcm.o ltm/bn_mp_lshd.o ltm/bn_mp_mod.o ltm/bn_mp_mod_2d.o \ +ltm/bn_mp_mod_d.o ltm/bn_mp_montgomery_calc_normalization.o ltm/bn_mp_montgomery_reduce.o \ +ltm/bn_mp_montgomery_setup.o ltm/bn_mp_mul.o ltm/bn_mp_mulmod.o ltm/bn_mp_mul_2.o \ +ltm/bn_mp_mul_2d.o ltm/bn_mp_mul_d.o ltm/bn_mp_neg.o ltm/bn_mp_n_root.o ltm/bn_mp_n_root_ex.o \ +ltm/bn_mp_or.o ltm/bn_mp_prime_fermat.o ltm/bn_mp_prime_is_divisible.o ltm/bn_mp_prime_is_prime.o \ +ltm/bn_mp_prime_miller_rabin.o ltm/bn_mp_prime_next_prime.o ltm/bn_mp_prime_rabin_miller_trials.o \ +ltm/bn_mp_prime_random_ex.o ltm/bn_mp_radix_size.o ltm/bn_mp_radix_smap.o ltm/bn_mp_rand.o \ +ltm/bn_mp_read_radix.o ltm/bn_mp_read_signed_bin.o ltm/bn_mp_read_unsigned_bin.o \ +ltm/bn_mp_reduce.o ltm/bn_mp_reduce_2k.o ltm/bn_mp_reduce_2k_l.o ltm/bn_mp_reduce_2k_setup.o \ +ltm/bn_mp_reduce_2k_setup_l.o ltm/bn_mp_reduce_is_2k.o ltm/bn_mp_reduce_is_2k_l.o \ +ltm/bn_mp_reduce_setup.o ltm/bn_mp_rshd.o ltm/bn_mp_set.o ltm/bn_mp_set_int.o ltm/bn_mp_set_long.o \ +ltm/bn_mp_set_long_long.o ltm/bn_mp_shrink.o ltm/bn_mp_signed_bin_size.o ltm/bn_mp_sqr.o \ +ltm/bn_mp_sqrmod.o ltm/bn_mp_sqrt.o ltm/bn_mp_sqrtmod_prime.o ltm/bn_mp_sub.o ltm/bn_mp_submod.o \ +ltm/bn_mp_sub_d.o ltm/bn_mp_toom_mul.o ltm/bn_mp_toom_sqr.o ltm/bn_mp_toradix.o ltm/bn_mp_toradix_n.o \ +ltm/bn_mp_to_signed_bin.o ltm/bn_mp_to_signed_bin_n.o ltm/bn_mp_to_unsigned_bin.o \ +ltm/bn_mp_to_unsigned_bin_n.o ltm/bn_mp_unsigned_bin_size.o ltm/bn_mp_xor.o ltm/bn_mp_zero.o \ +ltm/bn_prime_tab.o ltm/bn_reverse.o ltm/bn_s_mp_add.o ltm/bn_s_mp_exptmod.o ltm/bn_s_mp_mul_digs.o \ +ltm/bn_s_mp_mul_high_digs.o ltm/bn_s_mp_sqr.o ltm/bn_s_mp_sub.o + +LIB_EXT =.a +OBJ_EXT =.o +PERL =perl +RANLIB =ranlib +AR =ar +ARFLAGS =cr +RM_F =$(PERL) -MExtUtils::Command -e rm_f -- + +liballinone$(LIB_EXT): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + $(RANLIB) $@ + +clean: + $(RM_F) $(OBJS) liballinone$(LIB_EXT) + +#this is necessary fo compatibility with BSD make (namely on OpenBSD) +.SUFFIXES: .o .c + +.c$(OBJ_EXT): + $(CC) $(CFLAGS) -c $< -o $@ diff --git a/src/Makefile.nmake b/src/Makefile.nmake new file mode 100644 index 0000000..bf4abb5 --- /dev/null +++ b/src/Makefile.nmake @@ -0,0 +1,167 @@ +OBJS=ltc/ciphers/anubis.obj ltc/ciphers/blowfish.obj ltc/ciphers/camellia.obj ltc/ciphers/cast5.obj \ +ltc/ciphers/des.obj ltc/ciphers/kasumi.obj ltc/ciphers/khazad.obj ltc/ciphers/kseed.obj \ +ltc/ciphers/multi2.obj ltc/ciphers/noekeon.obj ltc/ciphers/rc2.obj ltc/ciphers/rc5.obj \ +ltc/ciphers/rc6.obj ltc/ciphers/skipjack.obj ltc/ciphers/xtea.obj ltc/ciphers/aes/aes.obj \ +ltc/ciphers/safer/safer.obj ltc/ciphers/safer/saferp.obj ltc/ciphers/twofish/twofish.obj \ +ltc/encauth/ccm/ccm_add_aad.obj ltc/encauth/ccm/ccm_add_nonce.obj ltc/encauth/ccm/ccm_done.obj \ +ltc/encauth/ccm/ccm_init.obj ltc/encauth/ccm/ccm_memory.obj ltc/encauth/ccm/ccm_process.obj \ +ltc/encauth/ccm/ccm_reset.obj ltc/encauth/chachapoly/chacha20poly1305_add_aad.obj \ +ltc/encauth/chachapoly/chacha20poly1305_decrypt.obj ltc/encauth/chachapoly/chacha20poly1305_done.obj \ +ltc/encauth/chachapoly/chacha20poly1305_encrypt.obj ltc/encauth/chachapoly/chacha20poly1305_init.obj \ +ltc/encauth/chachapoly/chacha20poly1305_memory.obj ltc/encauth/chachapoly/chacha20poly1305_setiv.obj \ +ltc/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.obj ltc/encauth/eax/eax_addheader.obj \ +ltc/encauth/eax/eax_decrypt.obj ltc/encauth/eax/eax_decrypt_verify_memory.obj ltc/encauth/eax/eax_done.obj \ +ltc/encauth/eax/eax_encrypt.obj ltc/encauth/eax/eax_encrypt_authenticate_memory.obj \ +ltc/encauth/eax/eax_init.obj ltc/encauth/gcm/gcm_add_aad.obj ltc/encauth/gcm/gcm_add_iv.obj \ +ltc/encauth/gcm/gcm_done.obj ltc/encauth/gcm/gcm_gf_mult.obj ltc/encauth/gcm/gcm_init.obj \ +ltc/encauth/gcm/gcm_memory.obj ltc/encauth/gcm/gcm_mult_h.obj ltc/encauth/gcm/gcm_process.obj \ +ltc/encauth/gcm/gcm_reset.obj ltc/encauth/ocb3/ocb3_add_aad.obj ltc/encauth/ocb3/ocb3_decrypt.obj \ +ltc/encauth/ocb3/ocb3_decrypt_last.obj ltc/encauth/ocb3/ocb3_decrypt_verify_memory.obj \ +ltc/encauth/ocb3/ocb3_done.obj ltc/encauth/ocb3/ocb3_encrypt.obj ltc/encauth/ocb3/ocb3_encrypt_authenticate_memory.obj \ +ltc/encauth/ocb3/ocb3_encrypt_last.obj ltc/encauth/ocb3/ocb3_init.obj ltc/encauth/ocb3/ocb3_int_aad_add_block.obj \ +ltc/encauth/ocb3/ocb3_int_calc_offset_zero.obj ltc/encauth/ocb3/ocb3_int_ntz.obj \ +ltc/encauth/ocb3/ocb3_int_xor_blocks.obj ltc/hashes/blake2b.obj ltc/hashes/blake2s.obj \ +ltc/hashes/md2.obj ltc/hashes/md4.obj ltc/hashes/md5.obj ltc/hashes/rmd128.obj ltc/hashes/rmd160.obj \ +ltc/hashes/rmd256.obj ltc/hashes/rmd320.obj ltc/hashes/sha1.obj ltc/hashes/sha3.obj \ +ltc/hashes/sha3_test.obj ltc/hashes/tiger.obj ltc/hashes/chc/chc.obj ltc/hashes/helper/hash_file.obj \ +ltc/hashes/helper/hash_filehandle.obj ltc/hashes/helper/hash_memory.obj ltc/hashes/helper/hash_memory_multi.obj \ +ltc/hashes/sha2/sha224.obj ltc/hashes/sha2/sha256.obj ltc/hashes/sha2/sha384.obj \ +ltc/hashes/sha2/sha512.obj ltc/hashes/sha2/sha512_224.obj ltc/hashes/sha2/sha512_256.obj \ +ltc/hashes/whirl/whirl.obj ltc/mac/blake2/blake2bmac.obj ltc/mac/blake2/blake2bmac_file.obj \ +ltc/mac/blake2/blake2bmac_memory.obj ltc/mac/blake2/blake2bmac_memory_multi.obj ltc/mac/blake2/blake2smac.obj \ +ltc/mac/blake2/blake2smac_file.obj ltc/mac/blake2/blake2smac_memory.obj ltc/mac/blake2/blake2smac_memory_multi.obj \ +ltc/mac/f9/f9_done.obj ltc/mac/f9/f9_file.obj ltc/mac/f9/f9_init.obj ltc/mac/f9/f9_memory.obj \ +ltc/mac/f9/f9_memory_multi.obj ltc/mac/f9/f9_process.obj ltc/mac/hmac/hmac_done.obj \ +ltc/mac/hmac/hmac_file.obj ltc/mac/hmac/hmac_init.obj ltc/mac/hmac/hmac_memory.obj \ +ltc/mac/hmac/hmac_memory_multi.obj ltc/mac/hmac/hmac_process.obj ltc/mac/omac/omac_done.obj \ +ltc/mac/omac/omac_file.obj ltc/mac/omac/omac_init.obj ltc/mac/omac/omac_memory.obj \ +ltc/mac/omac/omac_memory_multi.obj ltc/mac/omac/omac_process.obj ltc/mac/pelican/pelican.obj \ +ltc/mac/pelican/pelican_memory.obj ltc/mac/pmac/pmac_done.obj ltc/mac/pmac/pmac_file.obj \ +ltc/mac/pmac/pmac_init.obj ltc/mac/pmac/pmac_memory.obj ltc/mac/pmac/pmac_memory_multi.obj \ +ltc/mac/pmac/pmac_ntz.obj ltc/mac/pmac/pmac_process.obj ltc/mac/pmac/pmac_shift_xor.obj \ +ltc/mac/poly1305/poly1305.obj ltc/mac/poly1305/poly1305_file.obj ltc/mac/poly1305/poly1305_memory.obj \ +ltc/mac/poly1305/poly1305_memory_multi.obj ltc/mac/xcbc/xcbc_done.obj ltc/mac/xcbc/xcbc_file.obj \ +ltc/mac/xcbc/xcbc_init.obj ltc/mac/xcbc/xcbc_memory.obj ltc/mac/xcbc/xcbc_memory_multi.obj \ +ltc/mac/xcbc/xcbc_process.obj ltc/math/ltm_desc.obj ltc/math/multi.obj ltc/math/rand_bn.obj \ +ltc/math/rand_prime.obj ltc/math/tfm_desc.obj ltc/math/fp/ltc_ecc_fp_mulmod.obj ltc/misc/adler32.obj \ +ltc/misc/burn_stack.obj ltc/misc/crc32.obj ltc/misc/error_to_string.obj ltc/misc/mem_neq.obj \ +ltc/misc/pk_get_oid.obj ltc/misc/zeromem.obj ltc/misc/base64/base64_decode.obj ltc/misc/base64/base64_encode.obj \ +ltc/misc/crypt/crypt.obj ltc/misc/crypt/crypt_argchk.obj ltc/misc/crypt/crypt_cipher_descriptor.obj \ +ltc/misc/crypt/crypt_cipher_is_valid.obj ltc/misc/crypt/crypt_find_cipher.obj ltc/misc/crypt/crypt_find_cipher_any.obj \ +ltc/misc/crypt/crypt_find_cipher_id.obj ltc/misc/crypt/crypt_find_hash.obj ltc/misc/crypt/crypt_find_hash_any.obj \ +ltc/misc/crypt/crypt_find_hash_id.obj ltc/misc/crypt/crypt_find_hash_oid.obj ltc/misc/crypt/crypt_find_prng.obj \ +ltc/misc/crypt/crypt_fsa.obj ltc/misc/crypt/crypt_hash_descriptor.obj ltc/misc/crypt/crypt_hash_is_valid.obj \ +ltc/misc/crypt/crypt_inits.obj ltc/misc/crypt/crypt_ltc_mp_descriptor.obj ltc/misc/crypt/crypt_prng_descriptor.obj \ +ltc/misc/crypt/crypt_prng_is_valid.obj ltc/misc/crypt/crypt_register_cipher.obj ltc/misc/crypt/crypt_register_hash.obj \ +ltc/misc/crypt/crypt_register_prng.obj ltc/misc/crypt/crypt_unregister_cipher.obj \ +ltc/misc/crypt/crypt_unregister_hash.obj ltc/misc/crypt/crypt_unregister_prng.obj \ +ltc/misc/hkdf/hkdf.obj ltc/misc/pkcs5/pkcs_5_1.obj ltc/misc/pkcs5/pkcs_5_2.obj ltc/modes/cbc/cbc_decrypt.obj \ +ltc/modes/cbc/cbc_done.obj ltc/modes/cbc/cbc_encrypt.obj ltc/modes/cbc/cbc_getiv.obj \ +ltc/modes/cbc/cbc_setiv.obj ltc/modes/cbc/cbc_start.obj ltc/modes/cfb/cfb_decrypt.obj \ +ltc/modes/cfb/cfb_done.obj ltc/modes/cfb/cfb_encrypt.obj ltc/modes/cfb/cfb_getiv.obj \ +ltc/modes/cfb/cfb_setiv.obj ltc/modes/cfb/cfb_start.obj ltc/modes/ctr/ctr_decrypt.obj \ +ltc/modes/ctr/ctr_done.obj ltc/modes/ctr/ctr_encrypt.obj ltc/modes/ctr/ctr_getiv.obj \ +ltc/modes/ctr/ctr_setiv.obj ltc/modes/ctr/ctr_start.obj ltc/modes/ecb/ecb_decrypt.obj \ +ltc/modes/ecb/ecb_done.obj ltc/modes/ecb/ecb_encrypt.obj ltc/modes/ecb/ecb_start.obj \ +ltc/modes/ofb/ofb_decrypt.obj ltc/modes/ofb/ofb_done.obj ltc/modes/ofb/ofb_encrypt.obj \ +ltc/modes/ofb/ofb_getiv.obj ltc/modes/ofb/ofb_setiv.obj ltc/modes/ofb/ofb_start.obj \ +ltc/pk/asn1/der/bit/der_decode_bit_string.obj ltc/pk/asn1/der/bit/der_decode_raw_bit_string.obj \ +ltc/pk/asn1/der/bit/der_encode_bit_string.obj ltc/pk/asn1/der/bit/der_encode_raw_bit_string.obj \ +ltc/pk/asn1/der/bit/der_length_bit_string.obj ltc/pk/asn1/der/boolean/der_decode_boolean.obj \ +ltc/pk/asn1/der/boolean/der_encode_boolean.obj ltc/pk/asn1/der/boolean/der_length_boolean.obj \ +ltc/pk/asn1/der/choice/der_decode_choice.obj ltc/pk/asn1/der/generalizedtime/der_decode_generalizedtime.obj \ +ltc/pk/asn1/der/generalizedtime/der_encode_generalizedtime.obj ltc/pk/asn1/der/generalizedtime/der_length_generalizedtime.obj \ +ltc/pk/asn1/der/ia5/der_decode_ia5_string.obj ltc/pk/asn1/der/ia5/der_encode_ia5_string.obj \ +ltc/pk/asn1/der/ia5/der_length_ia5_string.obj ltc/pk/asn1/der/integer/der_decode_integer.obj \ +ltc/pk/asn1/der/integer/der_encode_integer.obj ltc/pk/asn1/der/integer/der_length_integer.obj \ +ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.obj ltc/pk/asn1/der/object_identifier/der_encode_object_identifier.obj \ +ltc/pk/asn1/der/object_identifier/der_length_object_identifier.obj ltc/pk/asn1/der/octet/der_decode_octet_string.obj \ +ltc/pk/asn1/der/octet/der_encode_octet_string.obj ltc/pk/asn1/der/octet/der_length_octet_string.obj \ +ltc/pk/asn1/der/printable_string/der_decode_printable_string.obj ltc/pk/asn1/der/printable_string/der_encode_printable_string.obj \ +ltc/pk/asn1/der/printable_string/der_length_printable_string.obj ltc/pk/asn1/der/sequence/der_decode_sequence_ex.obj \ +ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.obj ltc/pk/asn1/der/sequence/der_decode_sequence_multi.obj \ +ltc/pk/asn1/der/sequence/der_decode_subject_public_key_info.obj ltc/pk/asn1/der/sequence/der_encode_sequence_ex.obj \ +ltc/pk/asn1/der/sequence/der_encode_sequence_multi.obj ltc/pk/asn1/der/sequence/der_encode_subject_public_key_info.obj \ +ltc/pk/asn1/der/sequence/der_length_sequence.obj ltc/pk/asn1/der/sequence/der_sequence_free.obj \ +ltc/pk/asn1/der/set/der_encode_set.obj ltc/pk/asn1/der/set/der_encode_setof.obj ltc/pk/asn1/der/short_integer/der_decode_short_integer.obj \ +ltc/pk/asn1/der/short_integer/der_encode_short_integer.obj ltc/pk/asn1/der/short_integer/der_length_short_integer.obj \ +ltc/pk/asn1/der/teletex_string/der_decode_teletex_string.obj ltc/pk/asn1/der/teletex_string/der_length_teletex_string.obj \ +ltc/pk/asn1/der/utctime/der_decode_utctime.obj ltc/pk/asn1/der/utctime/der_encode_utctime.obj \ +ltc/pk/asn1/der/utctime/der_length_utctime.obj ltc/pk/asn1/der/utf8/der_decode_utf8_string.obj \ +ltc/pk/asn1/der/utf8/der_encode_utf8_string.obj ltc/pk/asn1/der/utf8/der_length_utf8_string.obj \ +ltc/pk/dh/dh.obj ltc/pk/dh/dh_static.obj ltc/pk/dh/dh_sys.obj ltc/pk/dsa/dsa_decrypt_key.obj \ +ltc/pk/dsa/dsa_encrypt_key.obj ltc/pk/dsa/dsa_export.obj ltc/pk/dsa/dsa_free.obj \ +ltc/pk/dsa/dsa_import.obj ltc/pk/dsa/dsa_import_radix.obj ltc/pk/dsa/dsa_make_key.obj \ +ltc/pk/dsa/dsa_shared_secret.obj ltc/pk/dsa/dsa_sign_hash.obj ltc/pk/dsa/dsa_verify_hash.obj \ +ltc/pk/dsa/dsa_verify_key.obj ltc/pk/ecc/ecc.obj ltc/pk/ecc/ecc_ansi_x963_export.obj \ +ltc/pk/ecc/ecc_ansi_x963_import.obj ltc/pk/ecc/ecc_decrypt_key.obj ltc/pk/ecc/ecc_dp_clear.obj \ +ltc/pk/ecc/ecc_dp_fill_from_sets.obj ltc/pk/ecc/ecc_dp_from_oid.obj ltc/pk/ecc/ecc_dp_from_params.obj \ +ltc/pk/ecc/ecc_dp_init.obj ltc/pk/ecc/ecc_dp_set.obj ltc/pk/ecc/ecc_encrypt_key.obj \ +ltc/pk/ecc/ecc_export.obj ltc/pk/ecc/ecc_export_full.obj ltc/pk/ecc/ecc_export_raw.obj \ +ltc/pk/ecc/ecc_free.obj ltc/pk/ecc/ecc_get_size.obj ltc/pk/ecc/ecc_import.obj ltc/pk/ecc/ecc_import_full.obj \ +ltc/pk/ecc/ecc_import_pkcs8.obj ltc/pk/ecc/ecc_import_raw.obj ltc/pk/ecc/ecc_make_key.obj \ +ltc/pk/ecc/ecc_shared_secret.obj ltc/pk/ecc/ecc_sign_hash.obj ltc/pk/ecc/ecc_sizes.obj \ +ltc/pk/ecc/ecc_verify_hash.obj ltc/pk/ecc/ecc_verify_key.obj ltc/pk/ecc/ltc_ecc_export_point.obj \ +ltc/pk/ecc/ltc_ecc_import_point.obj ltc/pk/ecc/ltc_ecc_is_point.obj ltc/pk/ecc/ltc_ecc_is_point_at_infinity.obj \ +ltc/pk/ecc/ltc_ecc_is_valid_idx.obj ltc/pk/ecc/ltc_ecc_map.obj ltc/pk/ecc/ltc_ecc_mul2add.obj \ +ltc/pk/ecc/ltc_ecc_mulmod.obj ltc/pk/ecc/ltc_ecc_mulmod_timing.obj ltc/pk/ecc/ltc_ecc_points.obj \ +ltc/pk/ecc/ltc_ecc_projective_add_point.obj ltc/pk/ecc/ltc_ecc_projective_dbl_point.obj \ +ltc/pk/pkcs1/pkcs_1_i2osp.obj ltc/pk/pkcs1/pkcs_1_mgf1.obj ltc/pk/pkcs1/pkcs_1_oaep_decode.obj \ +ltc/pk/pkcs1/pkcs_1_oaep_encode.obj ltc/pk/pkcs1/pkcs_1_os2ip.obj ltc/pk/pkcs1/pkcs_1_pss_decode.obj \ +ltc/pk/pkcs1/pkcs_1_pss_encode.obj ltc/pk/pkcs1/pkcs_1_v1_5_decode.obj ltc/pk/pkcs1/pkcs_1_v1_5_encode.obj \ +ltc/pk/rsa/rsa_decrypt_key.obj ltc/pk/rsa/rsa_encrypt_key.obj ltc/pk/rsa/rsa_export.obj \ +ltc/pk/rsa/rsa_exptmod.obj ltc/pk/rsa/rsa_free.obj ltc/pk/rsa/rsa_get_size.obj ltc/pk/rsa/rsa_import.obj \ +ltc/pk/rsa/rsa_import_pkcs8.obj ltc/pk/rsa/rsa_import_radix.obj ltc/pk/rsa/rsa_import_x509.obj \ +ltc/pk/rsa/rsa_make_key.obj ltc/pk/rsa/rsa_sign_hash.obj ltc/pk/rsa/rsa_sign_saltlen_get.obj \ +ltc/pk/rsa/rsa_verify_hash.obj ltc/prngs/chacha20.obj ltc/prngs/fortuna.obj ltc/prngs/rc4.obj \ +ltc/prngs/rng_get_bytes.obj ltc/prngs/rng_make_prng.obj ltc/prngs/sober128.obj ltc/prngs/sprng.obj \ +ltc/prngs/yarrow.obj ltc/stream/chacha/chacha_crypt.obj ltc/stream/chacha/chacha_done.obj \ +ltc/stream/chacha/chacha_ivctr32.obj ltc/stream/chacha/chacha_ivctr64.obj ltc/stream/chacha/chacha_keystream.obj \ +ltc/stream/chacha/chacha_setup.obj ltc/stream/rc4/rc4.obj ltc/stream/sober128/sober128.obj \ +ltm/bncore.obj ltm/bn_error.obj ltm/bn_fast_mp_invmod.obj ltm/bn_fast_mp_montgomery_reduce.obj \ +ltm/bn_fast_s_mp_mul_digs.obj ltm/bn_fast_s_mp_mul_high_digs.obj ltm/bn_fast_s_mp_sqr.obj \ +ltm/bn_mp_2expt.obj ltm/bn_mp_abs.obj ltm/bn_mp_add.obj ltm/bn_mp_addmod.obj ltm/bn_mp_add_d.obj \ +ltm/bn_mp_and.obj ltm/bn_mp_clamp.obj ltm/bn_mp_clear.obj ltm/bn_mp_clear_multi.obj \ +ltm/bn_mp_cmp.obj ltm/bn_mp_cmp_d.obj ltm/bn_mp_cmp_mag.obj ltm/bn_mp_cnt_lsb.obj \ +ltm/bn_mp_copy.obj ltm/bn_mp_count_bits.obj ltm/bn_mp_div.obj ltm/bn_mp_div_2.obj \ +ltm/bn_mp_div_2d.obj ltm/bn_mp_div_3.obj ltm/bn_mp_div_d.obj ltm/bn_mp_dr_is_modulus.obj \ +ltm/bn_mp_dr_reduce.obj ltm/bn_mp_dr_setup.obj ltm/bn_mp_exch.obj ltm/bn_mp_export.obj \ +ltm/bn_mp_exptmod.obj ltm/bn_mp_exptmod_fast.obj ltm/bn_mp_expt_d.obj ltm/bn_mp_expt_d_ex.obj \ +ltm/bn_mp_exteuclid.obj ltm/bn_mp_fread.obj ltm/bn_mp_fwrite.obj ltm/bn_mp_gcd.obj \ +ltm/bn_mp_get_int.obj ltm/bn_mp_get_long.obj ltm/bn_mp_get_long_long.obj ltm/bn_mp_grow.obj \ +ltm/bn_mp_import.obj ltm/bn_mp_init.obj ltm/bn_mp_init_copy.obj ltm/bn_mp_init_multi.obj \ +ltm/bn_mp_init_set.obj ltm/bn_mp_init_set_int.obj ltm/bn_mp_init_size.obj ltm/bn_mp_invmod.obj \ +ltm/bn_mp_invmod_slow.obj ltm/bn_mp_is_square.obj ltm/bn_mp_jacobi.obj ltm/bn_mp_karatsuba_mul.obj \ +ltm/bn_mp_karatsuba_sqr.obj ltm/bn_mp_lcm.obj ltm/bn_mp_lshd.obj ltm/bn_mp_mod.obj \ +ltm/bn_mp_mod_2d.obj ltm/bn_mp_mod_d.obj ltm/bn_mp_montgomery_calc_normalization.obj \ +ltm/bn_mp_montgomery_reduce.obj ltm/bn_mp_montgomery_setup.obj ltm/bn_mp_mul.obj \ +ltm/bn_mp_mulmod.obj ltm/bn_mp_mul_2.obj ltm/bn_mp_mul_2d.obj ltm/bn_mp_mul_d.obj \ +ltm/bn_mp_neg.obj ltm/bn_mp_n_root.obj ltm/bn_mp_n_root_ex.obj ltm/bn_mp_or.obj ltm/bn_mp_prime_fermat.obj \ +ltm/bn_mp_prime_is_divisible.obj ltm/bn_mp_prime_is_prime.obj ltm/bn_mp_prime_miller_rabin.obj \ +ltm/bn_mp_prime_next_prime.obj ltm/bn_mp_prime_rabin_miller_trials.obj ltm/bn_mp_prime_random_ex.obj \ +ltm/bn_mp_radix_size.obj ltm/bn_mp_radix_smap.obj ltm/bn_mp_rand.obj ltm/bn_mp_read_radix.obj \ +ltm/bn_mp_read_signed_bin.obj ltm/bn_mp_read_unsigned_bin.obj ltm/bn_mp_reduce.obj \ +ltm/bn_mp_reduce_2k.obj ltm/bn_mp_reduce_2k_l.obj ltm/bn_mp_reduce_2k_setup.obj ltm/bn_mp_reduce_2k_setup_l.obj \ +ltm/bn_mp_reduce_is_2k.obj ltm/bn_mp_reduce_is_2k_l.obj ltm/bn_mp_reduce_setup.obj \ +ltm/bn_mp_rshd.obj ltm/bn_mp_set.obj ltm/bn_mp_set_int.obj ltm/bn_mp_set_long.obj \ +ltm/bn_mp_set_long_long.obj ltm/bn_mp_shrink.obj ltm/bn_mp_signed_bin_size.obj ltm/bn_mp_sqr.obj \ +ltm/bn_mp_sqrmod.obj ltm/bn_mp_sqrt.obj ltm/bn_mp_sqrtmod_prime.obj ltm/bn_mp_sub.obj \ +ltm/bn_mp_submod.obj ltm/bn_mp_sub_d.obj ltm/bn_mp_toom_mul.obj ltm/bn_mp_toom_sqr.obj \ +ltm/bn_mp_toradix.obj ltm/bn_mp_toradix_n.obj ltm/bn_mp_to_signed_bin.obj ltm/bn_mp_to_signed_bin_n.obj \ +ltm/bn_mp_to_unsigned_bin.obj ltm/bn_mp_to_unsigned_bin_n.obj ltm/bn_mp_unsigned_bin_size.obj \ +ltm/bn_mp_xor.obj ltm/bn_mp_zero.obj ltm/bn_prime_tab.obj ltm/bn_reverse.obj ltm/bn_s_mp_add.obj \ +ltm/bn_s_mp_exptmod.obj ltm/bn_s_mp_mul_digs.obj ltm/bn_s_mp_mul_high_digs.obj ltm/bn_s_mp_sqr.obj \ +ltm/bn_s_mp_sub.obj + +PERL =perl +RM_F =$(PERL) -MExtUtils::Command -e rm_f -- + +liballinone.lib: $(OBJS) + lib /OUT:$@ $(OBJS) + +clean: + $(RM_F) $(OBJS) liballinone.lib + +.c.obj: + cl $(CFLAGS) /c $< /Fo$@ + diff --git a/src/ltc/ciphers/aes/aes.c b/src/ltc/ciphers/aes/aes.c new file mode 100644 index 0000000..2bf7a00 --- /dev/null +++ b/src/ltc/ciphers/aes/aes.c @@ -0,0 +1,760 @@ +/* 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://libtom.org + */ + +/* AES implementation by Tom St Denis + * + * Derived from the Public Domain source code by + +--- + * rijndael-alg-fst.c + * + * @version 3.0 (December 2000) + * + * Optimised ANSI C code for the Rijndael cipher (now AES) + * + * @author Vincent Rijmen + * @author Antoon Bosselaers + * @author Paulo Barreto +--- + */ +/** + @file aes.c + Implementation of AES +*/ + +#include "tomcrypt.h" + +#ifdef LTC_RIJNDAEL + +#ifndef ENCRYPT_ONLY + +#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 + +const struct ltc_cipher_descriptor rijndael_desc = +{ + "rijndael", + 6, + 16, 32, 16, 10, + SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_DONE, ECB_KS, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +const struct ltc_cipher_descriptor aes_desc = +{ + "aes", + 6, + 16, 32, 16, 10, + SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_DONE, ECB_KS, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +#else + +#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_DONE, ECB_KS, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +const struct ltc_cipher_descriptor aes_enc_desc = +{ + "aes", + 6, + 16, 32, 16, 10, + SETUP, ECB_ENC, NULL, NULL, ECB_DONE, ECB_KS, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +#endif + +#define __LTC_AES_TAB_C__ +#include "aes_tab.c" + +static ulong32 setup_mix(ulong32 temp) +{ + return (Te4_3[byte(temp, 2)]) ^ + (Te4_2[byte(temp, 1)]) ^ + (Te4_1[byte(temp, 0)]) ^ + (Te4_0[byte(temp, 3)]); +} + +#ifndef ENCRYPT_ONLY +#ifdef LTC_SMALL_CODE +static ulong32 setup_mix2(ulong32 temp) +{ + return Td0(255 & Te4[byte(temp, 3)]) ^ + Td1(255 & Te4[byte(temp, 2)]) ^ + Td2(255 & Te4[byte(temp, 1)]) ^ + Td3(255 & Te4[byte(temp, 0)]); +} +#endif +#endif + + /** + Initialize the AES (Rijndael) block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +int SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int i; + ulong32 temp, *rk; +#ifndef ENCRYPT_ONLY + ulong32 *rrk; +#endif + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + if (keylen != 16 && keylen != 24 && keylen != 32) { + return CRYPT_INVALID_KEYSIZE; + } + + if (num_rounds != 0 && num_rounds != (10 + ((keylen/8)-2)*2)) { + return CRYPT_INVALID_ROUNDS; + } + + skey->rijndael.Nr = 10 + ((keylen/8)-2)*2; + + /* setup the forward key */ + i = 0; + rk = skey->rijndael.eK; + LOAD32H(rk[0], key ); + LOAD32H(rk[1], key + 4); + LOAD32H(rk[2], key + 8); + LOAD32H(rk[3], key + 12); + if (keylen == 16) { + for (;;) { + temp = rk[3]; + rk[4] = rk[0] ^ setup_mix(temp) ^ rcon[i]; + rk[5] = rk[1] ^ rk[4]; + rk[6] = rk[2] ^ rk[5]; + rk[7] = rk[3] ^ rk[6]; + if (++i == 10) { + break; + } + rk += 4; + } + } else if (keylen == 24) { + LOAD32H(rk[4], key + 16); + LOAD32H(rk[5], key + 20); + for (;;) { + #ifdef _MSC_VER + temp = skey->rijndael.eK[rk - skey->rijndael.eK + 5]; + #else + temp = rk[5]; + #endif + rk[ 6] = rk[ 0] ^ setup_mix(temp) ^ rcon[i]; + rk[ 7] = rk[ 1] ^ rk[ 6]; + rk[ 8] = rk[ 2] ^ rk[ 7]; + rk[ 9] = rk[ 3] ^ rk[ 8]; + if (++i == 8) { + break; + } + rk[10] = rk[ 4] ^ rk[ 9]; + rk[11] = rk[ 5] ^ rk[10]; + rk += 6; + } + } else if (keylen == 32) { + LOAD32H(rk[4], key + 16); + LOAD32H(rk[5], key + 20); + LOAD32H(rk[6], key + 24); + LOAD32H(rk[7], key + 28); + for (;;) { + #ifdef _MSC_VER + temp = skey->rijndael.eK[rk - skey->rijndael.eK + 7]; + #else + temp = rk[7]; + #endif + rk[ 8] = rk[ 0] ^ setup_mix(temp) ^ rcon[i]; + rk[ 9] = rk[ 1] ^ rk[ 8]; + rk[10] = rk[ 2] ^ rk[ 9]; + rk[11] = rk[ 3] ^ rk[10]; + if (++i == 7) { + break; + } + temp = rk[11]; + rk[12] = rk[ 4] ^ setup_mix(RORc(temp, 8)); + rk[13] = rk[ 5] ^ rk[12]; + rk[14] = rk[ 6] ^ rk[13]; + rk[15] = rk[ 7] ^ rk[14]; + rk += 8; + } + } else { + /* this can't happen */ + /* coverity[dead_error_line] */ + return CRYPT_ERROR; + } + +#ifndef ENCRYPT_ONLY + /* setup the inverse key now */ + rk = skey->rijndael.dK; + rrk = skey->rijndael.eK + (28 + keylen) - 4; + + /* apply the inverse MixColumn transform to all round keys but the first and the last: */ + /* copy first */ + *rk++ = *rrk++; + *rk++ = *rrk++; + *rk++ = *rrk++; + *rk = *rrk; + rk -= 3; rrk -= 3; + + for (i = 1; i < skey->rijndael.Nr; i++) { + rrk -= 4; + rk += 4; + #ifdef LTC_SMALL_CODE + temp = rrk[0]; + rk[0] = setup_mix2(temp); + temp = rrk[1]; + rk[1] = setup_mix2(temp); + temp = rrk[2]; + rk[2] = setup_mix2(temp); + temp = rrk[3]; + rk[3] = setup_mix2(temp); + #else + temp = rrk[0]; + rk[0] = + Tks0[byte(temp, 3)] ^ + Tks1[byte(temp, 2)] ^ + Tks2[byte(temp, 1)] ^ + Tks3[byte(temp, 0)]; + temp = rrk[1]; + rk[1] = + Tks0[byte(temp, 3)] ^ + Tks1[byte(temp, 2)] ^ + Tks2[byte(temp, 1)] ^ + Tks3[byte(temp, 0)]; + temp = rrk[2]; + rk[2] = + Tks0[byte(temp, 3)] ^ + Tks1[byte(temp, 2)] ^ + Tks2[byte(temp, 1)] ^ + Tks3[byte(temp, 0)]; + temp = rrk[3]; + rk[3] = + Tks0[byte(temp, 3)] ^ + Tks1[byte(temp, 2)] ^ + Tks2[byte(temp, 1)] ^ + Tks3[byte(temp, 0)]; + #endif + + } + + /* copy last */ + rrk -= 4; + rk += 4; + *rk++ = *rrk++; + *rk++ = *rrk++; + *rk++ = *rrk++; + *rk = *rrk; +#endif /* ENCRYPT_ONLY */ + + return CRYPT_OK; +} + +/** + Encrypts a block of text with AES + @param pt The input plaintext (16 bytes) + @param ct The output ciphertext (16 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +#ifdef LTC_CLEAN_STACK +static int _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#else +int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#endif +{ + ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk; + int Nr, r; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + + Nr = skey->rijndael.Nr; + rk = skey->rijndael.eK; + + /* + * map byte array block to cipher state + * and add initial round key: + */ + LOAD32H(s0, pt ); s0 ^= rk[0]; + LOAD32H(s1, pt + 4); s1 ^= rk[1]; + LOAD32H(s2, pt + 8); s2 ^= rk[2]; + LOAD32H(s3, pt + 12); s3 ^= rk[3]; + +#ifdef LTC_SMALL_CODE + + for (r = 0; ; r++) { + rk += 4; + t0 = + Te0(byte(s0, 3)) ^ + Te1(byte(s1, 2)) ^ + Te2(byte(s2, 1)) ^ + Te3(byte(s3, 0)) ^ + rk[0]; + t1 = + Te0(byte(s1, 3)) ^ + Te1(byte(s2, 2)) ^ + Te2(byte(s3, 1)) ^ + Te3(byte(s0, 0)) ^ + rk[1]; + t2 = + Te0(byte(s2, 3)) ^ + Te1(byte(s3, 2)) ^ + Te2(byte(s0, 1)) ^ + Te3(byte(s1, 0)) ^ + rk[2]; + t3 = + Te0(byte(s3, 3)) ^ + Te1(byte(s0, 2)) ^ + Te2(byte(s1, 1)) ^ + Te3(byte(s2, 0)) ^ + rk[3]; + if (r == Nr-2) { + break; + } + s0 = t0; s1 = t1; s2 = t2; s3 = t3; + } + rk += 4; + +#else + + /* + * Nr - 1 full rounds: + */ + r = Nr >> 1; + for (;;) { + t0 = + Te0(byte(s0, 3)) ^ + Te1(byte(s1, 2)) ^ + Te2(byte(s2, 1)) ^ + Te3(byte(s3, 0)) ^ + rk[4]; + t1 = + Te0(byte(s1, 3)) ^ + Te1(byte(s2, 2)) ^ + Te2(byte(s3, 1)) ^ + Te3(byte(s0, 0)) ^ + rk[5]; + t2 = + Te0(byte(s2, 3)) ^ + Te1(byte(s3, 2)) ^ + Te2(byte(s0, 1)) ^ + Te3(byte(s1, 0)) ^ + rk[6]; + t3 = + Te0(byte(s3, 3)) ^ + Te1(byte(s0, 2)) ^ + Te2(byte(s1, 1)) ^ + Te3(byte(s2, 0)) ^ + rk[7]; + + rk += 8; + if (--r == 0) { + break; + } + + s0 = + Te0(byte(t0, 3)) ^ + Te1(byte(t1, 2)) ^ + Te2(byte(t2, 1)) ^ + Te3(byte(t3, 0)) ^ + rk[0]; + s1 = + Te0(byte(t1, 3)) ^ + Te1(byte(t2, 2)) ^ + Te2(byte(t3, 1)) ^ + Te3(byte(t0, 0)) ^ + rk[1]; + s2 = + Te0(byte(t2, 3)) ^ + Te1(byte(t3, 2)) ^ + Te2(byte(t0, 1)) ^ + Te3(byte(t1, 0)) ^ + rk[2]; + s3 = + Te0(byte(t3, 3)) ^ + Te1(byte(t0, 2)) ^ + Te2(byte(t1, 1)) ^ + Te3(byte(t2, 0)) ^ + rk[3]; + } + +#endif + + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = + (Te4_3[byte(t0, 3)]) ^ + (Te4_2[byte(t1, 2)]) ^ + (Te4_1[byte(t2, 1)]) ^ + (Te4_0[byte(t3, 0)]) ^ + rk[0]; + STORE32H(s0, ct); + s1 = + (Te4_3[byte(t1, 3)]) ^ + (Te4_2[byte(t2, 2)]) ^ + (Te4_1[byte(t3, 1)]) ^ + (Te4_0[byte(t0, 0)]) ^ + rk[1]; + STORE32H(s1, ct+4); + s2 = + (Te4_3[byte(t2, 3)]) ^ + (Te4_2[byte(t3, 2)]) ^ + (Te4_1[byte(t0, 1)]) ^ + (Te4_0[byte(t1, 0)]) ^ + rk[2]; + STORE32H(s2, ct+8); + s3 = + (Te4_3[byte(t3, 3)]) ^ + (Te4_2[byte(t0, 2)]) ^ + (Te4_1[byte(t1, 1)]) ^ + (Te4_0[byte(t2, 0)]) ^ + rk[3]; + STORE32H(s3, ct+12); + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + int err = _rijndael_ecb_encrypt(pt, ct, skey); + burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2); + return err; +} +#endif + +#ifndef ENCRYPT_ONLY + +/** + Decrypts a block of text with AES + @param ct The input ciphertext (16 bytes) + @param pt The output plaintext (16 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +#ifdef LTC_CLEAN_STACK +static int _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#else +int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#endif +{ + ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk; + int Nr, r; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + + Nr = skey->rijndael.Nr; + rk = skey->rijndael.dK; + + /* + * map byte array block to cipher state + * and add initial round key: + */ + LOAD32H(s0, ct ); s0 ^= rk[0]; + LOAD32H(s1, ct + 4); s1 ^= rk[1]; + LOAD32H(s2, ct + 8); s2 ^= rk[2]; + LOAD32H(s3, ct + 12); s3 ^= rk[3]; + +#ifdef LTC_SMALL_CODE + for (r = 0; ; r++) { + rk += 4; + t0 = + Td0(byte(s0, 3)) ^ + Td1(byte(s3, 2)) ^ + Td2(byte(s2, 1)) ^ + Td3(byte(s1, 0)) ^ + rk[0]; + t1 = + Td0(byte(s1, 3)) ^ + Td1(byte(s0, 2)) ^ + Td2(byte(s3, 1)) ^ + Td3(byte(s2, 0)) ^ + rk[1]; + t2 = + Td0(byte(s2, 3)) ^ + Td1(byte(s1, 2)) ^ + Td2(byte(s0, 1)) ^ + Td3(byte(s3, 0)) ^ + rk[2]; + t3 = + Td0(byte(s3, 3)) ^ + Td1(byte(s2, 2)) ^ + Td2(byte(s1, 1)) ^ + Td3(byte(s0, 0)) ^ + rk[3]; + if (r == Nr-2) { + break; + } + s0 = t0; s1 = t1; s2 = t2; s3 = t3; + } + rk += 4; + +#else + + /* + * Nr - 1 full rounds: + */ + r = Nr >> 1; + for (;;) { + + t0 = + Td0(byte(s0, 3)) ^ + Td1(byte(s3, 2)) ^ + Td2(byte(s2, 1)) ^ + Td3(byte(s1, 0)) ^ + rk[4]; + t1 = + Td0(byte(s1, 3)) ^ + Td1(byte(s0, 2)) ^ + Td2(byte(s3, 1)) ^ + Td3(byte(s2, 0)) ^ + rk[5]; + t2 = + Td0(byte(s2, 3)) ^ + Td1(byte(s1, 2)) ^ + Td2(byte(s0, 1)) ^ + Td3(byte(s3, 0)) ^ + rk[6]; + t3 = + Td0(byte(s3, 3)) ^ + Td1(byte(s2, 2)) ^ + Td2(byte(s1, 1)) ^ + Td3(byte(s0, 0)) ^ + rk[7]; + + rk += 8; + if (--r == 0) { + break; + } + + + s0 = + Td0(byte(t0, 3)) ^ + Td1(byte(t3, 2)) ^ + Td2(byte(t2, 1)) ^ + Td3(byte(t1, 0)) ^ + rk[0]; + s1 = + Td0(byte(t1, 3)) ^ + Td1(byte(t0, 2)) ^ + Td2(byte(t3, 1)) ^ + Td3(byte(t2, 0)) ^ + rk[1]; + s2 = + Td0(byte(t2, 3)) ^ + Td1(byte(t1, 2)) ^ + Td2(byte(t0, 1)) ^ + Td3(byte(t3, 0)) ^ + rk[2]; + s3 = + Td0(byte(t3, 3)) ^ + Td1(byte(t2, 2)) ^ + Td2(byte(t1, 1)) ^ + Td3(byte(t0, 0)) ^ + rk[3]; + } +#endif + + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = + (Td4[byte(t0, 3)] & 0xff000000) ^ + (Td4[byte(t3, 2)] & 0x00ff0000) ^ + (Td4[byte(t2, 1)] & 0x0000ff00) ^ + (Td4[byte(t1, 0)] & 0x000000ff) ^ + rk[0]; + STORE32H(s0, pt); + s1 = + (Td4[byte(t1, 3)] & 0xff000000) ^ + (Td4[byte(t0, 2)] & 0x00ff0000) ^ + (Td4[byte(t3, 1)] & 0x0000ff00) ^ + (Td4[byte(t2, 0)] & 0x000000ff) ^ + rk[1]; + STORE32H(s1, pt+4); + s2 = + (Td4[byte(t2, 3)] & 0xff000000) ^ + (Td4[byte(t1, 2)] & 0x00ff0000) ^ + (Td4[byte(t0, 1)] & 0x0000ff00) ^ + (Td4[byte(t3, 0)] & 0x000000ff) ^ + rk[2]; + STORE32H(s2, pt+8); + s3 = + (Td4[byte(t3, 3)] & 0xff000000) ^ + (Td4[byte(t2, 2)] & 0x00ff0000) ^ + (Td4[byte(t1, 1)] & 0x0000ff00) ^ + (Td4[byte(t0, 0)] & 0x000000ff) ^ + rk[3]; + STORE32H(s3, pt+12); + + return CRYPT_OK; +} + + +#ifdef LTC_CLEAN_STACK +int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + int err = _rijndael_ecb_decrypt(ct, pt, skey); + burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2); + return err; +} +#endif + +/** + Performs a self-test of the AES block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int ECB_TEST(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + int err; + static const struct { + int keylen; + unsigned char key[32], pt[16], ct[16]; + } tests[] = { + { 16, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, + 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a } + }, { + 24, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 }, + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0, + 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 } + }, { + 32, + { 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 }, + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, + 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 } + } + }; + + symmetric_key key; + unsigned char tmp[2][16]; + int i, y; + + for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { + zeromem(&key, sizeof(key)); + if ((err = rijndael_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { + return err; + } + + rijndael_ecb_encrypt(tests[i].pt, tmp[0], &key); + rijndael_ecb_decrypt(tmp[0], tmp[1], &key); + if (XMEMCMP(tmp[0], tests[i].ct, 16) || XMEMCMP(tmp[1], tests[i].pt, 16)) { +#if 0 + printf("\n\nTest %d failed\n", i); + if (XMEMCMP(tmp[0], tests[i].ct, 16)) { + printf("CT: "); + for (i = 0; i < 16; i++) { + printf("%02x ", tmp[0][i]); + } + printf("\n"); + } else { + printf("PT: "); + for (i = 0; i < 16; i++) { + printf("%02x ", tmp[1][i]); + } + printf("\n"); + } +#endif + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 16; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) rijndael_ecb_encrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) rijndael_ecb_decrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; + #endif +} + +#endif /* ENCRYPT_ONLY */ + + +/** Terminate the context + @param skey The scheduled key +*/ +void ECB_DONE(symmetric_key *skey) +{ + LTC_UNUSED_PARAM(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. + @return CRYPT_OK if the input key size is acceptable. +*/ +int ECB_KS(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + + if (*keysize < 16) + return CRYPT_INVALID_KEYSIZE; + if (*keysize < 24) { + *keysize = 16; + return CRYPT_OK; + } else if (*keysize < 32) { + *keysize = 24; + return CRYPT_OK; + } else { + *keysize = 32; + return CRYPT_OK; + } +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/ciphers/aes/aes_tab.c b/src/ltc/ciphers/aes/aes_tab.c new file mode 100644 index 0000000..9c902e8 --- /dev/null +++ b/src/ltc/ciphers/aes/aes_tab.c @@ -0,0 +1,1032 @@ +/* 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://libtom.org + */ +/* The precomputed tables for AES */ +/* +Te0[x] = S [x].[02, 01, 01, 03]; +Te1[x] = S [x].[03, 02, 01, 01]; +Te2[x] = S [x].[01, 03, 02, 01]; +Te3[x] = S [x].[01, 01, 03, 02]; +Te4[x] = S [x].[01, 01, 01, 01]; + +Td0[x] = Si[x].[0e, 09, 0d, 0b]; +Td1[x] = Si[x].[0b, 0e, 09, 0d]; +Td2[x] = Si[x].[0d, 0b, 0e, 09]; +Td3[x] = Si[x].[09, 0d, 0b, 0e]; +Td4[x] = Si[x].[01, 01, 01, 01]; +*/ + +#ifdef __LTC_AES_TAB_C__ + +/** + @file aes_tab.c + AES tables +*/ +static const ulong32 TE0[256] = { + 0xc66363a5UL, 0xf87c7c84UL, 0xee777799UL, 0xf67b7b8dUL, + 0xfff2f20dUL, 0xd66b6bbdUL, 0xde6f6fb1UL, 0x91c5c554UL, + 0x60303050UL, 0x02010103UL, 0xce6767a9UL, 0x562b2b7dUL, + 0xe7fefe19UL, 0xb5d7d762UL, 0x4dababe6UL, 0xec76769aUL, + 0x8fcaca45UL, 0x1f82829dUL, 0x89c9c940UL, 0xfa7d7d87UL, + 0xeffafa15UL, 0xb25959ebUL, 0x8e4747c9UL, 0xfbf0f00bUL, + 0x41adadecUL, 0xb3d4d467UL, 0x5fa2a2fdUL, 0x45afafeaUL, + 0x239c9cbfUL, 0x53a4a4f7UL, 0xe4727296UL, 0x9bc0c05bUL, + 0x75b7b7c2UL, 0xe1fdfd1cUL, 0x3d9393aeUL, 0x4c26266aUL, + 0x6c36365aUL, 0x7e3f3f41UL, 0xf5f7f702UL, 0x83cccc4fUL, + 0x6834345cUL, 0x51a5a5f4UL, 0xd1e5e534UL, 0xf9f1f108UL, + 0xe2717193UL, 0xabd8d873UL, 0x62313153UL, 0x2a15153fUL, + 0x0804040cUL, 0x95c7c752UL, 0x46232365UL, 0x9dc3c35eUL, + 0x30181828UL, 0x379696a1UL, 0x0a05050fUL, 0x2f9a9ab5UL, + 0x0e070709UL, 0x24121236UL, 0x1b80809bUL, 0xdfe2e23dUL, + 0xcdebeb26UL, 0x4e272769UL, 0x7fb2b2cdUL, 0xea75759fUL, + 0x1209091bUL, 0x1d83839eUL, 0x582c2c74UL, 0x341a1a2eUL, + 0x361b1b2dUL, 0xdc6e6eb2UL, 0xb45a5aeeUL, 0x5ba0a0fbUL, + 0xa45252f6UL, 0x763b3b4dUL, 0xb7d6d661UL, 0x7db3b3ceUL, + 0x5229297bUL, 0xdde3e33eUL, 0x5e2f2f71UL, 0x13848497UL, + 0xa65353f5UL, 0xb9d1d168UL, 0x00000000UL, 0xc1eded2cUL, + 0x40202060UL, 0xe3fcfc1fUL, 0x79b1b1c8UL, 0xb65b5bedUL, + 0xd46a6abeUL, 0x8dcbcb46UL, 0x67bebed9UL, 0x7239394bUL, + 0x944a4adeUL, 0x984c4cd4UL, 0xb05858e8UL, 0x85cfcf4aUL, + 0xbbd0d06bUL, 0xc5efef2aUL, 0x4faaaae5UL, 0xedfbfb16UL, + 0x864343c5UL, 0x9a4d4dd7UL, 0x66333355UL, 0x11858594UL, + 0x8a4545cfUL, 0xe9f9f910UL, 0x04020206UL, 0xfe7f7f81UL, + 0xa05050f0UL, 0x783c3c44UL, 0x259f9fbaUL, 0x4ba8a8e3UL, + 0xa25151f3UL, 0x5da3a3feUL, 0x804040c0UL, 0x058f8f8aUL, + 0x3f9292adUL, 0x219d9dbcUL, 0x70383848UL, 0xf1f5f504UL, + 0x63bcbcdfUL, 0x77b6b6c1UL, 0xafdada75UL, 0x42212163UL, + 0x20101030UL, 0xe5ffff1aUL, 0xfdf3f30eUL, 0xbfd2d26dUL, + 0x81cdcd4cUL, 0x180c0c14UL, 0x26131335UL, 0xc3ecec2fUL, + 0xbe5f5fe1UL, 0x359797a2UL, 0x884444ccUL, 0x2e171739UL, + 0x93c4c457UL, 0x55a7a7f2UL, 0xfc7e7e82UL, 0x7a3d3d47UL, + 0xc86464acUL, 0xba5d5de7UL, 0x3219192bUL, 0xe6737395UL, + 0xc06060a0UL, 0x19818198UL, 0x9e4f4fd1UL, 0xa3dcdc7fUL, + 0x44222266UL, 0x542a2a7eUL, 0x3b9090abUL, 0x0b888883UL, + 0x8c4646caUL, 0xc7eeee29UL, 0x6bb8b8d3UL, 0x2814143cUL, + 0xa7dede79UL, 0xbc5e5ee2UL, 0x160b0b1dUL, 0xaddbdb76UL, + 0xdbe0e03bUL, 0x64323256UL, 0x743a3a4eUL, 0x140a0a1eUL, + 0x924949dbUL, 0x0c06060aUL, 0x4824246cUL, 0xb85c5ce4UL, + 0x9fc2c25dUL, 0xbdd3d36eUL, 0x43acacefUL, 0xc46262a6UL, + 0x399191a8UL, 0x319595a4UL, 0xd3e4e437UL, 0xf279798bUL, + 0xd5e7e732UL, 0x8bc8c843UL, 0x6e373759UL, 0xda6d6db7UL, + 0x018d8d8cUL, 0xb1d5d564UL, 0x9c4e4ed2UL, 0x49a9a9e0UL, + 0xd86c6cb4UL, 0xac5656faUL, 0xf3f4f407UL, 0xcfeaea25UL, + 0xca6565afUL, 0xf47a7a8eUL, 0x47aeaee9UL, 0x10080818UL, + 0x6fbabad5UL, 0xf0787888UL, 0x4a25256fUL, 0x5c2e2e72UL, + 0x381c1c24UL, 0x57a6a6f1UL, 0x73b4b4c7UL, 0x97c6c651UL, + 0xcbe8e823UL, 0xa1dddd7cUL, 0xe874749cUL, 0x3e1f1f21UL, + 0x964b4bddUL, 0x61bdbddcUL, 0x0d8b8b86UL, 0x0f8a8a85UL, + 0xe0707090UL, 0x7c3e3e42UL, 0x71b5b5c4UL, 0xcc6666aaUL, + 0x904848d8UL, 0x06030305UL, 0xf7f6f601UL, 0x1c0e0e12UL, + 0xc26161a3UL, 0x6a35355fUL, 0xae5757f9UL, 0x69b9b9d0UL, + 0x17868691UL, 0x99c1c158UL, 0x3a1d1d27UL, 0x279e9eb9UL, + 0xd9e1e138UL, 0xebf8f813UL, 0x2b9898b3UL, 0x22111133UL, + 0xd26969bbUL, 0xa9d9d970UL, 0x078e8e89UL, 0x339494a7UL, + 0x2d9b9bb6UL, 0x3c1e1e22UL, 0x15878792UL, 0xc9e9e920UL, + 0x87cece49UL, 0xaa5555ffUL, 0x50282878UL, 0xa5dfdf7aUL, + 0x038c8c8fUL, 0x59a1a1f8UL, 0x09898980UL, 0x1a0d0d17UL, + 0x65bfbfdaUL, 0xd7e6e631UL, 0x844242c6UL, 0xd06868b8UL, + 0x824141c3UL, 0x299999b0UL, 0x5a2d2d77UL, 0x1e0f0f11UL, + 0x7bb0b0cbUL, 0xa85454fcUL, 0x6dbbbbd6UL, 0x2c16163aUL, +}; + +#ifndef PELI_TAB +static const ulong32 Te4[256] = { + 0x63636363UL, 0x7c7c7c7cUL, 0x77777777UL, 0x7b7b7b7bUL, + 0xf2f2f2f2UL, 0x6b6b6b6bUL, 0x6f6f6f6fUL, 0xc5c5c5c5UL, + 0x30303030UL, 0x01010101UL, 0x67676767UL, 0x2b2b2b2bUL, + 0xfefefefeUL, 0xd7d7d7d7UL, 0xababababUL, 0x76767676UL, + 0xcacacacaUL, 0x82828282UL, 0xc9c9c9c9UL, 0x7d7d7d7dUL, + 0xfafafafaUL, 0x59595959UL, 0x47474747UL, 0xf0f0f0f0UL, + 0xadadadadUL, 0xd4d4d4d4UL, 0xa2a2a2a2UL, 0xafafafafUL, + 0x9c9c9c9cUL, 0xa4a4a4a4UL, 0x72727272UL, 0xc0c0c0c0UL, + 0xb7b7b7b7UL, 0xfdfdfdfdUL, 0x93939393UL, 0x26262626UL, + 0x36363636UL, 0x3f3f3f3fUL, 0xf7f7f7f7UL, 0xccccccccUL, + 0x34343434UL, 0xa5a5a5a5UL, 0xe5e5e5e5UL, 0xf1f1f1f1UL, + 0x71717171UL, 0xd8d8d8d8UL, 0x31313131UL, 0x15151515UL, + 0x04040404UL, 0xc7c7c7c7UL, 0x23232323UL, 0xc3c3c3c3UL, + 0x18181818UL, 0x96969696UL, 0x05050505UL, 0x9a9a9a9aUL, + 0x07070707UL, 0x12121212UL, 0x80808080UL, 0xe2e2e2e2UL, + 0xebebebebUL, 0x27272727UL, 0xb2b2b2b2UL, 0x75757575UL, + 0x09090909UL, 0x83838383UL, 0x2c2c2c2cUL, 0x1a1a1a1aUL, + 0x1b1b1b1bUL, 0x6e6e6e6eUL, 0x5a5a5a5aUL, 0xa0a0a0a0UL, + 0x52525252UL, 0x3b3b3b3bUL, 0xd6d6d6d6UL, 0xb3b3b3b3UL, + 0x29292929UL, 0xe3e3e3e3UL, 0x2f2f2f2fUL, 0x84848484UL, + 0x53535353UL, 0xd1d1d1d1UL, 0x00000000UL, 0xededededUL, + 0x20202020UL, 0xfcfcfcfcUL, 0xb1b1b1b1UL, 0x5b5b5b5bUL, + 0x6a6a6a6aUL, 0xcbcbcbcbUL, 0xbebebebeUL, 0x39393939UL, + 0x4a4a4a4aUL, 0x4c4c4c4cUL, 0x58585858UL, 0xcfcfcfcfUL, + 0xd0d0d0d0UL, 0xefefefefUL, 0xaaaaaaaaUL, 0xfbfbfbfbUL, + 0x43434343UL, 0x4d4d4d4dUL, 0x33333333UL, 0x85858585UL, + 0x45454545UL, 0xf9f9f9f9UL, 0x02020202UL, 0x7f7f7f7fUL, + 0x50505050UL, 0x3c3c3c3cUL, 0x9f9f9f9fUL, 0xa8a8a8a8UL, + 0x51515151UL, 0xa3a3a3a3UL, 0x40404040UL, 0x8f8f8f8fUL, + 0x92929292UL, 0x9d9d9d9dUL, 0x38383838UL, 0xf5f5f5f5UL, + 0xbcbcbcbcUL, 0xb6b6b6b6UL, 0xdadadadaUL, 0x21212121UL, + 0x10101010UL, 0xffffffffUL, 0xf3f3f3f3UL, 0xd2d2d2d2UL, + 0xcdcdcdcdUL, 0x0c0c0c0cUL, 0x13131313UL, 0xececececUL, + 0x5f5f5f5fUL, 0x97979797UL, 0x44444444UL, 0x17171717UL, + 0xc4c4c4c4UL, 0xa7a7a7a7UL, 0x7e7e7e7eUL, 0x3d3d3d3dUL, + 0x64646464UL, 0x5d5d5d5dUL, 0x19191919UL, 0x73737373UL, + 0x60606060UL, 0x81818181UL, 0x4f4f4f4fUL, 0xdcdcdcdcUL, + 0x22222222UL, 0x2a2a2a2aUL, 0x90909090UL, 0x88888888UL, + 0x46464646UL, 0xeeeeeeeeUL, 0xb8b8b8b8UL, 0x14141414UL, + 0xdedededeUL, 0x5e5e5e5eUL, 0x0b0b0b0bUL, 0xdbdbdbdbUL, + 0xe0e0e0e0UL, 0x32323232UL, 0x3a3a3a3aUL, 0x0a0a0a0aUL, + 0x49494949UL, 0x06060606UL, 0x24242424UL, 0x5c5c5c5cUL, + 0xc2c2c2c2UL, 0xd3d3d3d3UL, 0xacacacacUL, 0x62626262UL, + 0x91919191UL, 0x95959595UL, 0xe4e4e4e4UL, 0x79797979UL, + 0xe7e7e7e7UL, 0xc8c8c8c8UL, 0x37373737UL, 0x6d6d6d6dUL, + 0x8d8d8d8dUL, 0xd5d5d5d5UL, 0x4e4e4e4eUL, 0xa9a9a9a9UL, + 0x6c6c6c6cUL, 0x56565656UL, 0xf4f4f4f4UL, 0xeaeaeaeaUL, + 0x65656565UL, 0x7a7a7a7aUL, 0xaeaeaeaeUL, 0x08080808UL, + 0xbabababaUL, 0x78787878UL, 0x25252525UL, 0x2e2e2e2eUL, + 0x1c1c1c1cUL, 0xa6a6a6a6UL, 0xb4b4b4b4UL, 0xc6c6c6c6UL, + 0xe8e8e8e8UL, 0xddddddddUL, 0x74747474UL, 0x1f1f1f1fUL, + 0x4b4b4b4bUL, 0xbdbdbdbdUL, 0x8b8b8b8bUL, 0x8a8a8a8aUL, + 0x70707070UL, 0x3e3e3e3eUL, 0xb5b5b5b5UL, 0x66666666UL, + 0x48484848UL, 0x03030303UL, 0xf6f6f6f6UL, 0x0e0e0e0eUL, + 0x61616161UL, 0x35353535UL, 0x57575757UL, 0xb9b9b9b9UL, + 0x86868686UL, 0xc1c1c1c1UL, 0x1d1d1d1dUL, 0x9e9e9e9eUL, + 0xe1e1e1e1UL, 0xf8f8f8f8UL, 0x98989898UL, 0x11111111UL, + 0x69696969UL, 0xd9d9d9d9UL, 0x8e8e8e8eUL, 0x94949494UL, + 0x9b9b9b9bUL, 0x1e1e1e1eUL, 0x87878787UL, 0xe9e9e9e9UL, + 0xcecececeUL, 0x55555555UL, 0x28282828UL, 0xdfdfdfdfUL, + 0x8c8c8c8cUL, 0xa1a1a1a1UL, 0x89898989UL, 0x0d0d0d0dUL, + 0xbfbfbfbfUL, 0xe6e6e6e6UL, 0x42424242UL, 0x68686868UL, + 0x41414141UL, 0x99999999UL, 0x2d2d2d2dUL, 0x0f0f0f0fUL, + 0xb0b0b0b0UL, 0x54545454UL, 0xbbbbbbbbUL, 0x16161616UL, +}; +#endif + +#ifndef ENCRYPT_ONLY + +static const ulong32 TD0[256] = { + 0x51f4a750UL, 0x7e416553UL, 0x1a17a4c3UL, 0x3a275e96UL, + 0x3bab6bcbUL, 0x1f9d45f1UL, 0xacfa58abUL, 0x4be30393UL, + 0x2030fa55UL, 0xad766df6UL, 0x88cc7691UL, 0xf5024c25UL, + 0x4fe5d7fcUL, 0xc52acbd7UL, 0x26354480UL, 0xb562a38fUL, + 0xdeb15a49UL, 0x25ba1b67UL, 0x45ea0e98UL, 0x5dfec0e1UL, + 0xc32f7502UL, 0x814cf012UL, 0x8d4697a3UL, 0x6bd3f9c6UL, + 0x038f5fe7UL, 0x15929c95UL, 0xbf6d7aebUL, 0x955259daUL, + 0xd4be832dUL, 0x587421d3UL, 0x49e06929UL, 0x8ec9c844UL, + 0x75c2896aUL, 0xf48e7978UL, 0x99583e6bUL, 0x27b971ddUL, + 0xbee14fb6UL, 0xf088ad17UL, 0xc920ac66UL, 0x7dce3ab4UL, + 0x63df4a18UL, 0xe51a3182UL, 0x97513360UL, 0x62537f45UL, + 0xb16477e0UL, 0xbb6bae84UL, 0xfe81a01cUL, 0xf9082b94UL, + 0x70486858UL, 0x8f45fd19UL, 0x94de6c87UL, 0x527bf8b7UL, + 0xab73d323UL, 0x724b02e2UL, 0xe31f8f57UL, 0x6655ab2aUL, + 0xb2eb2807UL, 0x2fb5c203UL, 0x86c57b9aUL, 0xd33708a5UL, + 0x302887f2UL, 0x23bfa5b2UL, 0x02036abaUL, 0xed16825cUL, + 0x8acf1c2bUL, 0xa779b492UL, 0xf307f2f0UL, 0x4e69e2a1UL, + 0x65daf4cdUL, 0x0605bed5UL, 0xd134621fUL, 0xc4a6fe8aUL, + 0x342e539dUL, 0xa2f355a0UL, 0x058ae132UL, 0xa4f6eb75UL, + 0x0b83ec39UL, 0x4060efaaUL, 0x5e719f06UL, 0xbd6e1051UL, + 0x3e218af9UL, 0x96dd063dUL, 0xdd3e05aeUL, 0x4de6bd46UL, + 0x91548db5UL, 0x71c45d05UL, 0x0406d46fUL, 0x605015ffUL, + 0x1998fb24UL, 0xd6bde997UL, 0x894043ccUL, 0x67d99e77UL, + 0xb0e842bdUL, 0x07898b88UL, 0xe7195b38UL, 0x79c8eedbUL, + 0xa17c0a47UL, 0x7c420fe9UL, 0xf8841ec9UL, 0x00000000UL, + 0x09808683UL, 0x322bed48UL, 0x1e1170acUL, 0x6c5a724eUL, + 0xfd0efffbUL, 0x0f853856UL, 0x3daed51eUL, 0x362d3927UL, + 0x0a0fd964UL, 0x685ca621UL, 0x9b5b54d1UL, 0x24362e3aUL, + 0x0c0a67b1UL, 0x9357e70fUL, 0xb4ee96d2UL, 0x1b9b919eUL, + 0x80c0c54fUL, 0x61dc20a2UL, 0x5a774b69UL, 0x1c121a16UL, + 0xe293ba0aUL, 0xc0a02ae5UL, 0x3c22e043UL, 0x121b171dUL, + 0x0e090d0bUL, 0xf28bc7adUL, 0x2db6a8b9UL, 0x141ea9c8UL, + 0x57f11985UL, 0xaf75074cUL, 0xee99ddbbUL, 0xa37f60fdUL, + 0xf701269fUL, 0x5c72f5bcUL, 0x44663bc5UL, 0x5bfb7e34UL, + 0x8b432976UL, 0xcb23c6dcUL, 0xb6edfc68UL, 0xb8e4f163UL, + 0xd731dccaUL, 0x42638510UL, 0x13972240UL, 0x84c61120UL, + 0x854a247dUL, 0xd2bb3df8UL, 0xaef93211UL, 0xc729a16dUL, + 0x1d9e2f4bUL, 0xdcb230f3UL, 0x0d8652ecUL, 0x77c1e3d0UL, + 0x2bb3166cUL, 0xa970b999UL, 0x119448faUL, 0x47e96422UL, + 0xa8fc8cc4UL, 0xa0f03f1aUL, 0x567d2cd8UL, 0x223390efUL, + 0x87494ec7UL, 0xd938d1c1UL, 0x8ccaa2feUL, 0x98d40b36UL, + 0xa6f581cfUL, 0xa57ade28UL, 0xdab78e26UL, 0x3fadbfa4UL, + 0x2c3a9de4UL, 0x5078920dUL, 0x6a5fcc9bUL, 0x547e4662UL, + 0xf68d13c2UL, 0x90d8b8e8UL, 0x2e39f75eUL, 0x82c3aff5UL, + 0x9f5d80beUL, 0x69d0937cUL, 0x6fd52da9UL, 0xcf2512b3UL, + 0xc8ac993bUL, 0x10187da7UL, 0xe89c636eUL, 0xdb3bbb7bUL, + 0xcd267809UL, 0x6e5918f4UL, 0xec9ab701UL, 0x834f9aa8UL, + 0xe6956e65UL, 0xaaffe67eUL, 0x21bccf08UL, 0xef15e8e6UL, + 0xbae79bd9UL, 0x4a6f36ceUL, 0xea9f09d4UL, 0x29b07cd6UL, + 0x31a4b2afUL, 0x2a3f2331UL, 0xc6a59430UL, 0x35a266c0UL, + 0x744ebc37UL, 0xfc82caa6UL, 0xe090d0b0UL, 0x33a7d815UL, + 0xf104984aUL, 0x41ecdaf7UL, 0x7fcd500eUL, 0x1791f62fUL, + 0x764dd68dUL, 0x43efb04dUL, 0xccaa4d54UL, 0xe49604dfUL, + 0x9ed1b5e3UL, 0x4c6a881bUL, 0xc12c1fb8UL, 0x4665517fUL, + 0x9d5eea04UL, 0x018c355dUL, 0xfa877473UL, 0xfb0b412eUL, + 0xb3671d5aUL, 0x92dbd252UL, 0xe9105633UL, 0x6dd64713UL, + 0x9ad7618cUL, 0x37a10c7aUL, 0x59f8148eUL, 0xeb133c89UL, + 0xcea927eeUL, 0xb761c935UL, 0xe11ce5edUL, 0x7a47b13cUL, + 0x9cd2df59UL, 0x55f2733fUL, 0x1814ce79UL, 0x73c737bfUL, + 0x53f7cdeaUL, 0x5ffdaa5bUL, 0xdf3d6f14UL, 0x7844db86UL, + 0xcaaff381UL, 0xb968c43eUL, 0x3824342cUL, 0xc2a3405fUL, + 0x161dc372UL, 0xbce2250cUL, 0x283c498bUL, 0xff0d9541UL, + 0x39a80171UL, 0x080cb3deUL, 0xd8b4e49cUL, 0x6456c190UL, + 0x7bcb8461UL, 0xd532b670UL, 0x486c5c74UL, 0xd0b85742UL, +}; + +static const ulong32 Td4[256] = { + 0x52525252UL, 0x09090909UL, 0x6a6a6a6aUL, 0xd5d5d5d5UL, + 0x30303030UL, 0x36363636UL, 0xa5a5a5a5UL, 0x38383838UL, + 0xbfbfbfbfUL, 0x40404040UL, 0xa3a3a3a3UL, 0x9e9e9e9eUL, + 0x81818181UL, 0xf3f3f3f3UL, 0xd7d7d7d7UL, 0xfbfbfbfbUL, + 0x7c7c7c7cUL, 0xe3e3e3e3UL, 0x39393939UL, 0x82828282UL, + 0x9b9b9b9bUL, 0x2f2f2f2fUL, 0xffffffffUL, 0x87878787UL, + 0x34343434UL, 0x8e8e8e8eUL, 0x43434343UL, 0x44444444UL, + 0xc4c4c4c4UL, 0xdedededeUL, 0xe9e9e9e9UL, 0xcbcbcbcbUL, + 0x54545454UL, 0x7b7b7b7bUL, 0x94949494UL, 0x32323232UL, + 0xa6a6a6a6UL, 0xc2c2c2c2UL, 0x23232323UL, 0x3d3d3d3dUL, + 0xeeeeeeeeUL, 0x4c4c4c4cUL, 0x95959595UL, 0x0b0b0b0bUL, + 0x42424242UL, 0xfafafafaUL, 0xc3c3c3c3UL, 0x4e4e4e4eUL, + 0x08080808UL, 0x2e2e2e2eUL, 0xa1a1a1a1UL, 0x66666666UL, + 0x28282828UL, 0xd9d9d9d9UL, 0x24242424UL, 0xb2b2b2b2UL, + 0x76767676UL, 0x5b5b5b5bUL, 0xa2a2a2a2UL, 0x49494949UL, + 0x6d6d6d6dUL, 0x8b8b8b8bUL, 0xd1d1d1d1UL, 0x25252525UL, + 0x72727272UL, 0xf8f8f8f8UL, 0xf6f6f6f6UL, 0x64646464UL, + 0x86868686UL, 0x68686868UL, 0x98989898UL, 0x16161616UL, + 0xd4d4d4d4UL, 0xa4a4a4a4UL, 0x5c5c5c5cUL, 0xccccccccUL, + 0x5d5d5d5dUL, 0x65656565UL, 0xb6b6b6b6UL, 0x92929292UL, + 0x6c6c6c6cUL, 0x70707070UL, 0x48484848UL, 0x50505050UL, + 0xfdfdfdfdUL, 0xededededUL, 0xb9b9b9b9UL, 0xdadadadaUL, + 0x5e5e5e5eUL, 0x15151515UL, 0x46464646UL, 0x57575757UL, + 0xa7a7a7a7UL, 0x8d8d8d8dUL, 0x9d9d9d9dUL, 0x84848484UL, + 0x90909090UL, 0xd8d8d8d8UL, 0xababababUL, 0x00000000UL, + 0x8c8c8c8cUL, 0xbcbcbcbcUL, 0xd3d3d3d3UL, 0x0a0a0a0aUL, + 0xf7f7f7f7UL, 0xe4e4e4e4UL, 0x58585858UL, 0x05050505UL, + 0xb8b8b8b8UL, 0xb3b3b3b3UL, 0x45454545UL, 0x06060606UL, + 0xd0d0d0d0UL, 0x2c2c2c2cUL, 0x1e1e1e1eUL, 0x8f8f8f8fUL, + 0xcacacacaUL, 0x3f3f3f3fUL, 0x0f0f0f0fUL, 0x02020202UL, + 0xc1c1c1c1UL, 0xafafafafUL, 0xbdbdbdbdUL, 0x03030303UL, + 0x01010101UL, 0x13131313UL, 0x8a8a8a8aUL, 0x6b6b6b6bUL, + 0x3a3a3a3aUL, 0x91919191UL, 0x11111111UL, 0x41414141UL, + 0x4f4f4f4fUL, 0x67676767UL, 0xdcdcdcdcUL, 0xeaeaeaeaUL, + 0x97979797UL, 0xf2f2f2f2UL, 0xcfcfcfcfUL, 0xcecececeUL, + 0xf0f0f0f0UL, 0xb4b4b4b4UL, 0xe6e6e6e6UL, 0x73737373UL, + 0x96969696UL, 0xacacacacUL, 0x74747474UL, 0x22222222UL, + 0xe7e7e7e7UL, 0xadadadadUL, 0x35353535UL, 0x85858585UL, + 0xe2e2e2e2UL, 0xf9f9f9f9UL, 0x37373737UL, 0xe8e8e8e8UL, + 0x1c1c1c1cUL, 0x75757575UL, 0xdfdfdfdfUL, 0x6e6e6e6eUL, + 0x47474747UL, 0xf1f1f1f1UL, 0x1a1a1a1aUL, 0x71717171UL, + 0x1d1d1d1dUL, 0x29292929UL, 0xc5c5c5c5UL, 0x89898989UL, + 0x6f6f6f6fUL, 0xb7b7b7b7UL, 0x62626262UL, 0x0e0e0e0eUL, + 0xaaaaaaaaUL, 0x18181818UL, 0xbebebebeUL, 0x1b1b1b1bUL, + 0xfcfcfcfcUL, 0x56565656UL, 0x3e3e3e3eUL, 0x4b4b4b4bUL, + 0xc6c6c6c6UL, 0xd2d2d2d2UL, 0x79797979UL, 0x20202020UL, + 0x9a9a9a9aUL, 0xdbdbdbdbUL, 0xc0c0c0c0UL, 0xfefefefeUL, + 0x78787878UL, 0xcdcdcdcdUL, 0x5a5a5a5aUL, 0xf4f4f4f4UL, + 0x1f1f1f1fUL, 0xddddddddUL, 0xa8a8a8a8UL, 0x33333333UL, + 0x88888888UL, 0x07070707UL, 0xc7c7c7c7UL, 0x31313131UL, + 0xb1b1b1b1UL, 0x12121212UL, 0x10101010UL, 0x59595959UL, + 0x27272727UL, 0x80808080UL, 0xececececUL, 0x5f5f5f5fUL, + 0x60606060UL, 0x51515151UL, 0x7f7f7f7fUL, 0xa9a9a9a9UL, + 0x19191919UL, 0xb5b5b5b5UL, 0x4a4a4a4aUL, 0x0d0d0d0dUL, + 0x2d2d2d2dUL, 0xe5e5e5e5UL, 0x7a7a7a7aUL, 0x9f9f9f9fUL, + 0x93939393UL, 0xc9c9c9c9UL, 0x9c9c9c9cUL, 0xefefefefUL, + 0xa0a0a0a0UL, 0xe0e0e0e0UL, 0x3b3b3b3bUL, 0x4d4d4d4dUL, + 0xaeaeaeaeUL, 0x2a2a2a2aUL, 0xf5f5f5f5UL, 0xb0b0b0b0UL, + 0xc8c8c8c8UL, 0xebebebebUL, 0xbbbbbbbbUL, 0x3c3c3c3cUL, + 0x83838383UL, 0x53535353UL, 0x99999999UL, 0x61616161UL, + 0x17171717UL, 0x2b2b2b2bUL, 0x04040404UL, 0x7e7e7e7eUL, + 0xbabababaUL, 0x77777777UL, 0xd6d6d6d6UL, 0x26262626UL, + 0xe1e1e1e1UL, 0x69696969UL, 0x14141414UL, 0x63636363UL, + 0x55555555UL, 0x21212121UL, 0x0c0c0c0cUL, 0x7d7d7d7dUL, +}; + +#endif /* ENCRYPT_ONLY */ + +#ifdef LTC_SMALL_CODE + +#define Te0(x) TE0[x] +#define Te1(x) RORc(TE0[x], 8) +#define Te2(x) RORc(TE0[x], 16) +#define Te3(x) RORc(TE0[x], 24) + +#define Td0(x) TD0[x] +#define Td1(x) RORc(TD0[x], 8) +#define Td2(x) RORc(TD0[x], 16) +#define Td3(x) RORc(TD0[x], 24) + +#define Te4_0 0x000000FF & Te4 +#define Te4_1 0x0000FF00 & Te4 +#define Te4_2 0x00FF0000 & Te4 +#define Te4_3 0xFF000000 & Te4 + +#else + +#define Te0(x) TE0[x] +#define Te1(x) TE1[x] +#define Te2(x) TE2[x] +#define Te3(x) TE3[x] + +#define Td0(x) TD0[x] +#define Td1(x) TD1[x] +#define Td2(x) TD2[x] +#define Td3(x) TD3[x] + +static const ulong32 TE1[256] = { + 0xa5c66363UL, 0x84f87c7cUL, 0x99ee7777UL, 0x8df67b7bUL, + 0x0dfff2f2UL, 0xbdd66b6bUL, 0xb1de6f6fUL, 0x5491c5c5UL, + 0x50603030UL, 0x03020101UL, 0xa9ce6767UL, 0x7d562b2bUL, + 0x19e7fefeUL, 0x62b5d7d7UL, 0xe64dababUL, 0x9aec7676UL, + 0x458fcacaUL, 0x9d1f8282UL, 0x4089c9c9UL, 0x87fa7d7dUL, + 0x15effafaUL, 0xebb25959UL, 0xc98e4747UL, 0x0bfbf0f0UL, + 0xec41adadUL, 0x67b3d4d4UL, 0xfd5fa2a2UL, 0xea45afafUL, + 0xbf239c9cUL, 0xf753a4a4UL, 0x96e47272UL, 0x5b9bc0c0UL, + 0xc275b7b7UL, 0x1ce1fdfdUL, 0xae3d9393UL, 0x6a4c2626UL, + 0x5a6c3636UL, 0x417e3f3fUL, 0x02f5f7f7UL, 0x4f83ccccUL, + 0x5c683434UL, 0xf451a5a5UL, 0x34d1e5e5UL, 0x08f9f1f1UL, + 0x93e27171UL, 0x73abd8d8UL, 0x53623131UL, 0x3f2a1515UL, + 0x0c080404UL, 0x5295c7c7UL, 0x65462323UL, 0x5e9dc3c3UL, + 0x28301818UL, 0xa1379696UL, 0x0f0a0505UL, 0xb52f9a9aUL, + 0x090e0707UL, 0x36241212UL, 0x9b1b8080UL, 0x3ddfe2e2UL, + 0x26cdebebUL, 0x694e2727UL, 0xcd7fb2b2UL, 0x9fea7575UL, + 0x1b120909UL, 0x9e1d8383UL, 0x74582c2cUL, 0x2e341a1aUL, + 0x2d361b1bUL, 0xb2dc6e6eUL, 0xeeb45a5aUL, 0xfb5ba0a0UL, + 0xf6a45252UL, 0x4d763b3bUL, 0x61b7d6d6UL, 0xce7db3b3UL, + 0x7b522929UL, 0x3edde3e3UL, 0x715e2f2fUL, 0x97138484UL, + 0xf5a65353UL, 0x68b9d1d1UL, 0x00000000UL, 0x2cc1ededUL, + 0x60402020UL, 0x1fe3fcfcUL, 0xc879b1b1UL, 0xedb65b5bUL, + 0xbed46a6aUL, 0x468dcbcbUL, 0xd967bebeUL, 0x4b723939UL, + 0xde944a4aUL, 0xd4984c4cUL, 0xe8b05858UL, 0x4a85cfcfUL, + 0x6bbbd0d0UL, 0x2ac5efefUL, 0xe54faaaaUL, 0x16edfbfbUL, + 0xc5864343UL, 0xd79a4d4dUL, 0x55663333UL, 0x94118585UL, + 0xcf8a4545UL, 0x10e9f9f9UL, 0x06040202UL, 0x81fe7f7fUL, + 0xf0a05050UL, 0x44783c3cUL, 0xba259f9fUL, 0xe34ba8a8UL, + 0xf3a25151UL, 0xfe5da3a3UL, 0xc0804040UL, 0x8a058f8fUL, + 0xad3f9292UL, 0xbc219d9dUL, 0x48703838UL, 0x04f1f5f5UL, + 0xdf63bcbcUL, 0xc177b6b6UL, 0x75afdadaUL, 0x63422121UL, + 0x30201010UL, 0x1ae5ffffUL, 0x0efdf3f3UL, 0x6dbfd2d2UL, + 0x4c81cdcdUL, 0x14180c0cUL, 0x35261313UL, 0x2fc3ececUL, + 0xe1be5f5fUL, 0xa2359797UL, 0xcc884444UL, 0x392e1717UL, + 0x5793c4c4UL, 0xf255a7a7UL, 0x82fc7e7eUL, 0x477a3d3dUL, + 0xacc86464UL, 0xe7ba5d5dUL, 0x2b321919UL, 0x95e67373UL, + 0xa0c06060UL, 0x98198181UL, 0xd19e4f4fUL, 0x7fa3dcdcUL, + 0x66442222UL, 0x7e542a2aUL, 0xab3b9090UL, 0x830b8888UL, + 0xca8c4646UL, 0x29c7eeeeUL, 0xd36bb8b8UL, 0x3c281414UL, + 0x79a7dedeUL, 0xe2bc5e5eUL, 0x1d160b0bUL, 0x76addbdbUL, + 0x3bdbe0e0UL, 0x56643232UL, 0x4e743a3aUL, 0x1e140a0aUL, + 0xdb924949UL, 0x0a0c0606UL, 0x6c482424UL, 0xe4b85c5cUL, + 0x5d9fc2c2UL, 0x6ebdd3d3UL, 0xef43acacUL, 0xa6c46262UL, + 0xa8399191UL, 0xa4319595UL, 0x37d3e4e4UL, 0x8bf27979UL, + 0x32d5e7e7UL, 0x438bc8c8UL, 0x596e3737UL, 0xb7da6d6dUL, + 0x8c018d8dUL, 0x64b1d5d5UL, 0xd29c4e4eUL, 0xe049a9a9UL, + 0xb4d86c6cUL, 0xfaac5656UL, 0x07f3f4f4UL, 0x25cfeaeaUL, + 0xafca6565UL, 0x8ef47a7aUL, 0xe947aeaeUL, 0x18100808UL, + 0xd56fbabaUL, 0x88f07878UL, 0x6f4a2525UL, 0x725c2e2eUL, + 0x24381c1cUL, 0xf157a6a6UL, 0xc773b4b4UL, 0x5197c6c6UL, + 0x23cbe8e8UL, 0x7ca1ddddUL, 0x9ce87474UL, 0x213e1f1fUL, + 0xdd964b4bUL, 0xdc61bdbdUL, 0x860d8b8bUL, 0x850f8a8aUL, + 0x90e07070UL, 0x427c3e3eUL, 0xc471b5b5UL, 0xaacc6666UL, + 0xd8904848UL, 0x05060303UL, 0x01f7f6f6UL, 0x121c0e0eUL, + 0xa3c26161UL, 0x5f6a3535UL, 0xf9ae5757UL, 0xd069b9b9UL, + 0x91178686UL, 0x5899c1c1UL, 0x273a1d1dUL, 0xb9279e9eUL, + 0x38d9e1e1UL, 0x13ebf8f8UL, 0xb32b9898UL, 0x33221111UL, + 0xbbd26969UL, 0x70a9d9d9UL, 0x89078e8eUL, 0xa7339494UL, + 0xb62d9b9bUL, 0x223c1e1eUL, 0x92158787UL, 0x20c9e9e9UL, + 0x4987ceceUL, 0xffaa5555UL, 0x78502828UL, 0x7aa5dfdfUL, + 0x8f038c8cUL, 0xf859a1a1UL, 0x80098989UL, 0x171a0d0dUL, + 0xda65bfbfUL, 0x31d7e6e6UL, 0xc6844242UL, 0xb8d06868UL, + 0xc3824141UL, 0xb0299999UL, 0x775a2d2dUL, 0x111e0f0fUL, + 0xcb7bb0b0UL, 0xfca85454UL, 0xd66dbbbbUL, 0x3a2c1616UL, +}; +static const ulong32 TE2[256] = { + 0x63a5c663UL, 0x7c84f87cUL, 0x7799ee77UL, 0x7b8df67bUL, + 0xf20dfff2UL, 0x6bbdd66bUL, 0x6fb1de6fUL, 0xc55491c5UL, + 0x30506030UL, 0x01030201UL, 0x67a9ce67UL, 0x2b7d562bUL, + 0xfe19e7feUL, 0xd762b5d7UL, 0xabe64dabUL, 0x769aec76UL, + 0xca458fcaUL, 0x829d1f82UL, 0xc94089c9UL, 0x7d87fa7dUL, + 0xfa15effaUL, 0x59ebb259UL, 0x47c98e47UL, 0xf00bfbf0UL, + 0xadec41adUL, 0xd467b3d4UL, 0xa2fd5fa2UL, 0xafea45afUL, + 0x9cbf239cUL, 0xa4f753a4UL, 0x7296e472UL, 0xc05b9bc0UL, + 0xb7c275b7UL, 0xfd1ce1fdUL, 0x93ae3d93UL, 0x266a4c26UL, + 0x365a6c36UL, 0x3f417e3fUL, 0xf702f5f7UL, 0xcc4f83ccUL, + 0x345c6834UL, 0xa5f451a5UL, 0xe534d1e5UL, 0xf108f9f1UL, + 0x7193e271UL, 0xd873abd8UL, 0x31536231UL, 0x153f2a15UL, + 0x040c0804UL, 0xc75295c7UL, 0x23654623UL, 0xc35e9dc3UL, + 0x18283018UL, 0x96a13796UL, 0x050f0a05UL, 0x9ab52f9aUL, + 0x07090e07UL, 0x12362412UL, 0x809b1b80UL, 0xe23ddfe2UL, + 0xeb26cdebUL, 0x27694e27UL, 0xb2cd7fb2UL, 0x759fea75UL, + 0x091b1209UL, 0x839e1d83UL, 0x2c74582cUL, 0x1a2e341aUL, + 0x1b2d361bUL, 0x6eb2dc6eUL, 0x5aeeb45aUL, 0xa0fb5ba0UL, + 0x52f6a452UL, 0x3b4d763bUL, 0xd661b7d6UL, 0xb3ce7db3UL, + 0x297b5229UL, 0xe33edde3UL, 0x2f715e2fUL, 0x84971384UL, + 0x53f5a653UL, 0xd168b9d1UL, 0x00000000UL, 0xed2cc1edUL, + 0x20604020UL, 0xfc1fe3fcUL, 0xb1c879b1UL, 0x5bedb65bUL, + 0x6abed46aUL, 0xcb468dcbUL, 0xbed967beUL, 0x394b7239UL, + 0x4ade944aUL, 0x4cd4984cUL, 0x58e8b058UL, 0xcf4a85cfUL, + 0xd06bbbd0UL, 0xef2ac5efUL, 0xaae54faaUL, 0xfb16edfbUL, + 0x43c58643UL, 0x4dd79a4dUL, 0x33556633UL, 0x85941185UL, + 0x45cf8a45UL, 0xf910e9f9UL, 0x02060402UL, 0x7f81fe7fUL, + 0x50f0a050UL, 0x3c44783cUL, 0x9fba259fUL, 0xa8e34ba8UL, + 0x51f3a251UL, 0xa3fe5da3UL, 0x40c08040UL, 0x8f8a058fUL, + 0x92ad3f92UL, 0x9dbc219dUL, 0x38487038UL, 0xf504f1f5UL, + 0xbcdf63bcUL, 0xb6c177b6UL, 0xda75afdaUL, 0x21634221UL, + 0x10302010UL, 0xff1ae5ffUL, 0xf30efdf3UL, 0xd26dbfd2UL, + 0xcd4c81cdUL, 0x0c14180cUL, 0x13352613UL, 0xec2fc3ecUL, + 0x5fe1be5fUL, 0x97a23597UL, 0x44cc8844UL, 0x17392e17UL, + 0xc45793c4UL, 0xa7f255a7UL, 0x7e82fc7eUL, 0x3d477a3dUL, + 0x64acc864UL, 0x5de7ba5dUL, 0x192b3219UL, 0x7395e673UL, + 0x60a0c060UL, 0x81981981UL, 0x4fd19e4fUL, 0xdc7fa3dcUL, + 0x22664422UL, 0x2a7e542aUL, 0x90ab3b90UL, 0x88830b88UL, + 0x46ca8c46UL, 0xee29c7eeUL, 0xb8d36bb8UL, 0x143c2814UL, + 0xde79a7deUL, 0x5ee2bc5eUL, 0x0b1d160bUL, 0xdb76addbUL, + 0xe03bdbe0UL, 0x32566432UL, 0x3a4e743aUL, 0x0a1e140aUL, + 0x49db9249UL, 0x060a0c06UL, 0x246c4824UL, 0x5ce4b85cUL, + 0xc25d9fc2UL, 0xd36ebdd3UL, 0xacef43acUL, 0x62a6c462UL, + 0x91a83991UL, 0x95a43195UL, 0xe437d3e4UL, 0x798bf279UL, + 0xe732d5e7UL, 0xc8438bc8UL, 0x37596e37UL, 0x6db7da6dUL, + 0x8d8c018dUL, 0xd564b1d5UL, 0x4ed29c4eUL, 0xa9e049a9UL, + 0x6cb4d86cUL, 0x56faac56UL, 0xf407f3f4UL, 0xea25cfeaUL, + 0x65afca65UL, 0x7a8ef47aUL, 0xaee947aeUL, 0x08181008UL, + 0xbad56fbaUL, 0x7888f078UL, 0x256f4a25UL, 0x2e725c2eUL, + 0x1c24381cUL, 0xa6f157a6UL, 0xb4c773b4UL, 0xc65197c6UL, + 0xe823cbe8UL, 0xdd7ca1ddUL, 0x749ce874UL, 0x1f213e1fUL, + 0x4bdd964bUL, 0xbddc61bdUL, 0x8b860d8bUL, 0x8a850f8aUL, + 0x7090e070UL, 0x3e427c3eUL, 0xb5c471b5UL, 0x66aacc66UL, + 0x48d89048UL, 0x03050603UL, 0xf601f7f6UL, 0x0e121c0eUL, + 0x61a3c261UL, 0x355f6a35UL, 0x57f9ae57UL, 0xb9d069b9UL, + 0x86911786UL, 0xc15899c1UL, 0x1d273a1dUL, 0x9eb9279eUL, + 0xe138d9e1UL, 0xf813ebf8UL, 0x98b32b98UL, 0x11332211UL, + 0x69bbd269UL, 0xd970a9d9UL, 0x8e89078eUL, 0x94a73394UL, + 0x9bb62d9bUL, 0x1e223c1eUL, 0x87921587UL, 0xe920c9e9UL, + 0xce4987ceUL, 0x55ffaa55UL, 0x28785028UL, 0xdf7aa5dfUL, + 0x8c8f038cUL, 0xa1f859a1UL, 0x89800989UL, 0x0d171a0dUL, + 0xbfda65bfUL, 0xe631d7e6UL, 0x42c68442UL, 0x68b8d068UL, + 0x41c38241UL, 0x99b02999UL, 0x2d775a2dUL, 0x0f111e0fUL, + 0xb0cb7bb0UL, 0x54fca854UL, 0xbbd66dbbUL, 0x163a2c16UL, +}; +static const ulong32 TE3[256] = { + + 0x6363a5c6UL, 0x7c7c84f8UL, 0x777799eeUL, 0x7b7b8df6UL, + 0xf2f20dffUL, 0x6b6bbdd6UL, 0x6f6fb1deUL, 0xc5c55491UL, + 0x30305060UL, 0x01010302UL, 0x6767a9ceUL, 0x2b2b7d56UL, + 0xfefe19e7UL, 0xd7d762b5UL, 0xababe64dUL, 0x76769aecUL, + 0xcaca458fUL, 0x82829d1fUL, 0xc9c94089UL, 0x7d7d87faUL, + 0xfafa15efUL, 0x5959ebb2UL, 0x4747c98eUL, 0xf0f00bfbUL, + 0xadadec41UL, 0xd4d467b3UL, 0xa2a2fd5fUL, 0xafafea45UL, + 0x9c9cbf23UL, 0xa4a4f753UL, 0x727296e4UL, 0xc0c05b9bUL, + 0xb7b7c275UL, 0xfdfd1ce1UL, 0x9393ae3dUL, 0x26266a4cUL, + 0x36365a6cUL, 0x3f3f417eUL, 0xf7f702f5UL, 0xcccc4f83UL, + 0x34345c68UL, 0xa5a5f451UL, 0xe5e534d1UL, 0xf1f108f9UL, + 0x717193e2UL, 0xd8d873abUL, 0x31315362UL, 0x15153f2aUL, + 0x04040c08UL, 0xc7c75295UL, 0x23236546UL, 0xc3c35e9dUL, + 0x18182830UL, 0x9696a137UL, 0x05050f0aUL, 0x9a9ab52fUL, + 0x0707090eUL, 0x12123624UL, 0x80809b1bUL, 0xe2e23ddfUL, + 0xebeb26cdUL, 0x2727694eUL, 0xb2b2cd7fUL, 0x75759feaUL, + 0x09091b12UL, 0x83839e1dUL, 0x2c2c7458UL, 0x1a1a2e34UL, + 0x1b1b2d36UL, 0x6e6eb2dcUL, 0x5a5aeeb4UL, 0xa0a0fb5bUL, + 0x5252f6a4UL, 0x3b3b4d76UL, 0xd6d661b7UL, 0xb3b3ce7dUL, + 0x29297b52UL, 0xe3e33eddUL, 0x2f2f715eUL, 0x84849713UL, + 0x5353f5a6UL, 0xd1d168b9UL, 0x00000000UL, 0xeded2cc1UL, + 0x20206040UL, 0xfcfc1fe3UL, 0xb1b1c879UL, 0x5b5bedb6UL, + 0x6a6abed4UL, 0xcbcb468dUL, 0xbebed967UL, 0x39394b72UL, + 0x4a4ade94UL, 0x4c4cd498UL, 0x5858e8b0UL, 0xcfcf4a85UL, + 0xd0d06bbbUL, 0xefef2ac5UL, 0xaaaae54fUL, 0xfbfb16edUL, + 0x4343c586UL, 0x4d4dd79aUL, 0x33335566UL, 0x85859411UL, + 0x4545cf8aUL, 0xf9f910e9UL, 0x02020604UL, 0x7f7f81feUL, + 0x5050f0a0UL, 0x3c3c4478UL, 0x9f9fba25UL, 0xa8a8e34bUL, + 0x5151f3a2UL, 0xa3a3fe5dUL, 0x4040c080UL, 0x8f8f8a05UL, + 0x9292ad3fUL, 0x9d9dbc21UL, 0x38384870UL, 0xf5f504f1UL, + 0xbcbcdf63UL, 0xb6b6c177UL, 0xdada75afUL, 0x21216342UL, + 0x10103020UL, 0xffff1ae5UL, 0xf3f30efdUL, 0xd2d26dbfUL, + 0xcdcd4c81UL, 0x0c0c1418UL, 0x13133526UL, 0xecec2fc3UL, + 0x5f5fe1beUL, 0x9797a235UL, 0x4444cc88UL, 0x1717392eUL, + 0xc4c45793UL, 0xa7a7f255UL, 0x7e7e82fcUL, 0x3d3d477aUL, + 0x6464acc8UL, 0x5d5de7baUL, 0x19192b32UL, 0x737395e6UL, + 0x6060a0c0UL, 0x81819819UL, 0x4f4fd19eUL, 0xdcdc7fa3UL, + 0x22226644UL, 0x2a2a7e54UL, 0x9090ab3bUL, 0x8888830bUL, + 0x4646ca8cUL, 0xeeee29c7UL, 0xb8b8d36bUL, 0x14143c28UL, + 0xdede79a7UL, 0x5e5ee2bcUL, 0x0b0b1d16UL, 0xdbdb76adUL, + 0xe0e03bdbUL, 0x32325664UL, 0x3a3a4e74UL, 0x0a0a1e14UL, + 0x4949db92UL, 0x06060a0cUL, 0x24246c48UL, 0x5c5ce4b8UL, + 0xc2c25d9fUL, 0xd3d36ebdUL, 0xacacef43UL, 0x6262a6c4UL, + 0x9191a839UL, 0x9595a431UL, 0xe4e437d3UL, 0x79798bf2UL, + 0xe7e732d5UL, 0xc8c8438bUL, 0x3737596eUL, 0x6d6db7daUL, + 0x8d8d8c01UL, 0xd5d564b1UL, 0x4e4ed29cUL, 0xa9a9e049UL, + 0x6c6cb4d8UL, 0x5656faacUL, 0xf4f407f3UL, 0xeaea25cfUL, + 0x6565afcaUL, 0x7a7a8ef4UL, 0xaeaee947UL, 0x08081810UL, + 0xbabad56fUL, 0x787888f0UL, 0x25256f4aUL, 0x2e2e725cUL, + 0x1c1c2438UL, 0xa6a6f157UL, 0xb4b4c773UL, 0xc6c65197UL, + 0xe8e823cbUL, 0xdddd7ca1UL, 0x74749ce8UL, 0x1f1f213eUL, + 0x4b4bdd96UL, 0xbdbddc61UL, 0x8b8b860dUL, 0x8a8a850fUL, + 0x707090e0UL, 0x3e3e427cUL, 0xb5b5c471UL, 0x6666aaccUL, + 0x4848d890UL, 0x03030506UL, 0xf6f601f7UL, 0x0e0e121cUL, + 0x6161a3c2UL, 0x35355f6aUL, 0x5757f9aeUL, 0xb9b9d069UL, + 0x86869117UL, 0xc1c15899UL, 0x1d1d273aUL, 0x9e9eb927UL, + 0xe1e138d9UL, 0xf8f813ebUL, 0x9898b32bUL, 0x11113322UL, + 0x6969bbd2UL, 0xd9d970a9UL, 0x8e8e8907UL, 0x9494a733UL, + 0x9b9bb62dUL, 0x1e1e223cUL, 0x87879215UL, 0xe9e920c9UL, + 0xcece4987UL, 0x5555ffaaUL, 0x28287850UL, 0xdfdf7aa5UL, + 0x8c8c8f03UL, 0xa1a1f859UL, 0x89898009UL, 0x0d0d171aUL, + 0xbfbfda65UL, 0xe6e631d7UL, 0x4242c684UL, 0x6868b8d0UL, + 0x4141c382UL, 0x9999b029UL, 0x2d2d775aUL, 0x0f0f111eUL, + 0xb0b0cb7bUL, 0x5454fca8UL, 0xbbbbd66dUL, 0x16163a2cUL, +}; + +#ifndef PELI_TAB +static const ulong32 Te4_0[] = { +0x00000063UL, 0x0000007cUL, 0x00000077UL, 0x0000007bUL, 0x000000f2UL, 0x0000006bUL, 0x0000006fUL, 0x000000c5UL, +0x00000030UL, 0x00000001UL, 0x00000067UL, 0x0000002bUL, 0x000000feUL, 0x000000d7UL, 0x000000abUL, 0x00000076UL, +0x000000caUL, 0x00000082UL, 0x000000c9UL, 0x0000007dUL, 0x000000faUL, 0x00000059UL, 0x00000047UL, 0x000000f0UL, +0x000000adUL, 0x000000d4UL, 0x000000a2UL, 0x000000afUL, 0x0000009cUL, 0x000000a4UL, 0x00000072UL, 0x000000c0UL, +0x000000b7UL, 0x000000fdUL, 0x00000093UL, 0x00000026UL, 0x00000036UL, 0x0000003fUL, 0x000000f7UL, 0x000000ccUL, +0x00000034UL, 0x000000a5UL, 0x000000e5UL, 0x000000f1UL, 0x00000071UL, 0x000000d8UL, 0x00000031UL, 0x00000015UL, +0x00000004UL, 0x000000c7UL, 0x00000023UL, 0x000000c3UL, 0x00000018UL, 0x00000096UL, 0x00000005UL, 0x0000009aUL, +0x00000007UL, 0x00000012UL, 0x00000080UL, 0x000000e2UL, 0x000000ebUL, 0x00000027UL, 0x000000b2UL, 0x00000075UL, +0x00000009UL, 0x00000083UL, 0x0000002cUL, 0x0000001aUL, 0x0000001bUL, 0x0000006eUL, 0x0000005aUL, 0x000000a0UL, +0x00000052UL, 0x0000003bUL, 0x000000d6UL, 0x000000b3UL, 0x00000029UL, 0x000000e3UL, 0x0000002fUL, 0x00000084UL, +0x00000053UL, 0x000000d1UL, 0x00000000UL, 0x000000edUL, 0x00000020UL, 0x000000fcUL, 0x000000b1UL, 0x0000005bUL, +0x0000006aUL, 0x000000cbUL, 0x000000beUL, 0x00000039UL, 0x0000004aUL, 0x0000004cUL, 0x00000058UL, 0x000000cfUL, +0x000000d0UL, 0x000000efUL, 0x000000aaUL, 0x000000fbUL, 0x00000043UL, 0x0000004dUL, 0x00000033UL, 0x00000085UL, +0x00000045UL, 0x000000f9UL, 0x00000002UL, 0x0000007fUL, 0x00000050UL, 0x0000003cUL, 0x0000009fUL, 0x000000a8UL, +0x00000051UL, 0x000000a3UL, 0x00000040UL, 0x0000008fUL, 0x00000092UL, 0x0000009dUL, 0x00000038UL, 0x000000f5UL, +0x000000bcUL, 0x000000b6UL, 0x000000daUL, 0x00000021UL, 0x00000010UL, 0x000000ffUL, 0x000000f3UL, 0x000000d2UL, +0x000000cdUL, 0x0000000cUL, 0x00000013UL, 0x000000ecUL, 0x0000005fUL, 0x00000097UL, 0x00000044UL, 0x00000017UL, +0x000000c4UL, 0x000000a7UL, 0x0000007eUL, 0x0000003dUL, 0x00000064UL, 0x0000005dUL, 0x00000019UL, 0x00000073UL, +0x00000060UL, 0x00000081UL, 0x0000004fUL, 0x000000dcUL, 0x00000022UL, 0x0000002aUL, 0x00000090UL, 0x00000088UL, +0x00000046UL, 0x000000eeUL, 0x000000b8UL, 0x00000014UL, 0x000000deUL, 0x0000005eUL, 0x0000000bUL, 0x000000dbUL, +0x000000e0UL, 0x00000032UL, 0x0000003aUL, 0x0000000aUL, 0x00000049UL, 0x00000006UL, 0x00000024UL, 0x0000005cUL, +0x000000c2UL, 0x000000d3UL, 0x000000acUL, 0x00000062UL, 0x00000091UL, 0x00000095UL, 0x000000e4UL, 0x00000079UL, +0x000000e7UL, 0x000000c8UL, 0x00000037UL, 0x0000006dUL, 0x0000008dUL, 0x000000d5UL, 0x0000004eUL, 0x000000a9UL, +0x0000006cUL, 0x00000056UL, 0x000000f4UL, 0x000000eaUL, 0x00000065UL, 0x0000007aUL, 0x000000aeUL, 0x00000008UL, +0x000000baUL, 0x00000078UL, 0x00000025UL, 0x0000002eUL, 0x0000001cUL, 0x000000a6UL, 0x000000b4UL, 0x000000c6UL, +0x000000e8UL, 0x000000ddUL, 0x00000074UL, 0x0000001fUL, 0x0000004bUL, 0x000000bdUL, 0x0000008bUL, 0x0000008aUL, +0x00000070UL, 0x0000003eUL, 0x000000b5UL, 0x00000066UL, 0x00000048UL, 0x00000003UL, 0x000000f6UL, 0x0000000eUL, +0x00000061UL, 0x00000035UL, 0x00000057UL, 0x000000b9UL, 0x00000086UL, 0x000000c1UL, 0x0000001dUL, 0x0000009eUL, +0x000000e1UL, 0x000000f8UL, 0x00000098UL, 0x00000011UL, 0x00000069UL, 0x000000d9UL, 0x0000008eUL, 0x00000094UL, +0x0000009bUL, 0x0000001eUL, 0x00000087UL, 0x000000e9UL, 0x000000ceUL, 0x00000055UL, 0x00000028UL, 0x000000dfUL, +0x0000008cUL, 0x000000a1UL, 0x00000089UL, 0x0000000dUL, 0x000000bfUL, 0x000000e6UL, 0x00000042UL, 0x00000068UL, +0x00000041UL, 0x00000099UL, 0x0000002dUL, 0x0000000fUL, 0x000000b0UL, 0x00000054UL, 0x000000bbUL, 0x00000016UL +}; + +static const ulong32 Te4_1[] = { +0x00006300UL, 0x00007c00UL, 0x00007700UL, 0x00007b00UL, 0x0000f200UL, 0x00006b00UL, 0x00006f00UL, 0x0000c500UL, +0x00003000UL, 0x00000100UL, 0x00006700UL, 0x00002b00UL, 0x0000fe00UL, 0x0000d700UL, 0x0000ab00UL, 0x00007600UL, +0x0000ca00UL, 0x00008200UL, 0x0000c900UL, 0x00007d00UL, 0x0000fa00UL, 0x00005900UL, 0x00004700UL, 0x0000f000UL, +0x0000ad00UL, 0x0000d400UL, 0x0000a200UL, 0x0000af00UL, 0x00009c00UL, 0x0000a400UL, 0x00007200UL, 0x0000c000UL, +0x0000b700UL, 0x0000fd00UL, 0x00009300UL, 0x00002600UL, 0x00003600UL, 0x00003f00UL, 0x0000f700UL, 0x0000cc00UL, +0x00003400UL, 0x0000a500UL, 0x0000e500UL, 0x0000f100UL, 0x00007100UL, 0x0000d800UL, 0x00003100UL, 0x00001500UL, +0x00000400UL, 0x0000c700UL, 0x00002300UL, 0x0000c300UL, 0x00001800UL, 0x00009600UL, 0x00000500UL, 0x00009a00UL, +0x00000700UL, 0x00001200UL, 0x00008000UL, 0x0000e200UL, 0x0000eb00UL, 0x00002700UL, 0x0000b200UL, 0x00007500UL, +0x00000900UL, 0x00008300UL, 0x00002c00UL, 0x00001a00UL, 0x00001b00UL, 0x00006e00UL, 0x00005a00UL, 0x0000a000UL, +0x00005200UL, 0x00003b00UL, 0x0000d600UL, 0x0000b300UL, 0x00002900UL, 0x0000e300UL, 0x00002f00UL, 0x00008400UL, +0x00005300UL, 0x0000d100UL, 0x00000000UL, 0x0000ed00UL, 0x00002000UL, 0x0000fc00UL, 0x0000b100UL, 0x00005b00UL, +0x00006a00UL, 0x0000cb00UL, 0x0000be00UL, 0x00003900UL, 0x00004a00UL, 0x00004c00UL, 0x00005800UL, 0x0000cf00UL, +0x0000d000UL, 0x0000ef00UL, 0x0000aa00UL, 0x0000fb00UL, 0x00004300UL, 0x00004d00UL, 0x00003300UL, 0x00008500UL, +0x00004500UL, 0x0000f900UL, 0x00000200UL, 0x00007f00UL, 0x00005000UL, 0x00003c00UL, 0x00009f00UL, 0x0000a800UL, +0x00005100UL, 0x0000a300UL, 0x00004000UL, 0x00008f00UL, 0x00009200UL, 0x00009d00UL, 0x00003800UL, 0x0000f500UL, +0x0000bc00UL, 0x0000b600UL, 0x0000da00UL, 0x00002100UL, 0x00001000UL, 0x0000ff00UL, 0x0000f300UL, 0x0000d200UL, +0x0000cd00UL, 0x00000c00UL, 0x00001300UL, 0x0000ec00UL, 0x00005f00UL, 0x00009700UL, 0x00004400UL, 0x00001700UL, +0x0000c400UL, 0x0000a700UL, 0x00007e00UL, 0x00003d00UL, 0x00006400UL, 0x00005d00UL, 0x00001900UL, 0x00007300UL, +0x00006000UL, 0x00008100UL, 0x00004f00UL, 0x0000dc00UL, 0x00002200UL, 0x00002a00UL, 0x00009000UL, 0x00008800UL, +0x00004600UL, 0x0000ee00UL, 0x0000b800UL, 0x00001400UL, 0x0000de00UL, 0x00005e00UL, 0x00000b00UL, 0x0000db00UL, +0x0000e000UL, 0x00003200UL, 0x00003a00UL, 0x00000a00UL, 0x00004900UL, 0x00000600UL, 0x00002400UL, 0x00005c00UL, +0x0000c200UL, 0x0000d300UL, 0x0000ac00UL, 0x00006200UL, 0x00009100UL, 0x00009500UL, 0x0000e400UL, 0x00007900UL, +0x0000e700UL, 0x0000c800UL, 0x00003700UL, 0x00006d00UL, 0x00008d00UL, 0x0000d500UL, 0x00004e00UL, 0x0000a900UL, +0x00006c00UL, 0x00005600UL, 0x0000f400UL, 0x0000ea00UL, 0x00006500UL, 0x00007a00UL, 0x0000ae00UL, 0x00000800UL, +0x0000ba00UL, 0x00007800UL, 0x00002500UL, 0x00002e00UL, 0x00001c00UL, 0x0000a600UL, 0x0000b400UL, 0x0000c600UL, +0x0000e800UL, 0x0000dd00UL, 0x00007400UL, 0x00001f00UL, 0x00004b00UL, 0x0000bd00UL, 0x00008b00UL, 0x00008a00UL, +0x00007000UL, 0x00003e00UL, 0x0000b500UL, 0x00006600UL, 0x00004800UL, 0x00000300UL, 0x0000f600UL, 0x00000e00UL, +0x00006100UL, 0x00003500UL, 0x00005700UL, 0x0000b900UL, 0x00008600UL, 0x0000c100UL, 0x00001d00UL, 0x00009e00UL, +0x0000e100UL, 0x0000f800UL, 0x00009800UL, 0x00001100UL, 0x00006900UL, 0x0000d900UL, 0x00008e00UL, 0x00009400UL, +0x00009b00UL, 0x00001e00UL, 0x00008700UL, 0x0000e900UL, 0x0000ce00UL, 0x00005500UL, 0x00002800UL, 0x0000df00UL, +0x00008c00UL, 0x0000a100UL, 0x00008900UL, 0x00000d00UL, 0x0000bf00UL, 0x0000e600UL, 0x00004200UL, 0x00006800UL, +0x00004100UL, 0x00009900UL, 0x00002d00UL, 0x00000f00UL, 0x0000b000UL, 0x00005400UL, 0x0000bb00UL, 0x00001600UL +}; + +static const ulong32 Te4_2[] = { +0x00630000UL, 0x007c0000UL, 0x00770000UL, 0x007b0000UL, 0x00f20000UL, 0x006b0000UL, 0x006f0000UL, 0x00c50000UL, +0x00300000UL, 0x00010000UL, 0x00670000UL, 0x002b0000UL, 0x00fe0000UL, 0x00d70000UL, 0x00ab0000UL, 0x00760000UL, +0x00ca0000UL, 0x00820000UL, 0x00c90000UL, 0x007d0000UL, 0x00fa0000UL, 0x00590000UL, 0x00470000UL, 0x00f00000UL, +0x00ad0000UL, 0x00d40000UL, 0x00a20000UL, 0x00af0000UL, 0x009c0000UL, 0x00a40000UL, 0x00720000UL, 0x00c00000UL, +0x00b70000UL, 0x00fd0000UL, 0x00930000UL, 0x00260000UL, 0x00360000UL, 0x003f0000UL, 0x00f70000UL, 0x00cc0000UL, +0x00340000UL, 0x00a50000UL, 0x00e50000UL, 0x00f10000UL, 0x00710000UL, 0x00d80000UL, 0x00310000UL, 0x00150000UL, +0x00040000UL, 0x00c70000UL, 0x00230000UL, 0x00c30000UL, 0x00180000UL, 0x00960000UL, 0x00050000UL, 0x009a0000UL, +0x00070000UL, 0x00120000UL, 0x00800000UL, 0x00e20000UL, 0x00eb0000UL, 0x00270000UL, 0x00b20000UL, 0x00750000UL, +0x00090000UL, 0x00830000UL, 0x002c0000UL, 0x001a0000UL, 0x001b0000UL, 0x006e0000UL, 0x005a0000UL, 0x00a00000UL, +0x00520000UL, 0x003b0000UL, 0x00d60000UL, 0x00b30000UL, 0x00290000UL, 0x00e30000UL, 0x002f0000UL, 0x00840000UL, +0x00530000UL, 0x00d10000UL, 0x00000000UL, 0x00ed0000UL, 0x00200000UL, 0x00fc0000UL, 0x00b10000UL, 0x005b0000UL, +0x006a0000UL, 0x00cb0000UL, 0x00be0000UL, 0x00390000UL, 0x004a0000UL, 0x004c0000UL, 0x00580000UL, 0x00cf0000UL, +0x00d00000UL, 0x00ef0000UL, 0x00aa0000UL, 0x00fb0000UL, 0x00430000UL, 0x004d0000UL, 0x00330000UL, 0x00850000UL, +0x00450000UL, 0x00f90000UL, 0x00020000UL, 0x007f0000UL, 0x00500000UL, 0x003c0000UL, 0x009f0000UL, 0x00a80000UL, +0x00510000UL, 0x00a30000UL, 0x00400000UL, 0x008f0000UL, 0x00920000UL, 0x009d0000UL, 0x00380000UL, 0x00f50000UL, +0x00bc0000UL, 0x00b60000UL, 0x00da0000UL, 0x00210000UL, 0x00100000UL, 0x00ff0000UL, 0x00f30000UL, 0x00d20000UL, +0x00cd0000UL, 0x000c0000UL, 0x00130000UL, 0x00ec0000UL, 0x005f0000UL, 0x00970000UL, 0x00440000UL, 0x00170000UL, +0x00c40000UL, 0x00a70000UL, 0x007e0000UL, 0x003d0000UL, 0x00640000UL, 0x005d0000UL, 0x00190000UL, 0x00730000UL, +0x00600000UL, 0x00810000UL, 0x004f0000UL, 0x00dc0000UL, 0x00220000UL, 0x002a0000UL, 0x00900000UL, 0x00880000UL, +0x00460000UL, 0x00ee0000UL, 0x00b80000UL, 0x00140000UL, 0x00de0000UL, 0x005e0000UL, 0x000b0000UL, 0x00db0000UL, +0x00e00000UL, 0x00320000UL, 0x003a0000UL, 0x000a0000UL, 0x00490000UL, 0x00060000UL, 0x00240000UL, 0x005c0000UL, +0x00c20000UL, 0x00d30000UL, 0x00ac0000UL, 0x00620000UL, 0x00910000UL, 0x00950000UL, 0x00e40000UL, 0x00790000UL, +0x00e70000UL, 0x00c80000UL, 0x00370000UL, 0x006d0000UL, 0x008d0000UL, 0x00d50000UL, 0x004e0000UL, 0x00a90000UL, +0x006c0000UL, 0x00560000UL, 0x00f40000UL, 0x00ea0000UL, 0x00650000UL, 0x007a0000UL, 0x00ae0000UL, 0x00080000UL, +0x00ba0000UL, 0x00780000UL, 0x00250000UL, 0x002e0000UL, 0x001c0000UL, 0x00a60000UL, 0x00b40000UL, 0x00c60000UL, +0x00e80000UL, 0x00dd0000UL, 0x00740000UL, 0x001f0000UL, 0x004b0000UL, 0x00bd0000UL, 0x008b0000UL, 0x008a0000UL, +0x00700000UL, 0x003e0000UL, 0x00b50000UL, 0x00660000UL, 0x00480000UL, 0x00030000UL, 0x00f60000UL, 0x000e0000UL, +0x00610000UL, 0x00350000UL, 0x00570000UL, 0x00b90000UL, 0x00860000UL, 0x00c10000UL, 0x001d0000UL, 0x009e0000UL, +0x00e10000UL, 0x00f80000UL, 0x00980000UL, 0x00110000UL, 0x00690000UL, 0x00d90000UL, 0x008e0000UL, 0x00940000UL, +0x009b0000UL, 0x001e0000UL, 0x00870000UL, 0x00e90000UL, 0x00ce0000UL, 0x00550000UL, 0x00280000UL, 0x00df0000UL, +0x008c0000UL, 0x00a10000UL, 0x00890000UL, 0x000d0000UL, 0x00bf0000UL, 0x00e60000UL, 0x00420000UL, 0x00680000UL, +0x00410000UL, 0x00990000UL, 0x002d0000UL, 0x000f0000UL, 0x00b00000UL, 0x00540000UL, 0x00bb0000UL, 0x00160000UL +}; + +static const ulong32 Te4_3[] = { +0x63000000UL, 0x7c000000UL, 0x77000000UL, 0x7b000000UL, 0xf2000000UL, 0x6b000000UL, 0x6f000000UL, 0xc5000000UL, +0x30000000UL, 0x01000000UL, 0x67000000UL, 0x2b000000UL, 0xfe000000UL, 0xd7000000UL, 0xab000000UL, 0x76000000UL, +0xca000000UL, 0x82000000UL, 0xc9000000UL, 0x7d000000UL, 0xfa000000UL, 0x59000000UL, 0x47000000UL, 0xf0000000UL, +0xad000000UL, 0xd4000000UL, 0xa2000000UL, 0xaf000000UL, 0x9c000000UL, 0xa4000000UL, 0x72000000UL, 0xc0000000UL, +0xb7000000UL, 0xfd000000UL, 0x93000000UL, 0x26000000UL, 0x36000000UL, 0x3f000000UL, 0xf7000000UL, 0xcc000000UL, +0x34000000UL, 0xa5000000UL, 0xe5000000UL, 0xf1000000UL, 0x71000000UL, 0xd8000000UL, 0x31000000UL, 0x15000000UL, +0x04000000UL, 0xc7000000UL, 0x23000000UL, 0xc3000000UL, 0x18000000UL, 0x96000000UL, 0x05000000UL, 0x9a000000UL, +0x07000000UL, 0x12000000UL, 0x80000000UL, 0xe2000000UL, 0xeb000000UL, 0x27000000UL, 0xb2000000UL, 0x75000000UL, +0x09000000UL, 0x83000000UL, 0x2c000000UL, 0x1a000000UL, 0x1b000000UL, 0x6e000000UL, 0x5a000000UL, 0xa0000000UL, +0x52000000UL, 0x3b000000UL, 0xd6000000UL, 0xb3000000UL, 0x29000000UL, 0xe3000000UL, 0x2f000000UL, 0x84000000UL, +0x53000000UL, 0xd1000000UL, 0x00000000UL, 0xed000000UL, 0x20000000UL, 0xfc000000UL, 0xb1000000UL, 0x5b000000UL, +0x6a000000UL, 0xcb000000UL, 0xbe000000UL, 0x39000000UL, 0x4a000000UL, 0x4c000000UL, 0x58000000UL, 0xcf000000UL, +0xd0000000UL, 0xef000000UL, 0xaa000000UL, 0xfb000000UL, 0x43000000UL, 0x4d000000UL, 0x33000000UL, 0x85000000UL, +0x45000000UL, 0xf9000000UL, 0x02000000UL, 0x7f000000UL, 0x50000000UL, 0x3c000000UL, 0x9f000000UL, 0xa8000000UL, +0x51000000UL, 0xa3000000UL, 0x40000000UL, 0x8f000000UL, 0x92000000UL, 0x9d000000UL, 0x38000000UL, 0xf5000000UL, +0xbc000000UL, 0xb6000000UL, 0xda000000UL, 0x21000000UL, 0x10000000UL, 0xff000000UL, 0xf3000000UL, 0xd2000000UL, +0xcd000000UL, 0x0c000000UL, 0x13000000UL, 0xec000000UL, 0x5f000000UL, 0x97000000UL, 0x44000000UL, 0x17000000UL, +0xc4000000UL, 0xa7000000UL, 0x7e000000UL, 0x3d000000UL, 0x64000000UL, 0x5d000000UL, 0x19000000UL, 0x73000000UL, +0x60000000UL, 0x81000000UL, 0x4f000000UL, 0xdc000000UL, 0x22000000UL, 0x2a000000UL, 0x90000000UL, 0x88000000UL, +0x46000000UL, 0xee000000UL, 0xb8000000UL, 0x14000000UL, 0xde000000UL, 0x5e000000UL, 0x0b000000UL, 0xdb000000UL, +0xe0000000UL, 0x32000000UL, 0x3a000000UL, 0x0a000000UL, 0x49000000UL, 0x06000000UL, 0x24000000UL, 0x5c000000UL, +0xc2000000UL, 0xd3000000UL, 0xac000000UL, 0x62000000UL, 0x91000000UL, 0x95000000UL, 0xe4000000UL, 0x79000000UL, +0xe7000000UL, 0xc8000000UL, 0x37000000UL, 0x6d000000UL, 0x8d000000UL, 0xd5000000UL, 0x4e000000UL, 0xa9000000UL, +0x6c000000UL, 0x56000000UL, 0xf4000000UL, 0xea000000UL, 0x65000000UL, 0x7a000000UL, 0xae000000UL, 0x08000000UL, +0xba000000UL, 0x78000000UL, 0x25000000UL, 0x2e000000UL, 0x1c000000UL, 0xa6000000UL, 0xb4000000UL, 0xc6000000UL, +0xe8000000UL, 0xdd000000UL, 0x74000000UL, 0x1f000000UL, 0x4b000000UL, 0xbd000000UL, 0x8b000000UL, 0x8a000000UL, +0x70000000UL, 0x3e000000UL, 0xb5000000UL, 0x66000000UL, 0x48000000UL, 0x03000000UL, 0xf6000000UL, 0x0e000000UL, +0x61000000UL, 0x35000000UL, 0x57000000UL, 0xb9000000UL, 0x86000000UL, 0xc1000000UL, 0x1d000000UL, 0x9e000000UL, +0xe1000000UL, 0xf8000000UL, 0x98000000UL, 0x11000000UL, 0x69000000UL, 0xd9000000UL, 0x8e000000UL, 0x94000000UL, +0x9b000000UL, 0x1e000000UL, 0x87000000UL, 0xe9000000UL, 0xce000000UL, 0x55000000UL, 0x28000000UL, 0xdf000000UL, +0x8c000000UL, 0xa1000000UL, 0x89000000UL, 0x0d000000UL, 0xbf000000UL, 0xe6000000UL, 0x42000000UL, 0x68000000UL, +0x41000000UL, 0x99000000UL, 0x2d000000UL, 0x0f000000UL, 0xb0000000UL, 0x54000000UL, 0xbb000000UL, 0x16000000UL +}; +#endif /* pelimac */ + +#ifndef ENCRYPT_ONLY + +static const ulong32 TD1[256] = { + 0x5051f4a7UL, 0x537e4165UL, 0xc31a17a4UL, 0x963a275eUL, + 0xcb3bab6bUL, 0xf11f9d45UL, 0xabacfa58UL, 0x934be303UL, + 0x552030faUL, 0xf6ad766dUL, 0x9188cc76UL, 0x25f5024cUL, + 0xfc4fe5d7UL, 0xd7c52acbUL, 0x80263544UL, 0x8fb562a3UL, + 0x49deb15aUL, 0x6725ba1bUL, 0x9845ea0eUL, 0xe15dfec0UL, + 0x02c32f75UL, 0x12814cf0UL, 0xa38d4697UL, 0xc66bd3f9UL, + 0xe7038f5fUL, 0x9515929cUL, 0xebbf6d7aUL, 0xda955259UL, + 0x2dd4be83UL, 0xd3587421UL, 0x2949e069UL, 0x448ec9c8UL, + 0x6a75c289UL, 0x78f48e79UL, 0x6b99583eUL, 0xdd27b971UL, + 0xb6bee14fUL, 0x17f088adUL, 0x66c920acUL, 0xb47dce3aUL, + 0x1863df4aUL, 0x82e51a31UL, 0x60975133UL, 0x4562537fUL, + 0xe0b16477UL, 0x84bb6baeUL, 0x1cfe81a0UL, 0x94f9082bUL, + 0x58704868UL, 0x198f45fdUL, 0x8794de6cUL, 0xb7527bf8UL, + 0x23ab73d3UL, 0xe2724b02UL, 0x57e31f8fUL, 0x2a6655abUL, + 0x07b2eb28UL, 0x032fb5c2UL, 0x9a86c57bUL, 0xa5d33708UL, + 0xf2302887UL, 0xb223bfa5UL, 0xba02036aUL, 0x5ced1682UL, + 0x2b8acf1cUL, 0x92a779b4UL, 0xf0f307f2UL, 0xa14e69e2UL, + 0xcd65daf4UL, 0xd50605beUL, 0x1fd13462UL, 0x8ac4a6feUL, + 0x9d342e53UL, 0xa0a2f355UL, 0x32058ae1UL, 0x75a4f6ebUL, + 0x390b83ecUL, 0xaa4060efUL, 0x065e719fUL, 0x51bd6e10UL, + 0xf93e218aUL, 0x3d96dd06UL, 0xaedd3e05UL, 0x464de6bdUL, + 0xb591548dUL, 0x0571c45dUL, 0x6f0406d4UL, 0xff605015UL, + 0x241998fbUL, 0x97d6bde9UL, 0xcc894043UL, 0x7767d99eUL, + 0xbdb0e842UL, 0x8807898bUL, 0x38e7195bUL, 0xdb79c8eeUL, + 0x47a17c0aUL, 0xe97c420fUL, 0xc9f8841eUL, 0x00000000UL, + 0x83098086UL, 0x48322bedUL, 0xac1e1170UL, 0x4e6c5a72UL, + 0xfbfd0effUL, 0x560f8538UL, 0x1e3daed5UL, 0x27362d39UL, + 0x640a0fd9UL, 0x21685ca6UL, 0xd19b5b54UL, 0x3a24362eUL, + 0xb10c0a67UL, 0x0f9357e7UL, 0xd2b4ee96UL, 0x9e1b9b91UL, + 0x4f80c0c5UL, 0xa261dc20UL, 0x695a774bUL, 0x161c121aUL, + 0x0ae293baUL, 0xe5c0a02aUL, 0x433c22e0UL, 0x1d121b17UL, + 0x0b0e090dUL, 0xadf28bc7UL, 0xb92db6a8UL, 0xc8141ea9UL, + 0x8557f119UL, 0x4caf7507UL, 0xbbee99ddUL, 0xfda37f60UL, + 0x9ff70126UL, 0xbc5c72f5UL, 0xc544663bUL, 0x345bfb7eUL, + 0x768b4329UL, 0xdccb23c6UL, 0x68b6edfcUL, 0x63b8e4f1UL, + 0xcad731dcUL, 0x10426385UL, 0x40139722UL, 0x2084c611UL, + 0x7d854a24UL, 0xf8d2bb3dUL, 0x11aef932UL, 0x6dc729a1UL, + 0x4b1d9e2fUL, 0xf3dcb230UL, 0xec0d8652UL, 0xd077c1e3UL, + 0x6c2bb316UL, 0x99a970b9UL, 0xfa119448UL, 0x2247e964UL, + 0xc4a8fc8cUL, 0x1aa0f03fUL, 0xd8567d2cUL, 0xef223390UL, + 0xc787494eUL, 0xc1d938d1UL, 0xfe8ccaa2UL, 0x3698d40bUL, + 0xcfa6f581UL, 0x28a57adeUL, 0x26dab78eUL, 0xa43fadbfUL, + 0xe42c3a9dUL, 0x0d507892UL, 0x9b6a5fccUL, 0x62547e46UL, + 0xc2f68d13UL, 0xe890d8b8UL, 0x5e2e39f7UL, 0xf582c3afUL, + 0xbe9f5d80UL, 0x7c69d093UL, 0xa96fd52dUL, 0xb3cf2512UL, + 0x3bc8ac99UL, 0xa710187dUL, 0x6ee89c63UL, 0x7bdb3bbbUL, + 0x09cd2678UL, 0xf46e5918UL, 0x01ec9ab7UL, 0xa8834f9aUL, + 0x65e6956eUL, 0x7eaaffe6UL, 0x0821bccfUL, 0xe6ef15e8UL, + 0xd9bae79bUL, 0xce4a6f36UL, 0xd4ea9f09UL, 0xd629b07cUL, + 0xaf31a4b2UL, 0x312a3f23UL, 0x30c6a594UL, 0xc035a266UL, + 0x37744ebcUL, 0xa6fc82caUL, 0xb0e090d0UL, 0x1533a7d8UL, + 0x4af10498UL, 0xf741ecdaUL, 0x0e7fcd50UL, 0x2f1791f6UL, + 0x8d764dd6UL, 0x4d43efb0UL, 0x54ccaa4dUL, 0xdfe49604UL, + 0xe39ed1b5UL, 0x1b4c6a88UL, 0xb8c12c1fUL, 0x7f466551UL, + 0x049d5eeaUL, 0x5d018c35UL, 0x73fa8774UL, 0x2efb0b41UL, + 0x5ab3671dUL, 0x5292dbd2UL, 0x33e91056UL, 0x136dd647UL, + 0x8c9ad761UL, 0x7a37a10cUL, 0x8e59f814UL, 0x89eb133cUL, + 0xeecea927UL, 0x35b761c9UL, 0xede11ce5UL, 0x3c7a47b1UL, + 0x599cd2dfUL, 0x3f55f273UL, 0x791814ceUL, 0xbf73c737UL, + 0xea53f7cdUL, 0x5b5ffdaaUL, 0x14df3d6fUL, 0x867844dbUL, + 0x81caaff3UL, 0x3eb968c4UL, 0x2c382434UL, 0x5fc2a340UL, + 0x72161dc3UL, 0x0cbce225UL, 0x8b283c49UL, 0x41ff0d95UL, + 0x7139a801UL, 0xde080cb3UL, 0x9cd8b4e4UL, 0x906456c1UL, + 0x617bcb84UL, 0x70d532b6UL, 0x74486c5cUL, 0x42d0b857UL, +}; +static const ulong32 TD2[256] = { + 0xa75051f4UL, 0x65537e41UL, 0xa4c31a17UL, 0x5e963a27UL, + 0x6bcb3babUL, 0x45f11f9dUL, 0x58abacfaUL, 0x03934be3UL, + 0xfa552030UL, 0x6df6ad76UL, 0x769188ccUL, 0x4c25f502UL, + 0xd7fc4fe5UL, 0xcbd7c52aUL, 0x44802635UL, 0xa38fb562UL, + 0x5a49deb1UL, 0x1b6725baUL, 0x0e9845eaUL, 0xc0e15dfeUL, + 0x7502c32fUL, 0xf012814cUL, 0x97a38d46UL, 0xf9c66bd3UL, + 0x5fe7038fUL, 0x9c951592UL, 0x7aebbf6dUL, 0x59da9552UL, + 0x832dd4beUL, 0x21d35874UL, 0x692949e0UL, 0xc8448ec9UL, + 0x896a75c2UL, 0x7978f48eUL, 0x3e6b9958UL, 0x71dd27b9UL, + 0x4fb6bee1UL, 0xad17f088UL, 0xac66c920UL, 0x3ab47dceUL, + 0x4a1863dfUL, 0x3182e51aUL, 0x33609751UL, 0x7f456253UL, + 0x77e0b164UL, 0xae84bb6bUL, 0xa01cfe81UL, 0x2b94f908UL, + 0x68587048UL, 0xfd198f45UL, 0x6c8794deUL, 0xf8b7527bUL, + 0xd323ab73UL, 0x02e2724bUL, 0x8f57e31fUL, 0xab2a6655UL, + 0x2807b2ebUL, 0xc2032fb5UL, 0x7b9a86c5UL, 0x08a5d337UL, + 0x87f23028UL, 0xa5b223bfUL, 0x6aba0203UL, 0x825ced16UL, + 0x1c2b8acfUL, 0xb492a779UL, 0xf2f0f307UL, 0xe2a14e69UL, + 0xf4cd65daUL, 0xbed50605UL, 0x621fd134UL, 0xfe8ac4a6UL, + 0x539d342eUL, 0x55a0a2f3UL, 0xe132058aUL, 0xeb75a4f6UL, + 0xec390b83UL, 0xefaa4060UL, 0x9f065e71UL, 0x1051bd6eUL, + 0x8af93e21UL, 0x063d96ddUL, 0x05aedd3eUL, 0xbd464de6UL, + 0x8db59154UL, 0x5d0571c4UL, 0xd46f0406UL, 0x15ff6050UL, + 0xfb241998UL, 0xe997d6bdUL, 0x43cc8940UL, 0x9e7767d9UL, + 0x42bdb0e8UL, 0x8b880789UL, 0x5b38e719UL, 0xeedb79c8UL, + 0x0a47a17cUL, 0x0fe97c42UL, 0x1ec9f884UL, 0x00000000UL, + 0x86830980UL, 0xed48322bUL, 0x70ac1e11UL, 0x724e6c5aUL, + 0xfffbfd0eUL, 0x38560f85UL, 0xd51e3daeUL, 0x3927362dUL, + 0xd9640a0fUL, 0xa621685cUL, 0x54d19b5bUL, 0x2e3a2436UL, + 0x67b10c0aUL, 0xe70f9357UL, 0x96d2b4eeUL, 0x919e1b9bUL, + 0xc54f80c0UL, 0x20a261dcUL, 0x4b695a77UL, 0x1a161c12UL, + 0xba0ae293UL, 0x2ae5c0a0UL, 0xe0433c22UL, 0x171d121bUL, + 0x0d0b0e09UL, 0xc7adf28bUL, 0xa8b92db6UL, 0xa9c8141eUL, + 0x198557f1UL, 0x074caf75UL, 0xddbbee99UL, 0x60fda37fUL, + 0x269ff701UL, 0xf5bc5c72UL, 0x3bc54466UL, 0x7e345bfbUL, + 0x29768b43UL, 0xc6dccb23UL, 0xfc68b6edUL, 0xf163b8e4UL, + 0xdccad731UL, 0x85104263UL, 0x22401397UL, 0x112084c6UL, + 0x247d854aUL, 0x3df8d2bbUL, 0x3211aef9UL, 0xa16dc729UL, + 0x2f4b1d9eUL, 0x30f3dcb2UL, 0x52ec0d86UL, 0xe3d077c1UL, + 0x166c2bb3UL, 0xb999a970UL, 0x48fa1194UL, 0x642247e9UL, + 0x8cc4a8fcUL, 0x3f1aa0f0UL, 0x2cd8567dUL, 0x90ef2233UL, + 0x4ec78749UL, 0xd1c1d938UL, 0xa2fe8ccaUL, 0x0b3698d4UL, + 0x81cfa6f5UL, 0xde28a57aUL, 0x8e26dab7UL, 0xbfa43fadUL, + 0x9de42c3aUL, 0x920d5078UL, 0xcc9b6a5fUL, 0x4662547eUL, + 0x13c2f68dUL, 0xb8e890d8UL, 0xf75e2e39UL, 0xaff582c3UL, + 0x80be9f5dUL, 0x937c69d0UL, 0x2da96fd5UL, 0x12b3cf25UL, + 0x993bc8acUL, 0x7da71018UL, 0x636ee89cUL, 0xbb7bdb3bUL, + 0x7809cd26UL, 0x18f46e59UL, 0xb701ec9aUL, 0x9aa8834fUL, + 0x6e65e695UL, 0xe67eaaffUL, 0xcf0821bcUL, 0xe8e6ef15UL, + 0x9bd9bae7UL, 0x36ce4a6fUL, 0x09d4ea9fUL, 0x7cd629b0UL, + 0xb2af31a4UL, 0x23312a3fUL, 0x9430c6a5UL, 0x66c035a2UL, + 0xbc37744eUL, 0xcaa6fc82UL, 0xd0b0e090UL, 0xd81533a7UL, + 0x984af104UL, 0xdaf741ecUL, 0x500e7fcdUL, 0xf62f1791UL, + 0xd68d764dUL, 0xb04d43efUL, 0x4d54ccaaUL, 0x04dfe496UL, + 0xb5e39ed1UL, 0x881b4c6aUL, 0x1fb8c12cUL, 0x517f4665UL, + 0xea049d5eUL, 0x355d018cUL, 0x7473fa87UL, 0x412efb0bUL, + 0x1d5ab367UL, 0xd25292dbUL, 0x5633e910UL, 0x47136dd6UL, + 0x618c9ad7UL, 0x0c7a37a1UL, 0x148e59f8UL, 0x3c89eb13UL, + 0x27eecea9UL, 0xc935b761UL, 0xe5ede11cUL, 0xb13c7a47UL, + 0xdf599cd2UL, 0x733f55f2UL, 0xce791814UL, 0x37bf73c7UL, + 0xcdea53f7UL, 0xaa5b5ffdUL, 0x6f14df3dUL, 0xdb867844UL, + 0xf381caafUL, 0xc43eb968UL, 0x342c3824UL, 0x405fc2a3UL, + 0xc372161dUL, 0x250cbce2UL, 0x498b283cUL, 0x9541ff0dUL, + 0x017139a8UL, 0xb3de080cUL, 0xe49cd8b4UL, 0xc1906456UL, + 0x84617bcbUL, 0xb670d532UL, 0x5c74486cUL, 0x5742d0b8UL, +}; +static const ulong32 TD3[256] = { + 0xf4a75051UL, 0x4165537eUL, 0x17a4c31aUL, 0x275e963aUL, + 0xab6bcb3bUL, 0x9d45f11fUL, 0xfa58abacUL, 0xe303934bUL, + 0x30fa5520UL, 0x766df6adUL, 0xcc769188UL, 0x024c25f5UL, + 0xe5d7fc4fUL, 0x2acbd7c5UL, 0x35448026UL, 0x62a38fb5UL, + 0xb15a49deUL, 0xba1b6725UL, 0xea0e9845UL, 0xfec0e15dUL, + 0x2f7502c3UL, 0x4cf01281UL, 0x4697a38dUL, 0xd3f9c66bUL, + 0x8f5fe703UL, 0x929c9515UL, 0x6d7aebbfUL, 0x5259da95UL, + 0xbe832dd4UL, 0x7421d358UL, 0xe0692949UL, 0xc9c8448eUL, + 0xc2896a75UL, 0x8e7978f4UL, 0x583e6b99UL, 0xb971dd27UL, + 0xe14fb6beUL, 0x88ad17f0UL, 0x20ac66c9UL, 0xce3ab47dUL, + 0xdf4a1863UL, 0x1a3182e5UL, 0x51336097UL, 0x537f4562UL, + 0x6477e0b1UL, 0x6bae84bbUL, 0x81a01cfeUL, 0x082b94f9UL, + 0x48685870UL, 0x45fd198fUL, 0xde6c8794UL, 0x7bf8b752UL, + 0x73d323abUL, 0x4b02e272UL, 0x1f8f57e3UL, 0x55ab2a66UL, + 0xeb2807b2UL, 0xb5c2032fUL, 0xc57b9a86UL, 0x3708a5d3UL, + 0x2887f230UL, 0xbfa5b223UL, 0x036aba02UL, 0x16825cedUL, + 0xcf1c2b8aUL, 0x79b492a7UL, 0x07f2f0f3UL, 0x69e2a14eUL, + 0xdaf4cd65UL, 0x05bed506UL, 0x34621fd1UL, 0xa6fe8ac4UL, + 0x2e539d34UL, 0xf355a0a2UL, 0x8ae13205UL, 0xf6eb75a4UL, + 0x83ec390bUL, 0x60efaa40UL, 0x719f065eUL, 0x6e1051bdUL, + 0x218af93eUL, 0xdd063d96UL, 0x3e05aeddUL, 0xe6bd464dUL, + 0x548db591UL, 0xc45d0571UL, 0x06d46f04UL, 0x5015ff60UL, + 0x98fb2419UL, 0xbde997d6UL, 0x4043cc89UL, 0xd99e7767UL, + 0xe842bdb0UL, 0x898b8807UL, 0x195b38e7UL, 0xc8eedb79UL, + 0x7c0a47a1UL, 0x420fe97cUL, 0x841ec9f8UL, 0x00000000UL, + 0x80868309UL, 0x2bed4832UL, 0x1170ac1eUL, 0x5a724e6cUL, + 0x0efffbfdUL, 0x8538560fUL, 0xaed51e3dUL, 0x2d392736UL, + 0x0fd9640aUL, 0x5ca62168UL, 0x5b54d19bUL, 0x362e3a24UL, + 0x0a67b10cUL, 0x57e70f93UL, 0xee96d2b4UL, 0x9b919e1bUL, + 0xc0c54f80UL, 0xdc20a261UL, 0x774b695aUL, 0x121a161cUL, + 0x93ba0ae2UL, 0xa02ae5c0UL, 0x22e0433cUL, 0x1b171d12UL, + 0x090d0b0eUL, 0x8bc7adf2UL, 0xb6a8b92dUL, 0x1ea9c814UL, + 0xf1198557UL, 0x75074cafUL, 0x99ddbbeeUL, 0x7f60fda3UL, + 0x01269ff7UL, 0x72f5bc5cUL, 0x663bc544UL, 0xfb7e345bUL, + 0x4329768bUL, 0x23c6dccbUL, 0xedfc68b6UL, 0xe4f163b8UL, + 0x31dccad7UL, 0x63851042UL, 0x97224013UL, 0xc6112084UL, + 0x4a247d85UL, 0xbb3df8d2UL, 0xf93211aeUL, 0x29a16dc7UL, + 0x9e2f4b1dUL, 0xb230f3dcUL, 0x8652ec0dUL, 0xc1e3d077UL, + 0xb3166c2bUL, 0x70b999a9UL, 0x9448fa11UL, 0xe9642247UL, + 0xfc8cc4a8UL, 0xf03f1aa0UL, 0x7d2cd856UL, 0x3390ef22UL, + 0x494ec787UL, 0x38d1c1d9UL, 0xcaa2fe8cUL, 0xd40b3698UL, + 0xf581cfa6UL, 0x7ade28a5UL, 0xb78e26daUL, 0xadbfa43fUL, + 0x3a9de42cUL, 0x78920d50UL, 0x5fcc9b6aUL, 0x7e466254UL, + 0x8d13c2f6UL, 0xd8b8e890UL, 0x39f75e2eUL, 0xc3aff582UL, + 0x5d80be9fUL, 0xd0937c69UL, 0xd52da96fUL, 0x2512b3cfUL, + 0xac993bc8UL, 0x187da710UL, 0x9c636ee8UL, 0x3bbb7bdbUL, + 0x267809cdUL, 0x5918f46eUL, 0x9ab701ecUL, 0x4f9aa883UL, + 0x956e65e6UL, 0xffe67eaaUL, 0xbccf0821UL, 0x15e8e6efUL, + 0xe79bd9baUL, 0x6f36ce4aUL, 0x9f09d4eaUL, 0xb07cd629UL, + 0xa4b2af31UL, 0x3f23312aUL, 0xa59430c6UL, 0xa266c035UL, + 0x4ebc3774UL, 0x82caa6fcUL, 0x90d0b0e0UL, 0xa7d81533UL, + 0x04984af1UL, 0xecdaf741UL, 0xcd500e7fUL, 0x91f62f17UL, + 0x4dd68d76UL, 0xefb04d43UL, 0xaa4d54ccUL, 0x9604dfe4UL, + 0xd1b5e39eUL, 0x6a881b4cUL, 0x2c1fb8c1UL, 0x65517f46UL, + 0x5eea049dUL, 0x8c355d01UL, 0x877473faUL, 0x0b412efbUL, + 0x671d5ab3UL, 0xdbd25292UL, 0x105633e9UL, 0xd647136dUL, + 0xd7618c9aUL, 0xa10c7a37UL, 0xf8148e59UL, 0x133c89ebUL, + 0xa927eeceUL, 0x61c935b7UL, 0x1ce5ede1UL, 0x47b13c7aUL, + 0xd2df599cUL, 0xf2733f55UL, 0x14ce7918UL, 0xc737bf73UL, + 0xf7cdea53UL, 0xfdaa5b5fUL, 0x3d6f14dfUL, 0x44db8678UL, + 0xaff381caUL, 0x68c43eb9UL, 0x24342c38UL, 0xa3405fc2UL, + 0x1dc37216UL, 0xe2250cbcUL, 0x3c498b28UL, 0x0d9541ffUL, + 0xa8017139UL, 0x0cb3de08UL, 0xb4e49cd8UL, 0x56c19064UL, + 0xcb84617bUL, 0x32b670d5UL, 0x6c5c7448UL, 0xb85742d0UL, +}; + +static const ulong32 Tks0[] = { +0x00000000UL, 0x0e090d0bUL, 0x1c121a16UL, 0x121b171dUL, 0x3824342cUL, 0x362d3927UL, 0x24362e3aUL, 0x2a3f2331UL, +0x70486858UL, 0x7e416553UL, 0x6c5a724eUL, 0x62537f45UL, 0x486c5c74UL, 0x4665517fUL, 0x547e4662UL, 0x5a774b69UL, +0xe090d0b0UL, 0xee99ddbbUL, 0xfc82caa6UL, 0xf28bc7adUL, 0xd8b4e49cUL, 0xd6bde997UL, 0xc4a6fe8aUL, 0xcaaff381UL, +0x90d8b8e8UL, 0x9ed1b5e3UL, 0x8ccaa2feUL, 0x82c3aff5UL, 0xa8fc8cc4UL, 0xa6f581cfUL, 0xb4ee96d2UL, 0xbae79bd9UL, +0xdb3bbb7bUL, 0xd532b670UL, 0xc729a16dUL, 0xc920ac66UL, 0xe31f8f57UL, 0xed16825cUL, 0xff0d9541UL, 0xf104984aUL, +0xab73d323UL, 0xa57ade28UL, 0xb761c935UL, 0xb968c43eUL, 0x9357e70fUL, 0x9d5eea04UL, 0x8f45fd19UL, 0x814cf012UL, +0x3bab6bcbUL, 0x35a266c0UL, 0x27b971ddUL, 0x29b07cd6UL, 0x038f5fe7UL, 0x0d8652ecUL, 0x1f9d45f1UL, 0x119448faUL, +0x4be30393UL, 0x45ea0e98UL, 0x57f11985UL, 0x59f8148eUL, 0x73c737bfUL, 0x7dce3ab4UL, 0x6fd52da9UL, 0x61dc20a2UL, +0xad766df6UL, 0xa37f60fdUL, 0xb16477e0UL, 0xbf6d7aebUL, 0x955259daUL, 0x9b5b54d1UL, 0x894043ccUL, 0x87494ec7UL, +0xdd3e05aeUL, 0xd33708a5UL, 0xc12c1fb8UL, 0xcf2512b3UL, 0xe51a3182UL, 0xeb133c89UL, 0xf9082b94UL, 0xf701269fUL, +0x4de6bd46UL, 0x43efb04dUL, 0x51f4a750UL, 0x5ffdaa5bUL, 0x75c2896aUL, 0x7bcb8461UL, 0x69d0937cUL, 0x67d99e77UL, +0x3daed51eUL, 0x33a7d815UL, 0x21bccf08UL, 0x2fb5c203UL, 0x058ae132UL, 0x0b83ec39UL, 0x1998fb24UL, 0x1791f62fUL, +0x764dd68dUL, 0x7844db86UL, 0x6a5fcc9bUL, 0x6456c190UL, 0x4e69e2a1UL, 0x4060efaaUL, 0x527bf8b7UL, 0x5c72f5bcUL, +0x0605bed5UL, 0x080cb3deUL, 0x1a17a4c3UL, 0x141ea9c8UL, 0x3e218af9UL, 0x302887f2UL, 0x223390efUL, 0x2c3a9de4UL, +0x96dd063dUL, 0x98d40b36UL, 0x8acf1c2bUL, 0x84c61120UL, 0xaef93211UL, 0xa0f03f1aUL, 0xb2eb2807UL, 0xbce2250cUL, +0xe6956e65UL, 0xe89c636eUL, 0xfa877473UL, 0xf48e7978UL, 0xdeb15a49UL, 0xd0b85742UL, 0xc2a3405fUL, 0xccaa4d54UL, +0x41ecdaf7UL, 0x4fe5d7fcUL, 0x5dfec0e1UL, 0x53f7cdeaUL, 0x79c8eedbUL, 0x77c1e3d0UL, 0x65daf4cdUL, 0x6bd3f9c6UL, +0x31a4b2afUL, 0x3fadbfa4UL, 0x2db6a8b9UL, 0x23bfa5b2UL, 0x09808683UL, 0x07898b88UL, 0x15929c95UL, 0x1b9b919eUL, +0xa17c0a47UL, 0xaf75074cUL, 0xbd6e1051UL, 0xb3671d5aUL, 0x99583e6bUL, 0x97513360UL, 0x854a247dUL, 0x8b432976UL, +0xd134621fUL, 0xdf3d6f14UL, 0xcd267809UL, 0xc32f7502UL, 0xe9105633UL, 0xe7195b38UL, 0xf5024c25UL, 0xfb0b412eUL, +0x9ad7618cUL, 0x94de6c87UL, 0x86c57b9aUL, 0x88cc7691UL, 0xa2f355a0UL, 0xacfa58abUL, 0xbee14fb6UL, 0xb0e842bdUL, +0xea9f09d4UL, 0xe49604dfUL, 0xf68d13c2UL, 0xf8841ec9UL, 0xd2bb3df8UL, 0xdcb230f3UL, 0xcea927eeUL, 0xc0a02ae5UL, +0x7a47b13cUL, 0x744ebc37UL, 0x6655ab2aUL, 0x685ca621UL, 0x42638510UL, 0x4c6a881bUL, 0x5e719f06UL, 0x5078920dUL, +0x0a0fd964UL, 0x0406d46fUL, 0x161dc372UL, 0x1814ce79UL, 0x322bed48UL, 0x3c22e043UL, 0x2e39f75eUL, 0x2030fa55UL, +0xec9ab701UL, 0xe293ba0aUL, 0xf088ad17UL, 0xfe81a01cUL, 0xd4be832dUL, 0xdab78e26UL, 0xc8ac993bUL, 0xc6a59430UL, +0x9cd2df59UL, 0x92dbd252UL, 0x80c0c54fUL, 0x8ec9c844UL, 0xa4f6eb75UL, 0xaaffe67eUL, 0xb8e4f163UL, 0xb6edfc68UL, +0x0c0a67b1UL, 0x02036abaUL, 0x10187da7UL, 0x1e1170acUL, 0x342e539dUL, 0x3a275e96UL, 0x283c498bUL, 0x26354480UL, +0x7c420fe9UL, 0x724b02e2UL, 0x605015ffUL, 0x6e5918f4UL, 0x44663bc5UL, 0x4a6f36ceUL, 0x587421d3UL, 0x567d2cd8UL, +0x37a10c7aUL, 0x39a80171UL, 0x2bb3166cUL, 0x25ba1b67UL, 0x0f853856UL, 0x018c355dUL, 0x13972240UL, 0x1d9e2f4bUL, +0x47e96422UL, 0x49e06929UL, 0x5bfb7e34UL, 0x55f2733fUL, 0x7fcd500eUL, 0x71c45d05UL, 0x63df4a18UL, 0x6dd64713UL, +0xd731dccaUL, 0xd938d1c1UL, 0xcb23c6dcUL, 0xc52acbd7UL, 0xef15e8e6UL, 0xe11ce5edUL, 0xf307f2f0UL, 0xfd0efffbUL, +0xa779b492UL, 0xa970b999UL, 0xbb6bae84UL, 0xb562a38fUL, 0x9f5d80beUL, 0x91548db5UL, 0x834f9aa8UL, 0x8d4697a3UL +}; + +static const ulong32 Tks1[] = { +0x00000000UL, 0x0b0e090dUL, 0x161c121aUL, 0x1d121b17UL, 0x2c382434UL, 0x27362d39UL, 0x3a24362eUL, 0x312a3f23UL, +0x58704868UL, 0x537e4165UL, 0x4e6c5a72UL, 0x4562537fUL, 0x74486c5cUL, 0x7f466551UL, 0x62547e46UL, 0x695a774bUL, +0xb0e090d0UL, 0xbbee99ddUL, 0xa6fc82caUL, 0xadf28bc7UL, 0x9cd8b4e4UL, 0x97d6bde9UL, 0x8ac4a6feUL, 0x81caaff3UL, +0xe890d8b8UL, 0xe39ed1b5UL, 0xfe8ccaa2UL, 0xf582c3afUL, 0xc4a8fc8cUL, 0xcfa6f581UL, 0xd2b4ee96UL, 0xd9bae79bUL, +0x7bdb3bbbUL, 0x70d532b6UL, 0x6dc729a1UL, 0x66c920acUL, 0x57e31f8fUL, 0x5ced1682UL, 0x41ff0d95UL, 0x4af10498UL, +0x23ab73d3UL, 0x28a57adeUL, 0x35b761c9UL, 0x3eb968c4UL, 0x0f9357e7UL, 0x049d5eeaUL, 0x198f45fdUL, 0x12814cf0UL, +0xcb3bab6bUL, 0xc035a266UL, 0xdd27b971UL, 0xd629b07cUL, 0xe7038f5fUL, 0xec0d8652UL, 0xf11f9d45UL, 0xfa119448UL, +0x934be303UL, 0x9845ea0eUL, 0x8557f119UL, 0x8e59f814UL, 0xbf73c737UL, 0xb47dce3aUL, 0xa96fd52dUL, 0xa261dc20UL, +0xf6ad766dUL, 0xfda37f60UL, 0xe0b16477UL, 0xebbf6d7aUL, 0xda955259UL, 0xd19b5b54UL, 0xcc894043UL, 0xc787494eUL, +0xaedd3e05UL, 0xa5d33708UL, 0xb8c12c1fUL, 0xb3cf2512UL, 0x82e51a31UL, 0x89eb133cUL, 0x94f9082bUL, 0x9ff70126UL, +0x464de6bdUL, 0x4d43efb0UL, 0x5051f4a7UL, 0x5b5ffdaaUL, 0x6a75c289UL, 0x617bcb84UL, 0x7c69d093UL, 0x7767d99eUL, +0x1e3daed5UL, 0x1533a7d8UL, 0x0821bccfUL, 0x032fb5c2UL, 0x32058ae1UL, 0x390b83ecUL, 0x241998fbUL, 0x2f1791f6UL, +0x8d764dd6UL, 0x867844dbUL, 0x9b6a5fccUL, 0x906456c1UL, 0xa14e69e2UL, 0xaa4060efUL, 0xb7527bf8UL, 0xbc5c72f5UL, +0xd50605beUL, 0xde080cb3UL, 0xc31a17a4UL, 0xc8141ea9UL, 0xf93e218aUL, 0xf2302887UL, 0xef223390UL, 0xe42c3a9dUL, +0x3d96dd06UL, 0x3698d40bUL, 0x2b8acf1cUL, 0x2084c611UL, 0x11aef932UL, 0x1aa0f03fUL, 0x07b2eb28UL, 0x0cbce225UL, +0x65e6956eUL, 0x6ee89c63UL, 0x73fa8774UL, 0x78f48e79UL, 0x49deb15aUL, 0x42d0b857UL, 0x5fc2a340UL, 0x54ccaa4dUL, +0xf741ecdaUL, 0xfc4fe5d7UL, 0xe15dfec0UL, 0xea53f7cdUL, 0xdb79c8eeUL, 0xd077c1e3UL, 0xcd65daf4UL, 0xc66bd3f9UL, +0xaf31a4b2UL, 0xa43fadbfUL, 0xb92db6a8UL, 0xb223bfa5UL, 0x83098086UL, 0x8807898bUL, 0x9515929cUL, 0x9e1b9b91UL, +0x47a17c0aUL, 0x4caf7507UL, 0x51bd6e10UL, 0x5ab3671dUL, 0x6b99583eUL, 0x60975133UL, 0x7d854a24UL, 0x768b4329UL, +0x1fd13462UL, 0x14df3d6fUL, 0x09cd2678UL, 0x02c32f75UL, 0x33e91056UL, 0x38e7195bUL, 0x25f5024cUL, 0x2efb0b41UL, +0x8c9ad761UL, 0x8794de6cUL, 0x9a86c57bUL, 0x9188cc76UL, 0xa0a2f355UL, 0xabacfa58UL, 0xb6bee14fUL, 0xbdb0e842UL, +0xd4ea9f09UL, 0xdfe49604UL, 0xc2f68d13UL, 0xc9f8841eUL, 0xf8d2bb3dUL, 0xf3dcb230UL, 0xeecea927UL, 0xe5c0a02aUL, +0x3c7a47b1UL, 0x37744ebcUL, 0x2a6655abUL, 0x21685ca6UL, 0x10426385UL, 0x1b4c6a88UL, 0x065e719fUL, 0x0d507892UL, +0x640a0fd9UL, 0x6f0406d4UL, 0x72161dc3UL, 0x791814ceUL, 0x48322bedUL, 0x433c22e0UL, 0x5e2e39f7UL, 0x552030faUL, +0x01ec9ab7UL, 0x0ae293baUL, 0x17f088adUL, 0x1cfe81a0UL, 0x2dd4be83UL, 0x26dab78eUL, 0x3bc8ac99UL, 0x30c6a594UL, +0x599cd2dfUL, 0x5292dbd2UL, 0x4f80c0c5UL, 0x448ec9c8UL, 0x75a4f6ebUL, 0x7eaaffe6UL, 0x63b8e4f1UL, 0x68b6edfcUL, +0xb10c0a67UL, 0xba02036aUL, 0xa710187dUL, 0xac1e1170UL, 0x9d342e53UL, 0x963a275eUL, 0x8b283c49UL, 0x80263544UL, +0xe97c420fUL, 0xe2724b02UL, 0xff605015UL, 0xf46e5918UL, 0xc544663bUL, 0xce4a6f36UL, 0xd3587421UL, 0xd8567d2cUL, +0x7a37a10cUL, 0x7139a801UL, 0x6c2bb316UL, 0x6725ba1bUL, 0x560f8538UL, 0x5d018c35UL, 0x40139722UL, 0x4b1d9e2fUL, +0x2247e964UL, 0x2949e069UL, 0x345bfb7eUL, 0x3f55f273UL, 0x0e7fcd50UL, 0x0571c45dUL, 0x1863df4aUL, 0x136dd647UL, +0xcad731dcUL, 0xc1d938d1UL, 0xdccb23c6UL, 0xd7c52acbUL, 0xe6ef15e8UL, 0xede11ce5UL, 0xf0f307f2UL, 0xfbfd0effUL, +0x92a779b4UL, 0x99a970b9UL, 0x84bb6baeUL, 0x8fb562a3UL, 0xbe9f5d80UL, 0xb591548dUL, 0xa8834f9aUL, 0xa38d4697UL +}; + +static const ulong32 Tks2[] = { +0x00000000UL, 0x0d0b0e09UL, 0x1a161c12UL, 0x171d121bUL, 0x342c3824UL, 0x3927362dUL, 0x2e3a2436UL, 0x23312a3fUL, +0x68587048UL, 0x65537e41UL, 0x724e6c5aUL, 0x7f456253UL, 0x5c74486cUL, 0x517f4665UL, 0x4662547eUL, 0x4b695a77UL, +0xd0b0e090UL, 0xddbbee99UL, 0xcaa6fc82UL, 0xc7adf28bUL, 0xe49cd8b4UL, 0xe997d6bdUL, 0xfe8ac4a6UL, 0xf381caafUL, +0xb8e890d8UL, 0xb5e39ed1UL, 0xa2fe8ccaUL, 0xaff582c3UL, 0x8cc4a8fcUL, 0x81cfa6f5UL, 0x96d2b4eeUL, 0x9bd9bae7UL, +0xbb7bdb3bUL, 0xb670d532UL, 0xa16dc729UL, 0xac66c920UL, 0x8f57e31fUL, 0x825ced16UL, 0x9541ff0dUL, 0x984af104UL, +0xd323ab73UL, 0xde28a57aUL, 0xc935b761UL, 0xc43eb968UL, 0xe70f9357UL, 0xea049d5eUL, 0xfd198f45UL, 0xf012814cUL, +0x6bcb3babUL, 0x66c035a2UL, 0x71dd27b9UL, 0x7cd629b0UL, 0x5fe7038fUL, 0x52ec0d86UL, 0x45f11f9dUL, 0x48fa1194UL, +0x03934be3UL, 0x0e9845eaUL, 0x198557f1UL, 0x148e59f8UL, 0x37bf73c7UL, 0x3ab47dceUL, 0x2da96fd5UL, 0x20a261dcUL, +0x6df6ad76UL, 0x60fda37fUL, 0x77e0b164UL, 0x7aebbf6dUL, 0x59da9552UL, 0x54d19b5bUL, 0x43cc8940UL, 0x4ec78749UL, +0x05aedd3eUL, 0x08a5d337UL, 0x1fb8c12cUL, 0x12b3cf25UL, 0x3182e51aUL, 0x3c89eb13UL, 0x2b94f908UL, 0x269ff701UL, +0xbd464de6UL, 0xb04d43efUL, 0xa75051f4UL, 0xaa5b5ffdUL, 0x896a75c2UL, 0x84617bcbUL, 0x937c69d0UL, 0x9e7767d9UL, +0xd51e3daeUL, 0xd81533a7UL, 0xcf0821bcUL, 0xc2032fb5UL, 0xe132058aUL, 0xec390b83UL, 0xfb241998UL, 0xf62f1791UL, +0xd68d764dUL, 0xdb867844UL, 0xcc9b6a5fUL, 0xc1906456UL, 0xe2a14e69UL, 0xefaa4060UL, 0xf8b7527bUL, 0xf5bc5c72UL, +0xbed50605UL, 0xb3de080cUL, 0xa4c31a17UL, 0xa9c8141eUL, 0x8af93e21UL, 0x87f23028UL, 0x90ef2233UL, 0x9de42c3aUL, +0x063d96ddUL, 0x0b3698d4UL, 0x1c2b8acfUL, 0x112084c6UL, 0x3211aef9UL, 0x3f1aa0f0UL, 0x2807b2ebUL, 0x250cbce2UL, +0x6e65e695UL, 0x636ee89cUL, 0x7473fa87UL, 0x7978f48eUL, 0x5a49deb1UL, 0x5742d0b8UL, 0x405fc2a3UL, 0x4d54ccaaUL, +0xdaf741ecUL, 0xd7fc4fe5UL, 0xc0e15dfeUL, 0xcdea53f7UL, 0xeedb79c8UL, 0xe3d077c1UL, 0xf4cd65daUL, 0xf9c66bd3UL, +0xb2af31a4UL, 0xbfa43fadUL, 0xa8b92db6UL, 0xa5b223bfUL, 0x86830980UL, 0x8b880789UL, 0x9c951592UL, 0x919e1b9bUL, +0x0a47a17cUL, 0x074caf75UL, 0x1051bd6eUL, 0x1d5ab367UL, 0x3e6b9958UL, 0x33609751UL, 0x247d854aUL, 0x29768b43UL, +0x621fd134UL, 0x6f14df3dUL, 0x7809cd26UL, 0x7502c32fUL, 0x5633e910UL, 0x5b38e719UL, 0x4c25f502UL, 0x412efb0bUL, +0x618c9ad7UL, 0x6c8794deUL, 0x7b9a86c5UL, 0x769188ccUL, 0x55a0a2f3UL, 0x58abacfaUL, 0x4fb6bee1UL, 0x42bdb0e8UL, +0x09d4ea9fUL, 0x04dfe496UL, 0x13c2f68dUL, 0x1ec9f884UL, 0x3df8d2bbUL, 0x30f3dcb2UL, 0x27eecea9UL, 0x2ae5c0a0UL, +0xb13c7a47UL, 0xbc37744eUL, 0xab2a6655UL, 0xa621685cUL, 0x85104263UL, 0x881b4c6aUL, 0x9f065e71UL, 0x920d5078UL, +0xd9640a0fUL, 0xd46f0406UL, 0xc372161dUL, 0xce791814UL, 0xed48322bUL, 0xe0433c22UL, 0xf75e2e39UL, 0xfa552030UL, +0xb701ec9aUL, 0xba0ae293UL, 0xad17f088UL, 0xa01cfe81UL, 0x832dd4beUL, 0x8e26dab7UL, 0x993bc8acUL, 0x9430c6a5UL, +0xdf599cd2UL, 0xd25292dbUL, 0xc54f80c0UL, 0xc8448ec9UL, 0xeb75a4f6UL, 0xe67eaaffUL, 0xf163b8e4UL, 0xfc68b6edUL, +0x67b10c0aUL, 0x6aba0203UL, 0x7da71018UL, 0x70ac1e11UL, 0x539d342eUL, 0x5e963a27UL, 0x498b283cUL, 0x44802635UL, +0x0fe97c42UL, 0x02e2724bUL, 0x15ff6050UL, 0x18f46e59UL, 0x3bc54466UL, 0x36ce4a6fUL, 0x21d35874UL, 0x2cd8567dUL, +0x0c7a37a1UL, 0x017139a8UL, 0x166c2bb3UL, 0x1b6725baUL, 0x38560f85UL, 0x355d018cUL, 0x22401397UL, 0x2f4b1d9eUL, +0x642247e9UL, 0x692949e0UL, 0x7e345bfbUL, 0x733f55f2UL, 0x500e7fcdUL, 0x5d0571c4UL, 0x4a1863dfUL, 0x47136dd6UL, +0xdccad731UL, 0xd1c1d938UL, 0xc6dccb23UL, 0xcbd7c52aUL, 0xe8e6ef15UL, 0xe5ede11cUL, 0xf2f0f307UL, 0xfffbfd0eUL, +0xb492a779UL, 0xb999a970UL, 0xae84bb6bUL, 0xa38fb562UL, 0x80be9f5dUL, 0x8db59154UL, 0x9aa8834fUL, 0x97a38d46UL +}; + +static const ulong32 Tks3[] = { +0x00000000UL, 0x090d0b0eUL, 0x121a161cUL, 0x1b171d12UL, 0x24342c38UL, 0x2d392736UL, 0x362e3a24UL, 0x3f23312aUL, +0x48685870UL, 0x4165537eUL, 0x5a724e6cUL, 0x537f4562UL, 0x6c5c7448UL, 0x65517f46UL, 0x7e466254UL, 0x774b695aUL, +0x90d0b0e0UL, 0x99ddbbeeUL, 0x82caa6fcUL, 0x8bc7adf2UL, 0xb4e49cd8UL, 0xbde997d6UL, 0xa6fe8ac4UL, 0xaff381caUL, +0xd8b8e890UL, 0xd1b5e39eUL, 0xcaa2fe8cUL, 0xc3aff582UL, 0xfc8cc4a8UL, 0xf581cfa6UL, 0xee96d2b4UL, 0xe79bd9baUL, +0x3bbb7bdbUL, 0x32b670d5UL, 0x29a16dc7UL, 0x20ac66c9UL, 0x1f8f57e3UL, 0x16825cedUL, 0x0d9541ffUL, 0x04984af1UL, +0x73d323abUL, 0x7ade28a5UL, 0x61c935b7UL, 0x68c43eb9UL, 0x57e70f93UL, 0x5eea049dUL, 0x45fd198fUL, 0x4cf01281UL, +0xab6bcb3bUL, 0xa266c035UL, 0xb971dd27UL, 0xb07cd629UL, 0x8f5fe703UL, 0x8652ec0dUL, 0x9d45f11fUL, 0x9448fa11UL, +0xe303934bUL, 0xea0e9845UL, 0xf1198557UL, 0xf8148e59UL, 0xc737bf73UL, 0xce3ab47dUL, 0xd52da96fUL, 0xdc20a261UL, +0x766df6adUL, 0x7f60fda3UL, 0x6477e0b1UL, 0x6d7aebbfUL, 0x5259da95UL, 0x5b54d19bUL, 0x4043cc89UL, 0x494ec787UL, +0x3e05aeddUL, 0x3708a5d3UL, 0x2c1fb8c1UL, 0x2512b3cfUL, 0x1a3182e5UL, 0x133c89ebUL, 0x082b94f9UL, 0x01269ff7UL, +0xe6bd464dUL, 0xefb04d43UL, 0xf4a75051UL, 0xfdaa5b5fUL, 0xc2896a75UL, 0xcb84617bUL, 0xd0937c69UL, 0xd99e7767UL, +0xaed51e3dUL, 0xa7d81533UL, 0xbccf0821UL, 0xb5c2032fUL, 0x8ae13205UL, 0x83ec390bUL, 0x98fb2419UL, 0x91f62f17UL, +0x4dd68d76UL, 0x44db8678UL, 0x5fcc9b6aUL, 0x56c19064UL, 0x69e2a14eUL, 0x60efaa40UL, 0x7bf8b752UL, 0x72f5bc5cUL, +0x05bed506UL, 0x0cb3de08UL, 0x17a4c31aUL, 0x1ea9c814UL, 0x218af93eUL, 0x2887f230UL, 0x3390ef22UL, 0x3a9de42cUL, +0xdd063d96UL, 0xd40b3698UL, 0xcf1c2b8aUL, 0xc6112084UL, 0xf93211aeUL, 0xf03f1aa0UL, 0xeb2807b2UL, 0xe2250cbcUL, +0x956e65e6UL, 0x9c636ee8UL, 0x877473faUL, 0x8e7978f4UL, 0xb15a49deUL, 0xb85742d0UL, 0xa3405fc2UL, 0xaa4d54ccUL, +0xecdaf741UL, 0xe5d7fc4fUL, 0xfec0e15dUL, 0xf7cdea53UL, 0xc8eedb79UL, 0xc1e3d077UL, 0xdaf4cd65UL, 0xd3f9c66bUL, +0xa4b2af31UL, 0xadbfa43fUL, 0xb6a8b92dUL, 0xbfa5b223UL, 0x80868309UL, 0x898b8807UL, 0x929c9515UL, 0x9b919e1bUL, +0x7c0a47a1UL, 0x75074cafUL, 0x6e1051bdUL, 0x671d5ab3UL, 0x583e6b99UL, 0x51336097UL, 0x4a247d85UL, 0x4329768bUL, +0x34621fd1UL, 0x3d6f14dfUL, 0x267809cdUL, 0x2f7502c3UL, 0x105633e9UL, 0x195b38e7UL, 0x024c25f5UL, 0x0b412efbUL, +0xd7618c9aUL, 0xde6c8794UL, 0xc57b9a86UL, 0xcc769188UL, 0xf355a0a2UL, 0xfa58abacUL, 0xe14fb6beUL, 0xe842bdb0UL, +0x9f09d4eaUL, 0x9604dfe4UL, 0x8d13c2f6UL, 0x841ec9f8UL, 0xbb3df8d2UL, 0xb230f3dcUL, 0xa927eeceUL, 0xa02ae5c0UL, +0x47b13c7aUL, 0x4ebc3774UL, 0x55ab2a66UL, 0x5ca62168UL, 0x63851042UL, 0x6a881b4cUL, 0x719f065eUL, 0x78920d50UL, +0x0fd9640aUL, 0x06d46f04UL, 0x1dc37216UL, 0x14ce7918UL, 0x2bed4832UL, 0x22e0433cUL, 0x39f75e2eUL, 0x30fa5520UL, +0x9ab701ecUL, 0x93ba0ae2UL, 0x88ad17f0UL, 0x81a01cfeUL, 0xbe832dd4UL, 0xb78e26daUL, 0xac993bc8UL, 0xa59430c6UL, +0xd2df599cUL, 0xdbd25292UL, 0xc0c54f80UL, 0xc9c8448eUL, 0xf6eb75a4UL, 0xffe67eaaUL, 0xe4f163b8UL, 0xedfc68b6UL, +0x0a67b10cUL, 0x036aba02UL, 0x187da710UL, 0x1170ac1eUL, 0x2e539d34UL, 0x275e963aUL, 0x3c498b28UL, 0x35448026UL, +0x420fe97cUL, 0x4b02e272UL, 0x5015ff60UL, 0x5918f46eUL, 0x663bc544UL, 0x6f36ce4aUL, 0x7421d358UL, 0x7d2cd856UL, +0xa10c7a37UL, 0xa8017139UL, 0xb3166c2bUL, 0xba1b6725UL, 0x8538560fUL, 0x8c355d01UL, 0x97224013UL, 0x9e2f4b1dUL, +0xe9642247UL, 0xe0692949UL, 0xfb7e345bUL, 0xf2733f55UL, 0xcd500e7fUL, 0xc45d0571UL, 0xdf4a1863UL, 0xd647136dUL, +0x31dccad7UL, 0x38d1c1d9UL, 0x23c6dccbUL, 0x2acbd7c5UL, 0x15e8e6efUL, 0x1ce5ede1UL, 0x07f2f0f3UL, 0x0efffbfdUL, +0x79b492a7UL, 0x70b999a9UL, 0x6bae84bbUL, 0x62a38fb5UL, 0x5d80be9fUL, 0x548db591UL, 0x4f9aa883UL, 0x4697a38dUL +}; + +#endif /* ENCRYPT_ONLY */ + +#endif /* SMALL CODE */ + +static const ulong32 rcon[] = { + 0x01000000UL, 0x02000000UL, 0x04000000UL, 0x08000000UL, + 0x10000000UL, 0x20000000UL, 0x40000000UL, 0x80000000UL, + 0x1B000000UL, 0x36000000UL, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ +}; + +#endif /* __LTC_AES_TAB_C__ */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/ciphers/anubis.c b/src/ltc/ciphers/anubis.c new file mode 100644 index 0000000..f819421 --- /dev/null +++ b/src/ltc/ciphers/anubis.c @@ -0,0 +1,1559 @@ +/* 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://libtom.org + */ + +/** + @file anubis.c + Anubis implementation derived from public domain source + Authors: Paulo S.L.M. Barreto and Vincent Rijmen. +*/ + +#include "tomcrypt.h" + +#ifdef LTC_ANUBIS + +const struct ltc_cipher_descriptor anubis_desc = { + "anubis", + 19, + 16, 40, 16, 12, + &anubis_setup, + &anubis_ecb_encrypt, + &anubis_ecb_decrypt, + &anubis_test, + &anubis_done, + &anubis_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +#define MIN_N 4 +#define MAX_N 10 +#define MIN_ROUNDS (8 + MIN_N) +#define MAX_ROUNDS (8 + MAX_N) +#define MIN_KEYSIZEB (4*MIN_N) +#define MAX_KEYSIZEB (4*MAX_N) +#define BLOCKSIZE 128 +#define BLOCKSIZEB (BLOCKSIZE/8) + + +/* + * Though Anubis is endianness-neutral, the encryption tables are listed + * in BIG-ENDIAN format, which is adopted throughout this implementation + * (but little-endian notation would be equally suitable if consistently + * employed). + */ +#if defined(LTC_ANUBIS_TWEAK) + +static const ulong32 T0[256] = { + 0xba69d2bbU, 0x54a84de5U, 0x2f5ebce2U, 0x74e8cd25U, + 0x53a651f7U, 0xd3bb6bd0U, 0xd2b96fd6U, 0x4d9a29b3U, + 0x50a05dfdU, 0xac458acfU, 0x8d070e09U, 0xbf63c6a5U, + 0x70e0dd3dU, 0x52a455f1U, 0x9a29527bU, 0x4c982db5U, + 0xeac98f46U, 0xd5b773c4U, 0x97336655U, 0xd1bf63dcU, + 0x3366ccaaU, 0x51a259fbU, 0x5bb671c7U, 0xa651a2f3U, + 0xdea15ffeU, 0x48903dadU, 0xa84d9ad7U, 0x992f5e71U, + 0xdbab4be0U, 0x3264c8acU, 0xb773e695U, 0xfce5d732U, + 0xe3dbab70U, 0x9e214263U, 0x913f7e41U, 0x9b2b567dU, + 0xe2d9af76U, 0xbb6bd6bdU, 0x4182199bU, 0x6edca579U, + 0xa557aef9U, 0xcb8b0b80U, 0x6bd6b167U, 0x95376e59U, + 0xa15fbee1U, 0xf3fbeb10U, 0xb17ffe81U, 0x0204080cU, + 0xcc851792U, 0xc49537a2U, 0x1d3a744eU, 0x14285078U, + 0xc39b2bb0U, 0x63c69157U, 0xdaa94fe6U, 0x5dba69d3U, + 0x5fbe61dfU, 0xdca557f2U, 0x7dfae913U, 0xcd871394U, + 0x7ffee11fU, 0x5ab475c1U, 0x6cd8ad75U, 0x5cb86dd5U, + 0xf7f3fb08U, 0x264c98d4U, 0xffe3db38U, 0xedc79354U, + 0xe8cd874aU, 0x9d274e69U, 0x6fdea17fU, 0x8e010203U, + 0x19326456U, 0xa05dbae7U, 0xf0fde71aU, 0x890f1e11U, + 0x0f1e3c22U, 0x070e1c12U, 0xaf4386c5U, 0xfbebcb20U, + 0x08102030U, 0x152a547eU, 0x0d1a342eU, 0x04081018U, + 0x01020406U, 0x64c88d45U, 0xdfa35bf8U, 0x76ecc529U, + 0x79f2f90bU, 0xdda753f4U, 0x3d7af48eU, 0x162c5874U, + 0x3f7efc82U, 0x376edcb2U, 0x6ddaa973U, 0x3870e090U, + 0xb96fdeb1U, 0x73e6d137U, 0xe9cf834cU, 0x356ad4beU, + 0x55aa49e3U, 0x71e2d93bU, 0x7bf6f107U, 0x8c050a0fU, + 0x72e4d531U, 0x880d1a17U, 0xf6f1ff0eU, 0x2a54a8fcU, + 0x3e7cf884U, 0x5ebc65d9U, 0x274e9cd2U, 0x468c0589U, + 0x0c183028U, 0x65ca8943U, 0x68d0bd6dU, 0x61c2995bU, + 0x03060c0aU, 0xc19f23bcU, 0x57ae41efU, 0xd6b17fceU, + 0xd9af43ecU, 0x58b07dcdU, 0xd8ad47eaU, 0x66cc8549U, + 0xd7b37bc8U, 0x3a74e89cU, 0xc88d078aU, 0x3c78f088U, + 0xfae9cf26U, 0x96316253U, 0xa753a6f5U, 0x982d5a77U, + 0xecc59752U, 0xb86ddab7U, 0xc7933ba8U, 0xae4182c3U, + 0x69d2b96bU, 0x4b9631a7U, 0xab4b96ddU, 0xa94f9ed1U, + 0x67ce814fU, 0x0a14283cU, 0x478e018fU, 0xf2f9ef16U, + 0xb577ee99U, 0x224488ccU, 0xe5d7b364U, 0xeec19f5eU, + 0xbe61c2a3U, 0x2b56acfaU, 0x811f3e21U, 0x1224486cU, + 0x831b362dU, 0x1b366c5aU, 0x0e1c3824U, 0x23468ccaU, + 0xf5f7f304U, 0x458a0983U, 0x214284c6U, 0xce811f9eU, + 0x499239abU, 0x2c58b0e8U, 0xf9efc32cU, 0xe6d1bf6eU, + 0xb671e293U, 0x2850a0f0U, 0x172e5c72U, 0x8219322bU, + 0x1a34685cU, 0x8b0b161dU, 0xfee1df3eU, 0x8a09121bU, + 0x09122436U, 0xc98f038cU, 0x87132635U, 0x4e9c25b9U, + 0xe1dfa37cU, 0x2e5cb8e4U, 0xe4d5b762U, 0xe0dda77aU, + 0xebcb8b40U, 0x903d7a47U, 0xa455aaffU, 0x1e3c7844U, + 0x85172e39U, 0x60c09d5dU, 0x00000000U, 0x254a94deU, + 0xf4f5f702U, 0xf1ffe31cU, 0x94356a5fU, 0x0b162c3aU, + 0xe7d3bb68U, 0x75eac923U, 0xefc39b58U, 0x3468d0b8U, + 0x3162c4a6U, 0xd4b577c2U, 0xd0bd67daU, 0x86112233U, + 0x7efce519U, 0xad478ec9U, 0xfde7d334U, 0x2952a4f6U, + 0x3060c0a0U, 0x3b76ec9aU, 0x9f234665U, 0xf8edc72aU, + 0xc6913faeU, 0x13264c6aU, 0x060c1814U, 0x050a141eU, + 0xc59733a4U, 0x11224466U, 0x77eec12fU, 0x7cf8ed15U, + 0x7af4f501U, 0x78f0fd0dU, 0x366cd8b4U, 0x1c387048U, + 0x3972e496U, 0x59b279cbU, 0x18306050U, 0x56ac45e9U, + 0xb37bf68dU, 0xb07dfa87U, 0x244890d8U, 0x204080c0U, + 0xb279f28bU, 0x9239724bU, 0xa35bb6edU, 0xc09d27baU, + 0x44880d85U, 0x62c49551U, 0x10204060U, 0xb475ea9fU, + 0x84152a3fU, 0x43861197U, 0x933b764dU, 0xc2992fb6U, + 0x4a9435a1U, 0xbd67cea9U, 0x8f030605U, 0x2d5ab4eeU, + 0xbc65caafU, 0x9c254a6fU, 0x6ad4b561U, 0x40801d9dU, + 0xcf831b98U, 0xa259b2ebU, 0x801d3a27U, 0x4f9e21bfU, + 0x1f3e7c42U, 0xca890f86U, 0xaa4992dbU, 0x42841591U, +}; + +static const ulong32 T1[256] = { + 0x69babbd2U, 0xa854e54dU, 0x5e2fe2bcU, 0xe87425cdU, + 0xa653f751U, 0xbbd3d06bU, 0xb9d2d66fU, 0x9a4db329U, + 0xa050fd5dU, 0x45accf8aU, 0x078d090eU, 0x63bfa5c6U, + 0xe0703dddU, 0xa452f155U, 0x299a7b52U, 0x984cb52dU, + 0xc9ea468fU, 0xb7d5c473U, 0x33975566U, 0xbfd1dc63U, + 0x6633aaccU, 0xa251fb59U, 0xb65bc771U, 0x51a6f3a2U, + 0xa1defe5fU, 0x9048ad3dU, 0x4da8d79aU, 0x2f99715eU, + 0xabdbe04bU, 0x6432acc8U, 0x73b795e6U, 0xe5fc32d7U, + 0xdbe370abU, 0x219e6342U, 0x3f91417eU, 0x2b9b7d56U, + 0xd9e276afU, 0x6bbbbdd6U, 0x82419b19U, 0xdc6e79a5U, + 0x57a5f9aeU, 0x8bcb800bU, 0xd66b67b1U, 0x3795596eU, + 0x5fa1e1beU, 0xfbf310ebU, 0x7fb181feU, 0x04020c08U, + 0x85cc9217U, 0x95c4a237U, 0x3a1d4e74U, 0x28147850U, + 0x9bc3b02bU, 0xc6635791U, 0xa9dae64fU, 0xba5dd369U, + 0xbe5fdf61U, 0xa5dcf257U, 0xfa7d13e9U, 0x87cd9413U, + 0xfe7f1fe1U, 0xb45ac175U, 0xd86c75adU, 0xb85cd56dU, + 0xf3f708fbU, 0x4c26d498U, 0xe3ff38dbU, 0xc7ed5493U, + 0xcde84a87U, 0x279d694eU, 0xde6f7fa1U, 0x018e0302U, + 0x32195664U, 0x5da0e7baU, 0xfdf01ae7U, 0x0f89111eU, + 0x1e0f223cU, 0x0e07121cU, 0x43afc586U, 0xebfb20cbU, + 0x10083020U, 0x2a157e54U, 0x1a0d2e34U, 0x08041810U, + 0x02010604U, 0xc864458dU, 0xa3dff85bU, 0xec7629c5U, + 0xf2790bf9U, 0xa7ddf453U, 0x7a3d8ef4U, 0x2c167458U, + 0x7e3f82fcU, 0x6e37b2dcU, 0xda6d73a9U, 0x703890e0U, + 0x6fb9b1deU, 0xe67337d1U, 0xcfe94c83U, 0x6a35bed4U, + 0xaa55e349U, 0xe2713bd9U, 0xf67b07f1U, 0x058c0f0aU, + 0xe47231d5U, 0x0d88171aU, 0xf1f60effU, 0x542afca8U, + 0x7c3e84f8U, 0xbc5ed965U, 0x4e27d29cU, 0x8c468905U, + 0x180c2830U, 0xca654389U, 0xd0686dbdU, 0xc2615b99U, + 0x06030a0cU, 0x9fc1bc23U, 0xae57ef41U, 0xb1d6ce7fU, + 0xafd9ec43U, 0xb058cd7dU, 0xadd8ea47U, 0xcc664985U, + 0xb3d7c87bU, 0x743a9ce8U, 0x8dc88a07U, 0x783c88f0U, + 0xe9fa26cfU, 0x31965362U, 0x53a7f5a6U, 0x2d98775aU, + 0xc5ec5297U, 0x6db8b7daU, 0x93c7a83bU, 0x41aec382U, + 0xd2696bb9U, 0x964ba731U, 0x4babdd96U, 0x4fa9d19eU, + 0xce674f81U, 0x140a3c28U, 0x8e478f01U, 0xf9f216efU, + 0x77b599eeU, 0x4422cc88U, 0xd7e564b3U, 0xc1ee5e9fU, + 0x61bea3c2U, 0x562bfaacU, 0x1f81213eU, 0x24126c48U, + 0x1b832d36U, 0x361b5a6cU, 0x1c0e2438U, 0x4623ca8cU, + 0xf7f504f3U, 0x8a458309U, 0x4221c684U, 0x81ce9e1fU, + 0x9249ab39U, 0x582ce8b0U, 0xeff92cc3U, 0xd1e66ebfU, + 0x71b693e2U, 0x5028f0a0U, 0x2e17725cU, 0x19822b32U, + 0x341a5c68U, 0x0b8b1d16U, 0xe1fe3edfU, 0x098a1b12U, + 0x12093624U, 0x8fc98c03U, 0x13873526U, 0x9c4eb925U, + 0xdfe17ca3U, 0x5c2ee4b8U, 0xd5e462b7U, 0xdde07aa7U, + 0xcbeb408bU, 0x3d90477aU, 0x55a4ffaaU, 0x3c1e4478U, + 0x1785392eU, 0xc0605d9dU, 0x00000000U, 0x4a25de94U, + 0xf5f402f7U, 0xfff11ce3U, 0x35945f6aU, 0x160b3a2cU, + 0xd3e768bbU, 0xea7523c9U, 0xc3ef589bU, 0x6834b8d0U, + 0x6231a6c4U, 0xb5d4c277U, 0xbdd0da67U, 0x11863322U, + 0xfc7e19e5U, 0x47adc98eU, 0xe7fd34d3U, 0x5229f6a4U, + 0x6030a0c0U, 0x763b9aecU, 0x239f6546U, 0xedf82ac7U, + 0x91c6ae3fU, 0x26136a4cU, 0x0c061418U, 0x0a051e14U, + 0x97c5a433U, 0x22116644U, 0xee772fc1U, 0xf87c15edU, + 0xf47a01f5U, 0xf0780dfdU, 0x6c36b4d8U, 0x381c4870U, + 0x723996e4U, 0xb259cb79U, 0x30185060U, 0xac56e945U, + 0x7bb38df6U, 0x7db087faU, 0x4824d890U, 0x4020c080U, + 0x79b28bf2U, 0x39924b72U, 0x5ba3edb6U, 0x9dc0ba27U, + 0x8844850dU, 0xc4625195U, 0x20106040U, 0x75b49feaU, + 0x15843f2aU, 0x86439711U, 0x3b934d76U, 0x99c2b62fU, + 0x944aa135U, 0x67bda9ceU, 0x038f0506U, 0x5a2deeb4U, + 0x65bcafcaU, 0x259c6f4aU, 0xd46a61b5U, 0x80409d1dU, + 0x83cf981bU, 0x59a2ebb2U, 0x1d80273aU, 0x9e4fbf21U, + 0x3e1f427cU, 0x89ca860fU, 0x49aadb92U, 0x84429115U, +}; + +static const ulong32 T2[256] = { + 0xd2bbba69U, 0x4de554a8U, 0xbce22f5eU, 0xcd2574e8U, + 0x51f753a6U, 0x6bd0d3bbU, 0x6fd6d2b9U, 0x29b34d9aU, + 0x5dfd50a0U, 0x8acfac45U, 0x0e098d07U, 0xc6a5bf63U, + 0xdd3d70e0U, 0x55f152a4U, 0x527b9a29U, 0x2db54c98U, + 0x8f46eac9U, 0x73c4d5b7U, 0x66559733U, 0x63dcd1bfU, + 0xccaa3366U, 0x59fb51a2U, 0x71c75bb6U, 0xa2f3a651U, + 0x5ffedea1U, 0x3dad4890U, 0x9ad7a84dU, 0x5e71992fU, + 0x4be0dbabU, 0xc8ac3264U, 0xe695b773U, 0xd732fce5U, + 0xab70e3dbU, 0x42639e21U, 0x7e41913fU, 0x567d9b2bU, + 0xaf76e2d9U, 0xd6bdbb6bU, 0x199b4182U, 0xa5796edcU, + 0xaef9a557U, 0x0b80cb8bU, 0xb1676bd6U, 0x6e599537U, + 0xbee1a15fU, 0xeb10f3fbU, 0xfe81b17fU, 0x080c0204U, + 0x1792cc85U, 0x37a2c495U, 0x744e1d3aU, 0x50781428U, + 0x2bb0c39bU, 0x915763c6U, 0x4fe6daa9U, 0x69d35dbaU, + 0x61df5fbeU, 0x57f2dca5U, 0xe9137dfaU, 0x1394cd87U, + 0xe11f7ffeU, 0x75c15ab4U, 0xad756cd8U, 0x6dd55cb8U, + 0xfb08f7f3U, 0x98d4264cU, 0xdb38ffe3U, 0x9354edc7U, + 0x874ae8cdU, 0x4e699d27U, 0xa17f6fdeU, 0x02038e01U, + 0x64561932U, 0xbae7a05dU, 0xe71af0fdU, 0x1e11890fU, + 0x3c220f1eU, 0x1c12070eU, 0x86c5af43U, 0xcb20fbebU, + 0x20300810U, 0x547e152aU, 0x342e0d1aU, 0x10180408U, + 0x04060102U, 0x8d4564c8U, 0x5bf8dfa3U, 0xc52976ecU, + 0xf90b79f2U, 0x53f4dda7U, 0xf48e3d7aU, 0x5874162cU, + 0xfc823f7eU, 0xdcb2376eU, 0xa9736ddaU, 0xe0903870U, + 0xdeb1b96fU, 0xd13773e6U, 0x834ce9cfU, 0xd4be356aU, + 0x49e355aaU, 0xd93b71e2U, 0xf1077bf6U, 0x0a0f8c05U, + 0xd53172e4U, 0x1a17880dU, 0xff0ef6f1U, 0xa8fc2a54U, + 0xf8843e7cU, 0x65d95ebcU, 0x9cd2274eU, 0x0589468cU, + 0x30280c18U, 0x894365caU, 0xbd6d68d0U, 0x995b61c2U, + 0x0c0a0306U, 0x23bcc19fU, 0x41ef57aeU, 0x7fced6b1U, + 0x43ecd9afU, 0x7dcd58b0U, 0x47ead8adU, 0x854966ccU, + 0x7bc8d7b3U, 0xe89c3a74U, 0x078ac88dU, 0xf0883c78U, + 0xcf26fae9U, 0x62539631U, 0xa6f5a753U, 0x5a77982dU, + 0x9752ecc5U, 0xdab7b86dU, 0x3ba8c793U, 0x82c3ae41U, + 0xb96b69d2U, 0x31a74b96U, 0x96ddab4bU, 0x9ed1a94fU, + 0x814f67ceU, 0x283c0a14U, 0x018f478eU, 0xef16f2f9U, + 0xee99b577U, 0x88cc2244U, 0xb364e5d7U, 0x9f5eeec1U, + 0xc2a3be61U, 0xacfa2b56U, 0x3e21811fU, 0x486c1224U, + 0x362d831bU, 0x6c5a1b36U, 0x38240e1cU, 0x8cca2346U, + 0xf304f5f7U, 0x0983458aU, 0x84c62142U, 0x1f9ece81U, + 0x39ab4992U, 0xb0e82c58U, 0xc32cf9efU, 0xbf6ee6d1U, + 0xe293b671U, 0xa0f02850U, 0x5c72172eU, 0x322b8219U, + 0x685c1a34U, 0x161d8b0bU, 0xdf3efee1U, 0x121b8a09U, + 0x24360912U, 0x038cc98fU, 0x26358713U, 0x25b94e9cU, + 0xa37ce1dfU, 0xb8e42e5cU, 0xb762e4d5U, 0xa77ae0ddU, + 0x8b40ebcbU, 0x7a47903dU, 0xaaffa455U, 0x78441e3cU, + 0x2e398517U, 0x9d5d60c0U, 0x00000000U, 0x94de254aU, + 0xf702f4f5U, 0xe31cf1ffU, 0x6a5f9435U, 0x2c3a0b16U, + 0xbb68e7d3U, 0xc92375eaU, 0x9b58efc3U, 0xd0b83468U, + 0xc4a63162U, 0x77c2d4b5U, 0x67dad0bdU, 0x22338611U, + 0xe5197efcU, 0x8ec9ad47U, 0xd334fde7U, 0xa4f62952U, + 0xc0a03060U, 0xec9a3b76U, 0x46659f23U, 0xc72af8edU, + 0x3faec691U, 0x4c6a1326U, 0x1814060cU, 0x141e050aU, + 0x33a4c597U, 0x44661122U, 0xc12f77eeU, 0xed157cf8U, + 0xf5017af4U, 0xfd0d78f0U, 0xd8b4366cU, 0x70481c38U, + 0xe4963972U, 0x79cb59b2U, 0x60501830U, 0x45e956acU, + 0xf68db37bU, 0xfa87b07dU, 0x90d82448U, 0x80c02040U, + 0xf28bb279U, 0x724b9239U, 0xb6eda35bU, 0x27bac09dU, + 0x0d854488U, 0x955162c4U, 0x40601020U, 0xea9fb475U, + 0x2a3f8415U, 0x11974386U, 0x764d933bU, 0x2fb6c299U, + 0x35a14a94U, 0xcea9bd67U, 0x06058f03U, 0xb4ee2d5aU, + 0xcaafbc65U, 0x4a6f9c25U, 0xb5616ad4U, 0x1d9d4080U, + 0x1b98cf83U, 0xb2eba259U, 0x3a27801dU, 0x21bf4f9eU, + 0x7c421f3eU, 0x0f86ca89U, 0x92dbaa49U, 0x15914284U, +}; + +static const ulong32 T3[256] = { + 0xbbd269baU, 0xe54da854U, 0xe2bc5e2fU, 0x25cde874U, + 0xf751a653U, 0xd06bbbd3U, 0xd66fb9d2U, 0xb3299a4dU, + 0xfd5da050U, 0xcf8a45acU, 0x090e078dU, 0xa5c663bfU, + 0x3ddde070U, 0xf155a452U, 0x7b52299aU, 0xb52d984cU, + 0x468fc9eaU, 0xc473b7d5U, 0x55663397U, 0xdc63bfd1U, + 0xaacc6633U, 0xfb59a251U, 0xc771b65bU, 0xf3a251a6U, + 0xfe5fa1deU, 0xad3d9048U, 0xd79a4da8U, 0x715e2f99U, + 0xe04babdbU, 0xacc86432U, 0x95e673b7U, 0x32d7e5fcU, + 0x70abdbe3U, 0x6342219eU, 0x417e3f91U, 0x7d562b9bU, + 0x76afd9e2U, 0xbdd66bbbU, 0x9b198241U, 0x79a5dc6eU, + 0xf9ae57a5U, 0x800b8bcbU, 0x67b1d66bU, 0x596e3795U, + 0xe1be5fa1U, 0x10ebfbf3U, 0x81fe7fb1U, 0x0c080402U, + 0x921785ccU, 0xa23795c4U, 0x4e743a1dU, 0x78502814U, + 0xb02b9bc3U, 0x5791c663U, 0xe64fa9daU, 0xd369ba5dU, + 0xdf61be5fU, 0xf257a5dcU, 0x13e9fa7dU, 0x941387cdU, + 0x1fe1fe7fU, 0xc175b45aU, 0x75add86cU, 0xd56db85cU, + 0x08fbf3f7U, 0xd4984c26U, 0x38dbe3ffU, 0x5493c7edU, + 0x4a87cde8U, 0x694e279dU, 0x7fa1de6fU, 0x0302018eU, + 0x56643219U, 0xe7ba5da0U, 0x1ae7fdf0U, 0x111e0f89U, + 0x223c1e0fU, 0x121c0e07U, 0xc58643afU, 0x20cbebfbU, + 0x30201008U, 0x7e542a15U, 0x2e341a0dU, 0x18100804U, + 0x06040201U, 0x458dc864U, 0xf85ba3dfU, 0x29c5ec76U, + 0x0bf9f279U, 0xf453a7ddU, 0x8ef47a3dU, 0x74582c16U, + 0x82fc7e3fU, 0xb2dc6e37U, 0x73a9da6dU, 0x90e07038U, + 0xb1de6fb9U, 0x37d1e673U, 0x4c83cfe9U, 0xbed46a35U, + 0xe349aa55U, 0x3bd9e271U, 0x07f1f67bU, 0x0f0a058cU, + 0x31d5e472U, 0x171a0d88U, 0x0efff1f6U, 0xfca8542aU, + 0x84f87c3eU, 0xd965bc5eU, 0xd29c4e27U, 0x89058c46U, + 0x2830180cU, 0x4389ca65U, 0x6dbdd068U, 0x5b99c261U, + 0x0a0c0603U, 0xbc239fc1U, 0xef41ae57U, 0xce7fb1d6U, + 0xec43afd9U, 0xcd7db058U, 0xea47add8U, 0x4985cc66U, + 0xc87bb3d7U, 0x9ce8743aU, 0x8a078dc8U, 0x88f0783cU, + 0x26cfe9faU, 0x53623196U, 0xf5a653a7U, 0x775a2d98U, + 0x5297c5ecU, 0xb7da6db8U, 0xa83b93c7U, 0xc38241aeU, + 0x6bb9d269U, 0xa731964bU, 0xdd964babU, 0xd19e4fa9U, + 0x4f81ce67U, 0x3c28140aU, 0x8f018e47U, 0x16eff9f2U, + 0x99ee77b5U, 0xcc884422U, 0x64b3d7e5U, 0x5e9fc1eeU, + 0xa3c261beU, 0xfaac562bU, 0x213e1f81U, 0x6c482412U, + 0x2d361b83U, 0x5a6c361bU, 0x24381c0eU, 0xca8c4623U, + 0x04f3f7f5U, 0x83098a45U, 0xc6844221U, 0x9e1f81ceU, + 0xab399249U, 0xe8b0582cU, 0x2cc3eff9U, 0x6ebfd1e6U, + 0x93e271b6U, 0xf0a05028U, 0x725c2e17U, 0x2b321982U, + 0x5c68341aU, 0x1d160b8bU, 0x3edfe1feU, 0x1b12098aU, + 0x36241209U, 0x8c038fc9U, 0x35261387U, 0xb9259c4eU, + 0x7ca3dfe1U, 0xe4b85c2eU, 0x62b7d5e4U, 0x7aa7dde0U, + 0x408bcbebU, 0x477a3d90U, 0xffaa55a4U, 0x44783c1eU, + 0x392e1785U, 0x5d9dc060U, 0x00000000U, 0xde944a25U, + 0x02f7f5f4U, 0x1ce3fff1U, 0x5f6a3594U, 0x3a2c160bU, + 0x68bbd3e7U, 0x23c9ea75U, 0x589bc3efU, 0xb8d06834U, + 0xa6c46231U, 0xc277b5d4U, 0xda67bdd0U, 0x33221186U, + 0x19e5fc7eU, 0xc98e47adU, 0x34d3e7fdU, 0xf6a45229U, + 0xa0c06030U, 0x9aec763bU, 0x6546239fU, 0x2ac7edf8U, + 0xae3f91c6U, 0x6a4c2613U, 0x14180c06U, 0x1e140a05U, + 0xa43397c5U, 0x66442211U, 0x2fc1ee77U, 0x15edf87cU, + 0x01f5f47aU, 0x0dfdf078U, 0xb4d86c36U, 0x4870381cU, + 0x96e47239U, 0xcb79b259U, 0x50603018U, 0xe945ac56U, + 0x8df67bb3U, 0x87fa7db0U, 0xd8904824U, 0xc0804020U, + 0x8bf279b2U, 0x4b723992U, 0xedb65ba3U, 0xba279dc0U, + 0x850d8844U, 0x5195c462U, 0x60402010U, 0x9fea75b4U, + 0x3f2a1584U, 0x97118643U, 0x4d763b93U, 0xb62f99c2U, + 0xa135944aU, 0xa9ce67bdU, 0x0506038fU, 0xeeb45a2dU, + 0xafca65bcU, 0x6f4a259cU, 0x61b5d46aU, 0x9d1d8040U, + 0x981b83cfU, 0xebb259a2U, 0x273a1d80U, 0xbf219e4fU, + 0x427c3e1fU, 0x860f89caU, 0xdb9249aaU, 0x91158442U, +}; + +static const ulong32 T4[256] = { + 0xbabababaU, 0x54545454U, 0x2f2f2f2fU, 0x74747474U, + 0x53535353U, 0xd3d3d3d3U, 0xd2d2d2d2U, 0x4d4d4d4dU, + 0x50505050U, 0xacacacacU, 0x8d8d8d8dU, 0xbfbfbfbfU, + 0x70707070U, 0x52525252U, 0x9a9a9a9aU, 0x4c4c4c4cU, + 0xeaeaeaeaU, 0xd5d5d5d5U, 0x97979797U, 0xd1d1d1d1U, + 0x33333333U, 0x51515151U, 0x5b5b5b5bU, 0xa6a6a6a6U, + 0xdedededeU, 0x48484848U, 0xa8a8a8a8U, 0x99999999U, + 0xdbdbdbdbU, 0x32323232U, 0xb7b7b7b7U, 0xfcfcfcfcU, + 0xe3e3e3e3U, 0x9e9e9e9eU, 0x91919191U, 0x9b9b9b9bU, + 0xe2e2e2e2U, 0xbbbbbbbbU, 0x41414141U, 0x6e6e6e6eU, + 0xa5a5a5a5U, 0xcbcbcbcbU, 0x6b6b6b6bU, 0x95959595U, + 0xa1a1a1a1U, 0xf3f3f3f3U, 0xb1b1b1b1U, 0x02020202U, + 0xccccccccU, 0xc4c4c4c4U, 0x1d1d1d1dU, 0x14141414U, + 0xc3c3c3c3U, 0x63636363U, 0xdadadadaU, 0x5d5d5d5dU, + 0x5f5f5f5fU, 0xdcdcdcdcU, 0x7d7d7d7dU, 0xcdcdcdcdU, + 0x7f7f7f7fU, 0x5a5a5a5aU, 0x6c6c6c6cU, 0x5c5c5c5cU, + 0xf7f7f7f7U, 0x26262626U, 0xffffffffU, 0xededededU, + 0xe8e8e8e8U, 0x9d9d9d9dU, 0x6f6f6f6fU, 0x8e8e8e8eU, + 0x19191919U, 0xa0a0a0a0U, 0xf0f0f0f0U, 0x89898989U, + 0x0f0f0f0fU, 0x07070707U, 0xafafafafU, 0xfbfbfbfbU, + 0x08080808U, 0x15151515U, 0x0d0d0d0dU, 0x04040404U, + 0x01010101U, 0x64646464U, 0xdfdfdfdfU, 0x76767676U, + 0x79797979U, 0xddddddddU, 0x3d3d3d3dU, 0x16161616U, + 0x3f3f3f3fU, 0x37373737U, 0x6d6d6d6dU, 0x38383838U, + 0xb9b9b9b9U, 0x73737373U, 0xe9e9e9e9U, 0x35353535U, + 0x55555555U, 0x71717171U, 0x7b7b7b7bU, 0x8c8c8c8cU, + 0x72727272U, 0x88888888U, 0xf6f6f6f6U, 0x2a2a2a2aU, + 0x3e3e3e3eU, 0x5e5e5e5eU, 0x27272727U, 0x46464646U, + 0x0c0c0c0cU, 0x65656565U, 0x68686868U, 0x61616161U, + 0x03030303U, 0xc1c1c1c1U, 0x57575757U, 0xd6d6d6d6U, + 0xd9d9d9d9U, 0x58585858U, 0xd8d8d8d8U, 0x66666666U, + 0xd7d7d7d7U, 0x3a3a3a3aU, 0xc8c8c8c8U, 0x3c3c3c3cU, + 0xfafafafaU, 0x96969696U, 0xa7a7a7a7U, 0x98989898U, + 0xececececU, 0xb8b8b8b8U, 0xc7c7c7c7U, 0xaeaeaeaeU, + 0x69696969U, 0x4b4b4b4bU, 0xababababU, 0xa9a9a9a9U, + 0x67676767U, 0x0a0a0a0aU, 0x47474747U, 0xf2f2f2f2U, + 0xb5b5b5b5U, 0x22222222U, 0xe5e5e5e5U, 0xeeeeeeeeU, + 0xbebebebeU, 0x2b2b2b2bU, 0x81818181U, 0x12121212U, + 0x83838383U, 0x1b1b1b1bU, 0x0e0e0e0eU, 0x23232323U, + 0xf5f5f5f5U, 0x45454545U, 0x21212121U, 0xcecececeU, + 0x49494949U, 0x2c2c2c2cU, 0xf9f9f9f9U, 0xe6e6e6e6U, + 0xb6b6b6b6U, 0x28282828U, 0x17171717U, 0x82828282U, + 0x1a1a1a1aU, 0x8b8b8b8bU, 0xfefefefeU, 0x8a8a8a8aU, + 0x09090909U, 0xc9c9c9c9U, 0x87878787U, 0x4e4e4e4eU, + 0xe1e1e1e1U, 0x2e2e2e2eU, 0xe4e4e4e4U, 0xe0e0e0e0U, + 0xebebebebU, 0x90909090U, 0xa4a4a4a4U, 0x1e1e1e1eU, + 0x85858585U, 0x60606060U, 0x00000000U, 0x25252525U, + 0xf4f4f4f4U, 0xf1f1f1f1U, 0x94949494U, 0x0b0b0b0bU, + 0xe7e7e7e7U, 0x75757575U, 0xefefefefU, 0x34343434U, + 0x31313131U, 0xd4d4d4d4U, 0xd0d0d0d0U, 0x86868686U, + 0x7e7e7e7eU, 0xadadadadU, 0xfdfdfdfdU, 0x29292929U, + 0x30303030U, 0x3b3b3b3bU, 0x9f9f9f9fU, 0xf8f8f8f8U, + 0xc6c6c6c6U, 0x13131313U, 0x06060606U, 0x05050505U, + 0xc5c5c5c5U, 0x11111111U, 0x77777777U, 0x7c7c7c7cU, + 0x7a7a7a7aU, 0x78787878U, 0x36363636U, 0x1c1c1c1cU, + 0x39393939U, 0x59595959U, 0x18181818U, 0x56565656U, + 0xb3b3b3b3U, 0xb0b0b0b0U, 0x24242424U, 0x20202020U, + 0xb2b2b2b2U, 0x92929292U, 0xa3a3a3a3U, 0xc0c0c0c0U, + 0x44444444U, 0x62626262U, 0x10101010U, 0xb4b4b4b4U, + 0x84848484U, 0x43434343U, 0x93939393U, 0xc2c2c2c2U, + 0x4a4a4a4aU, 0xbdbdbdbdU, 0x8f8f8f8fU, 0x2d2d2d2dU, + 0xbcbcbcbcU, 0x9c9c9c9cU, 0x6a6a6a6aU, 0x40404040U, + 0xcfcfcfcfU, 0xa2a2a2a2U, 0x80808080U, 0x4f4f4f4fU, + 0x1f1f1f1fU, 0xcacacacaU, 0xaaaaaaaaU, 0x42424242U, +}; + +static const ulong32 T5[256] = { + 0x00000000U, 0x01020608U, 0x02040c10U, 0x03060a18U, + 0x04081820U, 0x050a1e28U, 0x060c1430U, 0x070e1238U, + 0x08103040U, 0x09123648U, 0x0a143c50U, 0x0b163a58U, + 0x0c182860U, 0x0d1a2e68U, 0x0e1c2470U, 0x0f1e2278U, + 0x10206080U, 0x11226688U, 0x12246c90U, 0x13266a98U, + 0x142878a0U, 0x152a7ea8U, 0x162c74b0U, 0x172e72b8U, + 0x183050c0U, 0x193256c8U, 0x1a345cd0U, 0x1b365ad8U, + 0x1c3848e0U, 0x1d3a4ee8U, 0x1e3c44f0U, 0x1f3e42f8U, + 0x2040c01dU, 0x2142c615U, 0x2244cc0dU, 0x2346ca05U, + 0x2448d83dU, 0x254ade35U, 0x264cd42dU, 0x274ed225U, + 0x2850f05dU, 0x2952f655U, 0x2a54fc4dU, 0x2b56fa45U, + 0x2c58e87dU, 0x2d5aee75U, 0x2e5ce46dU, 0x2f5ee265U, + 0x3060a09dU, 0x3162a695U, 0x3264ac8dU, 0x3366aa85U, + 0x3468b8bdU, 0x356abeb5U, 0x366cb4adU, 0x376eb2a5U, + 0x387090ddU, 0x397296d5U, 0x3a749ccdU, 0x3b769ac5U, + 0x3c7888fdU, 0x3d7a8ef5U, 0x3e7c84edU, 0x3f7e82e5U, + 0x40809d3aU, 0x41829b32U, 0x4284912aU, 0x43869722U, + 0x4488851aU, 0x458a8312U, 0x468c890aU, 0x478e8f02U, + 0x4890ad7aU, 0x4992ab72U, 0x4a94a16aU, 0x4b96a762U, + 0x4c98b55aU, 0x4d9ab352U, 0x4e9cb94aU, 0x4f9ebf42U, + 0x50a0fdbaU, 0x51a2fbb2U, 0x52a4f1aaU, 0x53a6f7a2U, + 0x54a8e59aU, 0x55aae392U, 0x56ace98aU, 0x57aeef82U, + 0x58b0cdfaU, 0x59b2cbf2U, 0x5ab4c1eaU, 0x5bb6c7e2U, + 0x5cb8d5daU, 0x5dbad3d2U, 0x5ebcd9caU, 0x5fbedfc2U, + 0x60c05d27U, 0x61c25b2fU, 0x62c45137U, 0x63c6573fU, + 0x64c84507U, 0x65ca430fU, 0x66cc4917U, 0x67ce4f1fU, + 0x68d06d67U, 0x69d26b6fU, 0x6ad46177U, 0x6bd6677fU, + 0x6cd87547U, 0x6dda734fU, 0x6edc7957U, 0x6fde7f5fU, + 0x70e03da7U, 0x71e23bafU, 0x72e431b7U, 0x73e637bfU, + 0x74e82587U, 0x75ea238fU, 0x76ec2997U, 0x77ee2f9fU, + 0x78f00de7U, 0x79f20befU, 0x7af401f7U, 0x7bf607ffU, + 0x7cf815c7U, 0x7dfa13cfU, 0x7efc19d7U, 0x7ffe1fdfU, + 0x801d2774U, 0x811f217cU, 0x82192b64U, 0x831b2d6cU, + 0x84153f54U, 0x8517395cU, 0x86113344U, 0x8713354cU, + 0x880d1734U, 0x890f113cU, 0x8a091b24U, 0x8b0b1d2cU, + 0x8c050f14U, 0x8d07091cU, 0x8e010304U, 0x8f03050cU, + 0x903d47f4U, 0x913f41fcU, 0x92394be4U, 0x933b4decU, + 0x94355fd4U, 0x953759dcU, 0x963153c4U, 0x973355ccU, + 0x982d77b4U, 0x992f71bcU, 0x9a297ba4U, 0x9b2b7dacU, + 0x9c256f94U, 0x9d27699cU, 0x9e216384U, 0x9f23658cU, + 0xa05de769U, 0xa15fe161U, 0xa259eb79U, 0xa35bed71U, + 0xa455ff49U, 0xa557f941U, 0xa651f359U, 0xa753f551U, + 0xa84dd729U, 0xa94fd121U, 0xaa49db39U, 0xab4bdd31U, + 0xac45cf09U, 0xad47c901U, 0xae41c319U, 0xaf43c511U, + 0xb07d87e9U, 0xb17f81e1U, 0xb2798bf9U, 0xb37b8df1U, + 0xb4759fc9U, 0xb57799c1U, 0xb67193d9U, 0xb77395d1U, + 0xb86db7a9U, 0xb96fb1a1U, 0xba69bbb9U, 0xbb6bbdb1U, + 0xbc65af89U, 0xbd67a981U, 0xbe61a399U, 0xbf63a591U, + 0xc09dba4eU, 0xc19fbc46U, 0xc299b65eU, 0xc39bb056U, + 0xc495a26eU, 0xc597a466U, 0xc691ae7eU, 0xc793a876U, + 0xc88d8a0eU, 0xc98f8c06U, 0xca89861eU, 0xcb8b8016U, + 0xcc85922eU, 0xcd879426U, 0xce819e3eU, 0xcf839836U, + 0xd0bddaceU, 0xd1bfdcc6U, 0xd2b9d6deU, 0xd3bbd0d6U, + 0xd4b5c2eeU, 0xd5b7c4e6U, 0xd6b1cefeU, 0xd7b3c8f6U, + 0xd8adea8eU, 0xd9afec86U, 0xdaa9e69eU, 0xdbabe096U, + 0xdca5f2aeU, 0xdda7f4a6U, 0xdea1febeU, 0xdfa3f8b6U, + 0xe0dd7a53U, 0xe1df7c5bU, 0xe2d97643U, 0xe3db704bU, + 0xe4d56273U, 0xe5d7647bU, 0xe6d16e63U, 0xe7d3686bU, + 0xe8cd4a13U, 0xe9cf4c1bU, 0xeac94603U, 0xebcb400bU, + 0xecc55233U, 0xedc7543bU, 0xeec15e23U, 0xefc3582bU, + 0xf0fd1ad3U, 0xf1ff1cdbU, 0xf2f916c3U, 0xf3fb10cbU, + 0xf4f502f3U, 0xf5f704fbU, 0xf6f10ee3U, 0xf7f308ebU, + 0xf8ed2a93U, 0xf9ef2c9bU, 0xfae92683U, 0xfbeb208bU, + 0xfce532b3U, 0xfde734bbU, 0xfee13ea3U, 0xffe338abU, +}; + +/** + * The round constants. + */ +static const ulong32 rc[] = { + 0xba542f74U, 0x53d3d24dU, 0x50ac8dbfU, 0x70529a4cU, + 0xead597d1U, 0x33515ba6U, 0xde48a899U, 0xdb32b7fcU, + 0xe39e919bU, 0xe2bb416eU, 0xa5cb6b95U, 0xa1f3b102U, + 0xccc41d14U, 0xc363da5dU, 0x5fdc7dcdU, 0x7f5a6c5cU, + 0xf726ffedU, 0xe89d6f8eU, 0x19a0f089U, +}; + + + +#else + + +static const ulong32 T0[256] = { + 0xa753a6f5U, 0xd3bb6bd0U, 0xe6d1bf6eU, 0x71e2d93bU, + 0xd0bd67daU, 0xac458acfU, 0x4d9a29b3U, 0x79f2f90bU, + 0x3a74e89cU, 0xc98f038cU, 0x913f7e41U, 0xfce5d732U, + 0x1e3c7844U, 0x478e018fU, 0x54a84de5U, 0xbd67cea9U, + 0x8c050a0fU, 0xa557aef9U, 0x7af4f501U, 0xfbebcb20U, + 0x63c69157U, 0xb86ddab7U, 0xdda753f4U, 0xd4b577c2U, + 0xe5d7b364U, 0xb37bf68dU, 0xc59733a4U, 0xbe61c2a3U, + 0xa94f9ed1U, 0x880d1a17U, 0x0c183028U, 0xa259b2ebU, + 0x3972e496U, 0xdfa35bf8U, 0x2952a4f6U, 0xdaa94fe6U, + 0x2b56acfaU, 0xa84d9ad7U, 0xcb8b0b80U, 0x4c982db5U, + 0x4b9631a7U, 0x224488ccU, 0xaa4992dbU, 0x244890d8U, + 0x4182199bU, 0x70e0dd3dU, 0xa651a2f3U, 0xf9efc32cU, + 0x5ab475c1U, 0xe2d9af76U, 0xb07dfa87U, 0x366cd8b4U, + 0x7dfae913U, 0xe4d5b762U, 0x3366ccaaU, 0xffe3db38U, + 0x60c09d5dU, 0x204080c0U, 0x08102030U, 0x8b0b161dU, + 0x5ebc65d9U, 0xab4b96ddU, 0x7ffee11fU, 0x78f0fd0dU, + 0x7cf8ed15U, 0x2c58b0e8U, 0x57ae41efU, 0xd2b96fd6U, + 0xdca557f2U, 0x6ddaa973U, 0x7efce519U, 0x0d1a342eU, + 0x53a651f7U, 0x94356a5fU, 0xc39b2bb0U, 0x2850a0f0U, + 0x274e9cd2U, 0x060c1814U, 0x5fbe61dfU, 0xad478ec9U, + 0x67ce814fU, 0x5cb86dd5U, 0x55aa49e3U, 0x48903dadU, + 0x0e1c3824U, 0x52a455f1U, 0xeac98f46U, 0x42841591U, + 0x5bb671c7U, 0x5dba69d3U, 0x3060c0a0U, 0x58b07dcdU, + 0x51a259fbU, 0x59b279cbU, 0x3c78f088U, 0x4e9c25b9U, + 0x3870e090U, 0x8a09121bU, 0x72e4d531U, 0x14285078U, + 0xe7d3bb68U, 0xc6913faeU, 0xdea15ffeU, 0x50a05dfdU, + 0x8e010203U, 0x9239724bU, 0xd1bf63dcU, 0x77eec12fU, + 0x933b764dU, 0x458a0983U, 0x9a29527bU, 0xce811f9eU, + 0x2d5ab4eeU, 0x03060c0aU, 0x62c49551U, 0xb671e293U, + 0xb96fdeb1U, 0xbf63c6a5U, 0x96316253U, 0x6bd6b167U, + 0x3f7efc82U, 0x070e1c12U, 0x1224486cU, 0xae4182c3U, + 0x40801d9dU, 0x3468d0b8U, 0x468c0589U, 0x3e7cf884U, + 0xdbab4be0U, 0xcf831b98U, 0xecc59752U, 0xcc851792U, + 0xc19f23bcU, 0xa15fbee1U, 0xc09d27baU, 0xd6b17fceU, + 0x1d3a744eU, 0xf4f5f702U, 0x61c2995bU, 0x3b76ec9aU, + 0x10204060U, 0xd8ad47eaU, 0x68d0bd6dU, 0xa05dbae7U, + 0xb17ffe81U, 0x0a14283cU, 0x69d2b96bU, 0x6cd8ad75U, + 0x499239abU, 0xfae9cf26U, 0x76ecc529U, 0xc49537a2U, + 0x9e214263U, 0x9b2b567dU, 0x6edca579U, 0x992f5e71U, + 0xc2992fb6U, 0xb773e695U, 0x982d5a77U, 0xbc65caafU, + 0x8f030605U, 0x85172e39U, 0x1f3e7c42U, 0xb475ea9fU, + 0xf8edc72aU, 0x11224466U, 0x2e5cb8e4U, 0x00000000U, + 0x254a94deU, 0x1c387048U, 0x2a54a8fcU, 0x3d7af48eU, + 0x050a141eU, 0x4f9e21bfU, 0x7bf6f107U, 0xb279f28bU, + 0x3264c8acU, 0x903d7a47U, 0xaf4386c5U, 0x19326456U, + 0xa35bb6edU, 0xf7f3fb08U, 0x73e6d137U, 0x9d274e69U, + 0x152a547eU, 0x74e8cd25U, 0xeec19f5eU, 0xca890f86U, + 0x9f234665U, 0x0f1e3c22U, 0x1b366c5aU, 0x75eac923U, + 0x86112233U, 0x84152a3fU, 0x9c254a6fU, 0x4a9435a1U, + 0x97336655U, 0x1a34685cU, 0x65ca8943U, 0xf6f1ff0eU, + 0xedc79354U, 0x09122436U, 0xbb6bd6bdU, 0x264c98d4U, + 0x831b362dU, 0xebcb8b40U, 0x6fdea17fU, 0x811f3e21U, + 0x04081018U, 0x6ad4b561U, 0x43861197U, 0x01020406U, + 0x172e5c72U, 0xe1dfa37cU, 0x87132635U, 0xf5f7f304U, + 0x8d070e09U, 0xe3dbab70U, 0x23468ccaU, 0x801d3a27U, + 0x44880d85U, 0x162c5874U, 0x66cc8549U, 0x214284c6U, + 0xfee1df3eU, 0xd5b773c4U, 0x3162c4a6U, 0xd9af43ecU, + 0x356ad4beU, 0x18306050U, 0x0204080cU, 0x64c88d45U, + 0xf2f9ef16U, 0xf1ffe31cU, 0x56ac45e9U, 0xcd871394U, + 0x8219322bU, 0xc88d078aU, 0xba69d2bbU, 0xf0fde71aU, + 0xefc39b58U, 0xe9cf834cU, 0xe8cd874aU, 0xfde7d334U, + 0x890f1e11U, 0xd7b37bc8U, 0xc7933ba8U, 0xb577ee99U, + 0xa455aaffU, 0x2f5ebce2U, 0x95376e59U, 0x13264c6aU, + 0x0b162c3aU, 0xf3fbeb10U, 0xe0dda77aU, 0x376edcb2U, +}; + +static const ulong32 T1[256] = { + 0x53a7f5a6U, 0xbbd3d06bU, 0xd1e66ebfU, 0xe2713bd9U, + 0xbdd0da67U, 0x45accf8aU, 0x9a4db329U, 0xf2790bf9U, + 0x743a9ce8U, 0x8fc98c03U, 0x3f91417eU, 0xe5fc32d7U, + 0x3c1e4478U, 0x8e478f01U, 0xa854e54dU, 0x67bda9ceU, + 0x058c0f0aU, 0x57a5f9aeU, 0xf47a01f5U, 0xebfb20cbU, + 0xc6635791U, 0x6db8b7daU, 0xa7ddf453U, 0xb5d4c277U, + 0xd7e564b3U, 0x7bb38df6U, 0x97c5a433U, 0x61bea3c2U, + 0x4fa9d19eU, 0x0d88171aU, 0x180c2830U, 0x59a2ebb2U, + 0x723996e4U, 0xa3dff85bU, 0x5229f6a4U, 0xa9dae64fU, + 0x562bfaacU, 0x4da8d79aU, 0x8bcb800bU, 0x984cb52dU, + 0x964ba731U, 0x4422cc88U, 0x49aadb92U, 0x4824d890U, + 0x82419b19U, 0xe0703dddU, 0x51a6f3a2U, 0xeff92cc3U, + 0xb45ac175U, 0xd9e276afU, 0x7db087faU, 0x6c36b4d8U, + 0xfa7d13e9U, 0xd5e462b7U, 0x6633aaccU, 0xe3ff38dbU, + 0xc0605d9dU, 0x4020c080U, 0x10083020U, 0x0b8b1d16U, + 0xbc5ed965U, 0x4babdd96U, 0xfe7f1fe1U, 0xf0780dfdU, + 0xf87c15edU, 0x582ce8b0U, 0xae57ef41U, 0xb9d2d66fU, + 0xa5dcf257U, 0xda6d73a9U, 0xfc7e19e5U, 0x1a0d2e34U, + 0xa653f751U, 0x35945f6aU, 0x9bc3b02bU, 0x5028f0a0U, + 0x4e27d29cU, 0x0c061418U, 0xbe5fdf61U, 0x47adc98eU, + 0xce674f81U, 0xb85cd56dU, 0xaa55e349U, 0x9048ad3dU, + 0x1c0e2438U, 0xa452f155U, 0xc9ea468fU, 0x84429115U, + 0xb65bc771U, 0xba5dd369U, 0x6030a0c0U, 0xb058cd7dU, + 0xa251fb59U, 0xb259cb79U, 0x783c88f0U, 0x9c4eb925U, + 0x703890e0U, 0x098a1b12U, 0xe47231d5U, 0x28147850U, + 0xd3e768bbU, 0x91c6ae3fU, 0xa1defe5fU, 0xa050fd5dU, + 0x018e0302U, 0x39924b72U, 0xbfd1dc63U, 0xee772fc1U, + 0x3b934d76U, 0x8a458309U, 0x299a7b52U, 0x81ce9e1fU, + 0x5a2deeb4U, 0x06030a0cU, 0xc4625195U, 0x71b693e2U, + 0x6fb9b1deU, 0x63bfa5c6U, 0x31965362U, 0xd66b67b1U, + 0x7e3f82fcU, 0x0e07121cU, 0x24126c48U, 0x41aec382U, + 0x80409d1dU, 0x6834b8d0U, 0x8c468905U, 0x7c3e84f8U, + 0xabdbe04bU, 0x83cf981bU, 0xc5ec5297U, 0x85cc9217U, + 0x9fc1bc23U, 0x5fa1e1beU, 0x9dc0ba27U, 0xb1d6ce7fU, + 0x3a1d4e74U, 0xf5f402f7U, 0xc2615b99U, 0x763b9aecU, + 0x20106040U, 0xadd8ea47U, 0xd0686dbdU, 0x5da0e7baU, + 0x7fb181feU, 0x140a3c28U, 0xd2696bb9U, 0xd86c75adU, + 0x9249ab39U, 0xe9fa26cfU, 0xec7629c5U, 0x95c4a237U, + 0x219e6342U, 0x2b9b7d56U, 0xdc6e79a5U, 0x2f99715eU, + 0x99c2b62fU, 0x73b795e6U, 0x2d98775aU, 0x65bcafcaU, + 0x038f0506U, 0x1785392eU, 0x3e1f427cU, 0x75b49feaU, + 0xedf82ac7U, 0x22116644U, 0x5c2ee4b8U, 0x00000000U, + 0x4a25de94U, 0x381c4870U, 0x542afca8U, 0x7a3d8ef4U, + 0x0a051e14U, 0x9e4fbf21U, 0xf67b07f1U, 0x79b28bf2U, + 0x6432acc8U, 0x3d90477aU, 0x43afc586U, 0x32195664U, + 0x5ba3edb6U, 0xf3f708fbU, 0xe67337d1U, 0x279d694eU, + 0x2a157e54U, 0xe87425cdU, 0xc1ee5e9fU, 0x89ca860fU, + 0x239f6546U, 0x1e0f223cU, 0x361b5a6cU, 0xea7523c9U, + 0x11863322U, 0x15843f2aU, 0x259c6f4aU, 0x944aa135U, + 0x33975566U, 0x341a5c68U, 0xca654389U, 0xf1f60effU, + 0xc7ed5493U, 0x12093624U, 0x6bbbbdd6U, 0x4c26d498U, + 0x1b832d36U, 0xcbeb408bU, 0xde6f7fa1U, 0x1f81213eU, + 0x08041810U, 0xd46a61b5U, 0x86439711U, 0x02010604U, + 0x2e17725cU, 0xdfe17ca3U, 0x13873526U, 0xf7f504f3U, + 0x078d090eU, 0xdbe370abU, 0x4623ca8cU, 0x1d80273aU, + 0x8844850dU, 0x2c167458U, 0xcc664985U, 0x4221c684U, + 0xe1fe3edfU, 0xb7d5c473U, 0x6231a6c4U, 0xafd9ec43U, + 0x6a35bed4U, 0x30185060U, 0x04020c08U, 0xc864458dU, + 0xf9f216efU, 0xfff11ce3U, 0xac56e945U, 0x87cd9413U, + 0x19822b32U, 0x8dc88a07U, 0x69babbd2U, 0xfdf01ae7U, + 0xc3ef589bU, 0xcfe94c83U, 0xcde84a87U, 0xe7fd34d3U, + 0x0f89111eU, 0xb3d7c87bU, 0x93c7a83bU, 0x77b599eeU, + 0x55a4ffaaU, 0x5e2fe2bcU, 0x3795596eU, 0x26136a4cU, + 0x160b3a2cU, 0xfbf310ebU, 0xdde07aa7U, 0x6e37b2dcU, +}; + +static const ulong32 T2[256] = { + 0xa6f5a753U, 0x6bd0d3bbU, 0xbf6ee6d1U, 0xd93b71e2U, + 0x67dad0bdU, 0x8acfac45U, 0x29b34d9aU, 0xf90b79f2U, + 0xe89c3a74U, 0x038cc98fU, 0x7e41913fU, 0xd732fce5U, + 0x78441e3cU, 0x018f478eU, 0x4de554a8U, 0xcea9bd67U, + 0x0a0f8c05U, 0xaef9a557U, 0xf5017af4U, 0xcb20fbebU, + 0x915763c6U, 0xdab7b86dU, 0x53f4dda7U, 0x77c2d4b5U, + 0xb364e5d7U, 0xf68db37bU, 0x33a4c597U, 0xc2a3be61U, + 0x9ed1a94fU, 0x1a17880dU, 0x30280c18U, 0xb2eba259U, + 0xe4963972U, 0x5bf8dfa3U, 0xa4f62952U, 0x4fe6daa9U, + 0xacfa2b56U, 0x9ad7a84dU, 0x0b80cb8bU, 0x2db54c98U, + 0x31a74b96U, 0x88cc2244U, 0x92dbaa49U, 0x90d82448U, + 0x199b4182U, 0xdd3d70e0U, 0xa2f3a651U, 0xc32cf9efU, + 0x75c15ab4U, 0xaf76e2d9U, 0xfa87b07dU, 0xd8b4366cU, + 0xe9137dfaU, 0xb762e4d5U, 0xccaa3366U, 0xdb38ffe3U, + 0x9d5d60c0U, 0x80c02040U, 0x20300810U, 0x161d8b0bU, + 0x65d95ebcU, 0x96ddab4bU, 0xe11f7ffeU, 0xfd0d78f0U, + 0xed157cf8U, 0xb0e82c58U, 0x41ef57aeU, 0x6fd6d2b9U, + 0x57f2dca5U, 0xa9736ddaU, 0xe5197efcU, 0x342e0d1aU, + 0x51f753a6U, 0x6a5f9435U, 0x2bb0c39bU, 0xa0f02850U, + 0x9cd2274eU, 0x1814060cU, 0x61df5fbeU, 0x8ec9ad47U, + 0x814f67ceU, 0x6dd55cb8U, 0x49e355aaU, 0x3dad4890U, + 0x38240e1cU, 0x55f152a4U, 0x8f46eac9U, 0x15914284U, + 0x71c75bb6U, 0x69d35dbaU, 0xc0a03060U, 0x7dcd58b0U, + 0x59fb51a2U, 0x79cb59b2U, 0xf0883c78U, 0x25b94e9cU, + 0xe0903870U, 0x121b8a09U, 0xd53172e4U, 0x50781428U, + 0xbb68e7d3U, 0x3faec691U, 0x5ffedea1U, 0x5dfd50a0U, + 0x02038e01U, 0x724b9239U, 0x63dcd1bfU, 0xc12f77eeU, + 0x764d933bU, 0x0983458aU, 0x527b9a29U, 0x1f9ece81U, + 0xb4ee2d5aU, 0x0c0a0306U, 0x955162c4U, 0xe293b671U, + 0xdeb1b96fU, 0xc6a5bf63U, 0x62539631U, 0xb1676bd6U, + 0xfc823f7eU, 0x1c12070eU, 0x486c1224U, 0x82c3ae41U, + 0x1d9d4080U, 0xd0b83468U, 0x0589468cU, 0xf8843e7cU, + 0x4be0dbabU, 0x1b98cf83U, 0x9752ecc5U, 0x1792cc85U, + 0x23bcc19fU, 0xbee1a15fU, 0x27bac09dU, 0x7fced6b1U, + 0x744e1d3aU, 0xf702f4f5U, 0x995b61c2U, 0xec9a3b76U, + 0x40601020U, 0x47ead8adU, 0xbd6d68d0U, 0xbae7a05dU, + 0xfe81b17fU, 0x283c0a14U, 0xb96b69d2U, 0xad756cd8U, + 0x39ab4992U, 0xcf26fae9U, 0xc52976ecU, 0x37a2c495U, + 0x42639e21U, 0x567d9b2bU, 0xa5796edcU, 0x5e71992fU, + 0x2fb6c299U, 0xe695b773U, 0x5a77982dU, 0xcaafbc65U, + 0x06058f03U, 0x2e398517U, 0x7c421f3eU, 0xea9fb475U, + 0xc72af8edU, 0x44661122U, 0xb8e42e5cU, 0x00000000U, + 0x94de254aU, 0x70481c38U, 0xa8fc2a54U, 0xf48e3d7aU, + 0x141e050aU, 0x21bf4f9eU, 0xf1077bf6U, 0xf28bb279U, + 0xc8ac3264U, 0x7a47903dU, 0x86c5af43U, 0x64561932U, + 0xb6eda35bU, 0xfb08f7f3U, 0xd13773e6U, 0x4e699d27U, + 0x547e152aU, 0xcd2574e8U, 0x9f5eeec1U, 0x0f86ca89U, + 0x46659f23U, 0x3c220f1eU, 0x6c5a1b36U, 0xc92375eaU, + 0x22338611U, 0x2a3f8415U, 0x4a6f9c25U, 0x35a14a94U, + 0x66559733U, 0x685c1a34U, 0x894365caU, 0xff0ef6f1U, + 0x9354edc7U, 0x24360912U, 0xd6bdbb6bU, 0x98d4264cU, + 0x362d831bU, 0x8b40ebcbU, 0xa17f6fdeU, 0x3e21811fU, + 0x10180408U, 0xb5616ad4U, 0x11974386U, 0x04060102U, + 0x5c72172eU, 0xa37ce1dfU, 0x26358713U, 0xf304f5f7U, + 0x0e098d07U, 0xab70e3dbU, 0x8cca2346U, 0x3a27801dU, + 0x0d854488U, 0x5874162cU, 0x854966ccU, 0x84c62142U, + 0xdf3efee1U, 0x73c4d5b7U, 0xc4a63162U, 0x43ecd9afU, + 0xd4be356aU, 0x60501830U, 0x080c0204U, 0x8d4564c8U, + 0xef16f2f9U, 0xe31cf1ffU, 0x45e956acU, 0x1394cd87U, + 0x322b8219U, 0x078ac88dU, 0xd2bbba69U, 0xe71af0fdU, + 0x9b58efc3U, 0x834ce9cfU, 0x874ae8cdU, 0xd334fde7U, + 0x1e11890fU, 0x7bc8d7b3U, 0x3ba8c793U, 0xee99b577U, + 0xaaffa455U, 0xbce22f5eU, 0x6e599537U, 0x4c6a1326U, + 0x2c3a0b16U, 0xeb10f3fbU, 0xa77ae0ddU, 0xdcb2376eU, +}; + +static const ulong32 T3[256] = { + 0xf5a653a7U, 0xd06bbbd3U, 0x6ebfd1e6U, 0x3bd9e271U, + 0xda67bdd0U, 0xcf8a45acU, 0xb3299a4dU, 0x0bf9f279U, + 0x9ce8743aU, 0x8c038fc9U, 0x417e3f91U, 0x32d7e5fcU, + 0x44783c1eU, 0x8f018e47U, 0xe54da854U, 0xa9ce67bdU, + 0x0f0a058cU, 0xf9ae57a5U, 0x01f5f47aU, 0x20cbebfbU, + 0x5791c663U, 0xb7da6db8U, 0xf453a7ddU, 0xc277b5d4U, + 0x64b3d7e5U, 0x8df67bb3U, 0xa43397c5U, 0xa3c261beU, + 0xd19e4fa9U, 0x171a0d88U, 0x2830180cU, 0xebb259a2U, + 0x96e47239U, 0xf85ba3dfU, 0xf6a45229U, 0xe64fa9daU, + 0xfaac562bU, 0xd79a4da8U, 0x800b8bcbU, 0xb52d984cU, + 0xa731964bU, 0xcc884422U, 0xdb9249aaU, 0xd8904824U, + 0x9b198241U, 0x3ddde070U, 0xf3a251a6U, 0x2cc3eff9U, + 0xc175b45aU, 0x76afd9e2U, 0x87fa7db0U, 0xb4d86c36U, + 0x13e9fa7dU, 0x62b7d5e4U, 0xaacc6633U, 0x38dbe3ffU, + 0x5d9dc060U, 0xc0804020U, 0x30201008U, 0x1d160b8bU, + 0xd965bc5eU, 0xdd964babU, 0x1fe1fe7fU, 0x0dfdf078U, + 0x15edf87cU, 0xe8b0582cU, 0xef41ae57U, 0xd66fb9d2U, + 0xf257a5dcU, 0x73a9da6dU, 0x19e5fc7eU, 0x2e341a0dU, + 0xf751a653U, 0x5f6a3594U, 0xb02b9bc3U, 0xf0a05028U, + 0xd29c4e27U, 0x14180c06U, 0xdf61be5fU, 0xc98e47adU, + 0x4f81ce67U, 0xd56db85cU, 0xe349aa55U, 0xad3d9048U, + 0x24381c0eU, 0xf155a452U, 0x468fc9eaU, 0x91158442U, + 0xc771b65bU, 0xd369ba5dU, 0xa0c06030U, 0xcd7db058U, + 0xfb59a251U, 0xcb79b259U, 0x88f0783cU, 0xb9259c4eU, + 0x90e07038U, 0x1b12098aU, 0x31d5e472U, 0x78502814U, + 0x68bbd3e7U, 0xae3f91c6U, 0xfe5fa1deU, 0xfd5da050U, + 0x0302018eU, 0x4b723992U, 0xdc63bfd1U, 0x2fc1ee77U, + 0x4d763b93U, 0x83098a45U, 0x7b52299aU, 0x9e1f81ceU, + 0xeeb45a2dU, 0x0a0c0603U, 0x5195c462U, 0x93e271b6U, + 0xb1de6fb9U, 0xa5c663bfU, 0x53623196U, 0x67b1d66bU, + 0x82fc7e3fU, 0x121c0e07U, 0x6c482412U, 0xc38241aeU, + 0x9d1d8040U, 0xb8d06834U, 0x89058c46U, 0x84f87c3eU, + 0xe04babdbU, 0x981b83cfU, 0x5297c5ecU, 0x921785ccU, + 0xbc239fc1U, 0xe1be5fa1U, 0xba279dc0U, 0xce7fb1d6U, + 0x4e743a1dU, 0x02f7f5f4U, 0x5b99c261U, 0x9aec763bU, + 0x60402010U, 0xea47add8U, 0x6dbdd068U, 0xe7ba5da0U, + 0x81fe7fb1U, 0x3c28140aU, 0x6bb9d269U, 0x75add86cU, + 0xab399249U, 0x26cfe9faU, 0x29c5ec76U, 0xa23795c4U, + 0x6342219eU, 0x7d562b9bU, 0x79a5dc6eU, 0x715e2f99U, + 0xb62f99c2U, 0x95e673b7U, 0x775a2d98U, 0xafca65bcU, + 0x0506038fU, 0x392e1785U, 0x427c3e1fU, 0x9fea75b4U, + 0x2ac7edf8U, 0x66442211U, 0xe4b85c2eU, 0x00000000U, + 0xde944a25U, 0x4870381cU, 0xfca8542aU, 0x8ef47a3dU, + 0x1e140a05U, 0xbf219e4fU, 0x07f1f67bU, 0x8bf279b2U, + 0xacc86432U, 0x477a3d90U, 0xc58643afU, 0x56643219U, + 0xedb65ba3U, 0x08fbf3f7U, 0x37d1e673U, 0x694e279dU, + 0x7e542a15U, 0x25cde874U, 0x5e9fc1eeU, 0x860f89caU, + 0x6546239fU, 0x223c1e0fU, 0x5a6c361bU, 0x23c9ea75U, + 0x33221186U, 0x3f2a1584U, 0x6f4a259cU, 0xa135944aU, + 0x55663397U, 0x5c68341aU, 0x4389ca65U, 0x0efff1f6U, + 0x5493c7edU, 0x36241209U, 0xbdd66bbbU, 0xd4984c26U, + 0x2d361b83U, 0x408bcbebU, 0x7fa1de6fU, 0x213e1f81U, + 0x18100804U, 0x61b5d46aU, 0x97118643U, 0x06040201U, + 0x725c2e17U, 0x7ca3dfe1U, 0x35261387U, 0x04f3f7f5U, + 0x090e078dU, 0x70abdbe3U, 0xca8c4623U, 0x273a1d80U, + 0x850d8844U, 0x74582c16U, 0x4985cc66U, 0xc6844221U, + 0x3edfe1feU, 0xc473b7d5U, 0xa6c46231U, 0xec43afd9U, + 0xbed46a35U, 0x50603018U, 0x0c080402U, 0x458dc864U, + 0x16eff9f2U, 0x1ce3fff1U, 0xe945ac56U, 0x941387cdU, + 0x2b321982U, 0x8a078dc8U, 0xbbd269baU, 0x1ae7fdf0U, + 0x589bc3efU, 0x4c83cfe9U, 0x4a87cde8U, 0x34d3e7fdU, + 0x111e0f89U, 0xc87bb3d7U, 0xa83b93c7U, 0x99ee77b5U, + 0xffaa55a4U, 0xe2bc5e2fU, 0x596e3795U, 0x6a4c2613U, + 0x3a2c160bU, 0x10ebfbf3U, 0x7aa7dde0U, 0xb2dc6e37U, +}; + +static const ulong32 T4[256] = { + 0xa7a7a7a7U, 0xd3d3d3d3U, 0xe6e6e6e6U, 0x71717171U, + 0xd0d0d0d0U, 0xacacacacU, 0x4d4d4d4dU, 0x79797979U, + 0x3a3a3a3aU, 0xc9c9c9c9U, 0x91919191U, 0xfcfcfcfcU, + 0x1e1e1e1eU, 0x47474747U, 0x54545454U, 0xbdbdbdbdU, + 0x8c8c8c8cU, 0xa5a5a5a5U, 0x7a7a7a7aU, 0xfbfbfbfbU, + 0x63636363U, 0xb8b8b8b8U, 0xddddddddU, 0xd4d4d4d4U, + 0xe5e5e5e5U, 0xb3b3b3b3U, 0xc5c5c5c5U, 0xbebebebeU, + 0xa9a9a9a9U, 0x88888888U, 0x0c0c0c0cU, 0xa2a2a2a2U, + 0x39393939U, 0xdfdfdfdfU, 0x29292929U, 0xdadadadaU, + 0x2b2b2b2bU, 0xa8a8a8a8U, 0xcbcbcbcbU, 0x4c4c4c4cU, + 0x4b4b4b4bU, 0x22222222U, 0xaaaaaaaaU, 0x24242424U, + 0x41414141U, 0x70707070U, 0xa6a6a6a6U, 0xf9f9f9f9U, + 0x5a5a5a5aU, 0xe2e2e2e2U, 0xb0b0b0b0U, 0x36363636U, + 0x7d7d7d7dU, 0xe4e4e4e4U, 0x33333333U, 0xffffffffU, + 0x60606060U, 0x20202020U, 0x08080808U, 0x8b8b8b8bU, + 0x5e5e5e5eU, 0xababababU, 0x7f7f7f7fU, 0x78787878U, + 0x7c7c7c7cU, 0x2c2c2c2cU, 0x57575757U, 0xd2d2d2d2U, + 0xdcdcdcdcU, 0x6d6d6d6dU, 0x7e7e7e7eU, 0x0d0d0d0dU, + 0x53535353U, 0x94949494U, 0xc3c3c3c3U, 0x28282828U, + 0x27272727U, 0x06060606U, 0x5f5f5f5fU, 0xadadadadU, + 0x67676767U, 0x5c5c5c5cU, 0x55555555U, 0x48484848U, + 0x0e0e0e0eU, 0x52525252U, 0xeaeaeaeaU, 0x42424242U, + 0x5b5b5b5bU, 0x5d5d5d5dU, 0x30303030U, 0x58585858U, + 0x51515151U, 0x59595959U, 0x3c3c3c3cU, 0x4e4e4e4eU, + 0x38383838U, 0x8a8a8a8aU, 0x72727272U, 0x14141414U, + 0xe7e7e7e7U, 0xc6c6c6c6U, 0xdedededeU, 0x50505050U, + 0x8e8e8e8eU, 0x92929292U, 0xd1d1d1d1U, 0x77777777U, + 0x93939393U, 0x45454545U, 0x9a9a9a9aU, 0xcecececeU, + 0x2d2d2d2dU, 0x03030303U, 0x62626262U, 0xb6b6b6b6U, + 0xb9b9b9b9U, 0xbfbfbfbfU, 0x96969696U, 0x6b6b6b6bU, + 0x3f3f3f3fU, 0x07070707U, 0x12121212U, 0xaeaeaeaeU, + 0x40404040U, 0x34343434U, 0x46464646U, 0x3e3e3e3eU, + 0xdbdbdbdbU, 0xcfcfcfcfU, 0xececececU, 0xccccccccU, + 0xc1c1c1c1U, 0xa1a1a1a1U, 0xc0c0c0c0U, 0xd6d6d6d6U, + 0x1d1d1d1dU, 0xf4f4f4f4U, 0x61616161U, 0x3b3b3b3bU, + 0x10101010U, 0xd8d8d8d8U, 0x68686868U, 0xa0a0a0a0U, + 0xb1b1b1b1U, 0x0a0a0a0aU, 0x69696969U, 0x6c6c6c6cU, + 0x49494949U, 0xfafafafaU, 0x76767676U, 0xc4c4c4c4U, + 0x9e9e9e9eU, 0x9b9b9b9bU, 0x6e6e6e6eU, 0x99999999U, + 0xc2c2c2c2U, 0xb7b7b7b7U, 0x98989898U, 0xbcbcbcbcU, + 0x8f8f8f8fU, 0x85858585U, 0x1f1f1f1fU, 0xb4b4b4b4U, + 0xf8f8f8f8U, 0x11111111U, 0x2e2e2e2eU, 0x00000000U, + 0x25252525U, 0x1c1c1c1cU, 0x2a2a2a2aU, 0x3d3d3d3dU, + 0x05050505U, 0x4f4f4f4fU, 0x7b7b7b7bU, 0xb2b2b2b2U, + 0x32323232U, 0x90909090U, 0xafafafafU, 0x19191919U, + 0xa3a3a3a3U, 0xf7f7f7f7U, 0x73737373U, 0x9d9d9d9dU, + 0x15151515U, 0x74747474U, 0xeeeeeeeeU, 0xcacacacaU, + 0x9f9f9f9fU, 0x0f0f0f0fU, 0x1b1b1b1bU, 0x75757575U, + 0x86868686U, 0x84848484U, 0x9c9c9c9cU, 0x4a4a4a4aU, + 0x97979797U, 0x1a1a1a1aU, 0x65656565U, 0xf6f6f6f6U, + 0xededededU, 0x09090909U, 0xbbbbbbbbU, 0x26262626U, + 0x83838383U, 0xebebebebU, 0x6f6f6f6fU, 0x81818181U, + 0x04040404U, 0x6a6a6a6aU, 0x43434343U, 0x01010101U, + 0x17171717U, 0xe1e1e1e1U, 0x87878787U, 0xf5f5f5f5U, + 0x8d8d8d8dU, 0xe3e3e3e3U, 0x23232323U, 0x80808080U, + 0x44444444U, 0x16161616U, 0x66666666U, 0x21212121U, + 0xfefefefeU, 0xd5d5d5d5U, 0x31313131U, 0xd9d9d9d9U, + 0x35353535U, 0x18181818U, 0x02020202U, 0x64646464U, + 0xf2f2f2f2U, 0xf1f1f1f1U, 0x56565656U, 0xcdcdcdcdU, + 0x82828282U, 0xc8c8c8c8U, 0xbabababaU, 0xf0f0f0f0U, + 0xefefefefU, 0xe9e9e9e9U, 0xe8e8e8e8U, 0xfdfdfdfdU, + 0x89898989U, 0xd7d7d7d7U, 0xc7c7c7c7U, 0xb5b5b5b5U, + 0xa4a4a4a4U, 0x2f2f2f2fU, 0x95959595U, 0x13131313U, + 0x0b0b0b0bU, 0xf3f3f3f3U, 0xe0e0e0e0U, 0x37373737U, +}; + +static const ulong32 T5[256] = { + 0x00000000U, 0x01020608U, 0x02040c10U, 0x03060a18U, + 0x04081820U, 0x050a1e28U, 0x060c1430U, 0x070e1238U, + 0x08103040U, 0x09123648U, 0x0a143c50U, 0x0b163a58U, + 0x0c182860U, 0x0d1a2e68U, 0x0e1c2470U, 0x0f1e2278U, + 0x10206080U, 0x11226688U, 0x12246c90U, 0x13266a98U, + 0x142878a0U, 0x152a7ea8U, 0x162c74b0U, 0x172e72b8U, + 0x183050c0U, 0x193256c8U, 0x1a345cd0U, 0x1b365ad8U, + 0x1c3848e0U, 0x1d3a4ee8U, 0x1e3c44f0U, 0x1f3e42f8U, + 0x2040c01dU, 0x2142c615U, 0x2244cc0dU, 0x2346ca05U, + 0x2448d83dU, 0x254ade35U, 0x264cd42dU, 0x274ed225U, + 0x2850f05dU, 0x2952f655U, 0x2a54fc4dU, 0x2b56fa45U, + 0x2c58e87dU, 0x2d5aee75U, 0x2e5ce46dU, 0x2f5ee265U, + 0x3060a09dU, 0x3162a695U, 0x3264ac8dU, 0x3366aa85U, + 0x3468b8bdU, 0x356abeb5U, 0x366cb4adU, 0x376eb2a5U, + 0x387090ddU, 0x397296d5U, 0x3a749ccdU, 0x3b769ac5U, + 0x3c7888fdU, 0x3d7a8ef5U, 0x3e7c84edU, 0x3f7e82e5U, + 0x40809d3aU, 0x41829b32U, 0x4284912aU, 0x43869722U, + 0x4488851aU, 0x458a8312U, 0x468c890aU, 0x478e8f02U, + 0x4890ad7aU, 0x4992ab72U, 0x4a94a16aU, 0x4b96a762U, + 0x4c98b55aU, 0x4d9ab352U, 0x4e9cb94aU, 0x4f9ebf42U, + 0x50a0fdbaU, 0x51a2fbb2U, 0x52a4f1aaU, 0x53a6f7a2U, + 0x54a8e59aU, 0x55aae392U, 0x56ace98aU, 0x57aeef82U, + 0x58b0cdfaU, 0x59b2cbf2U, 0x5ab4c1eaU, 0x5bb6c7e2U, + 0x5cb8d5daU, 0x5dbad3d2U, 0x5ebcd9caU, 0x5fbedfc2U, + 0x60c05d27U, 0x61c25b2fU, 0x62c45137U, 0x63c6573fU, + 0x64c84507U, 0x65ca430fU, 0x66cc4917U, 0x67ce4f1fU, + 0x68d06d67U, 0x69d26b6fU, 0x6ad46177U, 0x6bd6677fU, + 0x6cd87547U, 0x6dda734fU, 0x6edc7957U, 0x6fde7f5fU, + 0x70e03da7U, 0x71e23bafU, 0x72e431b7U, 0x73e637bfU, + 0x74e82587U, 0x75ea238fU, 0x76ec2997U, 0x77ee2f9fU, + 0x78f00de7U, 0x79f20befU, 0x7af401f7U, 0x7bf607ffU, + 0x7cf815c7U, 0x7dfa13cfU, 0x7efc19d7U, 0x7ffe1fdfU, + 0x801d2774U, 0x811f217cU, 0x82192b64U, 0x831b2d6cU, + 0x84153f54U, 0x8517395cU, 0x86113344U, 0x8713354cU, + 0x880d1734U, 0x890f113cU, 0x8a091b24U, 0x8b0b1d2cU, + 0x8c050f14U, 0x8d07091cU, 0x8e010304U, 0x8f03050cU, + 0x903d47f4U, 0x913f41fcU, 0x92394be4U, 0x933b4decU, + 0x94355fd4U, 0x953759dcU, 0x963153c4U, 0x973355ccU, + 0x982d77b4U, 0x992f71bcU, 0x9a297ba4U, 0x9b2b7dacU, + 0x9c256f94U, 0x9d27699cU, 0x9e216384U, 0x9f23658cU, + 0xa05de769U, 0xa15fe161U, 0xa259eb79U, 0xa35bed71U, + 0xa455ff49U, 0xa557f941U, 0xa651f359U, 0xa753f551U, + 0xa84dd729U, 0xa94fd121U, 0xaa49db39U, 0xab4bdd31U, + 0xac45cf09U, 0xad47c901U, 0xae41c319U, 0xaf43c511U, + 0xb07d87e9U, 0xb17f81e1U, 0xb2798bf9U, 0xb37b8df1U, + 0xb4759fc9U, 0xb57799c1U, 0xb67193d9U, 0xb77395d1U, + 0xb86db7a9U, 0xb96fb1a1U, 0xba69bbb9U, 0xbb6bbdb1U, + 0xbc65af89U, 0xbd67a981U, 0xbe61a399U, 0xbf63a591U, + 0xc09dba4eU, 0xc19fbc46U, 0xc299b65eU, 0xc39bb056U, + 0xc495a26eU, 0xc597a466U, 0xc691ae7eU, 0xc793a876U, + 0xc88d8a0eU, 0xc98f8c06U, 0xca89861eU, 0xcb8b8016U, + 0xcc85922eU, 0xcd879426U, 0xce819e3eU, 0xcf839836U, + 0xd0bddaceU, 0xd1bfdcc6U, 0xd2b9d6deU, 0xd3bbd0d6U, + 0xd4b5c2eeU, 0xd5b7c4e6U, 0xd6b1cefeU, 0xd7b3c8f6U, + 0xd8adea8eU, 0xd9afec86U, 0xdaa9e69eU, 0xdbabe096U, + 0xdca5f2aeU, 0xdda7f4a6U, 0xdea1febeU, 0xdfa3f8b6U, + 0xe0dd7a53U, 0xe1df7c5bU, 0xe2d97643U, 0xe3db704bU, + 0xe4d56273U, 0xe5d7647bU, 0xe6d16e63U, 0xe7d3686bU, + 0xe8cd4a13U, 0xe9cf4c1bU, 0xeac94603U, 0xebcb400bU, + 0xecc55233U, 0xedc7543bU, 0xeec15e23U, 0xefc3582bU, + 0xf0fd1ad3U, 0xf1ff1cdbU, 0xf2f916c3U, 0xf3fb10cbU, + 0xf4f502f3U, 0xf5f704fbU, 0xf6f10ee3U, 0xf7f308ebU, + 0xf8ed2a93U, 0xf9ef2c9bU, 0xfae92683U, 0xfbeb208bU, + 0xfce532b3U, 0xfde734bbU, 0xfee13ea3U, 0xffe338abU, +}; + +/** + * The round constants. + */ +static const ulong32 rc[] = { + 0xa7d3e671U, 0xd0ac4d79U, 0x3ac991fcU, 0x1e4754bdU, + 0x8ca57afbU, 0x63b8ddd4U, 0xe5b3c5beU, 0xa9880ca2U, + 0x39df29daU, 0x2ba8cb4cU, 0x4b22aa24U, 0x4170a6f9U, + 0x5ae2b036U, 0x7de433ffU, 0x6020088bU, 0x5eab7f78U, + 0x7c2c57d2U, 0xdc6d7e0dU, 0x5394c328U, +}; + +#endif + + /** + Initialize the Anubis block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +#ifdef LTC_CLEAN_STACK +static int _anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#else +int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#endif +{ + int N, R, i, pos, r; + ulong32 kappa[MAX_N]; + ulong32 inter[MAX_N]; + ulong32 v, K0, K1, K2, K3; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + /* Valid sizes (in bytes) are 16, 20, 24, 28, 32, 36, and 40. */ + if ((keylen & 3) || (keylen < 16) || (keylen > 40)) { + return CRYPT_INVALID_KEYSIZE; + } + skey->anubis.keyBits = keylen*8; + + /* + * determine the N length parameter: + * (N.B. it is assumed that the key length is valid!) + */ + N = skey->anubis.keyBits >> 5; + + /* + * determine number of rounds from key size: + */ + skey->anubis.R = R = 8 + N; + + if (num_rounds != 0 && num_rounds != skey->anubis.R) { + return CRYPT_INVALID_ROUNDS; + } + + /* + * map cipher key to initial key state (mu): + */ + for (i = 0, pos = 0; i < N; i++, pos += 4) { + kappa[i] = + (((ulong32)key[pos ]) << 24) ^ + (((ulong32)key[pos + 1]) << 16) ^ + (((ulong32)key[pos + 2]) << 8) ^ + (((ulong32)key[pos + 3]) ); + } + + /* + * generate R + 1 round keys: + */ + for (r = 0; r <= R; r++) { + /* + * generate r-th round key K^r: + */ + K0 = T4[(kappa[N - 1] >> 24) & 0xff]; + K1 = T4[(kappa[N - 1] >> 16) & 0xff]; + K2 = T4[(kappa[N - 1] >> 8) & 0xff]; + K3 = T4[(kappa[N - 1] ) & 0xff]; + for (i = N - 2; i >= 0; i--) { + K0 = T4[(kappa[i] >> 24) & 0xff] ^ + (T5[(K0 >> 24) & 0xff] & 0xff000000U) ^ + (T5[(K0 >> 16) & 0xff] & 0x00ff0000U) ^ + (T5[(K0 >> 8) & 0xff] & 0x0000ff00U) ^ + (T5[(K0 ) & 0xff] & 0x000000ffU); + K1 = T4[(kappa[i] >> 16) & 0xff] ^ + (T5[(K1 >> 24) & 0xff] & 0xff000000U) ^ + (T5[(K1 >> 16) & 0xff] & 0x00ff0000U) ^ + (T5[(K1 >> 8) & 0xff] & 0x0000ff00U) ^ + (T5[(K1 ) & 0xff] & 0x000000ffU); + K2 = T4[(kappa[i] >> 8) & 0xff] ^ + (T5[(K2 >> 24) & 0xff] & 0xff000000U) ^ + (T5[(K2 >> 16) & 0xff] & 0x00ff0000U) ^ + (T5[(K2 >> 8) & 0xff] & 0x0000ff00U) ^ + (T5[(K2 ) & 0xff] & 0x000000ffU); + K3 = T4[(kappa[i] ) & 0xff] ^ + (T5[(K3 >> 24) & 0xff] & 0xff000000U) ^ + (T5[(K3 >> 16) & 0xff] & 0x00ff0000U) ^ + (T5[(K3 >> 8) & 0xff] & 0x0000ff00U) ^ + (T5[(K3 ) & 0xff] & 0x000000ffU); + } + /* + -- this is the code to use with the large U tables: + K0 = K1 = K2 = K3 = 0; + for (i = 0; i < N; i++) { + K0 ^= U[i][(kappa[i] >> 24) & 0xff]; + K1 ^= U[i][(kappa[i] >> 16) & 0xff]; + K2 ^= U[i][(kappa[i] >> 8) & 0xff]; + K3 ^= U[i][(kappa[i] ) & 0xff]; + } + */ + skey->anubis.roundKeyEnc[r][0] = K0; + skey->anubis.roundKeyEnc[r][1] = K1; + skey->anubis.roundKeyEnc[r][2] = K2; + skey->anubis.roundKeyEnc[r][3] = K3; + + /* + * compute kappa^{r+1} from kappa^r: + */ + if (r == R) { + break; + } + for (i = 0; i < N; i++) { + int j = i; + inter[i] = T0[(kappa[j--] >> 24) & 0xff]; if (j < 0) j = N - 1; + inter[i] ^= T1[(kappa[j--] >> 16) & 0xff]; if (j < 0) j = N - 1; + inter[i] ^= T2[(kappa[j--] >> 8) & 0xff]; if (j < 0) j = N - 1; + inter[i] ^= T3[(kappa[j ] ) & 0xff]; + } + kappa[0] = inter[0] ^ rc[r]; + for (i = 1; i < N; i++) { + kappa[i] = inter[i]; + } + } + + /* + * generate inverse key schedule: K'^0 = K^R, K'^R = K^0, K'^r = theta(K^{R-r}): + */ + for (i = 0; i < 4; i++) { + skey->anubis.roundKeyDec[0][i] = skey->anubis.roundKeyEnc[R][i]; + skey->anubis.roundKeyDec[R][i] = skey->anubis.roundKeyEnc[0][i]; + } + for (r = 1; r < R; r++) { + for (i = 0; i < 4; i++) { + v = skey->anubis.roundKeyEnc[R - r][i]; + skey->anubis.roundKeyDec[r][i] = + T0[T4[(v >> 24) & 0xff] & 0xff] ^ + T1[T4[(v >> 16) & 0xff] & 0xff] ^ + T2[T4[(v >> 8) & 0xff] & 0xff] ^ + T3[T4[(v ) & 0xff] & 0xff]; + } + } + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int err; + err = _anubis_setup(key, keylen, num_rounds, skey); + burn_stack(sizeof(int) * 5 + sizeof(ulong32) * (MAX_N + MAX_N + 5)); + return err; +} +#endif + + +static void anubis_crypt(const unsigned char *plaintext, unsigned char *ciphertext, + ulong32 roundKey[18 + 1][4], int R) { + int i, pos, r; + ulong32 state[4]; + ulong32 inter[4]; + + /* + * map plaintext block to cipher state (mu) + * and add initial round key (sigma[K^0]): + */ + for (i = 0, pos = 0; i < 4; i++, pos += 4) { + state[i] = + (((ulong32)plaintext[pos ]) << 24) ^ + (((ulong32)plaintext[pos + 1]) << 16) ^ + (((ulong32)plaintext[pos + 2]) << 8) ^ + (((ulong32)plaintext[pos + 3]) ) ^ + roundKey[0][i]; + } + + /* + * R - 1 full rounds: + */ + for (r = 1; r < R; r++) { + inter[0] = + T0[(state[0] >> 24) & 0xff] ^ + T1[(state[1] >> 24) & 0xff] ^ + T2[(state[2] >> 24) & 0xff] ^ + T3[(state[3] >> 24) & 0xff] ^ + roundKey[r][0]; + inter[1] = + T0[(state[0] >> 16) & 0xff] ^ + T1[(state[1] >> 16) & 0xff] ^ + T2[(state[2] >> 16) & 0xff] ^ + T3[(state[3] >> 16) & 0xff] ^ + roundKey[r][1]; + inter[2] = + T0[(state[0] >> 8) & 0xff] ^ + T1[(state[1] >> 8) & 0xff] ^ + T2[(state[2] >> 8) & 0xff] ^ + T3[(state[3] >> 8) & 0xff] ^ + roundKey[r][2]; + inter[3] = + T0[(state[0] ) & 0xff] ^ + T1[(state[1] ) & 0xff] ^ + T2[(state[2] ) & 0xff] ^ + T3[(state[3] ) & 0xff] ^ + roundKey[r][3]; + state[0] = inter[0]; + state[1] = inter[1]; + state[2] = inter[2]; + state[3] = inter[3]; + } + + /* + * last round: + */ + inter[0] = + (T0[(state[0] >> 24) & 0xff] & 0xff000000U) ^ + (T1[(state[1] >> 24) & 0xff] & 0x00ff0000U) ^ + (T2[(state[2] >> 24) & 0xff] & 0x0000ff00U) ^ + (T3[(state[3] >> 24) & 0xff] & 0x000000ffU) ^ + roundKey[R][0]; + inter[1] = + (T0[(state[0] >> 16) & 0xff] & 0xff000000U) ^ + (T1[(state[1] >> 16) & 0xff] & 0x00ff0000U) ^ + (T2[(state[2] >> 16) & 0xff] & 0x0000ff00U) ^ + (T3[(state[3] >> 16) & 0xff] & 0x000000ffU) ^ + roundKey[R][1]; + inter[2] = + (T0[(state[0] >> 8) & 0xff] & 0xff000000U) ^ + (T1[(state[1] >> 8) & 0xff] & 0x00ff0000U) ^ + (T2[(state[2] >> 8) & 0xff] & 0x0000ff00U) ^ + (T3[(state[3] >> 8) & 0xff] & 0x000000ffU) ^ + roundKey[R][2]; + inter[3] = + (T0[(state[0] ) & 0xff] & 0xff000000U) ^ + (T1[(state[1] ) & 0xff] & 0x00ff0000U) ^ + (T2[(state[2] ) & 0xff] & 0x0000ff00U) ^ + (T3[(state[3] ) & 0xff] & 0x000000ffU) ^ + roundKey[R][3]; + + /* + * map cipher state to ciphertext block (mu^{-1}): + */ + for (i = 0, pos = 0; i < 4; i++, pos += 4) { + ulong32 w = inter[i]; + ciphertext[pos ] = (unsigned char)(w >> 24); + ciphertext[pos + 1] = (unsigned char)(w >> 16); + ciphertext[pos + 2] = (unsigned char)(w >> 8); + ciphertext[pos + 3] = (unsigned char)(w ); + } +} + +/** + Encrypts a block of text with Anubis + @param pt The input plaintext (16 bytes) + @param ct The output ciphertext (16 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + anubis_crypt(pt, ct, skey->anubis.roundKeyEnc, skey->anubis.R); + return CRYPT_OK; +} + +/** + Decrypts a block of text with Anubis + @param ct The input ciphertext (16 bytes) + @param pt The output plaintext (16 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + anubis_crypt(ct, pt, skey->anubis.roundKeyDec, skey->anubis.R); + return CRYPT_OK; +} + +/** + Performs a self-test of the Anubis block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int anubis_test(void) +{ +#if !defined(LTC_TEST) + return CRYPT_NOP; +#else + static const struct test { + int keylen; + unsigned char pt[16], ct[16], key[40]; + } tests[] = { +#ifndef LTC_ANUBIS_TWEAK + /**** ORIGINAL LTC_ANUBIS ****/ + /* 128 bit keys */ +{ + 16, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xF0, 0x68, 0x60, 0xFC, 0x67, 0x30, 0xE8, 0x18, + 0xF1, 0x32, 0xC7, 0x8A, 0xF4, 0x13, 0x2A, 0xFE }, + { 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 }, + { 0xA8, 0x66, 0x84, 0x80, 0x07, 0x74, 0x5C, 0x89, + 0xFC, 0x5E, 0xB5, 0xBA, 0xD4, 0xFE, 0x32, 0x6D }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } +}, + + /* 160-bit keys */ +{ + 20, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xBD, 0x5E, 0x32, 0xBE, 0x51, 0x67, 0xA8, 0xE2, + 0x72, 0xD7, 0x95, 0x0F, 0x83, 0xC6, 0x8C, 0x31 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 } +}, { + 20, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x4C, 0x1F, 0x86, 0x2E, 0x11, 0xEB, 0xCE, 0xEB, + 0xFE, 0xB9, 0x73, 0xC9, 0xDF, 0xEF, 0x7A, 0xDB }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01 } +}, + + /* 192-bit keys */ +{ + 24, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x17, 0xAC, 0x57, 0x44, 0x9D, 0x59, 0x61, 0x66, + 0xD0, 0xC7, 0x9E, 0x04, 0x7C, 0xC7, 0x58, 0xF0 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}, { + 24, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x71, 0x52, 0xB4, 0xEB, 0x1D, 0xAA, 0x36, 0xFD, + 0x57, 0x14, 0x5F, 0x57, 0x04, 0x9F, 0x70, 0x74 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } +}, + + /* 224-bit keys */ +{ + 28, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xA2, 0xF0, 0xA6, 0xB9, 0x17, 0x93, 0x2A, 0x3B, + 0xEF, 0x08, 0xE8, 0x7A, 0x58, 0xD6, 0xF8, 0x53 }, + { 0x80, 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 } +}, { + 28, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xF0, 0xCA, 0xFC, 0x78, 0x8B, 0x4B, 0x4E, 0x53, + 0x8B, 0xC4, 0x32, 0x6A, 0xF5, 0xB9, 0x1B, 0x5F }, + { 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 } +}, + + /* 256-bit keys */ +{ + 32, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xE0, 0x86, 0xAC, 0x45, 0x6B, 0x3C, 0xE5, 0x13, + 0xED, 0xF5, 0xDF, 0xDD, 0xD6, 0x3B, 0x71, 0x93 }, + { 0x80, 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 } +}, { + 32, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x50, 0x01, 0xB9, 0xF5, 0x21, 0xC1, 0xC1, 0x29, + 0x00, 0xD5, 0xEC, 0x98, 0x2B, 0x9E, 0xE8, 0x21 }, + { 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 } +}, + + /* 288-bit keys */ +{ + 36, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xE8, 0xF4, 0xAF, 0x2B, 0x21, 0xA0, 0x87, 0x9B, + 0x41, 0x95, 0xB9, 0x71, 0x75, 0x79, 0x04, 0x7C }, + { 0x80, 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 } +}, { + 36, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xE6, 0xA6, 0xA5, 0xBC, 0x8B, 0x63, 0x6F, 0xE2, + 0xBD, 0xA7, 0xA7, 0x53, 0xAB, 0x40, 0x22, 0xE0 }, + { 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 } +}, + + /* 320-bit keys */ +{ + 40, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x17, 0x04, 0xD7, 0x2C, 0xC6, 0x85, 0x76, 0x02, + 0x4B, 0xCC, 0x39, 0x80, 0xD8, 0x22, 0xEA, 0xA4 }, + { 0x80, 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 } +}, { + 40, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x7A, 0x41, 0xE6, 0x7D, 0x4F, 0xD8, 0x64, 0xF0, + 0x44, 0xA8, 0x3C, 0x73, 0x81, 0x7E, 0x53, 0xD8 }, + { 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 } +} +#else + /**** Tweaked LTC_ANUBIS ****/ + /* 128 bit keys */ +{ + 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 }, + { 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 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } +}, + + /* 160-bit keys */ +{ + 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 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 } +}, { + 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 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01 } +}, + + /* 192-bit keys */ +{ + 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 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}, { + 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 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } +}, + + /* 224-bit keys */ +{ + 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 }, + { 0x80, 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 } +}, { + 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 }, + { 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 } +}, + + /* 256-bit keys */ +{ + 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 }, + { 0x80, 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 } +}, { + 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 }, + { 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 } +}, + + /* 288-bit keys */ +{ + 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 }, + { 0x80, 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 } +}, { + 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 }, + { 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 } +}, + + /* 320-bit keys */ +{ + 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 }, + { 0x80, 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 } +}, { + 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 }, + { 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 +}; + int x, y; + unsigned char buf[2][16]; + symmetric_key skey; + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + anubis_setup(tests[x].key, tests[x].keylen, 0, &skey); + anubis_ecb_encrypt(tests[x].pt, buf[0], &skey); + anubis_ecb_decrypt(buf[0], buf[1], &skey); + if (XMEMCMP(buf[0], tests[x].ct, 16) || XMEMCMP(buf[1], tests[x].pt, 16)) { + return CRYPT_FAIL_TESTVECTOR; + } + + for (y = 0; y < 1000; y++) anubis_ecb_encrypt(buf[0], buf[0], &skey); + for (y = 0; y < 1000; y++) anubis_ecb_decrypt(buf[0], buf[0], &skey); + if (XMEMCMP(buf[0], tests[x].ct, 16)) { + return CRYPT_FAIL_TESTVECTOR; + } + + } + return CRYPT_OK; +#endif +} + +/** Terminate the context + @param skey The scheduled key +*/ +void anubis_done(symmetric_key *skey) +{ + LTC_UNUSED_PARAM(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. + @return CRYPT_OK if the input key size is acceptable. +*/ +int anubis_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if (*keysize >= 40) { + *keysize = 40; + } else if (*keysize >= 36) { + *keysize = 36; + } else if (*keysize >= 32) { + *keysize = 32; + } else if (*keysize >= 28) { + *keysize = 28; + } else if (*keysize >= 24) { + *keysize = 24; + } else if (*keysize >= 20) { + *keysize = 20; + } else if (*keysize >= 16) { + *keysize = 16; + } else { + return CRYPT_INVALID_KEYSIZE; + } + return CRYPT_OK; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/ciphers/blowfish.c b/src/ltc/ciphers/blowfish.c new file mode 100644 index 0000000..9a78733 --- /dev/null +++ b/src/ltc/ciphers/blowfish.c @@ -0,0 +1,595 @@ +/* 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://libtom.org + */ +/** + @file blowfish.c + Implementation of the Blowfish block cipher, Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_BLOWFISH + +const struct ltc_cipher_descriptor blowfish_desc = +{ + "blowfish", + 0, + 8, 56, 8, 16, + &blowfish_setup, + &blowfish_ecb_encrypt, + &blowfish_ecb_decrypt, + &blowfish_test, + &blowfish_done, + &blowfish_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +static const ulong32 ORIG_P[16 + 2] = { + 0x243F6A88UL, 0x85A308D3UL, 0x13198A2EUL, 0x03707344UL, + 0xA4093822UL, 0x299F31D0UL, 0x082EFA98UL, 0xEC4E6C89UL, + 0x452821E6UL, 0x38D01377UL, 0xBE5466CFUL, 0x34E90C6CUL, + 0xC0AC29B7UL, 0xC97C50DDUL, 0x3F84D5B5UL, 0xB5470917UL, + 0x9216D5D9UL, 0x8979FB1BUL +}; + +static const ulong32 ORIG_S[4][256] = { + { 0xD1310BA6UL, 0x98DFB5ACUL, 0x2FFD72DBUL, 0xD01ADFB7UL, + 0xB8E1AFEDUL, 0x6A267E96UL, 0xBA7C9045UL, 0xF12C7F99UL, + 0x24A19947UL, 0xB3916CF7UL, 0x0801F2E2UL, 0x858EFC16UL, + 0x636920D8UL, 0x71574E69UL, 0xA458FEA3UL, 0xF4933D7EUL, + 0x0D95748FUL, 0x728EB658UL, 0x718BCD58UL, 0x82154AEEUL, + 0x7B54A41DUL, 0xC25A59B5UL, 0x9C30D539UL, 0x2AF26013UL, + 0xC5D1B023UL, 0x286085F0UL, 0xCA417918UL, 0xB8DB38EFUL, + 0x8E79DCB0UL, 0x603A180EUL, 0x6C9E0E8BUL, 0xB01E8A3EUL, + 0xD71577C1UL, 0xBD314B27UL, 0x78AF2FDAUL, 0x55605C60UL, + 0xE65525F3UL, 0xAA55AB94UL, 0x57489862UL, 0x63E81440UL, + 0x55CA396AUL, 0x2AAB10B6UL, 0xB4CC5C34UL, 0x1141E8CEUL, + 0xA15486AFUL, 0x7C72E993UL, 0xB3EE1411UL, 0x636FBC2AUL, + 0x2BA9C55DUL, 0x741831F6UL, 0xCE5C3E16UL, 0x9B87931EUL, + 0xAFD6BA33UL, 0x6C24CF5CUL, 0x7A325381UL, 0x28958677UL, + 0x3B8F4898UL, 0x6B4BB9AFUL, 0xC4BFE81BUL, 0x66282193UL, + 0x61D809CCUL, 0xFB21A991UL, 0x487CAC60UL, 0x5DEC8032UL, + 0xEF845D5DUL, 0xE98575B1UL, 0xDC262302UL, 0xEB651B88UL, + 0x23893E81UL, 0xD396ACC5UL, 0x0F6D6FF3UL, 0x83F44239UL, + 0x2E0B4482UL, 0xA4842004UL, 0x69C8F04AUL, 0x9E1F9B5EUL, + 0x21C66842UL, 0xF6E96C9AUL, 0x670C9C61UL, 0xABD388F0UL, + 0x6A51A0D2UL, 0xD8542F68UL, 0x960FA728UL, 0xAB5133A3UL, + 0x6EEF0B6CUL, 0x137A3BE4UL, 0xBA3BF050UL, 0x7EFB2A98UL, + 0xA1F1651DUL, 0x39AF0176UL, 0x66CA593EUL, 0x82430E88UL, + 0x8CEE8619UL, 0x456F9FB4UL, 0x7D84A5C3UL, 0x3B8B5EBEUL, + 0xE06F75D8UL, 0x85C12073UL, 0x401A449FUL, 0x56C16AA6UL, + 0x4ED3AA62UL, 0x363F7706UL, 0x1BFEDF72UL, 0x429B023DUL, + 0x37D0D724UL, 0xD00A1248UL, 0xDB0FEAD3UL, 0x49F1C09BUL, + 0x075372C9UL, 0x80991B7BUL, 0x25D479D8UL, 0xF6E8DEF7UL, + 0xE3FE501AUL, 0xB6794C3BUL, 0x976CE0BDUL, 0x04C006BAUL, + 0xC1A94FB6UL, 0x409F60C4UL, 0x5E5C9EC2UL, 0x196A2463UL, + 0x68FB6FAFUL, 0x3E6C53B5UL, 0x1339B2EBUL, 0x3B52EC6FUL, + 0x6DFC511FUL, 0x9B30952CUL, 0xCC814544UL, 0xAF5EBD09UL, + 0xBEE3D004UL, 0xDE334AFDUL, 0x660F2807UL, 0x192E4BB3UL, + 0xC0CBA857UL, 0x45C8740FUL, 0xD20B5F39UL, 0xB9D3FBDBUL, + 0x5579C0BDUL, 0x1A60320AUL, 0xD6A100C6UL, 0x402C7279UL, + 0x679F25FEUL, 0xFB1FA3CCUL, 0x8EA5E9F8UL, 0xDB3222F8UL, + 0x3C7516DFUL, 0xFD616B15UL, 0x2F501EC8UL, 0xAD0552ABUL, + 0x323DB5FAUL, 0xFD238760UL, 0x53317B48UL, 0x3E00DF82UL, + 0x9E5C57BBUL, 0xCA6F8CA0UL, 0x1A87562EUL, 0xDF1769DBUL, + 0xD542A8F6UL, 0x287EFFC3UL, 0xAC6732C6UL, 0x8C4F5573UL, + 0x695B27B0UL, 0xBBCA58C8UL, 0xE1FFA35DUL, 0xB8F011A0UL, + 0x10FA3D98UL, 0xFD2183B8UL, 0x4AFCB56CUL, 0x2DD1D35BUL, + 0x9A53E479UL, 0xB6F84565UL, 0xD28E49BCUL, 0x4BFB9790UL, + 0xE1DDF2DAUL, 0xA4CB7E33UL, 0x62FB1341UL, 0xCEE4C6E8UL, + 0xEF20CADAUL, 0x36774C01UL, 0xD07E9EFEUL, 0x2BF11FB4UL, + 0x95DBDA4DUL, 0xAE909198UL, 0xEAAD8E71UL, 0x6B93D5A0UL, + 0xD08ED1D0UL, 0xAFC725E0UL, 0x8E3C5B2FUL, 0x8E7594B7UL, + 0x8FF6E2FBUL, 0xF2122B64UL, 0x8888B812UL, 0x900DF01CUL, + 0x4FAD5EA0UL, 0x688FC31CUL, 0xD1CFF191UL, 0xB3A8C1ADUL, + 0x2F2F2218UL, 0xBE0E1777UL, 0xEA752DFEUL, 0x8B021FA1UL, + 0xE5A0CC0FUL, 0xB56F74E8UL, 0x18ACF3D6UL, 0xCE89E299UL, + 0xB4A84FE0UL, 0xFD13E0B7UL, 0x7CC43B81UL, 0xD2ADA8D9UL, + 0x165FA266UL, 0x80957705UL, 0x93CC7314UL, 0x211A1477UL, + 0xE6AD2065UL, 0x77B5FA86UL, 0xC75442F5UL, 0xFB9D35CFUL, + 0xEBCDAF0CUL, 0x7B3E89A0UL, 0xD6411BD3UL, 0xAE1E7E49UL, + 0x00250E2DUL, 0x2071B35EUL, 0x226800BBUL, 0x57B8E0AFUL, + 0x2464369BUL, 0xF009B91EUL, 0x5563911DUL, 0x59DFA6AAUL, + 0x78C14389UL, 0xD95A537FUL, 0x207D5BA2UL, 0x02E5B9C5UL, + 0x83260376UL, 0x6295CFA9UL, 0x11C81968UL, 0x4E734A41UL, + 0xB3472DCAUL, 0x7B14A94AUL, 0x1B510052UL, 0x9A532915UL, + 0xD60F573FUL, 0xBC9BC6E4UL, 0x2B60A476UL, 0x81E67400UL, + 0x08BA6FB5UL, 0x571BE91FUL, 0xF296EC6BUL, 0x2A0DD915UL, + 0xB6636521UL, 0xE7B9F9B6UL, 0xFF34052EUL, 0xC5855664UL, + 0x53B02D5DUL, 0xA99F8FA1UL, 0x08BA4799UL, 0x6E85076AUL }, + { 0x4B7A70E9UL, 0xB5B32944UL, 0xDB75092EUL, 0xC4192623UL, + 0xAD6EA6B0UL, 0x49A7DF7DUL, 0x9CEE60B8UL, 0x8FEDB266UL, + 0xECAA8C71UL, 0x699A17FFUL, 0x5664526CUL, 0xC2B19EE1UL, + 0x193602A5UL, 0x75094C29UL, 0xA0591340UL, 0xE4183A3EUL, + 0x3F54989AUL, 0x5B429D65UL, 0x6B8FE4D6UL, 0x99F73FD6UL, + 0xA1D29C07UL, 0xEFE830F5UL, 0x4D2D38E6UL, 0xF0255DC1UL, + 0x4CDD2086UL, 0x8470EB26UL, 0x6382E9C6UL, 0x021ECC5EUL, + 0x09686B3FUL, 0x3EBAEFC9UL, 0x3C971814UL, 0x6B6A70A1UL, + 0x687F3584UL, 0x52A0E286UL, 0xB79C5305UL, 0xAA500737UL, + 0x3E07841CUL, 0x7FDEAE5CUL, 0x8E7D44ECUL, 0x5716F2B8UL, + 0xB03ADA37UL, 0xF0500C0DUL, 0xF01C1F04UL, 0x0200B3FFUL, + 0xAE0CF51AUL, 0x3CB574B2UL, 0x25837A58UL, 0xDC0921BDUL, + 0xD19113F9UL, 0x7CA92FF6UL, 0x94324773UL, 0x22F54701UL, + 0x3AE5E581UL, 0x37C2DADCUL, 0xC8B57634UL, 0x9AF3DDA7UL, + 0xA9446146UL, 0x0FD0030EUL, 0xECC8C73EUL, 0xA4751E41UL, + 0xE238CD99UL, 0x3BEA0E2FUL, 0x3280BBA1UL, 0x183EB331UL, + 0x4E548B38UL, 0x4F6DB908UL, 0x6F420D03UL, 0xF60A04BFUL, + 0x2CB81290UL, 0x24977C79UL, 0x5679B072UL, 0xBCAF89AFUL, + 0xDE9A771FUL, 0xD9930810UL, 0xB38BAE12UL, 0xDCCF3F2EUL, + 0x5512721FUL, 0x2E6B7124UL, 0x501ADDE6UL, 0x9F84CD87UL, + 0x7A584718UL, 0x7408DA17UL, 0xBC9F9ABCUL, 0xE94B7D8CUL, + 0xEC7AEC3AUL, 0xDB851DFAUL, 0x63094366UL, 0xC464C3D2UL, + 0xEF1C1847UL, 0x3215D908UL, 0xDD433B37UL, 0x24C2BA16UL, + 0x12A14D43UL, 0x2A65C451UL, 0x50940002UL, 0x133AE4DDUL, + 0x71DFF89EUL, 0x10314E55UL, 0x81AC77D6UL, 0x5F11199BUL, + 0x043556F1UL, 0xD7A3C76BUL, 0x3C11183BUL, 0x5924A509UL, + 0xF28FE6EDUL, 0x97F1FBFAUL, 0x9EBABF2CUL, 0x1E153C6EUL, + 0x86E34570UL, 0xEAE96FB1UL, 0x860E5E0AUL, 0x5A3E2AB3UL, + 0x771FE71CUL, 0x4E3D06FAUL, 0x2965DCB9UL, 0x99E71D0FUL, + 0x803E89D6UL, 0x5266C825UL, 0x2E4CC978UL, 0x9C10B36AUL, + 0xC6150EBAUL, 0x94E2EA78UL, 0xA5FC3C53UL, 0x1E0A2DF4UL, + 0xF2F74EA7UL, 0x361D2B3DUL, 0x1939260FUL, 0x19C27960UL, + 0x5223A708UL, 0xF71312B6UL, 0xEBADFE6EUL, 0xEAC31F66UL, + 0xE3BC4595UL, 0xA67BC883UL, 0xB17F37D1UL, 0x018CFF28UL, + 0xC332DDEFUL, 0xBE6C5AA5UL, 0x65582185UL, 0x68AB9802UL, + 0xEECEA50FUL, 0xDB2F953BUL, 0x2AEF7DADUL, 0x5B6E2F84UL, + 0x1521B628UL, 0x29076170UL, 0xECDD4775UL, 0x619F1510UL, + 0x13CCA830UL, 0xEB61BD96UL, 0x0334FE1EUL, 0xAA0363CFUL, + 0xB5735C90UL, 0x4C70A239UL, 0xD59E9E0BUL, 0xCBAADE14UL, + 0xEECC86BCUL, 0x60622CA7UL, 0x9CAB5CABUL, 0xB2F3846EUL, + 0x648B1EAFUL, 0x19BDF0CAUL, 0xA02369B9UL, 0x655ABB50UL, + 0x40685A32UL, 0x3C2AB4B3UL, 0x319EE9D5UL, 0xC021B8F7UL, + 0x9B540B19UL, 0x875FA099UL, 0x95F7997EUL, 0x623D7DA8UL, + 0xF837889AUL, 0x97E32D77UL, 0x11ED935FUL, 0x16681281UL, + 0x0E358829UL, 0xC7E61FD6UL, 0x96DEDFA1UL, 0x7858BA99UL, + 0x57F584A5UL, 0x1B227263UL, 0x9B83C3FFUL, 0x1AC24696UL, + 0xCDB30AEBUL, 0x532E3054UL, 0x8FD948E4UL, 0x6DBC3128UL, + 0x58EBF2EFUL, 0x34C6FFEAUL, 0xFE28ED61UL, 0xEE7C3C73UL, + 0x5D4A14D9UL, 0xE864B7E3UL, 0x42105D14UL, 0x203E13E0UL, + 0x45EEE2B6UL, 0xA3AAABEAUL, 0xDB6C4F15UL, 0xFACB4FD0UL, + 0xC742F442UL, 0xEF6ABBB5UL, 0x654F3B1DUL, 0x41CD2105UL, + 0xD81E799EUL, 0x86854DC7UL, 0xE44B476AUL, 0x3D816250UL, + 0xCF62A1F2UL, 0x5B8D2646UL, 0xFC8883A0UL, 0xC1C7B6A3UL, + 0x7F1524C3UL, 0x69CB7492UL, 0x47848A0BUL, 0x5692B285UL, + 0x095BBF00UL, 0xAD19489DUL, 0x1462B174UL, 0x23820E00UL, + 0x58428D2AUL, 0x0C55F5EAUL, 0x1DADF43EUL, 0x233F7061UL, + 0x3372F092UL, 0x8D937E41UL, 0xD65FECF1UL, 0x6C223BDBUL, + 0x7CDE3759UL, 0xCBEE7460UL, 0x4085F2A7UL, 0xCE77326EUL, + 0xA6078084UL, 0x19F8509EUL, 0xE8EFD855UL, 0x61D99735UL, + 0xA969A7AAUL, 0xC50C06C2UL, 0x5A04ABFCUL, 0x800BCADCUL, + 0x9E447A2EUL, 0xC3453484UL, 0xFDD56705UL, 0x0E1E9EC9UL, + 0xDB73DBD3UL, 0x105588CDUL, 0x675FDA79UL, 0xE3674340UL, + 0xC5C43465UL, 0x713E38D8UL, 0x3D28F89EUL, 0xF16DFF20UL, + 0x153E21E7UL, 0x8FB03D4AUL, 0xE6E39F2BUL, 0xDB83ADF7UL }, + { 0xE93D5A68UL, 0x948140F7UL, 0xF64C261CUL, 0x94692934UL, + 0x411520F7UL, 0x7602D4F7UL, 0xBCF46B2EUL, 0xD4A20068UL, + 0xD4082471UL, 0x3320F46AUL, 0x43B7D4B7UL, 0x500061AFUL, + 0x1E39F62EUL, 0x97244546UL, 0x14214F74UL, 0xBF8B8840UL, + 0x4D95FC1DUL, 0x96B591AFUL, 0x70F4DDD3UL, 0x66A02F45UL, + 0xBFBC09ECUL, 0x03BD9785UL, 0x7FAC6DD0UL, 0x31CB8504UL, + 0x96EB27B3UL, 0x55FD3941UL, 0xDA2547E6UL, 0xABCA0A9AUL, + 0x28507825UL, 0x530429F4UL, 0x0A2C86DAUL, 0xE9B66DFBUL, + 0x68DC1462UL, 0xD7486900UL, 0x680EC0A4UL, 0x27A18DEEUL, + 0x4F3FFEA2UL, 0xE887AD8CUL, 0xB58CE006UL, 0x7AF4D6B6UL, + 0xAACE1E7CUL, 0xD3375FECUL, 0xCE78A399UL, 0x406B2A42UL, + 0x20FE9E35UL, 0xD9F385B9UL, 0xEE39D7ABUL, 0x3B124E8BUL, + 0x1DC9FAF7UL, 0x4B6D1856UL, 0x26A36631UL, 0xEAE397B2UL, + 0x3A6EFA74UL, 0xDD5B4332UL, 0x6841E7F7UL, 0xCA7820FBUL, + 0xFB0AF54EUL, 0xD8FEB397UL, 0x454056ACUL, 0xBA489527UL, + 0x55533A3AUL, 0x20838D87UL, 0xFE6BA9B7UL, 0xD096954BUL, + 0x55A867BCUL, 0xA1159A58UL, 0xCCA92963UL, 0x99E1DB33UL, + 0xA62A4A56UL, 0x3F3125F9UL, 0x5EF47E1CUL, 0x9029317CUL, + 0xFDF8E802UL, 0x04272F70UL, 0x80BB155CUL, 0x05282CE3UL, + 0x95C11548UL, 0xE4C66D22UL, 0x48C1133FUL, 0xC70F86DCUL, + 0x07F9C9EEUL, 0x41041F0FUL, 0x404779A4UL, 0x5D886E17UL, + 0x325F51EBUL, 0xD59BC0D1UL, 0xF2BCC18FUL, 0x41113564UL, + 0x257B7834UL, 0x602A9C60UL, 0xDFF8E8A3UL, 0x1F636C1BUL, + 0x0E12B4C2UL, 0x02E1329EUL, 0xAF664FD1UL, 0xCAD18115UL, + 0x6B2395E0UL, 0x333E92E1UL, 0x3B240B62UL, 0xEEBEB922UL, + 0x85B2A20EUL, 0xE6BA0D99UL, 0xDE720C8CUL, 0x2DA2F728UL, + 0xD0127845UL, 0x95B794FDUL, 0x647D0862UL, 0xE7CCF5F0UL, + 0x5449A36FUL, 0x877D48FAUL, 0xC39DFD27UL, 0xF33E8D1EUL, + 0x0A476341UL, 0x992EFF74UL, 0x3A6F6EABUL, 0xF4F8FD37UL, + 0xA812DC60UL, 0xA1EBDDF8UL, 0x991BE14CUL, 0xDB6E6B0DUL, + 0xC67B5510UL, 0x6D672C37UL, 0x2765D43BUL, 0xDCD0E804UL, + 0xF1290DC7UL, 0xCC00FFA3UL, 0xB5390F92UL, 0x690FED0BUL, + 0x667B9FFBUL, 0xCEDB7D9CUL, 0xA091CF0BUL, 0xD9155EA3UL, + 0xBB132F88UL, 0x515BAD24UL, 0x7B9479BFUL, 0x763BD6EBUL, + 0x37392EB3UL, 0xCC115979UL, 0x8026E297UL, 0xF42E312DUL, + 0x6842ADA7UL, 0xC66A2B3BUL, 0x12754CCCUL, 0x782EF11CUL, + 0x6A124237UL, 0xB79251E7UL, 0x06A1BBE6UL, 0x4BFB6350UL, + 0x1A6B1018UL, 0x11CAEDFAUL, 0x3D25BDD8UL, 0xE2E1C3C9UL, + 0x44421659UL, 0x0A121386UL, 0xD90CEC6EUL, 0xD5ABEA2AUL, + 0x64AF674EUL, 0xDA86A85FUL, 0xBEBFE988UL, 0x64E4C3FEUL, + 0x9DBC8057UL, 0xF0F7C086UL, 0x60787BF8UL, 0x6003604DUL, + 0xD1FD8346UL, 0xF6381FB0UL, 0x7745AE04UL, 0xD736FCCCUL, + 0x83426B33UL, 0xF01EAB71UL, 0xB0804187UL, 0x3C005E5FUL, + 0x77A057BEUL, 0xBDE8AE24UL, 0x55464299UL, 0xBF582E61UL, + 0x4E58F48FUL, 0xF2DDFDA2UL, 0xF474EF38UL, 0x8789BDC2UL, + 0x5366F9C3UL, 0xC8B38E74UL, 0xB475F255UL, 0x46FCD9B9UL, + 0x7AEB2661UL, 0x8B1DDF84UL, 0x846A0E79UL, 0x915F95E2UL, + 0x466E598EUL, 0x20B45770UL, 0x8CD55591UL, 0xC902DE4CUL, + 0xB90BACE1UL, 0xBB8205D0UL, 0x11A86248UL, 0x7574A99EUL, + 0xB77F19B6UL, 0xE0A9DC09UL, 0x662D09A1UL, 0xC4324633UL, + 0xE85A1F02UL, 0x09F0BE8CUL, 0x4A99A025UL, 0x1D6EFE10UL, + 0x1AB93D1DUL, 0x0BA5A4DFUL, 0xA186F20FUL, 0x2868F169UL, + 0xDCB7DA83UL, 0x573906FEUL, 0xA1E2CE9BUL, 0x4FCD7F52UL, + 0x50115E01UL, 0xA70683FAUL, 0xA002B5C4UL, 0x0DE6D027UL, + 0x9AF88C27UL, 0x773F8641UL, 0xC3604C06UL, 0x61A806B5UL, + 0xF0177A28UL, 0xC0F586E0UL, 0x006058AAUL, 0x30DC7D62UL, + 0x11E69ED7UL, 0x2338EA63UL, 0x53C2DD94UL, 0xC2C21634UL, + 0xBBCBEE56UL, 0x90BCB6DEUL, 0xEBFC7DA1UL, 0xCE591D76UL, + 0x6F05E409UL, 0x4B7C0188UL, 0x39720A3DUL, 0x7C927C24UL, + 0x86E3725FUL, 0x724D9DB9UL, 0x1AC15BB4UL, 0xD39EB8FCUL, + 0xED545578UL, 0x08FCA5B5UL, 0xD83D7CD3UL, 0x4DAD0FC4UL, + 0x1E50EF5EUL, 0xB161E6F8UL, 0xA28514D9UL, 0x6C51133CUL, + 0x6FD5C7E7UL, 0x56E14EC4UL, 0x362ABFCEUL, 0xDDC6C837UL, + 0xD79A3234UL, 0x92638212UL, 0x670EFA8EUL, 0x406000E0UL }, + { 0x3A39CE37UL, 0xD3FAF5CFUL, 0xABC27737UL, 0x5AC52D1BUL, + 0x5CB0679EUL, 0x4FA33742UL, 0xD3822740UL, 0x99BC9BBEUL, + 0xD5118E9DUL, 0xBF0F7315UL, 0xD62D1C7EUL, 0xC700C47BUL, + 0xB78C1B6BUL, 0x21A19045UL, 0xB26EB1BEUL, 0x6A366EB4UL, + 0x5748AB2FUL, 0xBC946E79UL, 0xC6A376D2UL, 0x6549C2C8UL, + 0x530FF8EEUL, 0x468DDE7DUL, 0xD5730A1DUL, 0x4CD04DC6UL, + 0x2939BBDBUL, 0xA9BA4650UL, 0xAC9526E8UL, 0xBE5EE304UL, + 0xA1FAD5F0UL, 0x6A2D519AUL, 0x63EF8CE2UL, 0x9A86EE22UL, + 0xC089C2B8UL, 0x43242EF6UL, 0xA51E03AAUL, 0x9CF2D0A4UL, + 0x83C061BAUL, 0x9BE96A4DUL, 0x8FE51550UL, 0xBA645BD6UL, + 0x2826A2F9UL, 0xA73A3AE1UL, 0x4BA99586UL, 0xEF5562E9UL, + 0xC72FEFD3UL, 0xF752F7DAUL, 0x3F046F69UL, 0x77FA0A59UL, + 0x80E4A915UL, 0x87B08601UL, 0x9B09E6ADUL, 0x3B3EE593UL, + 0xE990FD5AUL, 0x9E34D797UL, 0x2CF0B7D9UL, 0x022B8B51UL, + 0x96D5AC3AUL, 0x017DA67DUL, 0xD1CF3ED6UL, 0x7C7D2D28UL, + 0x1F9F25CFUL, 0xADF2B89BUL, 0x5AD6B472UL, 0x5A88F54CUL, + 0xE029AC71UL, 0xE019A5E6UL, 0x47B0ACFDUL, 0xED93FA9BUL, + 0xE8D3C48DUL, 0x283B57CCUL, 0xF8D56629UL, 0x79132E28UL, + 0x785F0191UL, 0xED756055UL, 0xF7960E44UL, 0xE3D35E8CUL, + 0x15056DD4UL, 0x88F46DBAUL, 0x03A16125UL, 0x0564F0BDUL, + 0xC3EB9E15UL, 0x3C9057A2UL, 0x97271AECUL, 0xA93A072AUL, + 0x1B3F6D9BUL, 0x1E6321F5UL, 0xF59C66FBUL, 0x26DCF319UL, + 0x7533D928UL, 0xB155FDF5UL, 0x03563482UL, 0x8ABA3CBBUL, + 0x28517711UL, 0xC20AD9F8UL, 0xABCC5167UL, 0xCCAD925FUL, + 0x4DE81751UL, 0x3830DC8EUL, 0x379D5862UL, 0x9320F991UL, + 0xEA7A90C2UL, 0xFB3E7BCEUL, 0x5121CE64UL, 0x774FBE32UL, + 0xA8B6E37EUL, 0xC3293D46UL, 0x48DE5369UL, 0x6413E680UL, + 0xA2AE0810UL, 0xDD6DB224UL, 0x69852DFDUL, 0x09072166UL, + 0xB39A460AUL, 0x6445C0DDUL, 0x586CDECFUL, 0x1C20C8AEUL, + 0x5BBEF7DDUL, 0x1B588D40UL, 0xCCD2017FUL, 0x6BB4E3BBUL, + 0xDDA26A7EUL, 0x3A59FF45UL, 0x3E350A44UL, 0xBCB4CDD5UL, + 0x72EACEA8UL, 0xFA6484BBUL, 0x8D6612AEUL, 0xBF3C6F47UL, + 0xD29BE463UL, 0x542F5D9EUL, 0xAEC2771BUL, 0xF64E6370UL, + 0x740E0D8DUL, 0xE75B1357UL, 0xF8721671UL, 0xAF537D5DUL, + 0x4040CB08UL, 0x4EB4E2CCUL, 0x34D2466AUL, 0x0115AF84UL, + 0xE1B00428UL, 0x95983A1DUL, 0x06B89FB4UL, 0xCE6EA048UL, + 0x6F3F3B82UL, 0x3520AB82UL, 0x011A1D4BUL, 0x277227F8UL, + 0x611560B1UL, 0xE7933FDCUL, 0xBB3A792BUL, 0x344525BDUL, + 0xA08839E1UL, 0x51CE794BUL, 0x2F32C9B7UL, 0xA01FBAC9UL, + 0xE01CC87EUL, 0xBCC7D1F6UL, 0xCF0111C3UL, 0xA1E8AAC7UL, + 0x1A908749UL, 0xD44FBD9AUL, 0xD0DADECBUL, 0xD50ADA38UL, + 0x0339C32AUL, 0xC6913667UL, 0x8DF9317CUL, 0xE0B12B4FUL, + 0xF79E59B7UL, 0x43F5BB3AUL, 0xF2D519FFUL, 0x27D9459CUL, + 0xBF97222CUL, 0x15E6FC2AUL, 0x0F91FC71UL, 0x9B941525UL, + 0xFAE59361UL, 0xCEB69CEBUL, 0xC2A86459UL, 0x12BAA8D1UL, + 0xB6C1075EUL, 0xE3056A0CUL, 0x10D25065UL, 0xCB03A442UL, + 0xE0EC6E0EUL, 0x1698DB3BUL, 0x4C98A0BEUL, 0x3278E964UL, + 0x9F1F9532UL, 0xE0D392DFUL, 0xD3A0342BUL, 0x8971F21EUL, + 0x1B0A7441UL, 0x4BA3348CUL, 0xC5BE7120UL, 0xC37632D8UL, + 0xDF359F8DUL, 0x9B992F2EUL, 0xE60B6F47UL, 0x0FE3F11DUL, + 0xE54CDA54UL, 0x1EDAD891UL, 0xCE6279CFUL, 0xCD3E7E6FUL, + 0x1618B166UL, 0xFD2C1D05UL, 0x848FD2C5UL, 0xF6FB2299UL, + 0xF523F357UL, 0xA6327623UL, 0x93A83531UL, 0x56CCCD02UL, + 0xACF08162UL, 0x5A75EBB5UL, 0x6E163697UL, 0x88D273CCUL, + 0xDE966292UL, 0x81B949D0UL, 0x4C50901BUL, 0x71C65614UL, + 0xE6C6C7BDUL, 0x327A140AUL, 0x45E1D006UL, 0xC3F27B9AUL, + 0xC9AA53FDUL, 0x62A80F00UL, 0xBB25BFE2UL, 0x35BDD2F6UL, + 0x71126905UL, 0xB2040222UL, 0xB6CBCF7CUL, 0xCD769C2BUL, + 0x53113EC0UL, 0x1640E3D3UL, 0x38ABBD60UL, 0x2547ADF0UL, + 0xBA38209CUL, 0xF746CE76UL, 0x77AFA1C5UL, 0x20756060UL, + 0x85CBFE4EUL, 0x8AE88DD8UL, 0x7AAAF9B0UL, 0x4CF9AA7EUL, + 0x1948C25CUL, 0x02FB8A8CUL, 0x01C36AE4UL, 0xD6EBE1F9UL, + 0x90D4F869UL, 0xA65CDEA0UL, 0x3F09252DUL, 0xC208E69FUL, + 0xB74E6132UL, 0xCE77E25BUL, 0x578FDFE3UL, 0x3AC372E6UL } +}; + + /** + Initialize the Blowfish block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +int blowfish_setup(const unsigned char *key, int keylen, int num_rounds, + symmetric_key *skey) +{ + ulong32 x, y, z, A; + unsigned char B[8]; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + /* check key length */ + if (keylen < 8 || keylen > 56) { + return CRYPT_INVALID_KEYSIZE; + } + + /* check rounds */ + if (num_rounds != 0 && num_rounds != 16) { + return CRYPT_INVALID_ROUNDS; + } + + /* load in key bytes (Supplied by David Hopwood) */ + for (x = y = 0; x < 18; x++) { + A = 0; + for (z = 0; z < 4; z++) { + A = (A << 8) | ((ulong32)key[y++] & 255); + if (y == (ulong32)keylen) { + y = 0; + } + } + skey->blowfish.K[x] = ORIG_P[x] ^ A; + } + + /* copy sboxes */ + for (x = 0; x < 4; x++) { + for (y = 0; y < 256; y++) { + skey->blowfish.S[x][y] = ORIG_S[x][y]; + } + } + + /* encrypt K array */ + for (x = 0; x < 8; x++) { + B[x] = 0; + } + + for (x = 0; x < 18; x += 2) { + /* encrypt it */ + blowfish_ecb_encrypt(B, B, skey); + /* copy it */ + LOAD32H(skey->blowfish.K[x], &B[0]); + LOAD32H(skey->blowfish.K[x+1], &B[4]); + } + + /* encrypt S array */ + for (x = 0; x < 4; x++) { + for (y = 0; y < 256; y += 2) { + /* encrypt it */ + blowfish_ecb_encrypt(B, B, skey); + /* copy it */ + LOAD32H(skey->blowfish.S[x][y], &B[0]); + LOAD32H(skey->blowfish.S[x][y+1], &B[4]); + } + } + +#ifdef LTC_CLEAN_STACK + zeromem(B, sizeof(B)); +#endif + + return CRYPT_OK; +} + +#ifndef __GNUC__ +#define F(x) ((S1[byte(x,3)] + S2[byte(x,2)]) ^ S3[byte(x,1)]) + S4[byte(x,0)] +#else +#define F(x) ((skey->blowfish.S[0][byte(x,3)] + skey->blowfish.S[1][byte(x,2)]) ^ skey->blowfish.S[2][byte(x,1)]) + skey->blowfish.S[3][byte(x,0)] +#endif + +/** + Encrypts a block of text with Blowfish + @param pt The input plaintext (8 bytes) + @param ct The output ciphertext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +#ifdef LTC_CLEAN_STACK +static int _blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#else +int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#endif +{ + ulong32 L, R; + int r; +#ifndef __GNUC__ + ulong32 *S1, *S2, *S3, *S4; +#endif + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + +#ifndef __GNUC__ + S1 = skey->blowfish.S[0]; + S2 = skey->blowfish.S[1]; + S3 = skey->blowfish.S[2]; + S4 = skey->blowfish.S[3]; +#endif + + /* load it */ + LOAD32H(L, &pt[0]); + LOAD32H(R, &pt[4]); + + /* do 16 rounds */ + for (r = 0; r < 16; ) { + L ^= skey->blowfish.K[r++]; R ^= F(L); + R ^= skey->blowfish.K[r++]; L ^= F(R); + L ^= skey->blowfish.K[r++]; R ^= F(L); + R ^= skey->blowfish.K[r++]; L ^= F(R); + } + + /* last keying */ + R ^= skey->blowfish.K[17]; + L ^= skey->blowfish.K[16]; + + /* store */ + STORE32H(R, &ct[0]); + STORE32H(L, &ct[4]); + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + int err = _blowfish_ecb_encrypt(pt, ct, skey); + burn_stack(sizeof(ulong32) * 2 + sizeof(int)); + return err; +} +#endif + +/** + Decrypts a block of text with Blowfish + @param ct The input ciphertext (8 bytes) + @param pt The output plaintext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +#ifdef LTC_CLEAN_STACK +static int _blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#else +int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#endif +{ + ulong32 L, R; + int r; +#ifndef __GNUC__ + ulong32 *S1, *S2, *S3, *S4; +#endif + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + +#ifndef __GNUC__ + S1 = skey->blowfish.S[0]; + S2 = skey->blowfish.S[1]; + S3 = skey->blowfish.S[2]; + S4 = skey->blowfish.S[3]; +#endif + + /* load it */ + LOAD32H(R, &ct[0]); + LOAD32H(L, &ct[4]); + + /* undo last keying */ + R ^= skey->blowfish.K[17]; + L ^= skey->blowfish.K[16]; + + /* do 16 rounds */ + for (r = 15; r > 0; ) { + L ^= F(R); R ^= skey->blowfish.K[r--]; + R ^= F(L); L ^= skey->blowfish.K[r--]; + L ^= F(R); R ^= skey->blowfish.K[r--]; + R ^= F(L); L ^= skey->blowfish.K[r--]; + } + + /* store */ + STORE32H(L, &pt[0]); + STORE32H(R, &pt[4]); + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + int err = _blowfish_ecb_decrypt(ct, pt, skey); + burn_stack(sizeof(ulong32) * 2 + sizeof(int)); + return err; +} +#endif + + +/** + Performs a self-test of the Blowfish block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int blowfish_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + int err; + symmetric_key key; + static const struct { + unsigned char key[8], pt[8], ct[8]; + } tests[] = { + { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + { 0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78} + }, + { + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + { 0x51, 0x86, 0x6F, 0xD5, 0xB8, 0x5E, 0xCB, 0x8A} + }, + { + { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + { 0x7D, 0x85, 0x6F, 0x9A, 0x61, 0x30, 0x63, 0xF2} + } + }; + unsigned char tmp[2][8]; + int x, y; + + for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) { + /* setup key */ + if ((err = blowfish_setup(tests[x].key, 8, 16, &key)) != CRYPT_OK) { + return err; + } + + /* encrypt and decrypt */ + blowfish_ecb_encrypt(tests[x].pt, tmp[0], &key); + blowfish_ecb_decrypt(tmp[0], tmp[1], &key); + + /* compare */ + if ((XMEMCMP(tmp[0], tests[x].ct, 8) != 0) || (XMEMCMP(tmp[1], tests[x].pt, 8) != 0)) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) blowfish_ecb_encrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) blowfish_ecb_decrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; + #endif +} + +/** Terminate the context + @param skey The scheduled key +*/ +void blowfish_done(symmetric_key *skey) +{ + LTC_UNUSED_PARAM(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. + @return CRYPT_OK if the input key size is acceptable. +*/ +int blowfish_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + + if (*keysize < 8) { + return CRYPT_INVALID_KEYSIZE; + } else if (*keysize > 56) { + *keysize = 56; + } + return CRYPT_OK; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/ciphers/camellia.c b/src/ltc/ciphers/camellia.c new file mode 100644 index 0000000..ad8f501 --- /dev/null +++ b/src/ltc/ciphers/camellia.c @@ -0,0 +1,742 @@ +/* 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://libtom.org + */ + +/** + @file camellia.c + Implementation by Tom St Denis of Elliptic Semiconductor +*/ + +#include "tomcrypt.h" + +#ifdef LTC_CAMELLIA + +const struct ltc_cipher_descriptor camellia_desc = { + "camellia", + 23, + 16, 32, 16, 18, + &camellia_setup, + &camellia_ecb_encrypt, + &camellia_ecb_decrypt, + &camellia_test, + &camellia_done, + &camellia_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +static const ulong32 SP1110[] = { +0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, 0xb3b3b300, 0x27272700, 0xc0c0c000, 0xe5e5e500, +0xe4e4e400, 0x85858500, 0x57575700, 0x35353500, 0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100, +0x23232300, 0xefefef00, 0x6b6b6b00, 0x93939300, 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100, +0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00, 0x1d1d1d00, 0x65656500, 0x92929200, 0xbdbdbd00, +0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00, 0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00, +0x3e3e3e00, 0x30303000, 0xdcdcdc00, 0x5f5f5f00, 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00, +0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00, 0xd5d5d500, 0x47474700, 0x5d5d5d00, 0x3d3d3d00, +0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600, 0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00, +0x8b8b8b00, 0x0d0d0d00, 0x9a9a9a00, 0x66666600, 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00, +0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000, 0xf0f0f000, 0xb1b1b100, 0x84848400, 0x99999900, +0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200, 0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500, +0x6d6d6d00, 0xb7b7b700, 0xa9a9a900, 0x31313100, 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700, +0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100, 0xdedede00, 0x1b1b1b00, 0x11111100, 0x1c1c1c00, +0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600, 0x53535300, 0x18181800, 0xf2f2f200, 0x22222200, +0xfefefe00, 0x44444400, 0xcfcfcf00, 0xb2b2b200, 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100, +0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800, 0x60606000, 0xfcfcfc00, 0x69696900, 0x50505000, +0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00, 0xa1a1a100, 0x89898900, 0x62626200, 0x97979700, +0x54545400, 0x5b5b5b00, 0x1e1e1e00, 0x95959500, 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200, +0x10101000, 0xc4c4c400, 0x00000000, 0x48484800, 0xa3a3a300, 0xf7f7f700, 0x75757500, 0xdbdbdb00, +0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00, 0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400, +0x87878700, 0x5c5c5c00, 0x83838300, 0x02020200, 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300, +0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300, 0x9d9d9d00, 0x7f7f7f00, 0xbfbfbf00, 0xe2e2e200, +0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600, 0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00, +0x81818100, 0x96969600, 0x6f6f6f00, 0x4b4b4b00, 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00, +0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00, 0x9f9f9f00, 0x6e6e6e00, 0xbcbcbc00, 0x8e8e8e00, +0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600, 0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900, +0x78787800, 0x98989800, 0x06060600, 0x6a6a6a00, 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00, +0xd4d4d400, 0x25252500, 0xababab00, 0x42424200, 0x88888800, 0xa2a2a200, 0x8d8d8d00, 0xfafafa00, +0x72727200, 0x07070700, 0xb9b9b900, 0x55555500, 0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00, +0x36363600, 0x49494900, 0x2a2a2a00, 0x68686800, 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400, +0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00, 0xbbbbbb00, 0xc9c9c900, 0x43434300, 0xc1c1c100, +0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400, 0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00, +}; + +static const ulong32 SP0222[] = { +0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9, 0x00676767, 0x004e4e4e, 0x00818181, 0x00cbcbcb, +0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a, 0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282, +0x00464646, 0x00dfdfdf, 0x00d6d6d6, 0x00272727, 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242, +0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c, 0x003a3a3a, 0x00cacaca, 0x00252525, 0x007b7b7b, +0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f, 0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d, +0x007c7c7c, 0x00606060, 0x00b9b9b9, 0x00bebebe, 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434, +0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595, 0x00ababab, 0x008e8e8e, 0x00bababa, 0x007a7a7a, +0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad, 0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a, +0x00171717, 0x001a1a1a, 0x00353535, 0x00cccccc, 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a, +0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040, 0x00e1e1e1, 0x00636363, 0x00090909, 0x00333333, +0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585, 0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a, +0x00dadada, 0x006f6f6f, 0x00535353, 0x00626262, 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf, +0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2, 0x00bdbdbd, 0x00363636, 0x00222222, 0x00383838, +0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c, 0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444, +0x00fdfdfd, 0x00888888, 0x009f9f9f, 0x00656565, 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323, +0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151, 0x00c0c0c0, 0x00f9f9f9, 0x00d2d2d2, 0x00a0a0a0, +0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa, 0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f, +0x00a8a8a8, 0x00b6b6b6, 0x003c3c3c, 0x002b2b2b, 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5, +0x00202020, 0x00898989, 0x00000000, 0x00909090, 0x00474747, 0x00efefef, 0x00eaeaea, 0x00b7b7b7, +0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5, 0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929, +0x000f0f0f, 0x00b8b8b8, 0x00070707, 0x00040404, 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666, +0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7, 0x003b3b3b, 0x00fefefe, 0x007f7f7f, 0x00c5c5c5, +0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c, 0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676, +0x00030303, 0x002d2d2d, 0x00dedede, 0x00969696, 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c, +0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919, 0x003f3f3f, 0x00dcdcdc, 0x00797979, 0x001d1d1d, +0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d, 0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2, +0x00f0f0f0, 0x00313131, 0x000c0c0c, 0x00d4d4d4, 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575, +0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484, 0x00111111, 0x00454545, 0x001b1b1b, 0x00f5f5f5, +0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa, 0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414, +0x006c6c6c, 0x00929292, 0x00545454, 0x00d0d0d0, 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949, +0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6, 0x00777777, 0x00939393, 0x00868686, 0x00838383, +0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9, 0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d, +}; + +static const ulong32 SP3033[] = { +0x38003838, 0x41004141, 0x16001616, 0x76007676, 0xd900d9d9, 0x93009393, 0x60006060, 0xf200f2f2, +0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a, 0x75007575, 0x06000606, 0x57005757, 0xa000a0a0, +0x91009191, 0xf700f7f7, 0xb500b5b5, 0xc900c9c9, 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090, +0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727, 0x8e008e8e, 0xb200b2b2, 0x49004949, 0xde00dede, +0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7, 0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767, +0x1f001f1f, 0x18001818, 0x6e006e6e, 0xaf00afaf, 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d, +0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565, 0xea00eaea, 0xa300a3a3, 0xae00aeae, 0x9e009e9e, +0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b, 0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6, +0xc500c5c5, 0x86008686, 0x4d004d4d, 0x33003333, 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696, +0x3a003a3a, 0x09000909, 0x95009595, 0x10001010, 0x78007878, 0xd800d8d8, 0x42004242, 0xcc00cccc, +0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161, 0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282, +0xb600b6b6, 0xdb00dbdb, 0xd400d4d4, 0x98009898, 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb, +0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0, 0x6f006f6f, 0x8d008d8d, 0x88008888, 0x0e000e0e, +0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b, 0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111, +0x7f007f7f, 0x22002222, 0xe700e7e7, 0x59005959, 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8, +0x12001212, 0x04000404, 0x74007474, 0x54005454, 0x30003030, 0x7e007e7e, 0xb400b4b4, 0x28002828, +0x55005555, 0x68006868, 0x50005050, 0xbe00bebe, 0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb, +0x2a002a2a, 0xad00adad, 0x0f000f0f, 0xca00caca, 0x70007070, 0xff00ffff, 0x32003232, 0x69006969, +0x08000808, 0x62006262, 0x00000000, 0x24002424, 0xd100d1d1, 0xfb00fbfb, 0xba00baba, 0xed00eded, +0x45004545, 0x81008181, 0x73007373, 0x6d006d6d, 0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a, +0xc300c3c3, 0x2e002e2e, 0xc100c1c1, 0x01000101, 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999, +0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9, 0xce00cece, 0xbf00bfbf, 0xdf00dfdf, 0x71007171, +0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313, 0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d, +0xc000c0c0, 0x4b004b4b, 0xb700b7b7, 0xa500a5a5, 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717, +0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646, 0xcf00cfcf, 0x37003737, 0x5e005e5e, 0x47004747, +0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b, 0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac, +0x3c003c3c, 0x4c004c4c, 0x03000303, 0x35003535, 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d, +0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121, 0x44004444, 0x51005151, 0xc600c6c6, 0x7d007d7d, +0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa, 0x7c007c7c, 0x77007777, 0x56005656, 0x05000505, +0x1b001b1b, 0xa400a4a4, 0x15001515, 0x34003434, 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252, +0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd, 0xdd00dddd, 0xe400e4e4, 0xa100a1a1, 0xe000e0e0, +0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a, 0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f, +}; + +static const ulong32 SP4404[] = { +0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0, 0xe4e400e4, 0x57570057, 0xeaea00ea, 0xaeae00ae, +0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5, 0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092, +0x86860086, 0xafaf00af, 0x7c7c007c, 0x1f1f001f, 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b, +0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d, 0xd9d900d9, 0x5a5a005a, 0x51510051, 0x6c6c006c, +0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0, 0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084, +0xdfdf00df, 0xcbcb00cb, 0x34340034, 0x76760076, 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004, +0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011, 0x32320032, 0x9c9c009c, 0x53530053, 0xf2f200f2, +0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a, 0x24240024, 0xe8e800e8, 0x60600060, 0x69690069, +0xaaaa00aa, 0xa0a000a0, 0xa1a100a1, 0x62620062, 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064, +0x10100010, 0x00000000, 0xa3a300a3, 0x75750075, 0x8a8a008a, 0xe6e600e6, 0x09090009, 0xdddd00dd, +0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090, 0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf, +0x52520052, 0xd8d800d8, 0xc8c800c8, 0xc6c600c6, 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063, +0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc, 0x29290029, 0xf9f900f9, 0x2f2f002f, 0xb4b400b4, +0x78780078, 0x06060006, 0xe7e700e7, 0x71710071, 0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d, +0x72720072, 0xb9b900b9, 0xf8f800f8, 0xacac00ac, 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1, +0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043, 0x15150015, 0xadad00ad, 0x77770077, 0x80800080, +0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5, 0x85850085, 0x35350035, 0x0c0c000c, 0x41410041, +0xefef00ef, 0x93930093, 0x19190019, 0x21210021, 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd, +0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce, 0x30300030, 0x5f5f005f, 0xc5c500c5, 0x1a1a001a, +0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d, 0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d, +0x0d0d000d, 0x66660066, 0xcccc00cc, 0x2d2d002d, 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099, +0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005, 0xb7b700b7, 0x31310031, 0x17170017, 0xd7d700d7, +0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c, 0x0f0f000f, 0x16160016, 0x18180018, 0x22220022, +0x44440044, 0xb2b200b2, 0xb5b500b5, 0x91910091, 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050, +0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097, 0x5b5b005b, 0x95950095, 0xffff00ff, 0xd2d200d2, +0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db, 0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094, +0x5c5c005c, 0x02020002, 0x4a4a004a, 0x33330033, 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2, +0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b, 0x96960096, 0x4b4b004b, 0xbebe00be, 0x2e2e002e, +0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e, 0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059, +0x98980098, 0x6a6a006a, 0x46460046, 0xbaba00ba, 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa, +0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a, 0x49490049, 0x68680068, 0x38380038, 0xa4a400a4, +0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1, 0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e, +}; + +static const ulong64 key_sigma[] = { + CONST64(0xA09E667F3BCC908B), + CONST64(0xB67AE8584CAA73B2), + CONST64(0xC6EF372FE94F82BE), + CONST64(0x54FF53A5F1D36F1C), + CONST64(0x10E527FADE682D1D), + CONST64(0xB05688C2B3E6C1FD) +}; + +static ulong64 F(ulong64 x) +{ + ulong32 D, U; + +#define loc(i) ((8-i)*8) + + D = SP1110[(x >> loc(8)) & 0xFF] ^ SP0222[(x >> loc(5)) & 0xFF] ^ SP3033[(x >> loc(6)) & 0xFF] ^ SP4404[(x >> loc(7)) & 0xFF]; + U = SP1110[(x >> loc(1)) & 0xFF] ^ SP0222[(x >> loc(2)) & 0xFF] ^ SP3033[(x >> loc(3)) & 0xFF] ^ SP4404[(x >> loc(4)) & 0xFF]; + + D ^= U; + U = D ^ RORc(U, 8); + + return ((ulong64)U) | (((ulong64)D) << CONST64(32)); +} + +static void rot_128(unsigned char *in, unsigned count, unsigned char *out) +{ + unsigned x, w, b; + + w = count >> 3; + b = count & 7; + + for (x = 0; x < 16; x++) { + out[x] = (in[(x+w)&15] << b) | (in[(x+w+1)&15] >> (8 - b)); + } +} + +int camellia_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + unsigned char T[48], kA[16], kB[16], kR[16], kL[16]; + int x; + ulong64 A, B; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + /* Valid sizes (in bytes) are 16, 24, 32 */ + if (keylen != 16 && keylen != 24 && keylen != 32) { + return CRYPT_INVALID_KEYSIZE; + } + + /* number of rounds */ + skey->camellia.R = (keylen == 16) ? 18 : 24; + + if (num_rounds != 0 && num_rounds != skey->camellia.R) { + return CRYPT_INVALID_ROUNDS; + } + + /* expand key */ + if (keylen == 16) { + for (x = 0; x < 16; x++) { + T[x] = key[x]; + T[x + 16] = 0; + } + } else if (keylen == 24) { + for (x = 0; x < 24; x++) { + T[x] = key[x]; + } + for (x = 24; x < 32; x++) { + T[x] = key[x-8] ^ 0xFF; + } + } else { + for (x = 0; x < 32; x++) { + T[x] = key[x]; + } + } + + for (x = 0; x < 16; x++) { + kL[x] = T[x]; + kR[x] = T[x + 16]; + } + + for (x = 32; x < 48; x++) { + T[x] = T[x - 32] ^ T[x - 16]; + } + + /* first two rounds */ + LOAD64H(A, T+32); LOAD64H(B, T+40); + B ^= F(A ^ key_sigma[0]); + A ^= F(B ^ key_sigma[1]); + STORE64H(A, T+32); STORE64H(B, T+40); + + /* xor kL in */ + for (x = 0; x < 16; x++) { T[x+32] ^= kL[x]; } + + /* next two rounds */ + LOAD64H(A, T+32); LOAD64H(B, T+40); + B ^= F(A ^ key_sigma[2]); + A ^= F(B ^ key_sigma[3]); + STORE64H(A, T+32); STORE64H(B, T+40); + + /* grab KA */ + for (x = 0; x < 16; x++) { kA[x] = T[x+32]; } + + /* xor kR in */ + for (x = 0; x < 16; x++) { T[x+32] ^= kR[x]; } + + if (keylen == 16) { + /* grab whitening keys kw1 and kw2 */ + LOAD64H(skey->camellia.kw[0], kL); + LOAD64H(skey->camellia.kw[1], kL+8); + + /* k1-k2 */ + LOAD64H(skey->camellia.k[0], kA); + LOAD64H(skey->camellia.k[1], kA+8); + + /* rotate kL by 15, k3/k4 */ + rot_128(kL, 15, T+32); + LOAD64H(skey->camellia.k[2], T+32); + LOAD64H(skey->camellia.k[3], T+40); + + /* rotate kA by 15, k5/k6 */ + rot_128(kA, 15, T+32); + LOAD64H(skey->camellia.k[4], T+32); + LOAD64H(skey->camellia.k[5], T+40); + + /* rotate kA by 30, kl1, kl2 */ + rot_128(kA, 30, T+32); + LOAD64H(skey->camellia.kl[0], T+32); + LOAD64H(skey->camellia.kl[1], T+40); + + /* rotate kL by 45, k7/k8 */ + rot_128(kL, 45, T+32); + LOAD64H(skey->camellia.k[6], T+32); + LOAD64H(skey->camellia.k[7], T+40); + + /* rotate kA by 45, k9/k10 */ + rot_128(kA, 45, T+32); + LOAD64H(skey->camellia.k[8], T+32); + rot_128(kL, 60, T+32); + LOAD64H(skey->camellia.k[9], T+40); + + /* rotate kA by 60, k11/k12 */ + rot_128(kA, 60, T+32); + LOAD64H(skey->camellia.k[10], T+32); + LOAD64H(skey->camellia.k[11], T+40); + + /* rotate kL by 77, kl3, kl4 */ + rot_128(kL, 77, T+32); + LOAD64H(skey->camellia.kl[2], T+32); + LOAD64H(skey->camellia.kl[3], T+40); + + /* rotate kL by 94, k13/k14 */ + rot_128(kL, 94, T+32); + LOAD64H(skey->camellia.k[12], T+32); + LOAD64H(skey->camellia.k[13], T+40); + + /* rotate kA by 94, k15/k16 */ + rot_128(kA, 94, T+32); + LOAD64H(skey->camellia.k[14], T+32); + LOAD64H(skey->camellia.k[15], T+40); + + /* rotate kL by 111, k17/k18 */ + rot_128(kL, 111, T+32); + LOAD64H(skey->camellia.k[16], T+32); + LOAD64H(skey->camellia.k[17], T+40); + + /* rotate kA by 111, kw3/kw4 */ + rot_128(kA, 111, T+32); + LOAD64H(skey->camellia.kw[2], T+32); + LOAD64H(skey->camellia.kw[3], T+40); + } else { + /* last two rounds */ + LOAD64H(A, T+32); LOAD64H(B, T+40); + B ^= F(A ^ key_sigma[4]); + A ^= F(B ^ key_sigma[5]); + STORE64H(A, T+32); STORE64H(B, T+40); + + /* grab kB */ + for (x = 0; x < 16; x++) { kB[x] = T[x+32]; } + + /* kw1/2 from kL*/ + LOAD64H(skey->camellia.kw[0], kL); + LOAD64H(skey->camellia.kw[1], kL+8); + + /* k1/k2 = kB */ + LOAD64H(skey->camellia.k[0], kB); + LOAD64H(skey->camellia.k[1], kB+8); + + /* k3/k4 = kR by 15 */ + rot_128(kR, 15, T+32); + LOAD64H(skey->camellia.k[2], T+32); + LOAD64H(skey->camellia.k[3], T+40); + + /* k5/k7 = kA by 15 */ + rot_128(kA, 15, T+32); + LOAD64H(skey->camellia.k[4], T+32); + LOAD64H(skey->camellia.k[5], T+40); + + /* kl1/2 = kR by 30 */ + rot_128(kR, 30, T+32); + LOAD64H(skey->camellia.kl[0], T+32); + LOAD64H(skey->camellia.kl[1], T+40); + + /* k7/k8 = kB by 30 */ + rot_128(kB, 30, T+32); + LOAD64H(skey->camellia.k[6], T+32); + LOAD64H(skey->camellia.k[7], T+40); + + /* k9/k10 = kL by 45 */ + rot_128(kL, 45, T+32); + LOAD64H(skey->camellia.k[8], T+32); + LOAD64H(skey->camellia.k[9], T+40); + + /* k11/k12 = kA by 45 */ + rot_128(kA, 45, T+32); + LOAD64H(skey->camellia.k[10], T+32); + LOAD64H(skey->camellia.k[11], T+40); + + /* kl3/4 = kL by 60 */ + rot_128(kL, 60, T+32); + LOAD64H(skey->camellia.kl[2], T+32); + LOAD64H(skey->camellia.kl[3], T+40); + + /* k13/k14 = kR by 60 */ + rot_128(kR, 60, T+32); + LOAD64H(skey->camellia.k[12], T+32); + LOAD64H(skey->camellia.k[13], T+40); + + /* k15/k16 = kB by 15 */ + rot_128(kB, 60, T+32); + LOAD64H(skey->camellia.k[14], T+32); + LOAD64H(skey->camellia.k[15], T+40); + + /* k17/k18 = kL by 77 */ + rot_128(kL, 77, T+32); + LOAD64H(skey->camellia.k[16], T+32); + LOAD64H(skey->camellia.k[17], T+40); + + /* kl5/6 = kA by 77 */ + rot_128(kA, 77, T+32); + LOAD64H(skey->camellia.kl[4], T+32); + LOAD64H(skey->camellia.kl[5], T+40); + + /* k19/k20 = kR by 94 */ + rot_128(kR, 94, T+32); + LOAD64H(skey->camellia.k[18], T+32); + LOAD64H(skey->camellia.k[19], T+40); + + /* k21/k22 = kA by 94 */ + rot_128(kA, 94, T+32); + LOAD64H(skey->camellia.k[20], T+32); + LOAD64H(skey->camellia.k[21], T+40); + + /* k23/k24 = kL by 111 */ + rot_128(kL, 111, T+32); + LOAD64H(skey->camellia.k[22], T+32); + LOAD64H(skey->camellia.k[23], T+40); + + /* kw2/kw3 = kB by 111 */ + rot_128(kB, 111, T+32); + LOAD64H(skey->camellia.kw[2], T+32); + LOAD64H(skey->camellia.kw[3], T+40); + } + + return CRYPT_OK; +} + +int camellia_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + ulong64 L, R; + ulong32 a, b; + + LOAD64H(L, pt+0); LOAD64H(R, pt+8); + L ^= skey->camellia.kw[0]; + R ^= skey->camellia.kw[1]; + + /* first 6 rounds */ + R ^= F(L ^ skey->camellia.k[0]); + L ^= F(R ^ skey->camellia.k[1]); + R ^= F(L ^ skey->camellia.k[2]); + L ^= F(R ^ skey->camellia.k[3]); + R ^= F(L ^ skey->camellia.k[4]); + L ^= F(R ^ skey->camellia.k[5]); + + /* FL */ + a = (ulong32)(L >> 32); + b = (ulong32)(L & 0xFFFFFFFFUL); + b ^= ROL((a & (ulong32)(skey->camellia.kl[0] >> 32)), 1); + a ^= b | (skey->camellia.kl[0] & 0xFFFFFFFFU); + L = (((ulong64)a) << 32) | b; + + /* FL^-1 */ + a = (ulong32)(R >> 32); + b = (ulong32)(R & 0xFFFFFFFFUL); + a ^= b | (skey->camellia.kl[1] & 0xFFFFFFFFU); + b ^= ROL((a & (ulong32)(skey->camellia.kl[1] >> 32)), 1); + R = (((ulong64)a) << 32) | b; + + /* second 6 rounds */ + R ^= F(L ^ skey->camellia.k[6]); + L ^= F(R ^ skey->camellia.k[7]); + R ^= F(L ^ skey->camellia.k[8]); + L ^= F(R ^ skey->camellia.k[9]); + R ^= F(L ^ skey->camellia.k[10]); + L ^= F(R ^ skey->camellia.k[11]); + + /* FL */ + a = (ulong32)(L >> 32); + b = (ulong32)(L & 0xFFFFFFFFUL); + b ^= ROL((a & (ulong32)(skey->camellia.kl[2] >> 32)), 1); + a ^= b | (skey->camellia.kl[2] & 0xFFFFFFFFU); + L = (((ulong64)a) << 32) | b; + + /* FL^-1 */ + a = (ulong32)(R >> 32); + b = (ulong32)(R & 0xFFFFFFFFUL); + a ^= b | (skey->camellia.kl[3] & 0xFFFFFFFFU); + b ^= ROL((a & (ulong32)(skey->camellia.kl[3] >> 32)), 1); + R = (((ulong64)a) << 32) | b; + + /* third 6 rounds */ + R ^= F(L ^ skey->camellia.k[12]); + L ^= F(R ^ skey->camellia.k[13]); + R ^= F(L ^ skey->camellia.k[14]); + L ^= F(R ^ skey->camellia.k[15]); + R ^= F(L ^ skey->camellia.k[16]); + L ^= F(R ^ skey->camellia.k[17]); + + /* next FL */ + if (skey->camellia.R == 24) { + /* FL */ + a = (ulong32)(L >> 32); + b = (ulong32)(L & 0xFFFFFFFFUL); + b ^= ROL((a & (ulong32)(skey->camellia.kl[4] >> 32)), 1); + a ^= b | (skey->camellia.kl[4] & 0xFFFFFFFFU); + L = (((ulong64)a) << 32) | b; + + /* FL^-1 */ + a = (ulong32)(R >> 32); + b = (ulong32)(R & 0xFFFFFFFFUL); + a ^= b | (skey->camellia.kl[5] & 0xFFFFFFFFU); + b ^= ROL((a & (ulong32)(skey->camellia.kl[5] >> 32)), 1); + R = (((ulong64)a) << 32) | b; + + /* fourth 6 rounds */ + R ^= F(L ^ skey->camellia.k[18]); + L ^= F(R ^ skey->camellia.k[19]); + R ^= F(L ^ skey->camellia.k[20]); + L ^= F(R ^ skey->camellia.k[21]); + R ^= F(L ^ skey->camellia.k[22]); + L ^= F(R ^ skey->camellia.k[23]); + } + + L ^= skey->camellia.kw[3]; + R ^= skey->camellia.kw[2]; + + STORE64H(R, ct+0); STORE64H(L, ct+8); + + return CRYPT_OK; +} + +int camellia_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + ulong64 L, R; + ulong32 a, b; + + LOAD64H(R, ct+0); LOAD64H(L, ct+8); + L ^= skey->camellia.kw[3]; + R ^= skey->camellia.kw[2]; + + /* next FL */ + if (skey->camellia.R == 24) { + /* fourth 6 rounds */ + L ^= F(R ^ skey->camellia.k[23]); + R ^= F(L ^ skey->camellia.k[22]); + L ^= F(R ^ skey->camellia.k[21]); + R ^= F(L ^ skey->camellia.k[20]); + L ^= F(R ^ skey->camellia.k[19]); + R ^= F(L ^ skey->camellia.k[18]); + + /* FL */ + a = (ulong32)(L >> 32); + b = (ulong32)(L & 0xFFFFFFFFUL); + a ^= b | (skey->camellia.kl[4] & 0xFFFFFFFFU); + b ^= ROL((a & (ulong32)(skey->camellia.kl[4] >> 32)), 1); + L = (((ulong64)a) << 32) | b; + + /* FL^-1 */ + a = (ulong32)(R >> 32); + b = (ulong32)(R & 0xFFFFFFFFUL); + b ^= ROL((a & (ulong32)(skey->camellia.kl[5] >> 32)), 1); + a ^= b | (skey->camellia.kl[5] & 0xFFFFFFFFU); + R = (((ulong64)a) << 32) | b; + + } + + /* third 6 rounds */ + L ^= F(R ^ skey->camellia.k[17]); + R ^= F(L ^ skey->camellia.k[16]); + L ^= F(R ^ skey->camellia.k[15]); + R ^= F(L ^ skey->camellia.k[14]); + L ^= F(R ^ skey->camellia.k[13]); + R ^= F(L ^ skey->camellia.k[12]); + + /* FL */ + a = (ulong32)(L >> 32); + b = (ulong32)(L & 0xFFFFFFFFUL); + a ^= b | (skey->camellia.kl[2] & 0xFFFFFFFFU); + b ^= ROL((a & (ulong32)(skey->camellia.kl[2] >> 32)), 1); + L = (((ulong64)a) << 32) | b; + + /* FL^-1 */ + a = (ulong32)(R >> 32); + b = (ulong32)(R & 0xFFFFFFFFUL); + b ^= ROL((a & (ulong32)(skey->camellia.kl[3] >> 32)), 1); + a ^= b | (skey->camellia.kl[3] & 0xFFFFFFFFU); + R = (((ulong64)a) << 32) | b; + + /* second 6 rounds */ + L ^= F(R ^ skey->camellia.k[11]); + R ^= F(L ^ skey->camellia.k[10]); + L ^= F(R ^ skey->camellia.k[9]); + R ^= F(L ^ skey->camellia.k[8]); + L ^= F(R ^ skey->camellia.k[7]); + R ^= F(L ^ skey->camellia.k[6]); + + /* FL */ + a = (ulong32)(L >> 32); + b = (ulong32)(L & 0xFFFFFFFFUL); + a ^= b | (skey->camellia.kl[0] & 0xFFFFFFFFU); + b ^= ROL((a & (ulong32)(skey->camellia.kl[0] >> 32)), 1); + L = (((ulong64)a) << 32) | b; + + /* FL^-1 */ + a = (ulong32)(R >> 32); + b = (ulong32)(R & 0xFFFFFFFFUL); + b ^= ROL((a & (ulong32)(skey->camellia.kl[1] >> 32)), 1); + a ^= b | (skey->camellia.kl[1] & 0xFFFFFFFFU); + R = (((ulong64)a) << 32) | b; + + /* first 6 rounds */ + L ^= F(R ^ skey->camellia.k[5]); + R ^= F(L ^ skey->camellia.k[4]); + L ^= F(R ^ skey->camellia.k[3]); + R ^= F(L ^ skey->camellia.k[2]); + L ^= F(R ^ skey->camellia.k[1]); + R ^= F(L ^ skey->camellia.k[0]); + + R ^= skey->camellia.kw[1]; + L ^= skey->camellia.kw[0]; + + STORE64H(R, pt+8); STORE64H(L, pt+0); + + return CRYPT_OK; +} + +int camellia_test(void) +{ + static const struct { + int keylen; + unsigned char key[32], pt[16], ct[16]; + } tests[] = { + +{ + 16, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, + { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73, + 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 } +}, + +{ + 24, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, + { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8, + 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 } +}, + + +{ + 32, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, + { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c, + 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 } +}, + +{ + 32, + { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, + 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, + 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, + 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }, + { 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, + 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 }, + { 0x79, 0x60, 0x10, 0x9F, 0xB6, 0xDC, 0x42, 0x94, + 0x7F, 0xCF, 0xE5, 0x9E, 0xA3, 0xC5, 0xEB, 0x6B } +} +}; + unsigned char buf[2][16]; + symmetric_key skey; + int err; + unsigned int x; + + for (x = 0; x < sizeof(tests)/sizeof(tests[0]); x++) { + zeromem(&skey, sizeof(skey)); + if ((err = camellia_setup(tests[x].key, tests[x].keylen, 0, &skey)) != CRYPT_OK) { + return err; + } + if ((err = camellia_ecb_encrypt(tests[x].pt, buf[0], &skey)) != CRYPT_OK) { + camellia_done(&skey); + return err; + } + if ((err = camellia_ecb_decrypt(tests[x].ct, buf[1], &skey)) != CRYPT_OK) { + camellia_done(&skey); + return err; + } + camellia_done(&skey); + if (XMEMCMP(tests[x].ct, buf[0], 16) || XMEMCMP(tests[x].pt, buf[1], 16)) { +#if 0 + int i, j; + printf ("\n\nLTC_CAMELLIA failed for x=%d, I got:\n", x); + for (i = 0; i < 2; i++) { + const unsigned char *expected, *actual; + expected = (i ? tests[x].pt : tests[x].ct); + actual = buf[i]; + printf ("expected actual (%s)\n", (i ? "plaintext" : "ciphertext")); + for (j = 0; j < 16; j++) { + const char *eq = (expected[j] == actual[j] ? "==" : "!="); + printf (" %02x %s %02x\n", expected[j], eq, actual[j]); + } + printf ("\n"); + } +#endif + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +} + +void camellia_done(symmetric_key *skey) +{ + LTC_UNUSED_PARAM(skey); +} + +int camellia_keysize(int *keysize) +{ + if (*keysize >= 32) { *keysize = 32; } + else if (*keysize >= 24) { *keysize = 24; } + else if (*keysize >= 16) { *keysize = 16; } + else return CRYPT_INVALID_KEYSIZE; + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/ciphers/cast5.c b/src/ltc/ciphers/cast5.c new file mode 100644 index 0000000..f4f9154 --- /dev/null +++ b/src/ltc/ciphers/cast5.c @@ -0,0 +1,721 @@ +/* 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://libtom.org + */ + + /** + @file cast5.c + Implementation of LTC_CAST5 (RFC 2144) by Tom St Denis + */ +#include "tomcrypt.h" + +#ifdef LTC_CAST5 + +const struct ltc_cipher_descriptor cast5_desc = { + "cast5", + 15, + 5, 16, 8, 16, + &cast5_setup, + &cast5_ecb_encrypt, + &cast5_ecb_decrypt, + &cast5_test, + &cast5_done, + &cast5_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +static const ulong32 S1[256] = { +0x30fb40d4UL, 0x9fa0ff0bUL, 0x6beccd2fUL, 0x3f258c7aUL, 0x1e213f2fUL, 0x9c004dd3UL, +0x6003e540UL, 0xcf9fc949UL, 0xbfd4af27UL, 0x88bbbdb5UL, 0xe2034090UL, 0x98d09675UL, +0x6e63a0e0UL, 0x15c361d2UL, 0xc2e7661dUL, 0x22d4ff8eUL, 0x28683b6fUL, 0xc07fd059UL, +0xff2379c8UL, 0x775f50e2UL, 0x43c340d3UL, 0xdf2f8656UL, 0x887ca41aUL, 0xa2d2bd2dUL, +0xa1c9e0d6UL, 0x346c4819UL, 0x61b76d87UL, 0x22540f2fUL, 0x2abe32e1UL, 0xaa54166bUL, +0x22568e3aUL, 0xa2d341d0UL, 0x66db40c8UL, 0xa784392fUL, 0x004dff2fUL, 0x2db9d2deUL, +0x97943facUL, 0x4a97c1d8UL, 0x527644b7UL, 0xb5f437a7UL, 0xb82cbaefUL, 0xd751d159UL, +0x6ff7f0edUL, 0x5a097a1fUL, 0x827b68d0UL, 0x90ecf52eUL, 0x22b0c054UL, 0xbc8e5935UL, +0x4b6d2f7fUL, 0x50bb64a2UL, 0xd2664910UL, 0xbee5812dUL, 0xb7332290UL, 0xe93b159fUL, +0xb48ee411UL, 0x4bff345dUL, 0xfd45c240UL, 0xad31973fUL, 0xc4f6d02eUL, 0x55fc8165UL, +0xd5b1caadUL, 0xa1ac2daeUL, 0xa2d4b76dUL, 0xc19b0c50UL, 0x882240f2UL, 0x0c6e4f38UL, +0xa4e4bfd7UL, 0x4f5ba272UL, 0x564c1d2fUL, 0xc59c5319UL, 0xb949e354UL, 0xb04669feUL, +0xb1b6ab8aUL, 0xc71358ddUL, 0x6385c545UL, 0x110f935dUL, 0x57538ad5UL, 0x6a390493UL, +0xe63d37e0UL, 0x2a54f6b3UL, 0x3a787d5fUL, 0x6276a0b5UL, 0x19a6fcdfUL, 0x7a42206aUL, +0x29f9d4d5UL, 0xf61b1891UL, 0xbb72275eUL, 0xaa508167UL, 0x38901091UL, 0xc6b505ebUL, +0x84c7cb8cUL, 0x2ad75a0fUL, 0x874a1427UL, 0xa2d1936bUL, 0x2ad286afUL, 0xaa56d291UL, +0xd7894360UL, 0x425c750dUL, 0x93b39e26UL, 0x187184c9UL, 0x6c00b32dUL, 0x73e2bb14UL, +0xa0bebc3cUL, 0x54623779UL, 0x64459eabUL, 0x3f328b82UL, 0x7718cf82UL, 0x59a2cea6UL, +0x04ee002eUL, 0x89fe78e6UL, 0x3fab0950UL, 0x325ff6c2UL, 0x81383f05UL, 0x6963c5c8UL, +0x76cb5ad6UL, 0xd49974c9UL, 0xca180dcfUL, 0x380782d5UL, 0xc7fa5cf6UL, 0x8ac31511UL, +0x35e79e13UL, 0x47da91d0UL, 0xf40f9086UL, 0xa7e2419eUL, 0x31366241UL, 0x051ef495UL, +0xaa573b04UL, 0x4a805d8dUL, 0x548300d0UL, 0x00322a3cUL, 0xbf64cddfUL, 0xba57a68eUL, +0x75c6372bUL, 0x50afd341UL, 0xa7c13275UL, 0x915a0bf5UL, 0x6b54bfabUL, 0x2b0b1426UL, +0xab4cc9d7UL, 0x449ccd82UL, 0xf7fbf265UL, 0xab85c5f3UL, 0x1b55db94UL, 0xaad4e324UL, +0xcfa4bd3fUL, 0x2deaa3e2UL, 0x9e204d02UL, 0xc8bd25acUL, 0xeadf55b3UL, 0xd5bd9e98UL, +0xe31231b2UL, 0x2ad5ad6cUL, 0x954329deUL, 0xadbe4528UL, 0xd8710f69UL, 0xaa51c90fUL, +0xaa786bf6UL, 0x22513f1eUL, 0xaa51a79bUL, 0x2ad344ccUL, 0x7b5a41f0UL, 0xd37cfbadUL, +0x1b069505UL, 0x41ece491UL, 0xb4c332e6UL, 0x032268d4UL, 0xc9600accUL, 0xce387e6dUL, +0xbf6bb16cUL, 0x6a70fb78UL, 0x0d03d9c9UL, 0xd4df39deUL, 0xe01063daUL, 0x4736f464UL, +0x5ad328d8UL, 0xb347cc96UL, 0x75bb0fc3UL, 0x98511bfbUL, 0x4ffbcc35UL, 0xb58bcf6aUL, +0xe11f0abcUL, 0xbfc5fe4aUL, 0xa70aec10UL, 0xac39570aUL, 0x3f04442fUL, 0x6188b153UL, +0xe0397a2eUL, 0x5727cb79UL, 0x9ceb418fUL, 0x1cacd68dUL, 0x2ad37c96UL, 0x0175cb9dUL, +0xc69dff09UL, 0xc75b65f0UL, 0xd9db40d8UL, 0xec0e7779UL, 0x4744ead4UL, 0xb11c3274UL, +0xdd24cb9eUL, 0x7e1c54bdUL, 0xf01144f9UL, 0xd2240eb1UL, 0x9675b3fdUL, 0xa3ac3755UL, +0xd47c27afUL, 0x51c85f4dUL, 0x56907596UL, 0xa5bb15e6UL, 0x580304f0UL, 0xca042cf1UL, +0x011a37eaUL, 0x8dbfaadbUL, 0x35ba3e4aUL, 0x3526ffa0UL, 0xc37b4d09UL, 0xbc306ed9UL, +0x98a52666UL, 0x5648f725UL, 0xff5e569dUL, 0x0ced63d0UL, 0x7c63b2cfUL, 0x700b45e1UL, +0xd5ea50f1UL, 0x85a92872UL, 0xaf1fbda7UL, 0xd4234870UL, 0xa7870bf3UL, 0x2d3b4d79UL, +0x42e04198UL, 0x0cd0ede7UL, 0x26470db8UL, 0xf881814cUL, 0x474d6ad7UL, 0x7c0c5e5cUL, +0xd1231959UL, 0x381b7298UL, 0xf5d2f4dbUL, 0xab838653UL, 0x6e2f1e23UL, 0x83719c9eUL, +0xbd91e046UL, 0x9a56456eUL, 0xdc39200cUL, 0x20c8c571UL, 0x962bda1cUL, 0xe1e696ffUL, +0xb141ab08UL, 0x7cca89b9UL, 0x1a69e783UL, 0x02cc4843UL, 0xa2f7c579UL, 0x429ef47dUL, +0x427b169cUL, 0x5ac9f049UL, 0xdd8f0f00UL, 0x5c8165bfUL}; + +static const ulong32 S2[256] = { +0x1f201094UL, 0xef0ba75bUL, 0x69e3cf7eUL, 0x393f4380UL, 0xfe61cf7aUL, 0xeec5207aUL, +0x55889c94UL, 0x72fc0651UL, 0xada7ef79UL, 0x4e1d7235UL, 0xd55a63ceUL, 0xde0436baUL, +0x99c430efUL, 0x5f0c0794UL, 0x18dcdb7dUL, 0xa1d6eff3UL, 0xa0b52f7bUL, 0x59e83605UL, +0xee15b094UL, 0xe9ffd909UL, 0xdc440086UL, 0xef944459UL, 0xba83ccb3UL, 0xe0c3cdfbUL, +0xd1da4181UL, 0x3b092ab1UL, 0xf997f1c1UL, 0xa5e6cf7bUL, 0x01420ddbUL, 0xe4e7ef5bUL, +0x25a1ff41UL, 0xe180f806UL, 0x1fc41080UL, 0x179bee7aUL, 0xd37ac6a9UL, 0xfe5830a4UL, +0x98de8b7fUL, 0x77e83f4eUL, 0x79929269UL, 0x24fa9f7bUL, 0xe113c85bUL, 0xacc40083UL, +0xd7503525UL, 0xf7ea615fUL, 0x62143154UL, 0x0d554b63UL, 0x5d681121UL, 0xc866c359UL, +0x3d63cf73UL, 0xcee234c0UL, 0xd4d87e87UL, 0x5c672b21UL, 0x071f6181UL, 0x39f7627fUL, +0x361e3084UL, 0xe4eb573bUL, 0x602f64a4UL, 0xd63acd9cUL, 0x1bbc4635UL, 0x9e81032dUL, +0x2701f50cUL, 0x99847ab4UL, 0xa0e3df79UL, 0xba6cf38cUL, 0x10843094UL, 0x2537a95eUL, +0xf46f6ffeUL, 0xa1ff3b1fUL, 0x208cfb6aUL, 0x8f458c74UL, 0xd9e0a227UL, 0x4ec73a34UL, +0xfc884f69UL, 0x3e4de8dfUL, 0xef0e0088UL, 0x3559648dUL, 0x8a45388cUL, 0x1d804366UL, +0x721d9bfdUL, 0xa58684bbUL, 0xe8256333UL, 0x844e8212UL, 0x128d8098UL, 0xfed33fb4UL, +0xce280ae1UL, 0x27e19ba5UL, 0xd5a6c252UL, 0xe49754bdUL, 0xc5d655ddUL, 0xeb667064UL, +0x77840b4dUL, 0xa1b6a801UL, 0x84db26a9UL, 0xe0b56714UL, 0x21f043b7UL, 0xe5d05860UL, +0x54f03084UL, 0x066ff472UL, 0xa31aa153UL, 0xdadc4755UL, 0xb5625dbfUL, 0x68561be6UL, +0x83ca6b94UL, 0x2d6ed23bUL, 0xeccf01dbUL, 0xa6d3d0baUL, 0xb6803d5cUL, 0xaf77a709UL, +0x33b4a34cUL, 0x397bc8d6UL, 0x5ee22b95UL, 0x5f0e5304UL, 0x81ed6f61UL, 0x20e74364UL, +0xb45e1378UL, 0xde18639bUL, 0x881ca122UL, 0xb96726d1UL, 0x8049a7e8UL, 0x22b7da7bUL, +0x5e552d25UL, 0x5272d237UL, 0x79d2951cUL, 0xc60d894cUL, 0x488cb402UL, 0x1ba4fe5bUL, +0xa4b09f6bUL, 0x1ca815cfUL, 0xa20c3005UL, 0x8871df63UL, 0xb9de2fcbUL, 0x0cc6c9e9UL, +0x0beeff53UL, 0xe3214517UL, 0xb4542835UL, 0x9f63293cUL, 0xee41e729UL, 0x6e1d2d7cUL, +0x50045286UL, 0x1e6685f3UL, 0xf33401c6UL, 0x30a22c95UL, 0x31a70850UL, 0x60930f13UL, +0x73f98417UL, 0xa1269859UL, 0xec645c44UL, 0x52c877a9UL, 0xcdff33a6UL, 0xa02b1741UL, +0x7cbad9a2UL, 0x2180036fUL, 0x50d99c08UL, 0xcb3f4861UL, 0xc26bd765UL, 0x64a3f6abUL, +0x80342676UL, 0x25a75e7bUL, 0xe4e6d1fcUL, 0x20c710e6UL, 0xcdf0b680UL, 0x17844d3bUL, +0x31eef84dUL, 0x7e0824e4UL, 0x2ccb49ebUL, 0x846a3baeUL, 0x8ff77888UL, 0xee5d60f6UL, +0x7af75673UL, 0x2fdd5cdbUL, 0xa11631c1UL, 0x30f66f43UL, 0xb3faec54UL, 0x157fd7faUL, +0xef8579ccUL, 0xd152de58UL, 0xdb2ffd5eUL, 0x8f32ce19UL, 0x306af97aUL, 0x02f03ef8UL, +0x99319ad5UL, 0xc242fa0fUL, 0xa7e3ebb0UL, 0xc68e4906UL, 0xb8da230cUL, 0x80823028UL, +0xdcdef3c8UL, 0xd35fb171UL, 0x088a1bc8UL, 0xbec0c560UL, 0x61a3c9e8UL, 0xbca8f54dUL, +0xc72feffaUL, 0x22822e99UL, 0x82c570b4UL, 0xd8d94e89UL, 0x8b1c34bcUL, 0x301e16e6UL, +0x273be979UL, 0xb0ffeaa6UL, 0x61d9b8c6UL, 0x00b24869UL, 0xb7ffce3fUL, 0x08dc283bUL, +0x43daf65aUL, 0xf7e19798UL, 0x7619b72fUL, 0x8f1c9ba4UL, 0xdc8637a0UL, 0x16a7d3b1UL, +0x9fc393b7UL, 0xa7136eebUL, 0xc6bcc63eUL, 0x1a513742UL, 0xef6828bcUL, 0x520365d6UL, +0x2d6a77abUL, 0x3527ed4bUL, 0x821fd216UL, 0x095c6e2eUL, 0xdb92f2fbUL, 0x5eea29cbUL, +0x145892f5UL, 0x91584f7fUL, 0x5483697bUL, 0x2667a8ccUL, 0x85196048UL, 0x8c4baceaUL, +0x833860d4UL, 0x0d23e0f9UL, 0x6c387e8aUL, 0x0ae6d249UL, 0xb284600cUL, 0xd835731dUL, +0xdcb1c647UL, 0xac4c56eaUL, 0x3ebd81b3UL, 0x230eabb0UL, 0x6438bc87UL, 0xf0b5b1faUL, +0x8f5ea2b3UL, 0xfc184642UL, 0x0a036b7aUL, 0x4fb089bdUL, 0x649da589UL, 0xa345415eUL, +0x5c038323UL, 0x3e5d3bb9UL, 0x43d79572UL, 0x7e6dd07cUL, 0x06dfdf1eUL, 0x6c6cc4efUL, +0x7160a539UL, 0x73bfbe70UL, 0x83877605UL, 0x4523ecf1UL}; + +static const ulong32 S3[256] = { +0x8defc240UL, 0x25fa5d9fUL, 0xeb903dbfUL, 0xe810c907UL, 0x47607fffUL, 0x369fe44bUL, +0x8c1fc644UL, 0xaececa90UL, 0xbeb1f9bfUL, 0xeefbcaeaUL, 0xe8cf1950UL, 0x51df07aeUL, +0x920e8806UL, 0xf0ad0548UL, 0xe13c8d83UL, 0x927010d5UL, 0x11107d9fUL, 0x07647db9UL, +0xb2e3e4d4UL, 0x3d4f285eUL, 0xb9afa820UL, 0xfade82e0UL, 0xa067268bUL, 0x8272792eUL, +0x553fb2c0UL, 0x489ae22bUL, 0xd4ef9794UL, 0x125e3fbcUL, 0x21fffceeUL, 0x825b1bfdUL, +0x9255c5edUL, 0x1257a240UL, 0x4e1a8302UL, 0xbae07fffUL, 0x528246e7UL, 0x8e57140eUL, +0x3373f7bfUL, 0x8c9f8188UL, 0xa6fc4ee8UL, 0xc982b5a5UL, 0xa8c01db7UL, 0x579fc264UL, +0x67094f31UL, 0xf2bd3f5fUL, 0x40fff7c1UL, 0x1fb78dfcUL, 0x8e6bd2c1UL, 0x437be59bUL, +0x99b03dbfUL, 0xb5dbc64bUL, 0x638dc0e6UL, 0x55819d99UL, 0xa197c81cUL, 0x4a012d6eUL, +0xc5884a28UL, 0xccc36f71UL, 0xb843c213UL, 0x6c0743f1UL, 0x8309893cUL, 0x0feddd5fUL, +0x2f7fe850UL, 0xd7c07f7eUL, 0x02507fbfUL, 0x5afb9a04UL, 0xa747d2d0UL, 0x1651192eUL, +0xaf70bf3eUL, 0x58c31380UL, 0x5f98302eUL, 0x727cc3c4UL, 0x0a0fb402UL, 0x0f7fef82UL, +0x8c96fdadUL, 0x5d2c2aaeUL, 0x8ee99a49UL, 0x50da88b8UL, 0x8427f4a0UL, 0x1eac5790UL, +0x796fb449UL, 0x8252dc15UL, 0xefbd7d9bUL, 0xa672597dUL, 0xada840d8UL, 0x45f54504UL, +0xfa5d7403UL, 0xe83ec305UL, 0x4f91751aUL, 0x925669c2UL, 0x23efe941UL, 0xa903f12eUL, +0x60270df2UL, 0x0276e4b6UL, 0x94fd6574UL, 0x927985b2UL, 0x8276dbcbUL, 0x02778176UL, +0xf8af918dUL, 0x4e48f79eUL, 0x8f616ddfUL, 0xe29d840eUL, 0x842f7d83UL, 0x340ce5c8UL, +0x96bbb682UL, 0x93b4b148UL, 0xef303cabUL, 0x984faf28UL, 0x779faf9bUL, 0x92dc560dUL, +0x224d1e20UL, 0x8437aa88UL, 0x7d29dc96UL, 0x2756d3dcUL, 0x8b907ceeUL, 0xb51fd240UL, +0xe7c07ce3UL, 0xe566b4a1UL, 0xc3e9615eUL, 0x3cf8209dUL, 0x6094d1e3UL, 0xcd9ca341UL, +0x5c76460eUL, 0x00ea983bUL, 0xd4d67881UL, 0xfd47572cUL, 0xf76cedd9UL, 0xbda8229cUL, +0x127dadaaUL, 0x438a074eUL, 0x1f97c090UL, 0x081bdb8aUL, 0x93a07ebeUL, 0xb938ca15UL, +0x97b03cffUL, 0x3dc2c0f8UL, 0x8d1ab2ecUL, 0x64380e51UL, 0x68cc7bfbUL, 0xd90f2788UL, +0x12490181UL, 0x5de5ffd4UL, 0xdd7ef86aUL, 0x76a2e214UL, 0xb9a40368UL, 0x925d958fUL, +0x4b39fffaUL, 0xba39aee9UL, 0xa4ffd30bUL, 0xfaf7933bUL, 0x6d498623UL, 0x193cbcfaUL, +0x27627545UL, 0x825cf47aUL, 0x61bd8ba0UL, 0xd11e42d1UL, 0xcead04f4UL, 0x127ea392UL, +0x10428db7UL, 0x8272a972UL, 0x9270c4a8UL, 0x127de50bUL, 0x285ba1c8UL, 0x3c62f44fUL, +0x35c0eaa5UL, 0xe805d231UL, 0x428929fbUL, 0xb4fcdf82UL, 0x4fb66a53UL, 0x0e7dc15bUL, +0x1f081fabUL, 0x108618aeUL, 0xfcfd086dUL, 0xf9ff2889UL, 0x694bcc11UL, 0x236a5caeUL, +0x12deca4dUL, 0x2c3f8cc5UL, 0xd2d02dfeUL, 0xf8ef5896UL, 0xe4cf52daUL, 0x95155b67UL, +0x494a488cUL, 0xb9b6a80cUL, 0x5c8f82bcUL, 0x89d36b45UL, 0x3a609437UL, 0xec00c9a9UL, +0x44715253UL, 0x0a874b49UL, 0xd773bc40UL, 0x7c34671cUL, 0x02717ef6UL, 0x4feb5536UL, +0xa2d02fffUL, 0xd2bf60c4UL, 0xd43f03c0UL, 0x50b4ef6dUL, 0x07478cd1UL, 0x006e1888UL, +0xa2e53f55UL, 0xb9e6d4bcUL, 0xa2048016UL, 0x97573833UL, 0xd7207d67UL, 0xde0f8f3dUL, +0x72f87b33UL, 0xabcc4f33UL, 0x7688c55dUL, 0x7b00a6b0UL, 0x947b0001UL, 0x570075d2UL, +0xf9bb88f8UL, 0x8942019eUL, 0x4264a5ffUL, 0x856302e0UL, 0x72dbd92bUL, 0xee971b69UL, +0x6ea22fdeUL, 0x5f08ae2bUL, 0xaf7a616dUL, 0xe5c98767UL, 0xcf1febd2UL, 0x61efc8c2UL, +0xf1ac2571UL, 0xcc8239c2UL, 0x67214cb8UL, 0xb1e583d1UL, 0xb7dc3e62UL, 0x7f10bdceUL, +0xf90a5c38UL, 0x0ff0443dUL, 0x606e6dc6UL, 0x60543a49UL, 0x5727c148UL, 0x2be98a1dUL, +0x8ab41738UL, 0x20e1be24UL, 0xaf96da0fUL, 0x68458425UL, 0x99833be5UL, 0x600d457dUL, +0x282f9350UL, 0x8334b362UL, 0xd91d1120UL, 0x2b6d8da0UL, 0x642b1e31UL, 0x9c305a00UL, +0x52bce688UL, 0x1b03588aUL, 0xf7baefd5UL, 0x4142ed9cUL, 0xa4315c11UL, 0x83323ec5UL, +0xdfef4636UL, 0xa133c501UL, 0xe9d3531cUL, 0xee353783UL}; + +static const ulong32 S4[256] = { +0x9db30420UL, 0x1fb6e9deUL, 0xa7be7befUL, 0xd273a298UL, 0x4a4f7bdbUL, 0x64ad8c57UL, +0x85510443UL, 0xfa020ed1UL, 0x7e287affUL, 0xe60fb663UL, 0x095f35a1UL, 0x79ebf120UL, +0xfd059d43UL, 0x6497b7b1UL, 0xf3641f63UL, 0x241e4adfUL, 0x28147f5fUL, 0x4fa2b8cdUL, +0xc9430040UL, 0x0cc32220UL, 0xfdd30b30UL, 0xc0a5374fUL, 0x1d2d00d9UL, 0x24147b15UL, +0xee4d111aUL, 0x0fca5167UL, 0x71ff904cUL, 0x2d195ffeUL, 0x1a05645fUL, 0x0c13fefeUL, +0x081b08caUL, 0x05170121UL, 0x80530100UL, 0xe83e5efeUL, 0xac9af4f8UL, 0x7fe72701UL, +0xd2b8ee5fUL, 0x06df4261UL, 0xbb9e9b8aUL, 0x7293ea25UL, 0xce84ffdfUL, 0xf5718801UL, +0x3dd64b04UL, 0xa26f263bUL, 0x7ed48400UL, 0x547eebe6UL, 0x446d4ca0UL, 0x6cf3d6f5UL, +0x2649abdfUL, 0xaea0c7f5UL, 0x36338cc1UL, 0x503f7e93UL, 0xd3772061UL, 0x11b638e1UL, +0x72500e03UL, 0xf80eb2bbUL, 0xabe0502eUL, 0xec8d77deUL, 0x57971e81UL, 0xe14f6746UL, +0xc9335400UL, 0x6920318fUL, 0x081dbb99UL, 0xffc304a5UL, 0x4d351805UL, 0x7f3d5ce3UL, +0xa6c866c6UL, 0x5d5bcca9UL, 0xdaec6feaUL, 0x9f926f91UL, 0x9f46222fUL, 0x3991467dUL, +0xa5bf6d8eUL, 0x1143c44fUL, 0x43958302UL, 0xd0214eebUL, 0x022083b8UL, 0x3fb6180cUL, +0x18f8931eUL, 0x281658e6UL, 0x26486e3eUL, 0x8bd78a70UL, 0x7477e4c1UL, 0xb506e07cUL, +0xf32d0a25UL, 0x79098b02UL, 0xe4eabb81UL, 0x28123b23UL, 0x69dead38UL, 0x1574ca16UL, +0xdf871b62UL, 0x211c40b7UL, 0xa51a9ef9UL, 0x0014377bUL, 0x041e8ac8UL, 0x09114003UL, +0xbd59e4d2UL, 0xe3d156d5UL, 0x4fe876d5UL, 0x2f91a340UL, 0x557be8deUL, 0x00eae4a7UL, +0x0ce5c2ecUL, 0x4db4bba6UL, 0xe756bdffUL, 0xdd3369acUL, 0xec17b035UL, 0x06572327UL, +0x99afc8b0UL, 0x56c8c391UL, 0x6b65811cUL, 0x5e146119UL, 0x6e85cb75UL, 0xbe07c002UL, +0xc2325577UL, 0x893ff4ecUL, 0x5bbfc92dUL, 0xd0ec3b25UL, 0xb7801ab7UL, 0x8d6d3b24UL, +0x20c763efUL, 0xc366a5fcUL, 0x9c382880UL, 0x0ace3205UL, 0xaac9548aUL, 0xeca1d7c7UL, +0x041afa32UL, 0x1d16625aUL, 0x6701902cUL, 0x9b757a54UL, 0x31d477f7UL, 0x9126b031UL, +0x36cc6fdbUL, 0xc70b8b46UL, 0xd9e66a48UL, 0x56e55a79UL, 0x026a4cebUL, 0x52437effUL, +0x2f8f76b4UL, 0x0df980a5UL, 0x8674cde3UL, 0xedda04ebUL, 0x17a9be04UL, 0x2c18f4dfUL, +0xb7747f9dUL, 0xab2af7b4UL, 0xefc34d20UL, 0x2e096b7cUL, 0x1741a254UL, 0xe5b6a035UL, +0x213d42f6UL, 0x2c1c7c26UL, 0x61c2f50fUL, 0x6552daf9UL, 0xd2c231f8UL, 0x25130f69UL, +0xd8167fa2UL, 0x0418f2c8UL, 0x001a96a6UL, 0x0d1526abUL, 0x63315c21UL, 0x5e0a72ecUL, +0x49bafefdUL, 0x187908d9UL, 0x8d0dbd86UL, 0x311170a7UL, 0x3e9b640cUL, 0xcc3e10d7UL, +0xd5cad3b6UL, 0x0caec388UL, 0xf73001e1UL, 0x6c728affUL, 0x71eae2a1UL, 0x1f9af36eUL, +0xcfcbd12fUL, 0xc1de8417UL, 0xac07be6bUL, 0xcb44a1d8UL, 0x8b9b0f56UL, 0x013988c3UL, +0xb1c52fcaUL, 0xb4be31cdUL, 0xd8782806UL, 0x12a3a4e2UL, 0x6f7de532UL, 0x58fd7eb6UL, +0xd01ee900UL, 0x24adffc2UL, 0xf4990fc5UL, 0x9711aac5UL, 0x001d7b95UL, 0x82e5e7d2UL, +0x109873f6UL, 0x00613096UL, 0xc32d9521UL, 0xada121ffUL, 0x29908415UL, 0x7fbb977fUL, +0xaf9eb3dbUL, 0x29c9ed2aUL, 0x5ce2a465UL, 0xa730f32cUL, 0xd0aa3fe8UL, 0x8a5cc091UL, +0xd49e2ce7UL, 0x0ce454a9UL, 0xd60acd86UL, 0x015f1919UL, 0x77079103UL, 0xdea03af6UL, +0x78a8565eUL, 0xdee356dfUL, 0x21f05cbeUL, 0x8b75e387UL, 0xb3c50651UL, 0xb8a5c3efUL, +0xd8eeb6d2UL, 0xe523be77UL, 0xc2154529UL, 0x2f69efdfUL, 0xafe67afbUL, 0xf470c4b2UL, +0xf3e0eb5bUL, 0xd6cc9876UL, 0x39e4460cUL, 0x1fda8538UL, 0x1987832fUL, 0xca007367UL, +0xa99144f8UL, 0x296b299eUL, 0x492fc295UL, 0x9266beabUL, 0xb5676e69UL, 0x9bd3dddaUL, +0xdf7e052fUL, 0xdb25701cUL, 0x1b5e51eeUL, 0xf65324e6UL, 0x6afce36cUL, 0x0316cc04UL, +0x8644213eUL, 0xb7dc59d0UL, 0x7965291fUL, 0xccd6fd43UL, 0x41823979UL, 0x932bcdf6UL, +0xb657c34dUL, 0x4edfd282UL, 0x7ae5290cUL, 0x3cb9536bUL, 0x851e20feUL, 0x9833557eUL, +0x13ecf0b0UL, 0xd3ffb372UL, 0x3f85c5c1UL, 0x0aef7ed2UL}; + +static const ulong32 S5[256] = { +0x7ec90c04UL, 0x2c6e74b9UL, 0x9b0e66dfUL, 0xa6337911UL, 0xb86a7fffUL, 0x1dd358f5UL, +0x44dd9d44UL, 0x1731167fUL, 0x08fbf1faUL, 0xe7f511ccUL, 0xd2051b00UL, 0x735aba00UL, +0x2ab722d8UL, 0x386381cbUL, 0xacf6243aUL, 0x69befd7aUL, 0xe6a2e77fUL, 0xf0c720cdUL, +0xc4494816UL, 0xccf5c180UL, 0x38851640UL, 0x15b0a848UL, 0xe68b18cbUL, 0x4caadeffUL, +0x5f480a01UL, 0x0412b2aaUL, 0x259814fcUL, 0x41d0efe2UL, 0x4e40b48dUL, 0x248eb6fbUL, +0x8dba1cfeUL, 0x41a99b02UL, 0x1a550a04UL, 0xba8f65cbUL, 0x7251f4e7UL, 0x95a51725UL, +0xc106ecd7UL, 0x97a5980aUL, 0xc539b9aaUL, 0x4d79fe6aUL, 0xf2f3f763UL, 0x68af8040UL, +0xed0c9e56UL, 0x11b4958bUL, 0xe1eb5a88UL, 0x8709e6b0UL, 0xd7e07156UL, 0x4e29fea7UL, +0x6366e52dUL, 0x02d1c000UL, 0xc4ac8e05UL, 0x9377f571UL, 0x0c05372aUL, 0x578535f2UL, +0x2261be02UL, 0xd642a0c9UL, 0xdf13a280UL, 0x74b55bd2UL, 0x682199c0UL, 0xd421e5ecUL, +0x53fb3ce8UL, 0xc8adedb3UL, 0x28a87fc9UL, 0x3d959981UL, 0x5c1ff900UL, 0xfe38d399UL, +0x0c4eff0bUL, 0x062407eaUL, 0xaa2f4fb1UL, 0x4fb96976UL, 0x90c79505UL, 0xb0a8a774UL, +0xef55a1ffUL, 0xe59ca2c2UL, 0xa6b62d27UL, 0xe66a4263UL, 0xdf65001fUL, 0x0ec50966UL, +0xdfdd55bcUL, 0x29de0655UL, 0x911e739aUL, 0x17af8975UL, 0x32c7911cUL, 0x89f89468UL, +0x0d01e980UL, 0x524755f4UL, 0x03b63cc9UL, 0x0cc844b2UL, 0xbcf3f0aaUL, 0x87ac36e9UL, +0xe53a7426UL, 0x01b3d82bUL, 0x1a9e7449UL, 0x64ee2d7eUL, 0xcddbb1daUL, 0x01c94910UL, +0xb868bf80UL, 0x0d26f3fdUL, 0x9342ede7UL, 0x04a5c284UL, 0x636737b6UL, 0x50f5b616UL, +0xf24766e3UL, 0x8eca36c1UL, 0x136e05dbUL, 0xfef18391UL, 0xfb887a37UL, 0xd6e7f7d4UL, +0xc7fb7dc9UL, 0x3063fcdfUL, 0xb6f589deUL, 0xec2941daUL, 0x26e46695UL, 0xb7566419UL, +0xf654efc5UL, 0xd08d58b7UL, 0x48925401UL, 0xc1bacb7fUL, 0xe5ff550fUL, 0xb6083049UL, +0x5bb5d0e8UL, 0x87d72e5aUL, 0xab6a6ee1UL, 0x223a66ceUL, 0xc62bf3cdUL, 0x9e0885f9UL, +0x68cb3e47UL, 0x086c010fUL, 0xa21de820UL, 0xd18b69deUL, 0xf3f65777UL, 0xfa02c3f6UL, +0x407edac3UL, 0xcbb3d550UL, 0x1793084dUL, 0xb0d70ebaUL, 0x0ab378d5UL, 0xd951fb0cUL, +0xded7da56UL, 0x4124bbe4UL, 0x94ca0b56UL, 0x0f5755d1UL, 0xe0e1e56eUL, 0x6184b5beUL, +0x580a249fUL, 0x94f74bc0UL, 0xe327888eUL, 0x9f7b5561UL, 0xc3dc0280UL, 0x05687715UL, +0x646c6bd7UL, 0x44904db3UL, 0x66b4f0a3UL, 0xc0f1648aUL, 0x697ed5afUL, 0x49e92ff6UL, +0x309e374fUL, 0x2cb6356aUL, 0x85808573UL, 0x4991f840UL, 0x76f0ae02UL, 0x083be84dUL, +0x28421c9aUL, 0x44489406UL, 0x736e4cb8UL, 0xc1092910UL, 0x8bc95fc6UL, 0x7d869cf4UL, +0x134f616fUL, 0x2e77118dUL, 0xb31b2be1UL, 0xaa90b472UL, 0x3ca5d717UL, 0x7d161bbaUL, +0x9cad9010UL, 0xaf462ba2UL, 0x9fe459d2UL, 0x45d34559UL, 0xd9f2da13UL, 0xdbc65487UL, +0xf3e4f94eUL, 0x176d486fUL, 0x097c13eaUL, 0x631da5c7UL, 0x445f7382UL, 0x175683f4UL, +0xcdc66a97UL, 0x70be0288UL, 0xb3cdcf72UL, 0x6e5dd2f3UL, 0x20936079UL, 0x459b80a5UL, +0xbe60e2dbUL, 0xa9c23101UL, 0xeba5315cUL, 0x224e42f2UL, 0x1c5c1572UL, 0xf6721b2cUL, +0x1ad2fff3UL, 0x8c25404eUL, 0x324ed72fUL, 0x4067b7fdUL, 0x0523138eUL, 0x5ca3bc78UL, +0xdc0fd66eUL, 0x75922283UL, 0x784d6b17UL, 0x58ebb16eUL, 0x44094f85UL, 0x3f481d87UL, +0xfcfeae7bUL, 0x77b5ff76UL, 0x8c2302bfUL, 0xaaf47556UL, 0x5f46b02aUL, 0x2b092801UL, +0x3d38f5f7UL, 0x0ca81f36UL, 0x52af4a8aUL, 0x66d5e7c0UL, 0xdf3b0874UL, 0x95055110UL, +0x1b5ad7a8UL, 0xf61ed5adUL, 0x6cf6e479UL, 0x20758184UL, 0xd0cefa65UL, 0x88f7be58UL, +0x4a046826UL, 0x0ff6f8f3UL, 0xa09c7f70UL, 0x5346aba0UL, 0x5ce96c28UL, 0xe176eda3UL, +0x6bac307fUL, 0x376829d2UL, 0x85360fa9UL, 0x17e3fe2aUL, 0x24b79767UL, 0xf5a96b20UL, +0xd6cd2595UL, 0x68ff1ebfUL, 0x7555442cUL, 0xf19f06beUL, 0xf9e0659aUL, 0xeeb9491dUL, +0x34010718UL, 0xbb30cab8UL, 0xe822fe15UL, 0x88570983UL, 0x750e6249UL, 0xda627e55UL, +0x5e76ffa8UL, 0xb1534546UL, 0x6d47de08UL, 0xefe9e7d4UL}; + +static const ulong32 S6[256] = { +0xf6fa8f9dUL, 0x2cac6ce1UL, 0x4ca34867UL, 0xe2337f7cUL, 0x95db08e7UL, 0x016843b4UL, +0xeced5cbcUL, 0x325553acUL, 0xbf9f0960UL, 0xdfa1e2edUL, 0x83f0579dUL, 0x63ed86b9UL, +0x1ab6a6b8UL, 0xde5ebe39UL, 0xf38ff732UL, 0x8989b138UL, 0x33f14961UL, 0xc01937bdUL, +0xf506c6daUL, 0xe4625e7eUL, 0xa308ea99UL, 0x4e23e33cUL, 0x79cbd7ccUL, 0x48a14367UL, +0xa3149619UL, 0xfec94bd5UL, 0xa114174aUL, 0xeaa01866UL, 0xa084db2dUL, 0x09a8486fUL, +0xa888614aUL, 0x2900af98UL, 0x01665991UL, 0xe1992863UL, 0xc8f30c60UL, 0x2e78ef3cUL, +0xd0d51932UL, 0xcf0fec14UL, 0xf7ca07d2UL, 0xd0a82072UL, 0xfd41197eUL, 0x9305a6b0UL, +0xe86be3daUL, 0x74bed3cdUL, 0x372da53cUL, 0x4c7f4448UL, 0xdab5d440UL, 0x6dba0ec3UL, +0x083919a7UL, 0x9fbaeed9UL, 0x49dbcfb0UL, 0x4e670c53UL, 0x5c3d9c01UL, 0x64bdb941UL, +0x2c0e636aUL, 0xba7dd9cdUL, 0xea6f7388UL, 0xe70bc762UL, 0x35f29adbUL, 0x5c4cdd8dUL, +0xf0d48d8cUL, 0xb88153e2UL, 0x08a19866UL, 0x1ae2eac8UL, 0x284caf89UL, 0xaa928223UL, +0x9334be53UL, 0x3b3a21bfUL, 0x16434be3UL, 0x9aea3906UL, 0xefe8c36eUL, 0xf890cdd9UL, +0x80226daeUL, 0xc340a4a3UL, 0xdf7e9c09UL, 0xa694a807UL, 0x5b7c5eccUL, 0x221db3a6UL, +0x9a69a02fUL, 0x68818a54UL, 0xceb2296fUL, 0x53c0843aUL, 0xfe893655UL, 0x25bfe68aUL, +0xb4628abcUL, 0xcf222ebfUL, 0x25ac6f48UL, 0xa9a99387UL, 0x53bddb65UL, 0xe76ffbe7UL, +0xe967fd78UL, 0x0ba93563UL, 0x8e342bc1UL, 0xe8a11be9UL, 0x4980740dUL, 0xc8087dfcUL, +0x8de4bf99UL, 0xa11101a0UL, 0x7fd37975UL, 0xda5a26c0UL, 0xe81f994fUL, 0x9528cd89UL, +0xfd339fedUL, 0xb87834bfUL, 0x5f04456dUL, 0x22258698UL, 0xc9c4c83bUL, 0x2dc156beUL, +0x4f628daaUL, 0x57f55ec5UL, 0xe2220abeUL, 0xd2916ebfUL, 0x4ec75b95UL, 0x24f2c3c0UL, +0x42d15d99UL, 0xcd0d7fa0UL, 0x7b6e27ffUL, 0xa8dc8af0UL, 0x7345c106UL, 0xf41e232fUL, +0x35162386UL, 0xe6ea8926UL, 0x3333b094UL, 0x157ec6f2UL, 0x372b74afUL, 0x692573e4UL, +0xe9a9d848UL, 0xf3160289UL, 0x3a62ef1dUL, 0xa787e238UL, 0xf3a5f676UL, 0x74364853UL, +0x20951063UL, 0x4576698dUL, 0xb6fad407UL, 0x592af950UL, 0x36f73523UL, 0x4cfb6e87UL, +0x7da4cec0UL, 0x6c152daaUL, 0xcb0396a8UL, 0xc50dfe5dUL, 0xfcd707abUL, 0x0921c42fUL, +0x89dff0bbUL, 0x5fe2be78UL, 0x448f4f33UL, 0x754613c9UL, 0x2b05d08dUL, 0x48b9d585UL, +0xdc049441UL, 0xc8098f9bUL, 0x7dede786UL, 0xc39a3373UL, 0x42410005UL, 0x6a091751UL, +0x0ef3c8a6UL, 0x890072d6UL, 0x28207682UL, 0xa9a9f7beUL, 0xbf32679dUL, 0xd45b5b75UL, +0xb353fd00UL, 0xcbb0e358UL, 0x830f220aUL, 0x1f8fb214UL, 0xd372cf08UL, 0xcc3c4a13UL, +0x8cf63166UL, 0x061c87beUL, 0x88c98f88UL, 0x6062e397UL, 0x47cf8e7aUL, 0xb6c85283UL, +0x3cc2acfbUL, 0x3fc06976UL, 0x4e8f0252UL, 0x64d8314dUL, 0xda3870e3UL, 0x1e665459UL, +0xc10908f0UL, 0x513021a5UL, 0x6c5b68b7UL, 0x822f8aa0UL, 0x3007cd3eUL, 0x74719eefUL, +0xdc872681UL, 0x073340d4UL, 0x7e432fd9UL, 0x0c5ec241UL, 0x8809286cUL, 0xf592d891UL, +0x08a930f6UL, 0x957ef305UL, 0xb7fbffbdUL, 0xc266e96fUL, 0x6fe4ac98UL, 0xb173ecc0UL, +0xbc60b42aUL, 0x953498daUL, 0xfba1ae12UL, 0x2d4bd736UL, 0x0f25faabUL, 0xa4f3fcebUL, +0xe2969123UL, 0x257f0c3dUL, 0x9348af49UL, 0x361400bcUL, 0xe8816f4aUL, 0x3814f200UL, +0xa3f94043UL, 0x9c7a54c2UL, 0xbc704f57UL, 0xda41e7f9UL, 0xc25ad33aUL, 0x54f4a084UL, +0xb17f5505UL, 0x59357cbeUL, 0xedbd15c8UL, 0x7f97c5abUL, 0xba5ac7b5UL, 0xb6f6deafUL, +0x3a479c3aUL, 0x5302da25UL, 0x653d7e6aUL, 0x54268d49UL, 0x51a477eaUL, 0x5017d55bUL, +0xd7d25d88UL, 0x44136c76UL, 0x0404a8c8UL, 0xb8e5a121UL, 0xb81a928aUL, 0x60ed5869UL, +0x97c55b96UL, 0xeaec991bUL, 0x29935913UL, 0x01fdb7f1UL, 0x088e8dfaUL, 0x9ab6f6f5UL, +0x3b4cbf9fUL, 0x4a5de3abUL, 0xe6051d35UL, 0xa0e1d855UL, 0xd36b4cf1UL, 0xf544edebUL, +0xb0e93524UL, 0xbebb8fbdUL, 0xa2d762cfUL, 0x49c92f54UL, 0x38b5f331UL, 0x7128a454UL, +0x48392905UL, 0xa65b1db8UL, 0x851c97bdUL, 0xd675cf2fUL}; + +static const ulong32 S7[256] = { +0x85e04019UL, 0x332bf567UL, 0x662dbfffUL, 0xcfc65693UL, 0x2a8d7f6fUL, 0xab9bc912UL, +0xde6008a1UL, 0x2028da1fUL, 0x0227bce7UL, 0x4d642916UL, 0x18fac300UL, 0x50f18b82UL, +0x2cb2cb11UL, 0xb232e75cUL, 0x4b3695f2UL, 0xb28707deUL, 0xa05fbcf6UL, 0xcd4181e9UL, +0xe150210cUL, 0xe24ef1bdUL, 0xb168c381UL, 0xfde4e789UL, 0x5c79b0d8UL, 0x1e8bfd43UL, +0x4d495001UL, 0x38be4341UL, 0x913cee1dUL, 0x92a79c3fUL, 0x089766beUL, 0xbaeeadf4UL, +0x1286becfUL, 0xb6eacb19UL, 0x2660c200UL, 0x7565bde4UL, 0x64241f7aUL, 0x8248dca9UL, +0xc3b3ad66UL, 0x28136086UL, 0x0bd8dfa8UL, 0x356d1cf2UL, 0x107789beUL, 0xb3b2e9ceUL, +0x0502aa8fUL, 0x0bc0351eUL, 0x166bf52aUL, 0xeb12ff82UL, 0xe3486911UL, 0xd34d7516UL, +0x4e7b3affUL, 0x5f43671bUL, 0x9cf6e037UL, 0x4981ac83UL, 0x334266ceUL, 0x8c9341b7UL, +0xd0d854c0UL, 0xcb3a6c88UL, 0x47bc2829UL, 0x4725ba37UL, 0xa66ad22bUL, 0x7ad61f1eUL, +0x0c5cbafaUL, 0x4437f107UL, 0xb6e79962UL, 0x42d2d816UL, 0x0a961288UL, 0xe1a5c06eUL, +0x13749e67UL, 0x72fc081aUL, 0xb1d139f7UL, 0xf9583745UL, 0xcf19df58UL, 0xbec3f756UL, +0xc06eba30UL, 0x07211b24UL, 0x45c28829UL, 0xc95e317fUL, 0xbc8ec511UL, 0x38bc46e9UL, +0xc6e6fa14UL, 0xbae8584aUL, 0xad4ebc46UL, 0x468f508bUL, 0x7829435fUL, 0xf124183bUL, +0x821dba9fUL, 0xaff60ff4UL, 0xea2c4e6dUL, 0x16e39264UL, 0x92544a8bUL, 0x009b4fc3UL, +0xaba68cedUL, 0x9ac96f78UL, 0x06a5b79aUL, 0xb2856e6eUL, 0x1aec3ca9UL, 0xbe838688UL, +0x0e0804e9UL, 0x55f1be56UL, 0xe7e5363bUL, 0xb3a1f25dUL, 0xf7debb85UL, 0x61fe033cUL, +0x16746233UL, 0x3c034c28UL, 0xda6d0c74UL, 0x79aac56cUL, 0x3ce4e1adUL, 0x51f0c802UL, +0x98f8f35aUL, 0x1626a49fUL, 0xeed82b29UL, 0x1d382fe3UL, 0x0c4fb99aUL, 0xbb325778UL, +0x3ec6d97bUL, 0x6e77a6a9UL, 0xcb658b5cUL, 0xd45230c7UL, 0x2bd1408bUL, 0x60c03eb7UL, +0xb9068d78UL, 0xa33754f4UL, 0xf430c87dUL, 0xc8a71302UL, 0xb96d8c32UL, 0xebd4e7beUL, +0xbe8b9d2dUL, 0x7979fb06UL, 0xe7225308UL, 0x8b75cf77UL, 0x11ef8da4UL, 0xe083c858UL, +0x8d6b786fUL, 0x5a6317a6UL, 0xfa5cf7a0UL, 0x5dda0033UL, 0xf28ebfb0UL, 0xf5b9c310UL, +0xa0eac280UL, 0x08b9767aUL, 0xa3d9d2b0UL, 0x79d34217UL, 0x021a718dUL, 0x9ac6336aUL, +0x2711fd60UL, 0x438050e3UL, 0x069908a8UL, 0x3d7fedc4UL, 0x826d2befUL, 0x4eeb8476UL, +0x488dcf25UL, 0x36c9d566UL, 0x28e74e41UL, 0xc2610acaUL, 0x3d49a9cfUL, 0xbae3b9dfUL, +0xb65f8de6UL, 0x92aeaf64UL, 0x3ac7d5e6UL, 0x9ea80509UL, 0xf22b017dUL, 0xa4173f70UL, +0xdd1e16c3UL, 0x15e0d7f9UL, 0x50b1b887UL, 0x2b9f4fd5UL, 0x625aba82UL, 0x6a017962UL, +0x2ec01b9cUL, 0x15488aa9UL, 0xd716e740UL, 0x40055a2cUL, 0x93d29a22UL, 0xe32dbf9aUL, +0x058745b9UL, 0x3453dc1eUL, 0xd699296eUL, 0x496cff6fUL, 0x1c9f4986UL, 0xdfe2ed07UL, +0xb87242d1UL, 0x19de7eaeUL, 0x053e561aUL, 0x15ad6f8cUL, 0x66626c1cUL, 0x7154c24cUL, +0xea082b2aUL, 0x93eb2939UL, 0x17dcb0f0UL, 0x58d4f2aeUL, 0x9ea294fbUL, 0x52cf564cUL, +0x9883fe66UL, 0x2ec40581UL, 0x763953c3UL, 0x01d6692eUL, 0xd3a0c108UL, 0xa1e7160eUL, +0xe4f2dfa6UL, 0x693ed285UL, 0x74904698UL, 0x4c2b0eddUL, 0x4f757656UL, 0x5d393378UL, +0xa132234fUL, 0x3d321c5dUL, 0xc3f5e194UL, 0x4b269301UL, 0xc79f022fUL, 0x3c997e7eUL, +0x5e4f9504UL, 0x3ffafbbdUL, 0x76f7ad0eUL, 0x296693f4UL, 0x3d1fce6fUL, 0xc61e45beUL, +0xd3b5ab34UL, 0xf72bf9b7UL, 0x1b0434c0UL, 0x4e72b567UL, 0x5592a33dUL, 0xb5229301UL, +0xcfd2a87fUL, 0x60aeb767UL, 0x1814386bUL, 0x30bcc33dUL, 0x38a0c07dUL, 0xfd1606f2UL, +0xc363519bUL, 0x589dd390UL, 0x5479f8e6UL, 0x1cb8d647UL, 0x97fd61a9UL, 0xea7759f4UL, +0x2d57539dUL, 0x569a58cfUL, 0xe84e63adUL, 0x462e1b78UL, 0x6580f87eUL, 0xf3817914UL, +0x91da55f4UL, 0x40a230f3UL, 0xd1988f35UL, 0xb6e318d2UL, 0x3ffa50bcUL, 0x3d40f021UL, +0xc3c0bdaeUL, 0x4958c24cUL, 0x518f36b2UL, 0x84b1d370UL, 0x0fedce83UL, 0x878ddadaUL, +0xf2a279c7UL, 0x94e01be8UL, 0x90716f4bUL, 0x954b8aa3UL}; + +static const ulong32 S8[256] = { +0xe216300dUL, 0xbbddfffcUL, 0xa7ebdabdUL, 0x35648095UL, 0x7789f8b7UL, 0xe6c1121bUL, +0x0e241600UL, 0x052ce8b5UL, 0x11a9cfb0UL, 0xe5952f11UL, 0xece7990aUL, 0x9386d174UL, +0x2a42931cUL, 0x76e38111UL, 0xb12def3aUL, 0x37ddddfcUL, 0xde9adeb1UL, 0x0a0cc32cUL, +0xbe197029UL, 0x84a00940UL, 0xbb243a0fUL, 0xb4d137cfUL, 0xb44e79f0UL, 0x049eedfdUL, +0x0b15a15dUL, 0x480d3168UL, 0x8bbbde5aUL, 0x669ded42UL, 0xc7ece831UL, 0x3f8f95e7UL, +0x72df191bUL, 0x7580330dUL, 0x94074251UL, 0x5c7dcdfaUL, 0xabbe6d63UL, 0xaa402164UL, +0xb301d40aUL, 0x02e7d1caUL, 0x53571daeUL, 0x7a3182a2UL, 0x12a8ddecUL, 0xfdaa335dUL, +0x176f43e8UL, 0x71fb46d4UL, 0x38129022UL, 0xce949ad4UL, 0xb84769adUL, 0x965bd862UL, +0x82f3d055UL, 0x66fb9767UL, 0x15b80b4eUL, 0x1d5b47a0UL, 0x4cfde06fUL, 0xc28ec4b8UL, +0x57e8726eUL, 0x647a78fcUL, 0x99865d44UL, 0x608bd593UL, 0x6c200e03UL, 0x39dc5ff6UL, +0x5d0b00a3UL, 0xae63aff2UL, 0x7e8bd632UL, 0x70108c0cUL, 0xbbd35049UL, 0x2998df04UL, +0x980cf42aUL, 0x9b6df491UL, 0x9e7edd53UL, 0x06918548UL, 0x58cb7e07UL, 0x3b74ef2eUL, +0x522fffb1UL, 0xd24708ccUL, 0x1c7e27cdUL, 0xa4eb215bUL, 0x3cf1d2e2UL, 0x19b47a38UL, +0x424f7618UL, 0x35856039UL, 0x9d17dee7UL, 0x27eb35e6UL, 0xc9aff67bUL, 0x36baf5b8UL, +0x09c467cdUL, 0xc18910b1UL, 0xe11dbf7bUL, 0x06cd1af8UL, 0x7170c608UL, 0x2d5e3354UL, +0xd4de495aUL, 0x64c6d006UL, 0xbcc0c62cUL, 0x3dd00db3UL, 0x708f8f34UL, 0x77d51b42UL, +0x264f620fUL, 0x24b8d2bfUL, 0x15c1b79eUL, 0x46a52564UL, 0xf8d7e54eUL, 0x3e378160UL, +0x7895cda5UL, 0x859c15a5UL, 0xe6459788UL, 0xc37bc75fUL, 0xdb07ba0cUL, 0x0676a3abUL, +0x7f229b1eUL, 0x31842e7bUL, 0x24259fd7UL, 0xf8bef472UL, 0x835ffcb8UL, 0x6df4c1f2UL, +0x96f5b195UL, 0xfd0af0fcUL, 0xb0fe134cUL, 0xe2506d3dUL, 0x4f9b12eaUL, 0xf215f225UL, +0xa223736fUL, 0x9fb4c428UL, 0x25d04979UL, 0x34c713f8UL, 0xc4618187UL, 0xea7a6e98UL, +0x7cd16efcUL, 0x1436876cUL, 0xf1544107UL, 0xbedeee14UL, 0x56e9af27UL, 0xa04aa441UL, +0x3cf7c899UL, 0x92ecbae6UL, 0xdd67016dUL, 0x151682ebUL, 0xa842eedfUL, 0xfdba60b4UL, +0xf1907b75UL, 0x20e3030fUL, 0x24d8c29eUL, 0xe139673bUL, 0xefa63fb8UL, 0x71873054UL, +0xb6f2cf3bUL, 0x9f326442UL, 0xcb15a4ccUL, 0xb01a4504UL, 0xf1e47d8dUL, 0x844a1be5UL, +0xbae7dfdcUL, 0x42cbda70UL, 0xcd7dae0aUL, 0x57e85b7aUL, 0xd53f5af6UL, 0x20cf4d8cUL, +0xcea4d428UL, 0x79d130a4UL, 0x3486ebfbUL, 0x33d3cddcUL, 0x77853b53UL, 0x37effcb5UL, +0xc5068778UL, 0xe580b3e6UL, 0x4e68b8f4UL, 0xc5c8b37eUL, 0x0d809ea2UL, 0x398feb7cUL, +0x132a4f94UL, 0x43b7950eUL, 0x2fee7d1cUL, 0x223613bdUL, 0xdd06caa2UL, 0x37df932bUL, +0xc4248289UL, 0xacf3ebc3UL, 0x5715f6b7UL, 0xef3478ddUL, 0xf267616fUL, 0xc148cbe4UL, +0x9052815eUL, 0x5e410fabUL, 0xb48a2465UL, 0x2eda7fa4UL, 0xe87b40e4UL, 0xe98ea084UL, +0x5889e9e1UL, 0xefd390fcUL, 0xdd07d35bUL, 0xdb485694UL, 0x38d7e5b2UL, 0x57720101UL, +0x730edebcUL, 0x5b643113UL, 0x94917e4fUL, 0x503c2fbaUL, 0x646f1282UL, 0x7523d24aUL, +0xe0779695UL, 0xf9c17a8fUL, 0x7a5b2121UL, 0xd187b896UL, 0x29263a4dUL, 0xba510cdfUL, +0x81f47c9fUL, 0xad1163edUL, 0xea7b5965UL, 0x1a00726eUL, 0x11403092UL, 0x00da6d77UL, +0x4a0cdd61UL, 0xad1f4603UL, 0x605bdfb0UL, 0x9eedc364UL, 0x22ebe6a8UL, 0xcee7d28aUL, +0xa0e736a0UL, 0x5564a6b9UL, 0x10853209UL, 0xc7eb8f37UL, 0x2de705caUL, 0x8951570fUL, +0xdf09822bUL, 0xbd691a6cUL, 0xaa12e4f2UL, 0x87451c0fUL, 0xe0f6a27aUL, 0x3ada4819UL, +0x4cf1764fUL, 0x0d771c2bUL, 0x67cdb156UL, 0x350d8384UL, 0x5938fa0fUL, 0x42399ef3UL, +0x36997b07UL, 0x0e84093dUL, 0x4aa93e61UL, 0x8360d87bUL, 0x1fa98b0cUL, 0x1149382cUL, +0xe97625a5UL, 0x0614d1b7UL, 0x0e25244bUL, 0x0c768347UL, 0x589e8d82UL, 0x0d2059d1UL, +0xa466bb1eUL, 0xf8da0a82UL, 0x04f19130UL, 0xba6e4ec0UL, 0x99265164UL, 0x1ee7230dUL, +0x50b2ad80UL, 0xeaee6801UL, 0x8db2a283UL, 0xea8bf59eUL}; + +/* returns the i'th byte of a variable */ +#ifdef _MSC_VER + #define GB(x, i) ((unsigned char)((x[(15-i)>>2])>>(unsigned)(8*((15-i)&3)))) +#else + #define GB(x, i) (((x[(15-i)>>2])>>(unsigned)(8*((15-i)&3)))&255) +#endif + + /** + Initialize the LTC_CAST5 block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +#ifdef LTC_CLEAN_STACK +static int _cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#else +int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#endif +{ + ulong32 x[4], z[4]; + unsigned char buf[16]; + int y, i; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + if (num_rounds != 12 && num_rounds != 16 && num_rounds != 0) { + return CRYPT_INVALID_ROUNDS; + } + + if (num_rounds == 12 && keylen > 10) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen < 5 || keylen > 16) { + return CRYPT_INVALID_KEYSIZE; + } + + /* extend the key as required */ + zeromem(buf, sizeof(buf)); + XMEMCPY(buf, key, (size_t)keylen); + + /* load and start the awful looking network */ + for (y = 0; y < 4; y++) { + LOAD32H(x[3-y],buf+4*y); + } + + for (i = y = 0; y < 2; y++) { + z[3] = x[3] ^ S5[GB(x, 0xD)] ^ S6[GB(x, 0xF)] ^ S7[GB(x, 0xC)] ^ S8[GB(x, 0xE)] ^ S7[GB(x, 0x8)]; + z[2] = x[1] ^ S5[GB(z, 0x0)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x3)] ^ S8[GB(x, 0xA)]; + z[1] = x[0] ^ S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S5[GB(x, 0x9)]; + z[0] = x[2] ^ S5[GB(z, 0xA)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0xb)] ^ S8[GB(z, 0x8)] ^ S6[GB(x, 0xB)]; + skey->cast5.K[i++] = S5[GB(z, 0x8)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0x7)] ^ S8[GB(z, 0x6)] ^ S5[GB(z, 0x2)]; + skey->cast5.K[i++] = S5[GB(z, 0xA)] ^ S6[GB(z, 0xB)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S6[GB(z, 0x6)]; + skey->cast5.K[i++] = S5[GB(z, 0xC)] ^ S6[GB(z, 0xd)] ^ S7[GB(z, 0x3)] ^ S8[GB(z, 0x2)] ^ S7[GB(z, 0x9)]; + skey->cast5.K[i++] = S5[GB(z, 0xE)] ^ S6[GB(z, 0xF)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x0)] ^ S8[GB(z, 0xc)]; + + x[3] = z[1] ^ S5[GB(z, 0x5)] ^ S6[GB(z, 0x7)] ^ S7[GB(z, 0x4)] ^ S8[GB(z, 0x6)] ^ S7[GB(z, 0x0)]; + x[2] = z[3] ^ S5[GB(x, 0x0)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x3)] ^ S8[GB(z, 0x2)]; + x[1] = z[2] ^ S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S5[GB(z, 0x1)]; + x[0] = z[0] ^ S5[GB(x, 0xA)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0xb)] ^ S8[GB(x, 0x8)] ^ S6[GB(z, 0x3)]; + skey->cast5.K[i++] = S5[GB(x, 0x3)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0xc)] ^ S8[GB(x, 0xd)] ^ S5[GB(x, 0x8)]; + skey->cast5.K[i++] = S5[GB(x, 0x1)] ^ S6[GB(x, 0x0)] ^ S7[GB(x, 0xe)] ^ S8[GB(x, 0xf)] ^ S6[GB(x, 0xd)]; + skey->cast5.K[i++] = S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x8)] ^ S8[GB(x, 0x9)] ^ S7[GB(x, 0x3)]; + skey->cast5.K[i++] = S5[GB(x, 0x5)] ^ S6[GB(x, 0x4)] ^ S7[GB(x, 0xa)] ^ S8[GB(x, 0xb)] ^ S8[GB(x, 0x7)]; + + /* second half */ + z[3] = x[3] ^ S5[GB(x, 0xD)] ^ S6[GB(x, 0xF)] ^ S7[GB(x, 0xC)] ^ S8[GB(x, 0xE)] ^ S7[GB(x, 0x8)]; + z[2] = x[1] ^ S5[GB(z, 0x0)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x3)] ^ S8[GB(x, 0xA)]; + z[1] = x[0] ^ S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S5[GB(x, 0x9)]; + z[0] = x[2] ^ S5[GB(z, 0xA)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0xb)] ^ S8[GB(z, 0x8)] ^ S6[GB(x, 0xB)]; + skey->cast5.K[i++] = S5[GB(z, 0x3)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0xc)] ^ S8[GB(z, 0xd)] ^ S5[GB(z, 0x9)]; + skey->cast5.K[i++] = S5[GB(z, 0x1)] ^ S6[GB(z, 0x0)] ^ S7[GB(z, 0xe)] ^ S8[GB(z, 0xf)] ^ S6[GB(z, 0xc)]; + skey->cast5.K[i++] = S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x8)] ^ S8[GB(z, 0x9)] ^ S7[GB(z, 0x2)]; + skey->cast5.K[i++] = S5[GB(z, 0x5)] ^ S6[GB(z, 0x4)] ^ S7[GB(z, 0xa)] ^ S8[GB(z, 0xb)] ^ S8[GB(z, 0x6)]; + + x[3] = z[1] ^ S5[GB(z, 0x5)] ^ S6[GB(z, 0x7)] ^ S7[GB(z, 0x4)] ^ S8[GB(z, 0x6)] ^ S7[GB(z, 0x0)]; + x[2] = z[3] ^ S5[GB(x, 0x0)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x3)] ^ S8[GB(z, 0x2)]; + x[1] = z[2] ^ S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S5[GB(z, 0x1)]; + x[0] = z[0] ^ S5[GB(x, 0xA)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0xb)] ^ S8[GB(x, 0x8)] ^ S6[GB(z, 0x3)]; + skey->cast5.K[i++] = S5[GB(x, 0x8)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0x7)] ^ S8[GB(x, 0x6)] ^ S5[GB(x, 0x3)]; + skey->cast5.K[i++] = S5[GB(x, 0xa)] ^ S6[GB(x, 0xb)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S6[GB(x, 0x7)]; + skey->cast5.K[i++] = S5[GB(x, 0xc)] ^ S6[GB(x, 0xd)] ^ S7[GB(x, 0x3)] ^ S8[GB(x, 0x2)] ^ S7[GB(x, 0x8)]; + skey->cast5.K[i++] = S5[GB(x, 0xe)] ^ S6[GB(x, 0xf)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x0)] ^ S8[GB(x, 0xd)]; + } + + skey->cast5.keylen = keylen; + +#ifdef LTC_CLEAN_STACK + zeromem(buf, sizeof(buf)); + zeromem(x, sizeof(x)); + zeromem(z, sizeof(z)); +#endif + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int z; + z = _cast5_setup(key, keylen, num_rounds, skey); + burn_stack(sizeof(ulong32)*8 + 16 + sizeof(int)*2); + return z; +} +#endif + +#ifdef _MSC_VER + #define INLINE __inline +#else + #define INLINE +#endif + +INLINE static ulong32 FI(ulong32 R, ulong32 Km, ulong32 Kr) +{ + ulong32 I; + I = (Km + R); + I = ROL(I, Kr); + return ((S1[byte(I, 3)] ^ S2[byte(I,2)]) - S3[byte(I,1)]) + S4[byte(I,0)]; +} + +INLINE static ulong32 FII(ulong32 R, ulong32 Km, ulong32 Kr) +{ + ulong32 I; + I = (Km ^ R); + I = ROL(I, Kr); + return ((S1[byte(I, 3)] - S2[byte(I,2)]) + S3[byte(I,1)]) ^ S4[byte(I,0)]; +} + +INLINE static ulong32 FIII(ulong32 R, ulong32 Km, ulong32 Kr) +{ + ulong32 I; + I = (Km - R); + I = ROL(I, Kr); + return ((S1[byte(I, 3)] + S2[byte(I,2)]) ^ S3[byte(I,1)]) - S4[byte(I,0)]; +} + +/** + Encrypts a block of text with LTC_CAST5 + @param pt The input plaintext (8 bytes) + @param ct The output ciphertext (8 bytes) + @param skey The key as scheduled +*/ +#ifdef LTC_CLEAN_STACK +static int _cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#else +int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#endif +{ + ulong32 R, L; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + + LOAD32H(L,&pt[0]); + LOAD32H(R,&pt[4]); + L ^= FI(R, skey->cast5.K[0], skey->cast5.K[16]); + R ^= FII(L, skey->cast5.K[1], skey->cast5.K[17]); + L ^= FIII(R, skey->cast5.K[2], skey->cast5.K[18]); + R ^= FI(L, skey->cast5.K[3], skey->cast5.K[19]); + L ^= FII(R, skey->cast5.K[4], skey->cast5.K[20]); + R ^= FIII(L, skey->cast5.K[5], skey->cast5.K[21]); + L ^= FI(R, skey->cast5.K[6], skey->cast5.K[22]); + R ^= FII(L, skey->cast5.K[7], skey->cast5.K[23]); + L ^= FIII(R, skey->cast5.K[8], skey->cast5.K[24]); + R ^= FI(L, skey->cast5.K[9], skey->cast5.K[25]); + L ^= FII(R, skey->cast5.K[10], skey->cast5.K[26]); + R ^= FIII(L, skey->cast5.K[11], skey->cast5.K[27]); + if (skey->cast5.keylen > 10) { + L ^= FI(R, skey->cast5.K[12], skey->cast5.K[28]); + R ^= FII(L, skey->cast5.K[13], skey->cast5.K[29]); + L ^= FIII(R, skey->cast5.K[14], skey->cast5.K[30]); + R ^= FI(L, skey->cast5.K[15], skey->cast5.K[31]); + } + STORE32H(R,&ct[0]); + STORE32H(L,&ct[4]); + return CRYPT_OK; +} + + +#ifdef LTC_CLEAN_STACK +int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + int err =_cast5_ecb_encrypt(pt,ct,skey); + burn_stack(sizeof(ulong32)*3); + return err; +} +#endif + +/** + Decrypts a block of text with LTC_CAST5 + @param ct The input ciphertext (8 bytes) + @param pt The output plaintext (8 bytes) + @param skey The key as scheduled +*/ +#ifdef LTC_CLEAN_STACK +static int _cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#else +int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#endif +{ + ulong32 R, L; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + + LOAD32H(R,&ct[0]); + LOAD32H(L,&ct[4]); + if (skey->cast5.keylen > 10) { + R ^= FI(L, skey->cast5.K[15], skey->cast5.K[31]); + L ^= FIII(R, skey->cast5.K[14], skey->cast5.K[30]); + R ^= FII(L, skey->cast5.K[13], skey->cast5.K[29]); + L ^= FI(R, skey->cast5.K[12], skey->cast5.K[28]); + } + R ^= FIII(L, skey->cast5.K[11], skey->cast5.K[27]); + L ^= FII(R, skey->cast5.K[10], skey->cast5.K[26]); + R ^= FI(L, skey->cast5.K[9], skey->cast5.K[25]); + L ^= FIII(R, skey->cast5.K[8], skey->cast5.K[24]); + R ^= FII(L, skey->cast5.K[7], skey->cast5.K[23]); + L ^= FI(R, skey->cast5.K[6], skey->cast5.K[22]); + R ^= FIII(L, skey->cast5.K[5], skey->cast5.K[21]); + L ^= FII(R, skey->cast5.K[4], skey->cast5.K[20]); + R ^= FI(L, skey->cast5.K[3], skey->cast5.K[19]); + L ^= FIII(R, skey->cast5.K[2], skey->cast5.K[18]); + R ^= FII(L, skey->cast5.K[1], skey->cast5.K[17]); + L ^= FI(R, skey->cast5.K[0], skey->cast5.K[16]); + STORE32H(L,&pt[0]); + STORE32H(R,&pt[4]); + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + int err = _cast5_ecb_decrypt(ct,pt,skey); + burn_stack(sizeof(ulong32)*3); + return err; +} +#endif + +/** + Performs a self-test of the LTC_CAST5 block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int cast5_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + int keylen; + unsigned char key[16]; + unsigned char pt[8]; + unsigned char ct[8]; + } tests[] = { + { 16, + {0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2} + }, + { 10, + {0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0xEB, 0x6A, 0x71, 0x1A, 0x2C, 0x02, 0x27, 0x1B}, + }, + { 5, + {0x01, 0x23, 0x45, 0x67, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0x7A, 0xC8, 0x16, 0xD1, 0x6E, 0x9B, 0x30, 0x2E} + } + }; + int i, y, err; + symmetric_key key; + unsigned char tmp[2][8]; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + if ((err = cast5_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { + return err; + } + cast5_ecb_encrypt(tests[i].pt, tmp[0], &key); + cast5_ecb_decrypt(tmp[0], tmp[1], &key); + if ((XMEMCMP(tmp[0], tests[i].ct, 8) != 0) || (XMEMCMP(tmp[1], tests[i].pt, 8) != 0)) { + return CRYPT_FAIL_TESTVECTOR; + } + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) cast5_ecb_encrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) cast5_ecb_decrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + + } + return CRYPT_OK; + #endif +} + +/** Terminate the context + @param skey The scheduled key +*/ +void cast5_done(symmetric_key *skey) +{ + LTC_UNUSED_PARAM(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. + @return CRYPT_OK if the input key size is acceptable. +*/ +int cast5_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if (*keysize < 5) { + return CRYPT_INVALID_KEYSIZE; + } else if (*keysize > 16) { + *keysize = 16; + } + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/ciphers/des.c b/src/ltc/ciphers/des.c new file mode 100644 index 0000000..712c1ae --- /dev/null +++ b/src/ltc/ciphers/des.c @@ -0,0 +1,2085 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file des.c + DES code submitted by Dobes Vandermeer +*/ + +#ifdef LTC_DES + +#define EN0 0 +#define DE1 1 + +const struct ltc_cipher_descriptor des_desc = +{ + "des", + 13, + 8, 8, 8, 16, + &des_setup, + &des_ecb_encrypt, + &des_ecb_decrypt, + &des_test, + &des_done, + &des_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +const struct ltc_cipher_descriptor des3_desc = +{ + "3des", + 14, + 24, 24, 8, 16, + &des3_setup, + &des3_ecb_encrypt, + &des3_ecb_decrypt, + &des3_test, + &des3_done, + &des3_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +static const ulong32 bytebit[8] = +{ + 0200, 0100, 040, 020, 010, 04, 02, 01 +}; + +static const ulong32 bigbyte[24] = +{ + 0x800000UL, 0x400000UL, 0x200000UL, 0x100000UL, + 0x80000UL, 0x40000UL, 0x20000UL, 0x10000UL, + 0x8000UL, 0x4000UL, 0x2000UL, 0x1000UL, + 0x800UL, 0x400UL, 0x200UL, 0x100UL, + 0x80UL, 0x40UL, 0x20UL, 0x10UL, + 0x8UL, 0x4UL, 0x2UL, 0x1L +}; + +/* Use the key schedule specific in the standard (ANSI X3.92-1981) */ + +static const unsigned char pc1[56] = { + 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, + 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, + 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, + 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 +}; + +static const unsigned char totrot[16] = { + 1, 2, 4, 6, + 8, 10, 12, 14, + 15, 17, 19, 21, + 23, 25, 27, 28 +}; + +static const unsigned char pc2[48] = { + 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, + 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, + 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, + 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 +}; + + +static const ulong32 SP1[64] = +{ + 0x01010400UL, 0x00000000UL, 0x00010000UL, 0x01010404UL, + 0x01010004UL, 0x00010404UL, 0x00000004UL, 0x00010000UL, + 0x00000400UL, 0x01010400UL, 0x01010404UL, 0x00000400UL, + 0x01000404UL, 0x01010004UL, 0x01000000UL, 0x00000004UL, + 0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00010400UL, + 0x00010400UL, 0x01010000UL, 0x01010000UL, 0x01000404UL, + 0x00010004UL, 0x01000004UL, 0x01000004UL, 0x00010004UL, + 0x00000000UL, 0x00000404UL, 0x00010404UL, 0x01000000UL, + 0x00010000UL, 0x01010404UL, 0x00000004UL, 0x01010000UL, + 0x01010400UL, 0x01000000UL, 0x01000000UL, 0x00000400UL, + 0x01010004UL, 0x00010000UL, 0x00010400UL, 0x01000004UL, + 0x00000400UL, 0x00000004UL, 0x01000404UL, 0x00010404UL, + 0x01010404UL, 0x00010004UL, 0x01010000UL, 0x01000404UL, + 0x01000004UL, 0x00000404UL, 0x00010404UL, 0x01010400UL, + 0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00000000UL, + 0x00010004UL, 0x00010400UL, 0x00000000UL, 0x01010004UL +}; + +static const ulong32 SP2[64] = +{ + 0x80108020UL, 0x80008000UL, 0x00008000UL, 0x00108020UL, + 0x00100000UL, 0x00000020UL, 0x80100020UL, 0x80008020UL, + 0x80000020UL, 0x80108020UL, 0x80108000UL, 0x80000000UL, + 0x80008000UL, 0x00100000UL, 0x00000020UL, 0x80100020UL, + 0x00108000UL, 0x00100020UL, 0x80008020UL, 0x00000000UL, + 0x80000000UL, 0x00008000UL, 0x00108020UL, 0x80100000UL, + 0x00100020UL, 0x80000020UL, 0x00000000UL, 0x00108000UL, + 0x00008020UL, 0x80108000UL, 0x80100000UL, 0x00008020UL, + 0x00000000UL, 0x00108020UL, 0x80100020UL, 0x00100000UL, + 0x80008020UL, 0x80100000UL, 0x80108000UL, 0x00008000UL, + 0x80100000UL, 0x80008000UL, 0x00000020UL, 0x80108020UL, + 0x00108020UL, 0x00000020UL, 0x00008000UL, 0x80000000UL, + 0x00008020UL, 0x80108000UL, 0x00100000UL, 0x80000020UL, + 0x00100020UL, 0x80008020UL, 0x80000020UL, 0x00100020UL, + 0x00108000UL, 0x00000000UL, 0x80008000UL, 0x00008020UL, + 0x80000000UL, 0x80100020UL, 0x80108020UL, 0x00108000UL +}; + +static const ulong32 SP3[64] = +{ + 0x00000208UL, 0x08020200UL, 0x00000000UL, 0x08020008UL, + 0x08000200UL, 0x00000000UL, 0x00020208UL, 0x08000200UL, + 0x00020008UL, 0x08000008UL, 0x08000008UL, 0x00020000UL, + 0x08020208UL, 0x00020008UL, 0x08020000UL, 0x00000208UL, + 0x08000000UL, 0x00000008UL, 0x08020200UL, 0x00000200UL, + 0x00020200UL, 0x08020000UL, 0x08020008UL, 0x00020208UL, + 0x08000208UL, 0x00020200UL, 0x00020000UL, 0x08000208UL, + 0x00000008UL, 0x08020208UL, 0x00000200UL, 0x08000000UL, + 0x08020200UL, 0x08000000UL, 0x00020008UL, 0x00000208UL, + 0x00020000UL, 0x08020200UL, 0x08000200UL, 0x00000000UL, + 0x00000200UL, 0x00020008UL, 0x08020208UL, 0x08000200UL, + 0x08000008UL, 0x00000200UL, 0x00000000UL, 0x08020008UL, + 0x08000208UL, 0x00020000UL, 0x08000000UL, 0x08020208UL, + 0x00000008UL, 0x00020208UL, 0x00020200UL, 0x08000008UL, + 0x08020000UL, 0x08000208UL, 0x00000208UL, 0x08020000UL, + 0x00020208UL, 0x00000008UL, 0x08020008UL, 0x00020200UL +}; + +static const ulong32 SP4[64] = +{ + 0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL, + 0x00802080UL, 0x00800081UL, 0x00800001UL, 0x00002001UL, + 0x00000000UL, 0x00802000UL, 0x00802000UL, 0x00802081UL, + 0x00000081UL, 0x00000000UL, 0x00800080UL, 0x00800001UL, + 0x00000001UL, 0x00002000UL, 0x00800000UL, 0x00802001UL, + 0x00000080UL, 0x00800000UL, 0x00002001UL, 0x00002080UL, + 0x00800081UL, 0x00000001UL, 0x00002080UL, 0x00800080UL, + 0x00002000UL, 0x00802080UL, 0x00802081UL, 0x00000081UL, + 0x00800080UL, 0x00800001UL, 0x00802000UL, 0x00802081UL, + 0x00000081UL, 0x00000000UL, 0x00000000UL, 0x00802000UL, + 0x00002080UL, 0x00800080UL, 0x00800081UL, 0x00000001UL, + 0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL, + 0x00802081UL, 0x00000081UL, 0x00000001UL, 0x00002000UL, + 0x00800001UL, 0x00002001UL, 0x00802080UL, 0x00800081UL, + 0x00002001UL, 0x00002080UL, 0x00800000UL, 0x00802001UL, + 0x00000080UL, 0x00800000UL, 0x00002000UL, 0x00802080UL +}; + +static const ulong32 SP5[64] = +{ + 0x00000100UL, 0x02080100UL, 0x02080000UL, 0x42000100UL, + 0x00080000UL, 0x00000100UL, 0x40000000UL, 0x02080000UL, + 0x40080100UL, 0x00080000UL, 0x02000100UL, 0x40080100UL, + 0x42000100UL, 0x42080000UL, 0x00080100UL, 0x40000000UL, + 0x02000000UL, 0x40080000UL, 0x40080000UL, 0x00000000UL, + 0x40000100UL, 0x42080100UL, 0x42080100UL, 0x02000100UL, + 0x42080000UL, 0x40000100UL, 0x00000000UL, 0x42000000UL, + 0x02080100UL, 0x02000000UL, 0x42000000UL, 0x00080100UL, + 0x00080000UL, 0x42000100UL, 0x00000100UL, 0x02000000UL, + 0x40000000UL, 0x02080000UL, 0x42000100UL, 0x40080100UL, + 0x02000100UL, 0x40000000UL, 0x42080000UL, 0x02080100UL, + 0x40080100UL, 0x00000100UL, 0x02000000UL, 0x42080000UL, + 0x42080100UL, 0x00080100UL, 0x42000000UL, 0x42080100UL, + 0x02080000UL, 0x00000000UL, 0x40080000UL, 0x42000000UL, + 0x00080100UL, 0x02000100UL, 0x40000100UL, 0x00080000UL, + 0x00000000UL, 0x40080000UL, 0x02080100UL, 0x40000100UL +}; + +static const ulong32 SP6[64] = +{ + 0x20000010UL, 0x20400000UL, 0x00004000UL, 0x20404010UL, + 0x20400000UL, 0x00000010UL, 0x20404010UL, 0x00400000UL, + 0x20004000UL, 0x00404010UL, 0x00400000UL, 0x20000010UL, + 0x00400010UL, 0x20004000UL, 0x20000000UL, 0x00004010UL, + 0x00000000UL, 0x00400010UL, 0x20004010UL, 0x00004000UL, + 0x00404000UL, 0x20004010UL, 0x00000010UL, 0x20400010UL, + 0x20400010UL, 0x00000000UL, 0x00404010UL, 0x20404000UL, + 0x00004010UL, 0x00404000UL, 0x20404000UL, 0x20000000UL, + 0x20004000UL, 0x00000010UL, 0x20400010UL, 0x00404000UL, + 0x20404010UL, 0x00400000UL, 0x00004010UL, 0x20000010UL, + 0x00400000UL, 0x20004000UL, 0x20000000UL, 0x00004010UL, + 0x20000010UL, 0x20404010UL, 0x00404000UL, 0x20400000UL, + 0x00404010UL, 0x20404000UL, 0x00000000UL, 0x20400010UL, + 0x00000010UL, 0x00004000UL, 0x20400000UL, 0x00404010UL, + 0x00004000UL, 0x00400010UL, 0x20004010UL, 0x00000000UL, + 0x20404000UL, 0x20000000UL, 0x00400010UL, 0x20004010UL +}; + +static const ulong32 SP7[64] = +{ + 0x00200000UL, 0x04200002UL, 0x04000802UL, 0x00000000UL, + 0x00000800UL, 0x04000802UL, 0x00200802UL, 0x04200800UL, + 0x04200802UL, 0x00200000UL, 0x00000000UL, 0x04000002UL, + 0x00000002UL, 0x04000000UL, 0x04200002UL, 0x00000802UL, + 0x04000800UL, 0x00200802UL, 0x00200002UL, 0x04000800UL, + 0x04000002UL, 0x04200000UL, 0x04200800UL, 0x00200002UL, + 0x04200000UL, 0x00000800UL, 0x00000802UL, 0x04200802UL, + 0x00200800UL, 0x00000002UL, 0x04000000UL, 0x00200800UL, + 0x04000000UL, 0x00200800UL, 0x00200000UL, 0x04000802UL, + 0x04000802UL, 0x04200002UL, 0x04200002UL, 0x00000002UL, + 0x00200002UL, 0x04000000UL, 0x04000800UL, 0x00200000UL, + 0x04200800UL, 0x00000802UL, 0x00200802UL, 0x04200800UL, + 0x00000802UL, 0x04000002UL, 0x04200802UL, 0x04200000UL, + 0x00200800UL, 0x00000000UL, 0x00000002UL, 0x04200802UL, + 0x00000000UL, 0x00200802UL, 0x04200000UL, 0x00000800UL, + 0x04000002UL, 0x04000800UL, 0x00000800UL, 0x00200002UL +}; + +static const ulong32 SP8[64] = +{ + 0x10001040UL, 0x00001000UL, 0x00040000UL, 0x10041040UL, + 0x10000000UL, 0x10001040UL, 0x00000040UL, 0x10000000UL, + 0x00040040UL, 0x10040000UL, 0x10041040UL, 0x00041000UL, + 0x10041000UL, 0x00041040UL, 0x00001000UL, 0x00000040UL, + 0x10040000UL, 0x10000040UL, 0x10001000UL, 0x00001040UL, + 0x00041000UL, 0x00040040UL, 0x10040040UL, 0x10041000UL, + 0x00001040UL, 0x00000000UL, 0x00000000UL, 0x10040040UL, + 0x10000040UL, 0x10001000UL, 0x00041040UL, 0x00040000UL, + 0x00041040UL, 0x00040000UL, 0x10041000UL, 0x00001000UL, + 0x00000040UL, 0x10040040UL, 0x00001000UL, 0x00041040UL, + 0x10001000UL, 0x00000040UL, 0x10000040UL, 0x10040000UL, + 0x10040040UL, 0x10000000UL, 0x00040000UL, 0x10001040UL, + 0x00000000UL, 0x10041040UL, 0x00040040UL, 0x10000040UL, + 0x10040000UL, 0x10001000UL, 0x10001040UL, 0x00000000UL, + 0x10041040UL, 0x00041000UL, 0x00041000UL, 0x00001040UL, + 0x00001040UL, 0x00040040UL, 0x10000000UL, 0x10041000UL +}; + +#ifndef LTC_SMALL_CODE + +static const ulong64 des_ip[8][256] = { + +{ CONST64(0x0000000000000000), CONST64(0x0000001000000000), CONST64(0x0000000000000010), CONST64(0x0000001000000010), + CONST64(0x0000100000000000), CONST64(0x0000101000000000), CONST64(0x0000100000000010), CONST64(0x0000101000000010), + CONST64(0x0000000000001000), CONST64(0x0000001000001000), CONST64(0x0000000000001010), CONST64(0x0000001000001010), + CONST64(0x0000100000001000), CONST64(0x0000101000001000), CONST64(0x0000100000001010), CONST64(0x0000101000001010), + CONST64(0x0010000000000000), CONST64(0x0010001000000000), CONST64(0x0010000000000010), CONST64(0x0010001000000010), + CONST64(0x0010100000000000), CONST64(0x0010101000000000), CONST64(0x0010100000000010), CONST64(0x0010101000000010), + CONST64(0x0010000000001000), CONST64(0x0010001000001000), CONST64(0x0010000000001010), CONST64(0x0010001000001010), + CONST64(0x0010100000001000), CONST64(0x0010101000001000), CONST64(0x0010100000001010), CONST64(0x0010101000001010), + CONST64(0x0000000000100000), CONST64(0x0000001000100000), CONST64(0x0000000000100010), CONST64(0x0000001000100010), + CONST64(0x0000100000100000), CONST64(0x0000101000100000), CONST64(0x0000100000100010), CONST64(0x0000101000100010), + CONST64(0x0000000000101000), CONST64(0x0000001000101000), CONST64(0x0000000000101010), CONST64(0x0000001000101010), + CONST64(0x0000100000101000), CONST64(0x0000101000101000), CONST64(0x0000100000101010), CONST64(0x0000101000101010), + CONST64(0x0010000000100000), CONST64(0x0010001000100000), CONST64(0x0010000000100010), CONST64(0x0010001000100010), + CONST64(0x0010100000100000), CONST64(0x0010101000100000), CONST64(0x0010100000100010), CONST64(0x0010101000100010), + CONST64(0x0010000000101000), CONST64(0x0010001000101000), CONST64(0x0010000000101010), CONST64(0x0010001000101010), + CONST64(0x0010100000101000), CONST64(0x0010101000101000), CONST64(0x0010100000101010), CONST64(0x0010101000101010), + CONST64(0x1000000000000000), CONST64(0x1000001000000000), CONST64(0x1000000000000010), CONST64(0x1000001000000010), + CONST64(0x1000100000000000), CONST64(0x1000101000000000), CONST64(0x1000100000000010), CONST64(0x1000101000000010), + CONST64(0x1000000000001000), CONST64(0x1000001000001000), CONST64(0x1000000000001010), CONST64(0x1000001000001010), + CONST64(0x1000100000001000), CONST64(0x1000101000001000), CONST64(0x1000100000001010), CONST64(0x1000101000001010), + CONST64(0x1010000000000000), CONST64(0x1010001000000000), CONST64(0x1010000000000010), CONST64(0x1010001000000010), + CONST64(0x1010100000000000), CONST64(0x1010101000000000), CONST64(0x1010100000000010), CONST64(0x1010101000000010), + CONST64(0x1010000000001000), CONST64(0x1010001000001000), CONST64(0x1010000000001010), CONST64(0x1010001000001010), + CONST64(0x1010100000001000), CONST64(0x1010101000001000), CONST64(0x1010100000001010), CONST64(0x1010101000001010), + CONST64(0x1000000000100000), CONST64(0x1000001000100000), CONST64(0x1000000000100010), CONST64(0x1000001000100010), + CONST64(0x1000100000100000), CONST64(0x1000101000100000), CONST64(0x1000100000100010), CONST64(0x1000101000100010), + CONST64(0x1000000000101000), CONST64(0x1000001000101000), CONST64(0x1000000000101010), CONST64(0x1000001000101010), + CONST64(0x1000100000101000), CONST64(0x1000101000101000), CONST64(0x1000100000101010), CONST64(0x1000101000101010), + CONST64(0x1010000000100000), CONST64(0x1010001000100000), CONST64(0x1010000000100010), CONST64(0x1010001000100010), + CONST64(0x1010100000100000), CONST64(0x1010101000100000), CONST64(0x1010100000100010), CONST64(0x1010101000100010), + CONST64(0x1010000000101000), CONST64(0x1010001000101000), CONST64(0x1010000000101010), CONST64(0x1010001000101010), + CONST64(0x1010100000101000), CONST64(0x1010101000101000), CONST64(0x1010100000101010), CONST64(0x1010101000101010), + CONST64(0x0000000010000000), CONST64(0x0000001010000000), CONST64(0x0000000010000010), CONST64(0x0000001010000010), + CONST64(0x0000100010000000), CONST64(0x0000101010000000), CONST64(0x0000100010000010), CONST64(0x0000101010000010), + CONST64(0x0000000010001000), CONST64(0x0000001010001000), CONST64(0x0000000010001010), CONST64(0x0000001010001010), + CONST64(0x0000100010001000), CONST64(0x0000101010001000), CONST64(0x0000100010001010), CONST64(0x0000101010001010), + CONST64(0x0010000010000000), CONST64(0x0010001010000000), CONST64(0x0010000010000010), CONST64(0x0010001010000010), + CONST64(0x0010100010000000), CONST64(0x0010101010000000), CONST64(0x0010100010000010), CONST64(0x0010101010000010), + CONST64(0x0010000010001000), CONST64(0x0010001010001000), CONST64(0x0010000010001010), CONST64(0x0010001010001010), + CONST64(0x0010100010001000), CONST64(0x0010101010001000), CONST64(0x0010100010001010), CONST64(0x0010101010001010), + CONST64(0x0000000010100000), CONST64(0x0000001010100000), CONST64(0x0000000010100010), CONST64(0x0000001010100010), + CONST64(0x0000100010100000), CONST64(0x0000101010100000), CONST64(0x0000100010100010), CONST64(0x0000101010100010), + CONST64(0x0000000010101000), CONST64(0x0000001010101000), CONST64(0x0000000010101010), CONST64(0x0000001010101010), + CONST64(0x0000100010101000), CONST64(0x0000101010101000), CONST64(0x0000100010101010), CONST64(0x0000101010101010), + CONST64(0x0010000010100000), CONST64(0x0010001010100000), CONST64(0x0010000010100010), CONST64(0x0010001010100010), + CONST64(0x0010100010100000), CONST64(0x0010101010100000), CONST64(0x0010100010100010), CONST64(0x0010101010100010), + CONST64(0x0010000010101000), CONST64(0x0010001010101000), CONST64(0x0010000010101010), CONST64(0x0010001010101010), + CONST64(0x0010100010101000), CONST64(0x0010101010101000), CONST64(0x0010100010101010), CONST64(0x0010101010101010), + CONST64(0x1000000010000000), CONST64(0x1000001010000000), CONST64(0x1000000010000010), CONST64(0x1000001010000010), + CONST64(0x1000100010000000), CONST64(0x1000101010000000), CONST64(0x1000100010000010), CONST64(0x1000101010000010), + CONST64(0x1000000010001000), CONST64(0x1000001010001000), CONST64(0x1000000010001010), CONST64(0x1000001010001010), + CONST64(0x1000100010001000), CONST64(0x1000101010001000), CONST64(0x1000100010001010), CONST64(0x1000101010001010), + CONST64(0x1010000010000000), CONST64(0x1010001010000000), CONST64(0x1010000010000010), CONST64(0x1010001010000010), + CONST64(0x1010100010000000), CONST64(0x1010101010000000), CONST64(0x1010100010000010), CONST64(0x1010101010000010), + CONST64(0x1010000010001000), CONST64(0x1010001010001000), CONST64(0x1010000010001010), CONST64(0x1010001010001010), + CONST64(0x1010100010001000), CONST64(0x1010101010001000), CONST64(0x1010100010001010), CONST64(0x1010101010001010), + CONST64(0x1000000010100000), CONST64(0x1000001010100000), CONST64(0x1000000010100010), CONST64(0x1000001010100010), + CONST64(0x1000100010100000), CONST64(0x1000101010100000), CONST64(0x1000100010100010), CONST64(0x1000101010100010), + CONST64(0x1000000010101000), CONST64(0x1000001010101000), CONST64(0x1000000010101010), CONST64(0x1000001010101010), + CONST64(0x1000100010101000), CONST64(0x1000101010101000), CONST64(0x1000100010101010), CONST64(0x1000101010101010), + CONST64(0x1010000010100000), CONST64(0x1010001010100000), CONST64(0x1010000010100010), CONST64(0x1010001010100010), + CONST64(0x1010100010100000), CONST64(0x1010101010100000), CONST64(0x1010100010100010), CONST64(0x1010101010100010), + CONST64(0x1010000010101000), CONST64(0x1010001010101000), CONST64(0x1010000010101010), CONST64(0x1010001010101010), + CONST64(0x1010100010101000), CONST64(0x1010101010101000), CONST64(0x1010100010101010), CONST64(0x1010101010101010) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000000800000000), CONST64(0x0000000000000008), CONST64(0x0000000800000008), + CONST64(0x0000080000000000), CONST64(0x0000080800000000), CONST64(0x0000080000000008), CONST64(0x0000080800000008), + CONST64(0x0000000000000800), CONST64(0x0000000800000800), CONST64(0x0000000000000808), CONST64(0x0000000800000808), + CONST64(0x0000080000000800), CONST64(0x0000080800000800), CONST64(0x0000080000000808), CONST64(0x0000080800000808), + CONST64(0x0008000000000000), CONST64(0x0008000800000000), CONST64(0x0008000000000008), CONST64(0x0008000800000008), + CONST64(0x0008080000000000), CONST64(0x0008080800000000), CONST64(0x0008080000000008), CONST64(0x0008080800000008), + CONST64(0x0008000000000800), CONST64(0x0008000800000800), CONST64(0x0008000000000808), CONST64(0x0008000800000808), + CONST64(0x0008080000000800), CONST64(0x0008080800000800), CONST64(0x0008080000000808), CONST64(0x0008080800000808), + CONST64(0x0000000000080000), CONST64(0x0000000800080000), CONST64(0x0000000000080008), CONST64(0x0000000800080008), + CONST64(0x0000080000080000), CONST64(0x0000080800080000), CONST64(0x0000080000080008), CONST64(0x0000080800080008), + CONST64(0x0000000000080800), CONST64(0x0000000800080800), CONST64(0x0000000000080808), CONST64(0x0000000800080808), + CONST64(0x0000080000080800), CONST64(0x0000080800080800), CONST64(0x0000080000080808), CONST64(0x0000080800080808), + CONST64(0x0008000000080000), CONST64(0x0008000800080000), CONST64(0x0008000000080008), CONST64(0x0008000800080008), + CONST64(0x0008080000080000), CONST64(0x0008080800080000), CONST64(0x0008080000080008), CONST64(0x0008080800080008), + CONST64(0x0008000000080800), CONST64(0x0008000800080800), CONST64(0x0008000000080808), CONST64(0x0008000800080808), + CONST64(0x0008080000080800), CONST64(0x0008080800080800), CONST64(0x0008080000080808), CONST64(0x0008080800080808), + CONST64(0x0800000000000000), CONST64(0x0800000800000000), CONST64(0x0800000000000008), CONST64(0x0800000800000008), + CONST64(0x0800080000000000), CONST64(0x0800080800000000), CONST64(0x0800080000000008), CONST64(0x0800080800000008), + CONST64(0x0800000000000800), CONST64(0x0800000800000800), CONST64(0x0800000000000808), CONST64(0x0800000800000808), + CONST64(0x0800080000000800), CONST64(0x0800080800000800), CONST64(0x0800080000000808), CONST64(0x0800080800000808), + CONST64(0x0808000000000000), CONST64(0x0808000800000000), CONST64(0x0808000000000008), CONST64(0x0808000800000008), + CONST64(0x0808080000000000), CONST64(0x0808080800000000), CONST64(0x0808080000000008), CONST64(0x0808080800000008), + CONST64(0x0808000000000800), CONST64(0x0808000800000800), CONST64(0x0808000000000808), CONST64(0x0808000800000808), + CONST64(0x0808080000000800), CONST64(0x0808080800000800), CONST64(0x0808080000000808), CONST64(0x0808080800000808), + CONST64(0x0800000000080000), CONST64(0x0800000800080000), CONST64(0x0800000000080008), CONST64(0x0800000800080008), + CONST64(0x0800080000080000), CONST64(0x0800080800080000), CONST64(0x0800080000080008), CONST64(0x0800080800080008), + CONST64(0x0800000000080800), CONST64(0x0800000800080800), CONST64(0x0800000000080808), CONST64(0x0800000800080808), + CONST64(0x0800080000080800), CONST64(0x0800080800080800), CONST64(0x0800080000080808), CONST64(0x0800080800080808), + CONST64(0x0808000000080000), CONST64(0x0808000800080000), CONST64(0x0808000000080008), CONST64(0x0808000800080008), + CONST64(0x0808080000080000), CONST64(0x0808080800080000), CONST64(0x0808080000080008), CONST64(0x0808080800080008), + CONST64(0x0808000000080800), CONST64(0x0808000800080800), CONST64(0x0808000000080808), CONST64(0x0808000800080808), + CONST64(0x0808080000080800), CONST64(0x0808080800080800), CONST64(0x0808080000080808), CONST64(0x0808080800080808), + CONST64(0x0000000008000000), CONST64(0x0000000808000000), CONST64(0x0000000008000008), CONST64(0x0000000808000008), + CONST64(0x0000080008000000), CONST64(0x0000080808000000), CONST64(0x0000080008000008), CONST64(0x0000080808000008), + CONST64(0x0000000008000800), CONST64(0x0000000808000800), CONST64(0x0000000008000808), CONST64(0x0000000808000808), + CONST64(0x0000080008000800), CONST64(0x0000080808000800), CONST64(0x0000080008000808), CONST64(0x0000080808000808), + CONST64(0x0008000008000000), CONST64(0x0008000808000000), CONST64(0x0008000008000008), CONST64(0x0008000808000008), + CONST64(0x0008080008000000), CONST64(0x0008080808000000), CONST64(0x0008080008000008), CONST64(0x0008080808000008), + CONST64(0x0008000008000800), CONST64(0x0008000808000800), CONST64(0x0008000008000808), CONST64(0x0008000808000808), + CONST64(0x0008080008000800), CONST64(0x0008080808000800), CONST64(0x0008080008000808), CONST64(0x0008080808000808), + CONST64(0x0000000008080000), CONST64(0x0000000808080000), CONST64(0x0000000008080008), CONST64(0x0000000808080008), + CONST64(0x0000080008080000), CONST64(0x0000080808080000), CONST64(0x0000080008080008), CONST64(0x0000080808080008), + CONST64(0x0000000008080800), CONST64(0x0000000808080800), CONST64(0x0000000008080808), CONST64(0x0000000808080808), + CONST64(0x0000080008080800), CONST64(0x0000080808080800), CONST64(0x0000080008080808), CONST64(0x0000080808080808), + CONST64(0x0008000008080000), CONST64(0x0008000808080000), CONST64(0x0008000008080008), CONST64(0x0008000808080008), + CONST64(0x0008080008080000), CONST64(0x0008080808080000), CONST64(0x0008080008080008), CONST64(0x0008080808080008), + CONST64(0x0008000008080800), CONST64(0x0008000808080800), CONST64(0x0008000008080808), CONST64(0x0008000808080808), + CONST64(0x0008080008080800), CONST64(0x0008080808080800), CONST64(0x0008080008080808), CONST64(0x0008080808080808), + CONST64(0x0800000008000000), CONST64(0x0800000808000000), CONST64(0x0800000008000008), CONST64(0x0800000808000008), + CONST64(0x0800080008000000), CONST64(0x0800080808000000), CONST64(0x0800080008000008), CONST64(0x0800080808000008), + CONST64(0x0800000008000800), CONST64(0x0800000808000800), CONST64(0x0800000008000808), CONST64(0x0800000808000808), + CONST64(0x0800080008000800), CONST64(0x0800080808000800), CONST64(0x0800080008000808), CONST64(0x0800080808000808), + CONST64(0x0808000008000000), CONST64(0x0808000808000000), CONST64(0x0808000008000008), CONST64(0x0808000808000008), + CONST64(0x0808080008000000), CONST64(0x0808080808000000), CONST64(0x0808080008000008), CONST64(0x0808080808000008), + CONST64(0x0808000008000800), CONST64(0x0808000808000800), CONST64(0x0808000008000808), CONST64(0x0808000808000808), + CONST64(0x0808080008000800), CONST64(0x0808080808000800), CONST64(0x0808080008000808), CONST64(0x0808080808000808), + CONST64(0x0800000008080000), CONST64(0x0800000808080000), CONST64(0x0800000008080008), CONST64(0x0800000808080008), + CONST64(0x0800080008080000), CONST64(0x0800080808080000), CONST64(0x0800080008080008), CONST64(0x0800080808080008), + CONST64(0x0800000008080800), CONST64(0x0800000808080800), CONST64(0x0800000008080808), CONST64(0x0800000808080808), + CONST64(0x0800080008080800), CONST64(0x0800080808080800), CONST64(0x0800080008080808), CONST64(0x0800080808080808), + CONST64(0x0808000008080000), CONST64(0x0808000808080000), CONST64(0x0808000008080008), CONST64(0x0808000808080008), + CONST64(0x0808080008080000), CONST64(0x0808080808080000), CONST64(0x0808080008080008), CONST64(0x0808080808080008), + CONST64(0x0808000008080800), CONST64(0x0808000808080800), CONST64(0x0808000008080808), CONST64(0x0808000808080808), + CONST64(0x0808080008080800), CONST64(0x0808080808080800), CONST64(0x0808080008080808), CONST64(0x0808080808080808) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000000400000000), CONST64(0x0000000000000004), CONST64(0x0000000400000004), + CONST64(0x0000040000000000), CONST64(0x0000040400000000), CONST64(0x0000040000000004), CONST64(0x0000040400000004), + CONST64(0x0000000000000400), CONST64(0x0000000400000400), CONST64(0x0000000000000404), CONST64(0x0000000400000404), + CONST64(0x0000040000000400), CONST64(0x0000040400000400), CONST64(0x0000040000000404), CONST64(0x0000040400000404), + CONST64(0x0004000000000000), CONST64(0x0004000400000000), CONST64(0x0004000000000004), CONST64(0x0004000400000004), + CONST64(0x0004040000000000), CONST64(0x0004040400000000), CONST64(0x0004040000000004), CONST64(0x0004040400000004), + CONST64(0x0004000000000400), CONST64(0x0004000400000400), CONST64(0x0004000000000404), CONST64(0x0004000400000404), + CONST64(0x0004040000000400), CONST64(0x0004040400000400), CONST64(0x0004040000000404), CONST64(0x0004040400000404), + CONST64(0x0000000000040000), CONST64(0x0000000400040000), CONST64(0x0000000000040004), CONST64(0x0000000400040004), + CONST64(0x0000040000040000), CONST64(0x0000040400040000), CONST64(0x0000040000040004), CONST64(0x0000040400040004), + CONST64(0x0000000000040400), CONST64(0x0000000400040400), CONST64(0x0000000000040404), CONST64(0x0000000400040404), + CONST64(0x0000040000040400), CONST64(0x0000040400040400), CONST64(0x0000040000040404), CONST64(0x0000040400040404), + CONST64(0x0004000000040000), CONST64(0x0004000400040000), CONST64(0x0004000000040004), CONST64(0x0004000400040004), + CONST64(0x0004040000040000), CONST64(0x0004040400040000), CONST64(0x0004040000040004), CONST64(0x0004040400040004), + CONST64(0x0004000000040400), CONST64(0x0004000400040400), CONST64(0x0004000000040404), CONST64(0x0004000400040404), + CONST64(0x0004040000040400), CONST64(0x0004040400040400), CONST64(0x0004040000040404), CONST64(0x0004040400040404), + CONST64(0x0400000000000000), CONST64(0x0400000400000000), CONST64(0x0400000000000004), CONST64(0x0400000400000004), + CONST64(0x0400040000000000), CONST64(0x0400040400000000), CONST64(0x0400040000000004), CONST64(0x0400040400000004), + CONST64(0x0400000000000400), CONST64(0x0400000400000400), CONST64(0x0400000000000404), CONST64(0x0400000400000404), + CONST64(0x0400040000000400), CONST64(0x0400040400000400), CONST64(0x0400040000000404), CONST64(0x0400040400000404), + CONST64(0x0404000000000000), CONST64(0x0404000400000000), CONST64(0x0404000000000004), CONST64(0x0404000400000004), + CONST64(0x0404040000000000), CONST64(0x0404040400000000), CONST64(0x0404040000000004), CONST64(0x0404040400000004), + CONST64(0x0404000000000400), CONST64(0x0404000400000400), CONST64(0x0404000000000404), CONST64(0x0404000400000404), + CONST64(0x0404040000000400), CONST64(0x0404040400000400), CONST64(0x0404040000000404), CONST64(0x0404040400000404), + CONST64(0x0400000000040000), CONST64(0x0400000400040000), CONST64(0x0400000000040004), CONST64(0x0400000400040004), + CONST64(0x0400040000040000), CONST64(0x0400040400040000), CONST64(0x0400040000040004), CONST64(0x0400040400040004), + CONST64(0x0400000000040400), CONST64(0x0400000400040400), CONST64(0x0400000000040404), CONST64(0x0400000400040404), + CONST64(0x0400040000040400), CONST64(0x0400040400040400), CONST64(0x0400040000040404), CONST64(0x0400040400040404), + CONST64(0x0404000000040000), CONST64(0x0404000400040000), CONST64(0x0404000000040004), CONST64(0x0404000400040004), + CONST64(0x0404040000040000), CONST64(0x0404040400040000), CONST64(0x0404040000040004), CONST64(0x0404040400040004), + CONST64(0x0404000000040400), CONST64(0x0404000400040400), CONST64(0x0404000000040404), CONST64(0x0404000400040404), + CONST64(0x0404040000040400), CONST64(0x0404040400040400), CONST64(0x0404040000040404), CONST64(0x0404040400040404), + CONST64(0x0000000004000000), CONST64(0x0000000404000000), CONST64(0x0000000004000004), CONST64(0x0000000404000004), + CONST64(0x0000040004000000), CONST64(0x0000040404000000), CONST64(0x0000040004000004), CONST64(0x0000040404000004), + CONST64(0x0000000004000400), CONST64(0x0000000404000400), CONST64(0x0000000004000404), CONST64(0x0000000404000404), + CONST64(0x0000040004000400), CONST64(0x0000040404000400), CONST64(0x0000040004000404), CONST64(0x0000040404000404), + CONST64(0x0004000004000000), CONST64(0x0004000404000000), CONST64(0x0004000004000004), CONST64(0x0004000404000004), + CONST64(0x0004040004000000), CONST64(0x0004040404000000), CONST64(0x0004040004000004), CONST64(0x0004040404000004), + CONST64(0x0004000004000400), CONST64(0x0004000404000400), CONST64(0x0004000004000404), CONST64(0x0004000404000404), + CONST64(0x0004040004000400), CONST64(0x0004040404000400), CONST64(0x0004040004000404), CONST64(0x0004040404000404), + CONST64(0x0000000004040000), CONST64(0x0000000404040000), CONST64(0x0000000004040004), CONST64(0x0000000404040004), + CONST64(0x0000040004040000), CONST64(0x0000040404040000), CONST64(0x0000040004040004), CONST64(0x0000040404040004), + CONST64(0x0000000004040400), CONST64(0x0000000404040400), CONST64(0x0000000004040404), CONST64(0x0000000404040404), + CONST64(0x0000040004040400), CONST64(0x0000040404040400), CONST64(0x0000040004040404), CONST64(0x0000040404040404), + CONST64(0x0004000004040000), CONST64(0x0004000404040000), CONST64(0x0004000004040004), CONST64(0x0004000404040004), + CONST64(0x0004040004040000), CONST64(0x0004040404040000), CONST64(0x0004040004040004), CONST64(0x0004040404040004), + CONST64(0x0004000004040400), CONST64(0x0004000404040400), CONST64(0x0004000004040404), CONST64(0x0004000404040404), + CONST64(0x0004040004040400), CONST64(0x0004040404040400), CONST64(0x0004040004040404), CONST64(0x0004040404040404), + CONST64(0x0400000004000000), CONST64(0x0400000404000000), CONST64(0x0400000004000004), CONST64(0x0400000404000004), + CONST64(0x0400040004000000), CONST64(0x0400040404000000), CONST64(0x0400040004000004), CONST64(0x0400040404000004), + CONST64(0x0400000004000400), CONST64(0x0400000404000400), CONST64(0x0400000004000404), CONST64(0x0400000404000404), + CONST64(0x0400040004000400), CONST64(0x0400040404000400), CONST64(0x0400040004000404), CONST64(0x0400040404000404), + CONST64(0x0404000004000000), CONST64(0x0404000404000000), CONST64(0x0404000004000004), CONST64(0x0404000404000004), + CONST64(0x0404040004000000), CONST64(0x0404040404000000), CONST64(0x0404040004000004), CONST64(0x0404040404000004), + CONST64(0x0404000004000400), CONST64(0x0404000404000400), CONST64(0x0404000004000404), CONST64(0x0404000404000404), + CONST64(0x0404040004000400), CONST64(0x0404040404000400), CONST64(0x0404040004000404), CONST64(0x0404040404000404), + CONST64(0x0400000004040000), CONST64(0x0400000404040000), CONST64(0x0400000004040004), CONST64(0x0400000404040004), + CONST64(0x0400040004040000), CONST64(0x0400040404040000), CONST64(0x0400040004040004), CONST64(0x0400040404040004), + CONST64(0x0400000004040400), CONST64(0x0400000404040400), CONST64(0x0400000004040404), CONST64(0x0400000404040404), + CONST64(0x0400040004040400), CONST64(0x0400040404040400), CONST64(0x0400040004040404), CONST64(0x0400040404040404), + CONST64(0x0404000004040000), CONST64(0x0404000404040000), CONST64(0x0404000004040004), CONST64(0x0404000404040004), + CONST64(0x0404040004040000), CONST64(0x0404040404040000), CONST64(0x0404040004040004), CONST64(0x0404040404040004), + CONST64(0x0404000004040400), CONST64(0x0404000404040400), CONST64(0x0404000004040404), CONST64(0x0404000404040404), + CONST64(0x0404040004040400), CONST64(0x0404040404040400), CONST64(0x0404040004040404), CONST64(0x0404040404040404) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000000200000000), CONST64(0x0000000000000002), CONST64(0x0000000200000002), + CONST64(0x0000020000000000), CONST64(0x0000020200000000), CONST64(0x0000020000000002), CONST64(0x0000020200000002), + CONST64(0x0000000000000200), CONST64(0x0000000200000200), CONST64(0x0000000000000202), CONST64(0x0000000200000202), + CONST64(0x0000020000000200), CONST64(0x0000020200000200), CONST64(0x0000020000000202), CONST64(0x0000020200000202), + CONST64(0x0002000000000000), CONST64(0x0002000200000000), CONST64(0x0002000000000002), CONST64(0x0002000200000002), + CONST64(0x0002020000000000), CONST64(0x0002020200000000), CONST64(0x0002020000000002), CONST64(0x0002020200000002), + CONST64(0x0002000000000200), CONST64(0x0002000200000200), CONST64(0x0002000000000202), CONST64(0x0002000200000202), + CONST64(0x0002020000000200), CONST64(0x0002020200000200), CONST64(0x0002020000000202), CONST64(0x0002020200000202), + CONST64(0x0000000000020000), CONST64(0x0000000200020000), CONST64(0x0000000000020002), CONST64(0x0000000200020002), + CONST64(0x0000020000020000), CONST64(0x0000020200020000), CONST64(0x0000020000020002), CONST64(0x0000020200020002), + CONST64(0x0000000000020200), CONST64(0x0000000200020200), CONST64(0x0000000000020202), CONST64(0x0000000200020202), + CONST64(0x0000020000020200), CONST64(0x0000020200020200), CONST64(0x0000020000020202), CONST64(0x0000020200020202), + CONST64(0x0002000000020000), CONST64(0x0002000200020000), CONST64(0x0002000000020002), CONST64(0x0002000200020002), + CONST64(0x0002020000020000), CONST64(0x0002020200020000), CONST64(0x0002020000020002), CONST64(0x0002020200020002), + CONST64(0x0002000000020200), CONST64(0x0002000200020200), CONST64(0x0002000000020202), CONST64(0x0002000200020202), + CONST64(0x0002020000020200), CONST64(0x0002020200020200), CONST64(0x0002020000020202), CONST64(0x0002020200020202), + CONST64(0x0200000000000000), CONST64(0x0200000200000000), CONST64(0x0200000000000002), CONST64(0x0200000200000002), + CONST64(0x0200020000000000), CONST64(0x0200020200000000), CONST64(0x0200020000000002), CONST64(0x0200020200000002), + CONST64(0x0200000000000200), CONST64(0x0200000200000200), CONST64(0x0200000000000202), CONST64(0x0200000200000202), + CONST64(0x0200020000000200), CONST64(0x0200020200000200), CONST64(0x0200020000000202), CONST64(0x0200020200000202), + CONST64(0x0202000000000000), CONST64(0x0202000200000000), CONST64(0x0202000000000002), CONST64(0x0202000200000002), + CONST64(0x0202020000000000), CONST64(0x0202020200000000), CONST64(0x0202020000000002), CONST64(0x0202020200000002), + CONST64(0x0202000000000200), CONST64(0x0202000200000200), CONST64(0x0202000000000202), CONST64(0x0202000200000202), + CONST64(0x0202020000000200), CONST64(0x0202020200000200), CONST64(0x0202020000000202), CONST64(0x0202020200000202), + CONST64(0x0200000000020000), CONST64(0x0200000200020000), CONST64(0x0200000000020002), CONST64(0x0200000200020002), + CONST64(0x0200020000020000), CONST64(0x0200020200020000), CONST64(0x0200020000020002), CONST64(0x0200020200020002), + CONST64(0x0200000000020200), CONST64(0x0200000200020200), CONST64(0x0200000000020202), CONST64(0x0200000200020202), + CONST64(0x0200020000020200), CONST64(0x0200020200020200), CONST64(0x0200020000020202), CONST64(0x0200020200020202), + CONST64(0x0202000000020000), CONST64(0x0202000200020000), CONST64(0x0202000000020002), CONST64(0x0202000200020002), + CONST64(0x0202020000020000), CONST64(0x0202020200020000), CONST64(0x0202020000020002), CONST64(0x0202020200020002), + CONST64(0x0202000000020200), CONST64(0x0202000200020200), CONST64(0x0202000000020202), CONST64(0x0202000200020202), + CONST64(0x0202020000020200), CONST64(0x0202020200020200), CONST64(0x0202020000020202), CONST64(0x0202020200020202), + CONST64(0x0000000002000000), CONST64(0x0000000202000000), CONST64(0x0000000002000002), CONST64(0x0000000202000002), + CONST64(0x0000020002000000), CONST64(0x0000020202000000), CONST64(0x0000020002000002), CONST64(0x0000020202000002), + CONST64(0x0000000002000200), CONST64(0x0000000202000200), CONST64(0x0000000002000202), CONST64(0x0000000202000202), + CONST64(0x0000020002000200), CONST64(0x0000020202000200), CONST64(0x0000020002000202), CONST64(0x0000020202000202), + CONST64(0x0002000002000000), CONST64(0x0002000202000000), CONST64(0x0002000002000002), CONST64(0x0002000202000002), + CONST64(0x0002020002000000), CONST64(0x0002020202000000), CONST64(0x0002020002000002), CONST64(0x0002020202000002), + CONST64(0x0002000002000200), CONST64(0x0002000202000200), CONST64(0x0002000002000202), CONST64(0x0002000202000202), + CONST64(0x0002020002000200), CONST64(0x0002020202000200), CONST64(0x0002020002000202), CONST64(0x0002020202000202), + CONST64(0x0000000002020000), CONST64(0x0000000202020000), CONST64(0x0000000002020002), CONST64(0x0000000202020002), + CONST64(0x0000020002020000), CONST64(0x0000020202020000), CONST64(0x0000020002020002), CONST64(0x0000020202020002), + CONST64(0x0000000002020200), CONST64(0x0000000202020200), CONST64(0x0000000002020202), CONST64(0x0000000202020202), + CONST64(0x0000020002020200), CONST64(0x0000020202020200), CONST64(0x0000020002020202), CONST64(0x0000020202020202), + CONST64(0x0002000002020000), CONST64(0x0002000202020000), CONST64(0x0002000002020002), CONST64(0x0002000202020002), + CONST64(0x0002020002020000), CONST64(0x0002020202020000), CONST64(0x0002020002020002), CONST64(0x0002020202020002), + CONST64(0x0002000002020200), CONST64(0x0002000202020200), CONST64(0x0002000002020202), CONST64(0x0002000202020202), + CONST64(0x0002020002020200), CONST64(0x0002020202020200), CONST64(0x0002020002020202), CONST64(0x0002020202020202), + CONST64(0x0200000002000000), CONST64(0x0200000202000000), CONST64(0x0200000002000002), CONST64(0x0200000202000002), + CONST64(0x0200020002000000), CONST64(0x0200020202000000), CONST64(0x0200020002000002), CONST64(0x0200020202000002), + CONST64(0x0200000002000200), CONST64(0x0200000202000200), CONST64(0x0200000002000202), CONST64(0x0200000202000202), + CONST64(0x0200020002000200), CONST64(0x0200020202000200), CONST64(0x0200020002000202), CONST64(0x0200020202000202), + CONST64(0x0202000002000000), CONST64(0x0202000202000000), CONST64(0x0202000002000002), CONST64(0x0202000202000002), + CONST64(0x0202020002000000), CONST64(0x0202020202000000), CONST64(0x0202020002000002), CONST64(0x0202020202000002), + CONST64(0x0202000002000200), CONST64(0x0202000202000200), CONST64(0x0202000002000202), CONST64(0x0202000202000202), + CONST64(0x0202020002000200), CONST64(0x0202020202000200), CONST64(0x0202020002000202), CONST64(0x0202020202000202), + CONST64(0x0200000002020000), CONST64(0x0200000202020000), CONST64(0x0200000002020002), CONST64(0x0200000202020002), + CONST64(0x0200020002020000), CONST64(0x0200020202020000), CONST64(0x0200020002020002), CONST64(0x0200020202020002), + CONST64(0x0200000002020200), CONST64(0x0200000202020200), CONST64(0x0200000002020202), CONST64(0x0200000202020202), + CONST64(0x0200020002020200), CONST64(0x0200020202020200), CONST64(0x0200020002020202), CONST64(0x0200020202020202), + CONST64(0x0202000002020000), CONST64(0x0202000202020000), CONST64(0x0202000002020002), CONST64(0x0202000202020002), + CONST64(0x0202020002020000), CONST64(0x0202020202020000), CONST64(0x0202020002020002), CONST64(0x0202020202020002), + CONST64(0x0202000002020200), CONST64(0x0202000202020200), CONST64(0x0202000002020202), CONST64(0x0202000202020202), + CONST64(0x0202020002020200), CONST64(0x0202020202020200), CONST64(0x0202020002020202), CONST64(0x0202020202020202) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000010000000000), CONST64(0x0000000000000100), CONST64(0x0000010000000100), + CONST64(0x0001000000000000), CONST64(0x0001010000000000), CONST64(0x0001000000000100), CONST64(0x0001010000000100), + CONST64(0x0000000000010000), CONST64(0x0000010000010000), CONST64(0x0000000000010100), CONST64(0x0000010000010100), + CONST64(0x0001000000010000), CONST64(0x0001010000010000), CONST64(0x0001000000010100), CONST64(0x0001010000010100), + CONST64(0x0100000000000000), CONST64(0x0100010000000000), CONST64(0x0100000000000100), CONST64(0x0100010000000100), + CONST64(0x0101000000000000), CONST64(0x0101010000000000), CONST64(0x0101000000000100), CONST64(0x0101010000000100), + CONST64(0x0100000000010000), CONST64(0x0100010000010000), CONST64(0x0100000000010100), CONST64(0x0100010000010100), + CONST64(0x0101000000010000), CONST64(0x0101010000010000), CONST64(0x0101000000010100), CONST64(0x0101010000010100), + CONST64(0x0000000001000000), CONST64(0x0000010001000000), CONST64(0x0000000001000100), CONST64(0x0000010001000100), + CONST64(0x0001000001000000), CONST64(0x0001010001000000), CONST64(0x0001000001000100), CONST64(0x0001010001000100), + CONST64(0x0000000001010000), CONST64(0x0000010001010000), CONST64(0x0000000001010100), CONST64(0x0000010001010100), + CONST64(0x0001000001010000), CONST64(0x0001010001010000), CONST64(0x0001000001010100), CONST64(0x0001010001010100), + CONST64(0x0100000001000000), CONST64(0x0100010001000000), CONST64(0x0100000001000100), CONST64(0x0100010001000100), + CONST64(0x0101000001000000), CONST64(0x0101010001000000), CONST64(0x0101000001000100), CONST64(0x0101010001000100), + CONST64(0x0100000001010000), CONST64(0x0100010001010000), CONST64(0x0100000001010100), CONST64(0x0100010001010100), + CONST64(0x0101000001010000), CONST64(0x0101010001010000), CONST64(0x0101000001010100), CONST64(0x0101010001010100), + CONST64(0x0000000100000000), CONST64(0x0000010100000000), CONST64(0x0000000100000100), CONST64(0x0000010100000100), + CONST64(0x0001000100000000), CONST64(0x0001010100000000), CONST64(0x0001000100000100), CONST64(0x0001010100000100), + CONST64(0x0000000100010000), CONST64(0x0000010100010000), CONST64(0x0000000100010100), CONST64(0x0000010100010100), + CONST64(0x0001000100010000), CONST64(0x0001010100010000), CONST64(0x0001000100010100), CONST64(0x0001010100010100), + CONST64(0x0100000100000000), CONST64(0x0100010100000000), CONST64(0x0100000100000100), CONST64(0x0100010100000100), + CONST64(0x0101000100000000), CONST64(0x0101010100000000), CONST64(0x0101000100000100), CONST64(0x0101010100000100), + CONST64(0x0100000100010000), CONST64(0x0100010100010000), CONST64(0x0100000100010100), CONST64(0x0100010100010100), + CONST64(0x0101000100010000), CONST64(0x0101010100010000), CONST64(0x0101000100010100), CONST64(0x0101010100010100), + CONST64(0x0000000101000000), CONST64(0x0000010101000000), CONST64(0x0000000101000100), CONST64(0x0000010101000100), + CONST64(0x0001000101000000), CONST64(0x0001010101000000), CONST64(0x0001000101000100), CONST64(0x0001010101000100), + CONST64(0x0000000101010000), CONST64(0x0000010101010000), CONST64(0x0000000101010100), CONST64(0x0000010101010100), + CONST64(0x0001000101010000), CONST64(0x0001010101010000), CONST64(0x0001000101010100), CONST64(0x0001010101010100), + CONST64(0x0100000101000000), CONST64(0x0100010101000000), CONST64(0x0100000101000100), CONST64(0x0100010101000100), + CONST64(0x0101000101000000), CONST64(0x0101010101000000), CONST64(0x0101000101000100), CONST64(0x0101010101000100), + CONST64(0x0100000101010000), CONST64(0x0100010101010000), CONST64(0x0100000101010100), CONST64(0x0100010101010100), + CONST64(0x0101000101010000), CONST64(0x0101010101010000), CONST64(0x0101000101010100), CONST64(0x0101010101010100), + CONST64(0x0000000000000001), CONST64(0x0000010000000001), CONST64(0x0000000000000101), CONST64(0x0000010000000101), + CONST64(0x0001000000000001), CONST64(0x0001010000000001), CONST64(0x0001000000000101), CONST64(0x0001010000000101), + CONST64(0x0000000000010001), CONST64(0x0000010000010001), CONST64(0x0000000000010101), CONST64(0x0000010000010101), + CONST64(0x0001000000010001), CONST64(0x0001010000010001), CONST64(0x0001000000010101), CONST64(0x0001010000010101), + CONST64(0x0100000000000001), CONST64(0x0100010000000001), CONST64(0x0100000000000101), CONST64(0x0100010000000101), + CONST64(0x0101000000000001), CONST64(0x0101010000000001), CONST64(0x0101000000000101), CONST64(0x0101010000000101), + CONST64(0x0100000000010001), CONST64(0x0100010000010001), CONST64(0x0100000000010101), CONST64(0x0100010000010101), + CONST64(0x0101000000010001), CONST64(0x0101010000010001), CONST64(0x0101000000010101), CONST64(0x0101010000010101), + CONST64(0x0000000001000001), CONST64(0x0000010001000001), CONST64(0x0000000001000101), CONST64(0x0000010001000101), + CONST64(0x0001000001000001), CONST64(0x0001010001000001), CONST64(0x0001000001000101), CONST64(0x0001010001000101), + CONST64(0x0000000001010001), CONST64(0x0000010001010001), CONST64(0x0000000001010101), CONST64(0x0000010001010101), + CONST64(0x0001000001010001), CONST64(0x0001010001010001), CONST64(0x0001000001010101), CONST64(0x0001010001010101), + CONST64(0x0100000001000001), CONST64(0x0100010001000001), CONST64(0x0100000001000101), CONST64(0x0100010001000101), + CONST64(0x0101000001000001), CONST64(0x0101010001000001), CONST64(0x0101000001000101), CONST64(0x0101010001000101), + CONST64(0x0100000001010001), CONST64(0x0100010001010001), CONST64(0x0100000001010101), CONST64(0x0100010001010101), + CONST64(0x0101000001010001), CONST64(0x0101010001010001), CONST64(0x0101000001010101), CONST64(0x0101010001010101), + CONST64(0x0000000100000001), CONST64(0x0000010100000001), CONST64(0x0000000100000101), CONST64(0x0000010100000101), + CONST64(0x0001000100000001), CONST64(0x0001010100000001), CONST64(0x0001000100000101), CONST64(0x0001010100000101), + CONST64(0x0000000100010001), CONST64(0x0000010100010001), CONST64(0x0000000100010101), CONST64(0x0000010100010101), + CONST64(0x0001000100010001), CONST64(0x0001010100010001), CONST64(0x0001000100010101), CONST64(0x0001010100010101), + CONST64(0x0100000100000001), CONST64(0x0100010100000001), CONST64(0x0100000100000101), CONST64(0x0100010100000101), + CONST64(0x0101000100000001), CONST64(0x0101010100000001), CONST64(0x0101000100000101), CONST64(0x0101010100000101), + CONST64(0x0100000100010001), CONST64(0x0100010100010001), CONST64(0x0100000100010101), CONST64(0x0100010100010101), + CONST64(0x0101000100010001), CONST64(0x0101010100010001), CONST64(0x0101000100010101), CONST64(0x0101010100010101), + CONST64(0x0000000101000001), CONST64(0x0000010101000001), CONST64(0x0000000101000101), CONST64(0x0000010101000101), + CONST64(0x0001000101000001), CONST64(0x0001010101000001), CONST64(0x0001000101000101), CONST64(0x0001010101000101), + CONST64(0x0000000101010001), CONST64(0x0000010101010001), CONST64(0x0000000101010101), CONST64(0x0000010101010101), + CONST64(0x0001000101010001), CONST64(0x0001010101010001), CONST64(0x0001000101010101), CONST64(0x0001010101010101), + CONST64(0x0100000101000001), CONST64(0x0100010101000001), CONST64(0x0100000101000101), CONST64(0x0100010101000101), + CONST64(0x0101000101000001), CONST64(0x0101010101000001), CONST64(0x0101000101000101), CONST64(0x0101010101000101), + CONST64(0x0100000101010001), CONST64(0x0100010101010001), CONST64(0x0100000101010101), CONST64(0x0100010101010101), + CONST64(0x0101000101010001), CONST64(0x0101010101010001), CONST64(0x0101000101010101), CONST64(0x0101010101010101) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000008000000000), CONST64(0x0000000000000080), CONST64(0x0000008000000080), + CONST64(0x0000800000000000), CONST64(0x0000808000000000), CONST64(0x0000800000000080), CONST64(0x0000808000000080), + CONST64(0x0000000000008000), CONST64(0x0000008000008000), CONST64(0x0000000000008080), CONST64(0x0000008000008080), + CONST64(0x0000800000008000), CONST64(0x0000808000008000), CONST64(0x0000800000008080), CONST64(0x0000808000008080), + CONST64(0x0080000000000000), CONST64(0x0080008000000000), CONST64(0x0080000000000080), CONST64(0x0080008000000080), + CONST64(0x0080800000000000), CONST64(0x0080808000000000), CONST64(0x0080800000000080), CONST64(0x0080808000000080), + CONST64(0x0080000000008000), CONST64(0x0080008000008000), CONST64(0x0080000000008080), CONST64(0x0080008000008080), + CONST64(0x0080800000008000), CONST64(0x0080808000008000), CONST64(0x0080800000008080), CONST64(0x0080808000008080), + CONST64(0x0000000000800000), CONST64(0x0000008000800000), CONST64(0x0000000000800080), CONST64(0x0000008000800080), + CONST64(0x0000800000800000), CONST64(0x0000808000800000), CONST64(0x0000800000800080), CONST64(0x0000808000800080), + CONST64(0x0000000000808000), CONST64(0x0000008000808000), CONST64(0x0000000000808080), CONST64(0x0000008000808080), + CONST64(0x0000800000808000), CONST64(0x0000808000808000), CONST64(0x0000800000808080), CONST64(0x0000808000808080), + CONST64(0x0080000000800000), CONST64(0x0080008000800000), CONST64(0x0080000000800080), CONST64(0x0080008000800080), + CONST64(0x0080800000800000), CONST64(0x0080808000800000), CONST64(0x0080800000800080), CONST64(0x0080808000800080), + CONST64(0x0080000000808000), CONST64(0x0080008000808000), CONST64(0x0080000000808080), CONST64(0x0080008000808080), + CONST64(0x0080800000808000), CONST64(0x0080808000808000), CONST64(0x0080800000808080), CONST64(0x0080808000808080), + CONST64(0x8000000000000000), CONST64(0x8000008000000000), CONST64(0x8000000000000080), CONST64(0x8000008000000080), + CONST64(0x8000800000000000), CONST64(0x8000808000000000), CONST64(0x8000800000000080), CONST64(0x8000808000000080), + CONST64(0x8000000000008000), CONST64(0x8000008000008000), CONST64(0x8000000000008080), CONST64(0x8000008000008080), + CONST64(0x8000800000008000), CONST64(0x8000808000008000), CONST64(0x8000800000008080), CONST64(0x8000808000008080), + CONST64(0x8080000000000000), CONST64(0x8080008000000000), CONST64(0x8080000000000080), CONST64(0x8080008000000080), + CONST64(0x8080800000000000), CONST64(0x8080808000000000), CONST64(0x8080800000000080), CONST64(0x8080808000000080), + CONST64(0x8080000000008000), CONST64(0x8080008000008000), CONST64(0x8080000000008080), CONST64(0x8080008000008080), + CONST64(0x8080800000008000), CONST64(0x8080808000008000), CONST64(0x8080800000008080), CONST64(0x8080808000008080), + CONST64(0x8000000000800000), CONST64(0x8000008000800000), CONST64(0x8000000000800080), CONST64(0x8000008000800080), + CONST64(0x8000800000800000), CONST64(0x8000808000800000), CONST64(0x8000800000800080), CONST64(0x8000808000800080), + CONST64(0x8000000000808000), CONST64(0x8000008000808000), CONST64(0x8000000000808080), CONST64(0x8000008000808080), + CONST64(0x8000800000808000), CONST64(0x8000808000808000), CONST64(0x8000800000808080), CONST64(0x8000808000808080), + CONST64(0x8080000000800000), CONST64(0x8080008000800000), CONST64(0x8080000000800080), CONST64(0x8080008000800080), + CONST64(0x8080800000800000), CONST64(0x8080808000800000), CONST64(0x8080800000800080), CONST64(0x8080808000800080), + CONST64(0x8080000000808000), CONST64(0x8080008000808000), CONST64(0x8080000000808080), CONST64(0x8080008000808080), + CONST64(0x8080800000808000), CONST64(0x8080808000808000), CONST64(0x8080800000808080), CONST64(0x8080808000808080), + CONST64(0x0000000080000000), CONST64(0x0000008080000000), CONST64(0x0000000080000080), CONST64(0x0000008080000080), + CONST64(0x0000800080000000), CONST64(0x0000808080000000), CONST64(0x0000800080000080), CONST64(0x0000808080000080), + CONST64(0x0000000080008000), CONST64(0x0000008080008000), CONST64(0x0000000080008080), CONST64(0x0000008080008080), + CONST64(0x0000800080008000), CONST64(0x0000808080008000), CONST64(0x0000800080008080), CONST64(0x0000808080008080), + CONST64(0x0080000080000000), CONST64(0x0080008080000000), CONST64(0x0080000080000080), CONST64(0x0080008080000080), + CONST64(0x0080800080000000), CONST64(0x0080808080000000), CONST64(0x0080800080000080), CONST64(0x0080808080000080), + CONST64(0x0080000080008000), CONST64(0x0080008080008000), CONST64(0x0080000080008080), CONST64(0x0080008080008080), + CONST64(0x0080800080008000), CONST64(0x0080808080008000), CONST64(0x0080800080008080), CONST64(0x0080808080008080), + CONST64(0x0000000080800000), CONST64(0x0000008080800000), CONST64(0x0000000080800080), CONST64(0x0000008080800080), + CONST64(0x0000800080800000), CONST64(0x0000808080800000), CONST64(0x0000800080800080), CONST64(0x0000808080800080), + CONST64(0x0000000080808000), CONST64(0x0000008080808000), CONST64(0x0000000080808080), CONST64(0x0000008080808080), + CONST64(0x0000800080808000), CONST64(0x0000808080808000), CONST64(0x0000800080808080), CONST64(0x0000808080808080), + CONST64(0x0080000080800000), CONST64(0x0080008080800000), CONST64(0x0080000080800080), CONST64(0x0080008080800080), + CONST64(0x0080800080800000), CONST64(0x0080808080800000), CONST64(0x0080800080800080), CONST64(0x0080808080800080), + CONST64(0x0080000080808000), CONST64(0x0080008080808000), CONST64(0x0080000080808080), CONST64(0x0080008080808080), + CONST64(0x0080800080808000), CONST64(0x0080808080808000), CONST64(0x0080800080808080), CONST64(0x0080808080808080), + CONST64(0x8000000080000000), CONST64(0x8000008080000000), CONST64(0x8000000080000080), CONST64(0x8000008080000080), + CONST64(0x8000800080000000), CONST64(0x8000808080000000), CONST64(0x8000800080000080), CONST64(0x8000808080000080), + CONST64(0x8000000080008000), CONST64(0x8000008080008000), CONST64(0x8000000080008080), CONST64(0x8000008080008080), + CONST64(0x8000800080008000), CONST64(0x8000808080008000), CONST64(0x8000800080008080), CONST64(0x8000808080008080), + CONST64(0x8080000080000000), CONST64(0x8080008080000000), CONST64(0x8080000080000080), CONST64(0x8080008080000080), + CONST64(0x8080800080000000), CONST64(0x8080808080000000), CONST64(0x8080800080000080), CONST64(0x8080808080000080), + CONST64(0x8080000080008000), CONST64(0x8080008080008000), CONST64(0x8080000080008080), CONST64(0x8080008080008080), + CONST64(0x8080800080008000), CONST64(0x8080808080008000), CONST64(0x8080800080008080), CONST64(0x8080808080008080), + CONST64(0x8000000080800000), CONST64(0x8000008080800000), CONST64(0x8000000080800080), CONST64(0x8000008080800080), + CONST64(0x8000800080800000), CONST64(0x8000808080800000), CONST64(0x8000800080800080), CONST64(0x8000808080800080), + CONST64(0x8000000080808000), CONST64(0x8000008080808000), CONST64(0x8000000080808080), CONST64(0x8000008080808080), + CONST64(0x8000800080808000), CONST64(0x8000808080808000), CONST64(0x8000800080808080), CONST64(0x8000808080808080), + CONST64(0x8080000080800000), CONST64(0x8080008080800000), CONST64(0x8080000080800080), CONST64(0x8080008080800080), + CONST64(0x8080800080800000), CONST64(0x8080808080800000), CONST64(0x8080800080800080), CONST64(0x8080808080800080), + CONST64(0x8080000080808000), CONST64(0x8080008080808000), CONST64(0x8080000080808080), CONST64(0x8080008080808080), + CONST64(0x8080800080808000), CONST64(0x8080808080808000), CONST64(0x8080800080808080), CONST64(0x8080808080808080) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000004000000000), CONST64(0x0000000000000040), CONST64(0x0000004000000040), + CONST64(0x0000400000000000), CONST64(0x0000404000000000), CONST64(0x0000400000000040), CONST64(0x0000404000000040), + CONST64(0x0000000000004000), CONST64(0x0000004000004000), CONST64(0x0000000000004040), CONST64(0x0000004000004040), + CONST64(0x0000400000004000), CONST64(0x0000404000004000), CONST64(0x0000400000004040), CONST64(0x0000404000004040), + CONST64(0x0040000000000000), CONST64(0x0040004000000000), CONST64(0x0040000000000040), CONST64(0x0040004000000040), + CONST64(0x0040400000000000), CONST64(0x0040404000000000), CONST64(0x0040400000000040), CONST64(0x0040404000000040), + CONST64(0x0040000000004000), CONST64(0x0040004000004000), CONST64(0x0040000000004040), CONST64(0x0040004000004040), + CONST64(0x0040400000004000), CONST64(0x0040404000004000), CONST64(0x0040400000004040), CONST64(0x0040404000004040), + CONST64(0x0000000000400000), CONST64(0x0000004000400000), CONST64(0x0000000000400040), CONST64(0x0000004000400040), + CONST64(0x0000400000400000), CONST64(0x0000404000400000), CONST64(0x0000400000400040), CONST64(0x0000404000400040), + CONST64(0x0000000000404000), CONST64(0x0000004000404000), CONST64(0x0000000000404040), CONST64(0x0000004000404040), + CONST64(0x0000400000404000), CONST64(0x0000404000404000), CONST64(0x0000400000404040), CONST64(0x0000404000404040), + CONST64(0x0040000000400000), CONST64(0x0040004000400000), CONST64(0x0040000000400040), CONST64(0x0040004000400040), + CONST64(0x0040400000400000), CONST64(0x0040404000400000), CONST64(0x0040400000400040), CONST64(0x0040404000400040), + CONST64(0x0040000000404000), CONST64(0x0040004000404000), CONST64(0x0040000000404040), CONST64(0x0040004000404040), + CONST64(0x0040400000404000), CONST64(0x0040404000404000), CONST64(0x0040400000404040), CONST64(0x0040404000404040), + CONST64(0x4000000000000000), CONST64(0x4000004000000000), CONST64(0x4000000000000040), CONST64(0x4000004000000040), + CONST64(0x4000400000000000), CONST64(0x4000404000000000), CONST64(0x4000400000000040), CONST64(0x4000404000000040), + CONST64(0x4000000000004000), CONST64(0x4000004000004000), CONST64(0x4000000000004040), CONST64(0x4000004000004040), + CONST64(0x4000400000004000), CONST64(0x4000404000004000), CONST64(0x4000400000004040), CONST64(0x4000404000004040), + CONST64(0x4040000000000000), CONST64(0x4040004000000000), CONST64(0x4040000000000040), CONST64(0x4040004000000040), + CONST64(0x4040400000000000), CONST64(0x4040404000000000), CONST64(0x4040400000000040), CONST64(0x4040404000000040), + CONST64(0x4040000000004000), CONST64(0x4040004000004000), CONST64(0x4040000000004040), CONST64(0x4040004000004040), + CONST64(0x4040400000004000), CONST64(0x4040404000004000), CONST64(0x4040400000004040), CONST64(0x4040404000004040), + CONST64(0x4000000000400000), CONST64(0x4000004000400000), CONST64(0x4000000000400040), CONST64(0x4000004000400040), + CONST64(0x4000400000400000), CONST64(0x4000404000400000), CONST64(0x4000400000400040), CONST64(0x4000404000400040), + CONST64(0x4000000000404000), CONST64(0x4000004000404000), CONST64(0x4000000000404040), CONST64(0x4000004000404040), + CONST64(0x4000400000404000), CONST64(0x4000404000404000), CONST64(0x4000400000404040), CONST64(0x4000404000404040), + CONST64(0x4040000000400000), CONST64(0x4040004000400000), CONST64(0x4040000000400040), CONST64(0x4040004000400040), + CONST64(0x4040400000400000), CONST64(0x4040404000400000), CONST64(0x4040400000400040), CONST64(0x4040404000400040), + CONST64(0x4040000000404000), CONST64(0x4040004000404000), CONST64(0x4040000000404040), CONST64(0x4040004000404040), + CONST64(0x4040400000404000), CONST64(0x4040404000404000), CONST64(0x4040400000404040), CONST64(0x4040404000404040), + CONST64(0x0000000040000000), CONST64(0x0000004040000000), CONST64(0x0000000040000040), CONST64(0x0000004040000040), + CONST64(0x0000400040000000), CONST64(0x0000404040000000), CONST64(0x0000400040000040), CONST64(0x0000404040000040), + CONST64(0x0000000040004000), CONST64(0x0000004040004000), CONST64(0x0000000040004040), CONST64(0x0000004040004040), + CONST64(0x0000400040004000), CONST64(0x0000404040004000), CONST64(0x0000400040004040), CONST64(0x0000404040004040), + CONST64(0x0040000040000000), CONST64(0x0040004040000000), CONST64(0x0040000040000040), CONST64(0x0040004040000040), + CONST64(0x0040400040000000), CONST64(0x0040404040000000), CONST64(0x0040400040000040), CONST64(0x0040404040000040), + CONST64(0x0040000040004000), CONST64(0x0040004040004000), CONST64(0x0040000040004040), CONST64(0x0040004040004040), + CONST64(0x0040400040004000), CONST64(0x0040404040004000), CONST64(0x0040400040004040), CONST64(0x0040404040004040), + CONST64(0x0000000040400000), CONST64(0x0000004040400000), CONST64(0x0000000040400040), CONST64(0x0000004040400040), + CONST64(0x0000400040400000), CONST64(0x0000404040400000), CONST64(0x0000400040400040), CONST64(0x0000404040400040), + CONST64(0x0000000040404000), CONST64(0x0000004040404000), CONST64(0x0000000040404040), CONST64(0x0000004040404040), + CONST64(0x0000400040404000), CONST64(0x0000404040404000), CONST64(0x0000400040404040), CONST64(0x0000404040404040), + CONST64(0x0040000040400000), CONST64(0x0040004040400000), CONST64(0x0040000040400040), CONST64(0x0040004040400040), + CONST64(0x0040400040400000), CONST64(0x0040404040400000), CONST64(0x0040400040400040), CONST64(0x0040404040400040), + CONST64(0x0040000040404000), CONST64(0x0040004040404000), CONST64(0x0040000040404040), CONST64(0x0040004040404040), + CONST64(0x0040400040404000), CONST64(0x0040404040404000), CONST64(0x0040400040404040), CONST64(0x0040404040404040), + CONST64(0x4000000040000000), CONST64(0x4000004040000000), CONST64(0x4000000040000040), CONST64(0x4000004040000040), + CONST64(0x4000400040000000), CONST64(0x4000404040000000), CONST64(0x4000400040000040), CONST64(0x4000404040000040), + CONST64(0x4000000040004000), CONST64(0x4000004040004000), CONST64(0x4000000040004040), CONST64(0x4000004040004040), + CONST64(0x4000400040004000), CONST64(0x4000404040004000), CONST64(0x4000400040004040), CONST64(0x4000404040004040), + CONST64(0x4040000040000000), CONST64(0x4040004040000000), CONST64(0x4040000040000040), CONST64(0x4040004040000040), + CONST64(0x4040400040000000), CONST64(0x4040404040000000), CONST64(0x4040400040000040), CONST64(0x4040404040000040), + CONST64(0x4040000040004000), CONST64(0x4040004040004000), CONST64(0x4040000040004040), CONST64(0x4040004040004040), + CONST64(0x4040400040004000), CONST64(0x4040404040004000), CONST64(0x4040400040004040), CONST64(0x4040404040004040), + CONST64(0x4000000040400000), CONST64(0x4000004040400000), CONST64(0x4000000040400040), CONST64(0x4000004040400040), + CONST64(0x4000400040400000), CONST64(0x4000404040400000), CONST64(0x4000400040400040), CONST64(0x4000404040400040), + CONST64(0x4000000040404000), CONST64(0x4000004040404000), CONST64(0x4000000040404040), CONST64(0x4000004040404040), + CONST64(0x4000400040404000), CONST64(0x4000404040404000), CONST64(0x4000400040404040), CONST64(0x4000404040404040), + CONST64(0x4040000040400000), CONST64(0x4040004040400000), CONST64(0x4040000040400040), CONST64(0x4040004040400040), + CONST64(0x4040400040400000), CONST64(0x4040404040400000), CONST64(0x4040400040400040), CONST64(0x4040404040400040), + CONST64(0x4040000040404000), CONST64(0x4040004040404000), CONST64(0x4040000040404040), CONST64(0x4040004040404040), + CONST64(0x4040400040404000), CONST64(0x4040404040404000), CONST64(0x4040400040404040), CONST64(0x4040404040404040) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000002000000000), CONST64(0x0000000000000020), CONST64(0x0000002000000020), + CONST64(0x0000200000000000), CONST64(0x0000202000000000), CONST64(0x0000200000000020), CONST64(0x0000202000000020), + CONST64(0x0000000000002000), CONST64(0x0000002000002000), CONST64(0x0000000000002020), CONST64(0x0000002000002020), + CONST64(0x0000200000002000), CONST64(0x0000202000002000), CONST64(0x0000200000002020), CONST64(0x0000202000002020), + CONST64(0x0020000000000000), CONST64(0x0020002000000000), CONST64(0x0020000000000020), CONST64(0x0020002000000020), + CONST64(0x0020200000000000), CONST64(0x0020202000000000), CONST64(0x0020200000000020), CONST64(0x0020202000000020), + CONST64(0x0020000000002000), CONST64(0x0020002000002000), CONST64(0x0020000000002020), CONST64(0x0020002000002020), + CONST64(0x0020200000002000), CONST64(0x0020202000002000), CONST64(0x0020200000002020), CONST64(0x0020202000002020), + CONST64(0x0000000000200000), CONST64(0x0000002000200000), CONST64(0x0000000000200020), CONST64(0x0000002000200020), + CONST64(0x0000200000200000), CONST64(0x0000202000200000), CONST64(0x0000200000200020), CONST64(0x0000202000200020), + CONST64(0x0000000000202000), CONST64(0x0000002000202000), CONST64(0x0000000000202020), CONST64(0x0000002000202020), + CONST64(0x0000200000202000), CONST64(0x0000202000202000), CONST64(0x0000200000202020), CONST64(0x0000202000202020), + CONST64(0x0020000000200000), CONST64(0x0020002000200000), CONST64(0x0020000000200020), CONST64(0x0020002000200020), + CONST64(0x0020200000200000), CONST64(0x0020202000200000), CONST64(0x0020200000200020), CONST64(0x0020202000200020), + CONST64(0x0020000000202000), CONST64(0x0020002000202000), CONST64(0x0020000000202020), CONST64(0x0020002000202020), + CONST64(0x0020200000202000), CONST64(0x0020202000202000), CONST64(0x0020200000202020), CONST64(0x0020202000202020), + CONST64(0x2000000000000000), CONST64(0x2000002000000000), CONST64(0x2000000000000020), CONST64(0x2000002000000020), + CONST64(0x2000200000000000), CONST64(0x2000202000000000), CONST64(0x2000200000000020), CONST64(0x2000202000000020), + CONST64(0x2000000000002000), CONST64(0x2000002000002000), CONST64(0x2000000000002020), CONST64(0x2000002000002020), + CONST64(0x2000200000002000), CONST64(0x2000202000002000), CONST64(0x2000200000002020), CONST64(0x2000202000002020), + CONST64(0x2020000000000000), CONST64(0x2020002000000000), CONST64(0x2020000000000020), CONST64(0x2020002000000020), + CONST64(0x2020200000000000), CONST64(0x2020202000000000), CONST64(0x2020200000000020), CONST64(0x2020202000000020), + CONST64(0x2020000000002000), CONST64(0x2020002000002000), CONST64(0x2020000000002020), CONST64(0x2020002000002020), + CONST64(0x2020200000002000), CONST64(0x2020202000002000), CONST64(0x2020200000002020), CONST64(0x2020202000002020), + CONST64(0x2000000000200000), CONST64(0x2000002000200000), CONST64(0x2000000000200020), CONST64(0x2000002000200020), + CONST64(0x2000200000200000), CONST64(0x2000202000200000), CONST64(0x2000200000200020), CONST64(0x2000202000200020), + CONST64(0x2000000000202000), CONST64(0x2000002000202000), CONST64(0x2000000000202020), CONST64(0x2000002000202020), + CONST64(0x2000200000202000), CONST64(0x2000202000202000), CONST64(0x2000200000202020), CONST64(0x2000202000202020), + CONST64(0x2020000000200000), CONST64(0x2020002000200000), CONST64(0x2020000000200020), CONST64(0x2020002000200020), + CONST64(0x2020200000200000), CONST64(0x2020202000200000), CONST64(0x2020200000200020), CONST64(0x2020202000200020), + CONST64(0x2020000000202000), CONST64(0x2020002000202000), CONST64(0x2020000000202020), CONST64(0x2020002000202020), + CONST64(0x2020200000202000), CONST64(0x2020202000202000), CONST64(0x2020200000202020), CONST64(0x2020202000202020), + CONST64(0x0000000020000000), CONST64(0x0000002020000000), CONST64(0x0000000020000020), CONST64(0x0000002020000020), + CONST64(0x0000200020000000), CONST64(0x0000202020000000), CONST64(0x0000200020000020), CONST64(0x0000202020000020), + CONST64(0x0000000020002000), CONST64(0x0000002020002000), CONST64(0x0000000020002020), CONST64(0x0000002020002020), + CONST64(0x0000200020002000), CONST64(0x0000202020002000), CONST64(0x0000200020002020), CONST64(0x0000202020002020), + CONST64(0x0020000020000000), CONST64(0x0020002020000000), CONST64(0x0020000020000020), CONST64(0x0020002020000020), + CONST64(0x0020200020000000), CONST64(0x0020202020000000), CONST64(0x0020200020000020), CONST64(0x0020202020000020), + CONST64(0x0020000020002000), CONST64(0x0020002020002000), CONST64(0x0020000020002020), CONST64(0x0020002020002020), + CONST64(0x0020200020002000), CONST64(0x0020202020002000), CONST64(0x0020200020002020), CONST64(0x0020202020002020), + CONST64(0x0000000020200000), CONST64(0x0000002020200000), CONST64(0x0000000020200020), CONST64(0x0000002020200020), + CONST64(0x0000200020200000), CONST64(0x0000202020200000), CONST64(0x0000200020200020), CONST64(0x0000202020200020), + CONST64(0x0000000020202000), CONST64(0x0000002020202000), CONST64(0x0000000020202020), CONST64(0x0000002020202020), + CONST64(0x0000200020202000), CONST64(0x0000202020202000), CONST64(0x0000200020202020), CONST64(0x0000202020202020), + CONST64(0x0020000020200000), CONST64(0x0020002020200000), CONST64(0x0020000020200020), CONST64(0x0020002020200020), + CONST64(0x0020200020200000), CONST64(0x0020202020200000), CONST64(0x0020200020200020), CONST64(0x0020202020200020), + CONST64(0x0020000020202000), CONST64(0x0020002020202000), CONST64(0x0020000020202020), CONST64(0x0020002020202020), + CONST64(0x0020200020202000), CONST64(0x0020202020202000), CONST64(0x0020200020202020), CONST64(0x0020202020202020), + CONST64(0x2000000020000000), CONST64(0x2000002020000000), CONST64(0x2000000020000020), CONST64(0x2000002020000020), + CONST64(0x2000200020000000), CONST64(0x2000202020000000), CONST64(0x2000200020000020), CONST64(0x2000202020000020), + CONST64(0x2000000020002000), CONST64(0x2000002020002000), CONST64(0x2000000020002020), CONST64(0x2000002020002020), + CONST64(0x2000200020002000), CONST64(0x2000202020002000), CONST64(0x2000200020002020), CONST64(0x2000202020002020), + CONST64(0x2020000020000000), CONST64(0x2020002020000000), CONST64(0x2020000020000020), CONST64(0x2020002020000020), + CONST64(0x2020200020000000), CONST64(0x2020202020000000), CONST64(0x2020200020000020), CONST64(0x2020202020000020), + CONST64(0x2020000020002000), CONST64(0x2020002020002000), CONST64(0x2020000020002020), CONST64(0x2020002020002020), + CONST64(0x2020200020002000), CONST64(0x2020202020002000), CONST64(0x2020200020002020), CONST64(0x2020202020002020), + CONST64(0x2000000020200000), CONST64(0x2000002020200000), CONST64(0x2000000020200020), CONST64(0x2000002020200020), + CONST64(0x2000200020200000), CONST64(0x2000202020200000), CONST64(0x2000200020200020), CONST64(0x2000202020200020), + CONST64(0x2000000020202000), CONST64(0x2000002020202000), CONST64(0x2000000020202020), CONST64(0x2000002020202020), + CONST64(0x2000200020202000), CONST64(0x2000202020202000), CONST64(0x2000200020202020), CONST64(0x2000202020202020), + CONST64(0x2020000020200000), CONST64(0x2020002020200000), CONST64(0x2020000020200020), CONST64(0x2020002020200020), + CONST64(0x2020200020200000), CONST64(0x2020202020200000), CONST64(0x2020200020200020), CONST64(0x2020202020200020), + CONST64(0x2020000020202000), CONST64(0x2020002020202000), CONST64(0x2020000020202020), CONST64(0x2020002020202020), + CONST64(0x2020200020202000), CONST64(0x2020202020202000), CONST64(0x2020200020202020), CONST64(0x2020202020202020) + }}; + +static const ulong64 des_fp[8][256] = { + +{ CONST64(0x0000000000000000), CONST64(0x0000008000000000), CONST64(0x0000000002000000), CONST64(0x0000008002000000), + CONST64(0x0000000000020000), CONST64(0x0000008000020000), CONST64(0x0000000002020000), CONST64(0x0000008002020000), + CONST64(0x0000000000000200), CONST64(0x0000008000000200), CONST64(0x0000000002000200), CONST64(0x0000008002000200), + CONST64(0x0000000000020200), CONST64(0x0000008000020200), CONST64(0x0000000002020200), CONST64(0x0000008002020200), + CONST64(0x0000000000000002), CONST64(0x0000008000000002), CONST64(0x0000000002000002), CONST64(0x0000008002000002), + CONST64(0x0000000000020002), CONST64(0x0000008000020002), CONST64(0x0000000002020002), CONST64(0x0000008002020002), + CONST64(0x0000000000000202), CONST64(0x0000008000000202), CONST64(0x0000000002000202), CONST64(0x0000008002000202), + CONST64(0x0000000000020202), CONST64(0x0000008000020202), CONST64(0x0000000002020202), CONST64(0x0000008002020202), + CONST64(0x0200000000000000), CONST64(0x0200008000000000), CONST64(0x0200000002000000), CONST64(0x0200008002000000), + CONST64(0x0200000000020000), CONST64(0x0200008000020000), CONST64(0x0200000002020000), CONST64(0x0200008002020000), + CONST64(0x0200000000000200), CONST64(0x0200008000000200), CONST64(0x0200000002000200), CONST64(0x0200008002000200), + CONST64(0x0200000000020200), CONST64(0x0200008000020200), CONST64(0x0200000002020200), CONST64(0x0200008002020200), + CONST64(0x0200000000000002), CONST64(0x0200008000000002), CONST64(0x0200000002000002), CONST64(0x0200008002000002), + CONST64(0x0200000000020002), CONST64(0x0200008000020002), CONST64(0x0200000002020002), CONST64(0x0200008002020002), + CONST64(0x0200000000000202), CONST64(0x0200008000000202), CONST64(0x0200000002000202), CONST64(0x0200008002000202), + CONST64(0x0200000000020202), CONST64(0x0200008000020202), CONST64(0x0200000002020202), CONST64(0x0200008002020202), + CONST64(0x0002000000000000), CONST64(0x0002008000000000), CONST64(0x0002000002000000), CONST64(0x0002008002000000), + CONST64(0x0002000000020000), CONST64(0x0002008000020000), CONST64(0x0002000002020000), CONST64(0x0002008002020000), + CONST64(0x0002000000000200), CONST64(0x0002008000000200), CONST64(0x0002000002000200), CONST64(0x0002008002000200), + CONST64(0x0002000000020200), CONST64(0x0002008000020200), CONST64(0x0002000002020200), CONST64(0x0002008002020200), + CONST64(0x0002000000000002), CONST64(0x0002008000000002), CONST64(0x0002000002000002), CONST64(0x0002008002000002), + CONST64(0x0002000000020002), CONST64(0x0002008000020002), CONST64(0x0002000002020002), CONST64(0x0002008002020002), + CONST64(0x0002000000000202), CONST64(0x0002008000000202), CONST64(0x0002000002000202), CONST64(0x0002008002000202), + CONST64(0x0002000000020202), CONST64(0x0002008000020202), CONST64(0x0002000002020202), CONST64(0x0002008002020202), + CONST64(0x0202000000000000), CONST64(0x0202008000000000), CONST64(0x0202000002000000), CONST64(0x0202008002000000), + CONST64(0x0202000000020000), CONST64(0x0202008000020000), CONST64(0x0202000002020000), CONST64(0x0202008002020000), + CONST64(0x0202000000000200), CONST64(0x0202008000000200), CONST64(0x0202000002000200), CONST64(0x0202008002000200), + CONST64(0x0202000000020200), CONST64(0x0202008000020200), CONST64(0x0202000002020200), CONST64(0x0202008002020200), + CONST64(0x0202000000000002), CONST64(0x0202008000000002), CONST64(0x0202000002000002), CONST64(0x0202008002000002), + CONST64(0x0202000000020002), CONST64(0x0202008000020002), CONST64(0x0202000002020002), CONST64(0x0202008002020002), + CONST64(0x0202000000000202), CONST64(0x0202008000000202), CONST64(0x0202000002000202), CONST64(0x0202008002000202), + CONST64(0x0202000000020202), CONST64(0x0202008000020202), CONST64(0x0202000002020202), CONST64(0x0202008002020202), + CONST64(0x0000020000000000), CONST64(0x0000028000000000), CONST64(0x0000020002000000), CONST64(0x0000028002000000), + CONST64(0x0000020000020000), CONST64(0x0000028000020000), CONST64(0x0000020002020000), CONST64(0x0000028002020000), + CONST64(0x0000020000000200), CONST64(0x0000028000000200), CONST64(0x0000020002000200), CONST64(0x0000028002000200), + CONST64(0x0000020000020200), CONST64(0x0000028000020200), CONST64(0x0000020002020200), CONST64(0x0000028002020200), + CONST64(0x0000020000000002), CONST64(0x0000028000000002), CONST64(0x0000020002000002), CONST64(0x0000028002000002), + CONST64(0x0000020000020002), CONST64(0x0000028000020002), CONST64(0x0000020002020002), CONST64(0x0000028002020002), + CONST64(0x0000020000000202), CONST64(0x0000028000000202), CONST64(0x0000020002000202), CONST64(0x0000028002000202), + CONST64(0x0000020000020202), CONST64(0x0000028000020202), CONST64(0x0000020002020202), CONST64(0x0000028002020202), + CONST64(0x0200020000000000), CONST64(0x0200028000000000), CONST64(0x0200020002000000), CONST64(0x0200028002000000), + CONST64(0x0200020000020000), CONST64(0x0200028000020000), CONST64(0x0200020002020000), CONST64(0x0200028002020000), + CONST64(0x0200020000000200), CONST64(0x0200028000000200), CONST64(0x0200020002000200), CONST64(0x0200028002000200), + CONST64(0x0200020000020200), CONST64(0x0200028000020200), CONST64(0x0200020002020200), CONST64(0x0200028002020200), + CONST64(0x0200020000000002), CONST64(0x0200028000000002), CONST64(0x0200020002000002), CONST64(0x0200028002000002), + CONST64(0x0200020000020002), CONST64(0x0200028000020002), CONST64(0x0200020002020002), CONST64(0x0200028002020002), + CONST64(0x0200020000000202), CONST64(0x0200028000000202), CONST64(0x0200020002000202), CONST64(0x0200028002000202), + CONST64(0x0200020000020202), CONST64(0x0200028000020202), CONST64(0x0200020002020202), CONST64(0x0200028002020202), + CONST64(0x0002020000000000), CONST64(0x0002028000000000), CONST64(0x0002020002000000), CONST64(0x0002028002000000), + CONST64(0x0002020000020000), CONST64(0x0002028000020000), CONST64(0x0002020002020000), CONST64(0x0002028002020000), + CONST64(0x0002020000000200), CONST64(0x0002028000000200), CONST64(0x0002020002000200), CONST64(0x0002028002000200), + CONST64(0x0002020000020200), CONST64(0x0002028000020200), CONST64(0x0002020002020200), CONST64(0x0002028002020200), + CONST64(0x0002020000000002), CONST64(0x0002028000000002), CONST64(0x0002020002000002), CONST64(0x0002028002000002), + CONST64(0x0002020000020002), CONST64(0x0002028000020002), CONST64(0x0002020002020002), CONST64(0x0002028002020002), + CONST64(0x0002020000000202), CONST64(0x0002028000000202), CONST64(0x0002020002000202), CONST64(0x0002028002000202), + CONST64(0x0002020000020202), CONST64(0x0002028000020202), CONST64(0x0002020002020202), CONST64(0x0002028002020202), + CONST64(0x0202020000000000), CONST64(0x0202028000000000), CONST64(0x0202020002000000), CONST64(0x0202028002000000), + CONST64(0x0202020000020000), CONST64(0x0202028000020000), CONST64(0x0202020002020000), CONST64(0x0202028002020000), + CONST64(0x0202020000000200), CONST64(0x0202028000000200), CONST64(0x0202020002000200), CONST64(0x0202028002000200), + CONST64(0x0202020000020200), CONST64(0x0202028000020200), CONST64(0x0202020002020200), CONST64(0x0202028002020200), + CONST64(0x0202020000000002), CONST64(0x0202028000000002), CONST64(0x0202020002000002), CONST64(0x0202028002000002), + CONST64(0x0202020000020002), CONST64(0x0202028000020002), CONST64(0x0202020002020002), CONST64(0x0202028002020002), + CONST64(0x0202020000000202), CONST64(0x0202028000000202), CONST64(0x0202020002000202), CONST64(0x0202028002000202), + CONST64(0x0202020000020202), CONST64(0x0202028000020202), CONST64(0x0202020002020202), CONST64(0x0202028002020202) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000000200000000), CONST64(0x0000000008000000), CONST64(0x0000000208000000), + CONST64(0x0000000000080000), CONST64(0x0000000200080000), CONST64(0x0000000008080000), CONST64(0x0000000208080000), + CONST64(0x0000000000000800), CONST64(0x0000000200000800), CONST64(0x0000000008000800), CONST64(0x0000000208000800), + CONST64(0x0000000000080800), CONST64(0x0000000200080800), CONST64(0x0000000008080800), CONST64(0x0000000208080800), + CONST64(0x0000000000000008), CONST64(0x0000000200000008), CONST64(0x0000000008000008), CONST64(0x0000000208000008), + CONST64(0x0000000000080008), CONST64(0x0000000200080008), CONST64(0x0000000008080008), CONST64(0x0000000208080008), + CONST64(0x0000000000000808), CONST64(0x0000000200000808), CONST64(0x0000000008000808), CONST64(0x0000000208000808), + CONST64(0x0000000000080808), CONST64(0x0000000200080808), CONST64(0x0000000008080808), CONST64(0x0000000208080808), + CONST64(0x0800000000000000), CONST64(0x0800000200000000), CONST64(0x0800000008000000), CONST64(0x0800000208000000), + CONST64(0x0800000000080000), CONST64(0x0800000200080000), CONST64(0x0800000008080000), CONST64(0x0800000208080000), + CONST64(0x0800000000000800), CONST64(0x0800000200000800), CONST64(0x0800000008000800), CONST64(0x0800000208000800), + CONST64(0x0800000000080800), CONST64(0x0800000200080800), CONST64(0x0800000008080800), CONST64(0x0800000208080800), + CONST64(0x0800000000000008), CONST64(0x0800000200000008), CONST64(0x0800000008000008), CONST64(0x0800000208000008), + CONST64(0x0800000000080008), CONST64(0x0800000200080008), CONST64(0x0800000008080008), CONST64(0x0800000208080008), + CONST64(0x0800000000000808), CONST64(0x0800000200000808), CONST64(0x0800000008000808), CONST64(0x0800000208000808), + CONST64(0x0800000000080808), CONST64(0x0800000200080808), CONST64(0x0800000008080808), CONST64(0x0800000208080808), + CONST64(0x0008000000000000), CONST64(0x0008000200000000), CONST64(0x0008000008000000), CONST64(0x0008000208000000), + CONST64(0x0008000000080000), CONST64(0x0008000200080000), CONST64(0x0008000008080000), CONST64(0x0008000208080000), + CONST64(0x0008000000000800), CONST64(0x0008000200000800), CONST64(0x0008000008000800), CONST64(0x0008000208000800), + CONST64(0x0008000000080800), CONST64(0x0008000200080800), CONST64(0x0008000008080800), CONST64(0x0008000208080800), + CONST64(0x0008000000000008), CONST64(0x0008000200000008), CONST64(0x0008000008000008), CONST64(0x0008000208000008), + CONST64(0x0008000000080008), CONST64(0x0008000200080008), CONST64(0x0008000008080008), CONST64(0x0008000208080008), + CONST64(0x0008000000000808), CONST64(0x0008000200000808), CONST64(0x0008000008000808), CONST64(0x0008000208000808), + CONST64(0x0008000000080808), CONST64(0x0008000200080808), CONST64(0x0008000008080808), CONST64(0x0008000208080808), + CONST64(0x0808000000000000), CONST64(0x0808000200000000), CONST64(0x0808000008000000), CONST64(0x0808000208000000), + CONST64(0x0808000000080000), CONST64(0x0808000200080000), CONST64(0x0808000008080000), CONST64(0x0808000208080000), + CONST64(0x0808000000000800), CONST64(0x0808000200000800), CONST64(0x0808000008000800), CONST64(0x0808000208000800), + CONST64(0x0808000000080800), CONST64(0x0808000200080800), CONST64(0x0808000008080800), CONST64(0x0808000208080800), + CONST64(0x0808000000000008), CONST64(0x0808000200000008), CONST64(0x0808000008000008), CONST64(0x0808000208000008), + CONST64(0x0808000000080008), CONST64(0x0808000200080008), CONST64(0x0808000008080008), CONST64(0x0808000208080008), + CONST64(0x0808000000000808), CONST64(0x0808000200000808), CONST64(0x0808000008000808), CONST64(0x0808000208000808), + CONST64(0x0808000000080808), CONST64(0x0808000200080808), CONST64(0x0808000008080808), CONST64(0x0808000208080808), + CONST64(0x0000080000000000), CONST64(0x0000080200000000), CONST64(0x0000080008000000), CONST64(0x0000080208000000), + CONST64(0x0000080000080000), CONST64(0x0000080200080000), CONST64(0x0000080008080000), CONST64(0x0000080208080000), + CONST64(0x0000080000000800), CONST64(0x0000080200000800), CONST64(0x0000080008000800), CONST64(0x0000080208000800), + CONST64(0x0000080000080800), CONST64(0x0000080200080800), CONST64(0x0000080008080800), CONST64(0x0000080208080800), + CONST64(0x0000080000000008), CONST64(0x0000080200000008), CONST64(0x0000080008000008), CONST64(0x0000080208000008), + CONST64(0x0000080000080008), CONST64(0x0000080200080008), CONST64(0x0000080008080008), CONST64(0x0000080208080008), + CONST64(0x0000080000000808), CONST64(0x0000080200000808), CONST64(0x0000080008000808), CONST64(0x0000080208000808), + CONST64(0x0000080000080808), CONST64(0x0000080200080808), CONST64(0x0000080008080808), CONST64(0x0000080208080808), + CONST64(0x0800080000000000), CONST64(0x0800080200000000), CONST64(0x0800080008000000), CONST64(0x0800080208000000), + CONST64(0x0800080000080000), CONST64(0x0800080200080000), CONST64(0x0800080008080000), CONST64(0x0800080208080000), + CONST64(0x0800080000000800), CONST64(0x0800080200000800), CONST64(0x0800080008000800), CONST64(0x0800080208000800), + CONST64(0x0800080000080800), CONST64(0x0800080200080800), CONST64(0x0800080008080800), CONST64(0x0800080208080800), + CONST64(0x0800080000000008), CONST64(0x0800080200000008), CONST64(0x0800080008000008), CONST64(0x0800080208000008), + CONST64(0x0800080000080008), CONST64(0x0800080200080008), CONST64(0x0800080008080008), CONST64(0x0800080208080008), + CONST64(0x0800080000000808), CONST64(0x0800080200000808), CONST64(0x0800080008000808), CONST64(0x0800080208000808), + CONST64(0x0800080000080808), CONST64(0x0800080200080808), CONST64(0x0800080008080808), CONST64(0x0800080208080808), + CONST64(0x0008080000000000), CONST64(0x0008080200000000), CONST64(0x0008080008000000), CONST64(0x0008080208000000), + CONST64(0x0008080000080000), CONST64(0x0008080200080000), CONST64(0x0008080008080000), CONST64(0x0008080208080000), + CONST64(0x0008080000000800), CONST64(0x0008080200000800), CONST64(0x0008080008000800), CONST64(0x0008080208000800), + CONST64(0x0008080000080800), CONST64(0x0008080200080800), CONST64(0x0008080008080800), CONST64(0x0008080208080800), + CONST64(0x0008080000000008), CONST64(0x0008080200000008), CONST64(0x0008080008000008), CONST64(0x0008080208000008), + CONST64(0x0008080000080008), CONST64(0x0008080200080008), CONST64(0x0008080008080008), CONST64(0x0008080208080008), + CONST64(0x0008080000000808), CONST64(0x0008080200000808), CONST64(0x0008080008000808), CONST64(0x0008080208000808), + CONST64(0x0008080000080808), CONST64(0x0008080200080808), CONST64(0x0008080008080808), CONST64(0x0008080208080808), + CONST64(0x0808080000000000), CONST64(0x0808080200000000), CONST64(0x0808080008000000), CONST64(0x0808080208000000), + CONST64(0x0808080000080000), CONST64(0x0808080200080000), CONST64(0x0808080008080000), CONST64(0x0808080208080000), + CONST64(0x0808080000000800), CONST64(0x0808080200000800), CONST64(0x0808080008000800), CONST64(0x0808080208000800), + CONST64(0x0808080000080800), CONST64(0x0808080200080800), CONST64(0x0808080008080800), CONST64(0x0808080208080800), + CONST64(0x0808080000000008), CONST64(0x0808080200000008), CONST64(0x0808080008000008), CONST64(0x0808080208000008), + CONST64(0x0808080000080008), CONST64(0x0808080200080008), CONST64(0x0808080008080008), CONST64(0x0808080208080008), + CONST64(0x0808080000000808), CONST64(0x0808080200000808), CONST64(0x0808080008000808), CONST64(0x0808080208000808), + CONST64(0x0808080000080808), CONST64(0x0808080200080808), CONST64(0x0808080008080808), CONST64(0x0808080208080808) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000000800000000), CONST64(0x0000000020000000), CONST64(0x0000000820000000), + CONST64(0x0000000000200000), CONST64(0x0000000800200000), CONST64(0x0000000020200000), CONST64(0x0000000820200000), + CONST64(0x0000000000002000), CONST64(0x0000000800002000), CONST64(0x0000000020002000), CONST64(0x0000000820002000), + CONST64(0x0000000000202000), CONST64(0x0000000800202000), CONST64(0x0000000020202000), CONST64(0x0000000820202000), + CONST64(0x0000000000000020), CONST64(0x0000000800000020), CONST64(0x0000000020000020), CONST64(0x0000000820000020), + CONST64(0x0000000000200020), CONST64(0x0000000800200020), CONST64(0x0000000020200020), CONST64(0x0000000820200020), + CONST64(0x0000000000002020), CONST64(0x0000000800002020), CONST64(0x0000000020002020), CONST64(0x0000000820002020), + CONST64(0x0000000000202020), CONST64(0x0000000800202020), CONST64(0x0000000020202020), CONST64(0x0000000820202020), + CONST64(0x2000000000000000), CONST64(0x2000000800000000), CONST64(0x2000000020000000), CONST64(0x2000000820000000), + CONST64(0x2000000000200000), CONST64(0x2000000800200000), CONST64(0x2000000020200000), CONST64(0x2000000820200000), + CONST64(0x2000000000002000), CONST64(0x2000000800002000), CONST64(0x2000000020002000), CONST64(0x2000000820002000), + CONST64(0x2000000000202000), CONST64(0x2000000800202000), CONST64(0x2000000020202000), CONST64(0x2000000820202000), + CONST64(0x2000000000000020), CONST64(0x2000000800000020), CONST64(0x2000000020000020), CONST64(0x2000000820000020), + CONST64(0x2000000000200020), CONST64(0x2000000800200020), CONST64(0x2000000020200020), CONST64(0x2000000820200020), + CONST64(0x2000000000002020), CONST64(0x2000000800002020), CONST64(0x2000000020002020), CONST64(0x2000000820002020), + CONST64(0x2000000000202020), CONST64(0x2000000800202020), CONST64(0x2000000020202020), CONST64(0x2000000820202020), + CONST64(0x0020000000000000), CONST64(0x0020000800000000), CONST64(0x0020000020000000), CONST64(0x0020000820000000), + CONST64(0x0020000000200000), CONST64(0x0020000800200000), CONST64(0x0020000020200000), CONST64(0x0020000820200000), + CONST64(0x0020000000002000), CONST64(0x0020000800002000), CONST64(0x0020000020002000), CONST64(0x0020000820002000), + CONST64(0x0020000000202000), CONST64(0x0020000800202000), CONST64(0x0020000020202000), CONST64(0x0020000820202000), + CONST64(0x0020000000000020), CONST64(0x0020000800000020), CONST64(0x0020000020000020), CONST64(0x0020000820000020), + CONST64(0x0020000000200020), CONST64(0x0020000800200020), CONST64(0x0020000020200020), CONST64(0x0020000820200020), + CONST64(0x0020000000002020), CONST64(0x0020000800002020), CONST64(0x0020000020002020), CONST64(0x0020000820002020), + CONST64(0x0020000000202020), CONST64(0x0020000800202020), CONST64(0x0020000020202020), CONST64(0x0020000820202020), + CONST64(0x2020000000000000), CONST64(0x2020000800000000), CONST64(0x2020000020000000), CONST64(0x2020000820000000), + CONST64(0x2020000000200000), CONST64(0x2020000800200000), CONST64(0x2020000020200000), CONST64(0x2020000820200000), + CONST64(0x2020000000002000), CONST64(0x2020000800002000), CONST64(0x2020000020002000), CONST64(0x2020000820002000), + CONST64(0x2020000000202000), CONST64(0x2020000800202000), CONST64(0x2020000020202000), CONST64(0x2020000820202000), + CONST64(0x2020000000000020), CONST64(0x2020000800000020), CONST64(0x2020000020000020), CONST64(0x2020000820000020), + CONST64(0x2020000000200020), CONST64(0x2020000800200020), CONST64(0x2020000020200020), CONST64(0x2020000820200020), + CONST64(0x2020000000002020), CONST64(0x2020000800002020), CONST64(0x2020000020002020), CONST64(0x2020000820002020), + CONST64(0x2020000000202020), CONST64(0x2020000800202020), CONST64(0x2020000020202020), CONST64(0x2020000820202020), + CONST64(0x0000200000000000), CONST64(0x0000200800000000), CONST64(0x0000200020000000), CONST64(0x0000200820000000), + CONST64(0x0000200000200000), CONST64(0x0000200800200000), CONST64(0x0000200020200000), CONST64(0x0000200820200000), + CONST64(0x0000200000002000), CONST64(0x0000200800002000), CONST64(0x0000200020002000), CONST64(0x0000200820002000), + CONST64(0x0000200000202000), CONST64(0x0000200800202000), CONST64(0x0000200020202000), CONST64(0x0000200820202000), + CONST64(0x0000200000000020), CONST64(0x0000200800000020), CONST64(0x0000200020000020), CONST64(0x0000200820000020), + CONST64(0x0000200000200020), CONST64(0x0000200800200020), CONST64(0x0000200020200020), CONST64(0x0000200820200020), + CONST64(0x0000200000002020), CONST64(0x0000200800002020), CONST64(0x0000200020002020), CONST64(0x0000200820002020), + CONST64(0x0000200000202020), CONST64(0x0000200800202020), CONST64(0x0000200020202020), CONST64(0x0000200820202020), + CONST64(0x2000200000000000), CONST64(0x2000200800000000), CONST64(0x2000200020000000), CONST64(0x2000200820000000), + CONST64(0x2000200000200000), CONST64(0x2000200800200000), CONST64(0x2000200020200000), CONST64(0x2000200820200000), + CONST64(0x2000200000002000), CONST64(0x2000200800002000), CONST64(0x2000200020002000), CONST64(0x2000200820002000), + CONST64(0x2000200000202000), CONST64(0x2000200800202000), CONST64(0x2000200020202000), CONST64(0x2000200820202000), + CONST64(0x2000200000000020), CONST64(0x2000200800000020), CONST64(0x2000200020000020), CONST64(0x2000200820000020), + CONST64(0x2000200000200020), CONST64(0x2000200800200020), CONST64(0x2000200020200020), CONST64(0x2000200820200020), + CONST64(0x2000200000002020), CONST64(0x2000200800002020), CONST64(0x2000200020002020), CONST64(0x2000200820002020), + CONST64(0x2000200000202020), CONST64(0x2000200800202020), CONST64(0x2000200020202020), CONST64(0x2000200820202020), + CONST64(0x0020200000000000), CONST64(0x0020200800000000), CONST64(0x0020200020000000), CONST64(0x0020200820000000), + CONST64(0x0020200000200000), CONST64(0x0020200800200000), CONST64(0x0020200020200000), CONST64(0x0020200820200000), + CONST64(0x0020200000002000), CONST64(0x0020200800002000), CONST64(0x0020200020002000), CONST64(0x0020200820002000), + CONST64(0x0020200000202000), CONST64(0x0020200800202000), CONST64(0x0020200020202000), CONST64(0x0020200820202000), + CONST64(0x0020200000000020), CONST64(0x0020200800000020), CONST64(0x0020200020000020), CONST64(0x0020200820000020), + CONST64(0x0020200000200020), CONST64(0x0020200800200020), CONST64(0x0020200020200020), CONST64(0x0020200820200020), + CONST64(0x0020200000002020), CONST64(0x0020200800002020), CONST64(0x0020200020002020), CONST64(0x0020200820002020), + CONST64(0x0020200000202020), CONST64(0x0020200800202020), CONST64(0x0020200020202020), CONST64(0x0020200820202020), + CONST64(0x2020200000000000), CONST64(0x2020200800000000), CONST64(0x2020200020000000), CONST64(0x2020200820000000), + CONST64(0x2020200000200000), CONST64(0x2020200800200000), CONST64(0x2020200020200000), CONST64(0x2020200820200000), + CONST64(0x2020200000002000), CONST64(0x2020200800002000), CONST64(0x2020200020002000), CONST64(0x2020200820002000), + CONST64(0x2020200000202000), CONST64(0x2020200800202000), CONST64(0x2020200020202000), CONST64(0x2020200820202000), + CONST64(0x2020200000000020), CONST64(0x2020200800000020), CONST64(0x2020200020000020), CONST64(0x2020200820000020), + CONST64(0x2020200000200020), CONST64(0x2020200800200020), CONST64(0x2020200020200020), CONST64(0x2020200820200020), + CONST64(0x2020200000002020), CONST64(0x2020200800002020), CONST64(0x2020200020002020), CONST64(0x2020200820002020), + CONST64(0x2020200000202020), CONST64(0x2020200800202020), CONST64(0x2020200020202020), CONST64(0x2020200820202020) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000002000000000), CONST64(0x0000000080000000), CONST64(0x0000002080000000), + CONST64(0x0000000000800000), CONST64(0x0000002000800000), CONST64(0x0000000080800000), CONST64(0x0000002080800000), + CONST64(0x0000000000008000), CONST64(0x0000002000008000), CONST64(0x0000000080008000), CONST64(0x0000002080008000), + CONST64(0x0000000000808000), CONST64(0x0000002000808000), CONST64(0x0000000080808000), CONST64(0x0000002080808000), + CONST64(0x0000000000000080), CONST64(0x0000002000000080), CONST64(0x0000000080000080), CONST64(0x0000002080000080), + CONST64(0x0000000000800080), CONST64(0x0000002000800080), CONST64(0x0000000080800080), CONST64(0x0000002080800080), + CONST64(0x0000000000008080), CONST64(0x0000002000008080), CONST64(0x0000000080008080), CONST64(0x0000002080008080), + CONST64(0x0000000000808080), CONST64(0x0000002000808080), CONST64(0x0000000080808080), CONST64(0x0000002080808080), + CONST64(0x8000000000000000), CONST64(0x8000002000000000), CONST64(0x8000000080000000), CONST64(0x8000002080000000), + CONST64(0x8000000000800000), CONST64(0x8000002000800000), CONST64(0x8000000080800000), CONST64(0x8000002080800000), + CONST64(0x8000000000008000), CONST64(0x8000002000008000), CONST64(0x8000000080008000), CONST64(0x8000002080008000), + CONST64(0x8000000000808000), CONST64(0x8000002000808000), CONST64(0x8000000080808000), CONST64(0x8000002080808000), + CONST64(0x8000000000000080), CONST64(0x8000002000000080), CONST64(0x8000000080000080), CONST64(0x8000002080000080), + CONST64(0x8000000000800080), CONST64(0x8000002000800080), CONST64(0x8000000080800080), CONST64(0x8000002080800080), + CONST64(0x8000000000008080), CONST64(0x8000002000008080), CONST64(0x8000000080008080), CONST64(0x8000002080008080), + CONST64(0x8000000000808080), CONST64(0x8000002000808080), CONST64(0x8000000080808080), CONST64(0x8000002080808080), + CONST64(0x0080000000000000), CONST64(0x0080002000000000), CONST64(0x0080000080000000), CONST64(0x0080002080000000), + CONST64(0x0080000000800000), CONST64(0x0080002000800000), CONST64(0x0080000080800000), CONST64(0x0080002080800000), + CONST64(0x0080000000008000), CONST64(0x0080002000008000), CONST64(0x0080000080008000), CONST64(0x0080002080008000), + CONST64(0x0080000000808000), CONST64(0x0080002000808000), CONST64(0x0080000080808000), CONST64(0x0080002080808000), + CONST64(0x0080000000000080), CONST64(0x0080002000000080), CONST64(0x0080000080000080), CONST64(0x0080002080000080), + CONST64(0x0080000000800080), CONST64(0x0080002000800080), CONST64(0x0080000080800080), CONST64(0x0080002080800080), + CONST64(0x0080000000008080), CONST64(0x0080002000008080), CONST64(0x0080000080008080), CONST64(0x0080002080008080), + CONST64(0x0080000000808080), CONST64(0x0080002000808080), CONST64(0x0080000080808080), CONST64(0x0080002080808080), + CONST64(0x8080000000000000), CONST64(0x8080002000000000), CONST64(0x8080000080000000), CONST64(0x8080002080000000), + CONST64(0x8080000000800000), CONST64(0x8080002000800000), CONST64(0x8080000080800000), CONST64(0x8080002080800000), + CONST64(0x8080000000008000), CONST64(0x8080002000008000), CONST64(0x8080000080008000), CONST64(0x8080002080008000), + CONST64(0x8080000000808000), CONST64(0x8080002000808000), CONST64(0x8080000080808000), CONST64(0x8080002080808000), + CONST64(0x8080000000000080), CONST64(0x8080002000000080), CONST64(0x8080000080000080), CONST64(0x8080002080000080), + CONST64(0x8080000000800080), CONST64(0x8080002000800080), CONST64(0x8080000080800080), CONST64(0x8080002080800080), + CONST64(0x8080000000008080), CONST64(0x8080002000008080), CONST64(0x8080000080008080), CONST64(0x8080002080008080), + CONST64(0x8080000000808080), CONST64(0x8080002000808080), CONST64(0x8080000080808080), CONST64(0x8080002080808080), + CONST64(0x0000800000000000), CONST64(0x0000802000000000), CONST64(0x0000800080000000), CONST64(0x0000802080000000), + CONST64(0x0000800000800000), CONST64(0x0000802000800000), CONST64(0x0000800080800000), CONST64(0x0000802080800000), + CONST64(0x0000800000008000), CONST64(0x0000802000008000), CONST64(0x0000800080008000), CONST64(0x0000802080008000), + CONST64(0x0000800000808000), CONST64(0x0000802000808000), CONST64(0x0000800080808000), CONST64(0x0000802080808000), + CONST64(0x0000800000000080), CONST64(0x0000802000000080), CONST64(0x0000800080000080), CONST64(0x0000802080000080), + CONST64(0x0000800000800080), CONST64(0x0000802000800080), CONST64(0x0000800080800080), CONST64(0x0000802080800080), + CONST64(0x0000800000008080), CONST64(0x0000802000008080), CONST64(0x0000800080008080), CONST64(0x0000802080008080), + CONST64(0x0000800000808080), CONST64(0x0000802000808080), CONST64(0x0000800080808080), CONST64(0x0000802080808080), + CONST64(0x8000800000000000), CONST64(0x8000802000000000), CONST64(0x8000800080000000), CONST64(0x8000802080000000), + CONST64(0x8000800000800000), CONST64(0x8000802000800000), CONST64(0x8000800080800000), CONST64(0x8000802080800000), + CONST64(0x8000800000008000), CONST64(0x8000802000008000), CONST64(0x8000800080008000), CONST64(0x8000802080008000), + CONST64(0x8000800000808000), CONST64(0x8000802000808000), CONST64(0x8000800080808000), CONST64(0x8000802080808000), + CONST64(0x8000800000000080), CONST64(0x8000802000000080), CONST64(0x8000800080000080), CONST64(0x8000802080000080), + CONST64(0x8000800000800080), CONST64(0x8000802000800080), CONST64(0x8000800080800080), CONST64(0x8000802080800080), + CONST64(0x8000800000008080), CONST64(0x8000802000008080), CONST64(0x8000800080008080), CONST64(0x8000802080008080), + CONST64(0x8000800000808080), CONST64(0x8000802000808080), CONST64(0x8000800080808080), CONST64(0x8000802080808080), + CONST64(0x0080800000000000), CONST64(0x0080802000000000), CONST64(0x0080800080000000), CONST64(0x0080802080000000), + CONST64(0x0080800000800000), CONST64(0x0080802000800000), CONST64(0x0080800080800000), CONST64(0x0080802080800000), + CONST64(0x0080800000008000), CONST64(0x0080802000008000), CONST64(0x0080800080008000), CONST64(0x0080802080008000), + CONST64(0x0080800000808000), CONST64(0x0080802000808000), CONST64(0x0080800080808000), CONST64(0x0080802080808000), + CONST64(0x0080800000000080), CONST64(0x0080802000000080), CONST64(0x0080800080000080), CONST64(0x0080802080000080), + CONST64(0x0080800000800080), CONST64(0x0080802000800080), CONST64(0x0080800080800080), CONST64(0x0080802080800080), + CONST64(0x0080800000008080), CONST64(0x0080802000008080), CONST64(0x0080800080008080), CONST64(0x0080802080008080), + CONST64(0x0080800000808080), CONST64(0x0080802000808080), CONST64(0x0080800080808080), CONST64(0x0080802080808080), + CONST64(0x8080800000000000), CONST64(0x8080802000000000), CONST64(0x8080800080000000), CONST64(0x8080802080000000), + CONST64(0x8080800000800000), CONST64(0x8080802000800000), CONST64(0x8080800080800000), CONST64(0x8080802080800000), + CONST64(0x8080800000008000), CONST64(0x8080802000008000), CONST64(0x8080800080008000), CONST64(0x8080802080008000), + CONST64(0x8080800000808000), CONST64(0x8080802000808000), CONST64(0x8080800080808000), CONST64(0x8080802080808000), + CONST64(0x8080800000000080), CONST64(0x8080802000000080), CONST64(0x8080800080000080), CONST64(0x8080802080000080), + CONST64(0x8080800000800080), CONST64(0x8080802000800080), CONST64(0x8080800080800080), CONST64(0x8080802080800080), + CONST64(0x8080800000008080), CONST64(0x8080802000008080), CONST64(0x8080800080008080), CONST64(0x8080802080008080), + CONST64(0x8080800000808080), CONST64(0x8080802000808080), CONST64(0x8080800080808080), CONST64(0x8080802080808080) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000004000000000), CONST64(0x0000000001000000), CONST64(0x0000004001000000), + CONST64(0x0000000000010000), CONST64(0x0000004000010000), CONST64(0x0000000001010000), CONST64(0x0000004001010000), + CONST64(0x0000000000000100), CONST64(0x0000004000000100), CONST64(0x0000000001000100), CONST64(0x0000004001000100), + CONST64(0x0000000000010100), CONST64(0x0000004000010100), CONST64(0x0000000001010100), CONST64(0x0000004001010100), + CONST64(0x0000000000000001), CONST64(0x0000004000000001), CONST64(0x0000000001000001), CONST64(0x0000004001000001), + CONST64(0x0000000000010001), CONST64(0x0000004000010001), CONST64(0x0000000001010001), CONST64(0x0000004001010001), + CONST64(0x0000000000000101), CONST64(0x0000004000000101), CONST64(0x0000000001000101), CONST64(0x0000004001000101), + CONST64(0x0000000000010101), CONST64(0x0000004000010101), CONST64(0x0000000001010101), CONST64(0x0000004001010101), + CONST64(0x0100000000000000), CONST64(0x0100004000000000), CONST64(0x0100000001000000), CONST64(0x0100004001000000), + CONST64(0x0100000000010000), CONST64(0x0100004000010000), CONST64(0x0100000001010000), CONST64(0x0100004001010000), + CONST64(0x0100000000000100), CONST64(0x0100004000000100), CONST64(0x0100000001000100), CONST64(0x0100004001000100), + CONST64(0x0100000000010100), CONST64(0x0100004000010100), CONST64(0x0100000001010100), CONST64(0x0100004001010100), + CONST64(0x0100000000000001), CONST64(0x0100004000000001), CONST64(0x0100000001000001), CONST64(0x0100004001000001), + CONST64(0x0100000000010001), CONST64(0x0100004000010001), CONST64(0x0100000001010001), CONST64(0x0100004001010001), + CONST64(0x0100000000000101), CONST64(0x0100004000000101), CONST64(0x0100000001000101), CONST64(0x0100004001000101), + CONST64(0x0100000000010101), CONST64(0x0100004000010101), CONST64(0x0100000001010101), CONST64(0x0100004001010101), + CONST64(0x0001000000000000), CONST64(0x0001004000000000), CONST64(0x0001000001000000), CONST64(0x0001004001000000), + CONST64(0x0001000000010000), CONST64(0x0001004000010000), CONST64(0x0001000001010000), CONST64(0x0001004001010000), + CONST64(0x0001000000000100), CONST64(0x0001004000000100), CONST64(0x0001000001000100), CONST64(0x0001004001000100), + CONST64(0x0001000000010100), CONST64(0x0001004000010100), CONST64(0x0001000001010100), CONST64(0x0001004001010100), + CONST64(0x0001000000000001), CONST64(0x0001004000000001), CONST64(0x0001000001000001), CONST64(0x0001004001000001), + CONST64(0x0001000000010001), CONST64(0x0001004000010001), CONST64(0x0001000001010001), CONST64(0x0001004001010001), + CONST64(0x0001000000000101), CONST64(0x0001004000000101), CONST64(0x0001000001000101), CONST64(0x0001004001000101), + CONST64(0x0001000000010101), CONST64(0x0001004000010101), CONST64(0x0001000001010101), CONST64(0x0001004001010101), + CONST64(0x0101000000000000), CONST64(0x0101004000000000), CONST64(0x0101000001000000), CONST64(0x0101004001000000), + CONST64(0x0101000000010000), CONST64(0x0101004000010000), CONST64(0x0101000001010000), CONST64(0x0101004001010000), + CONST64(0x0101000000000100), CONST64(0x0101004000000100), CONST64(0x0101000001000100), CONST64(0x0101004001000100), + CONST64(0x0101000000010100), CONST64(0x0101004000010100), CONST64(0x0101000001010100), CONST64(0x0101004001010100), + CONST64(0x0101000000000001), CONST64(0x0101004000000001), CONST64(0x0101000001000001), CONST64(0x0101004001000001), + CONST64(0x0101000000010001), CONST64(0x0101004000010001), CONST64(0x0101000001010001), CONST64(0x0101004001010001), + CONST64(0x0101000000000101), CONST64(0x0101004000000101), CONST64(0x0101000001000101), CONST64(0x0101004001000101), + CONST64(0x0101000000010101), CONST64(0x0101004000010101), CONST64(0x0101000001010101), CONST64(0x0101004001010101), + CONST64(0x0000010000000000), CONST64(0x0000014000000000), CONST64(0x0000010001000000), CONST64(0x0000014001000000), + CONST64(0x0000010000010000), CONST64(0x0000014000010000), CONST64(0x0000010001010000), CONST64(0x0000014001010000), + CONST64(0x0000010000000100), CONST64(0x0000014000000100), CONST64(0x0000010001000100), CONST64(0x0000014001000100), + CONST64(0x0000010000010100), CONST64(0x0000014000010100), CONST64(0x0000010001010100), CONST64(0x0000014001010100), + CONST64(0x0000010000000001), CONST64(0x0000014000000001), CONST64(0x0000010001000001), CONST64(0x0000014001000001), + CONST64(0x0000010000010001), CONST64(0x0000014000010001), CONST64(0x0000010001010001), CONST64(0x0000014001010001), + CONST64(0x0000010000000101), CONST64(0x0000014000000101), CONST64(0x0000010001000101), CONST64(0x0000014001000101), + CONST64(0x0000010000010101), CONST64(0x0000014000010101), CONST64(0x0000010001010101), CONST64(0x0000014001010101), + CONST64(0x0100010000000000), CONST64(0x0100014000000000), CONST64(0x0100010001000000), CONST64(0x0100014001000000), + CONST64(0x0100010000010000), CONST64(0x0100014000010000), CONST64(0x0100010001010000), CONST64(0x0100014001010000), + CONST64(0x0100010000000100), CONST64(0x0100014000000100), CONST64(0x0100010001000100), CONST64(0x0100014001000100), + CONST64(0x0100010000010100), CONST64(0x0100014000010100), CONST64(0x0100010001010100), CONST64(0x0100014001010100), + CONST64(0x0100010000000001), CONST64(0x0100014000000001), CONST64(0x0100010001000001), CONST64(0x0100014001000001), + CONST64(0x0100010000010001), CONST64(0x0100014000010001), CONST64(0x0100010001010001), CONST64(0x0100014001010001), + CONST64(0x0100010000000101), CONST64(0x0100014000000101), CONST64(0x0100010001000101), CONST64(0x0100014001000101), + CONST64(0x0100010000010101), CONST64(0x0100014000010101), CONST64(0x0100010001010101), CONST64(0x0100014001010101), + CONST64(0x0001010000000000), CONST64(0x0001014000000000), CONST64(0x0001010001000000), CONST64(0x0001014001000000), + CONST64(0x0001010000010000), CONST64(0x0001014000010000), CONST64(0x0001010001010000), CONST64(0x0001014001010000), + CONST64(0x0001010000000100), CONST64(0x0001014000000100), CONST64(0x0001010001000100), CONST64(0x0001014001000100), + CONST64(0x0001010000010100), CONST64(0x0001014000010100), CONST64(0x0001010001010100), CONST64(0x0001014001010100), + CONST64(0x0001010000000001), CONST64(0x0001014000000001), CONST64(0x0001010001000001), CONST64(0x0001014001000001), + CONST64(0x0001010000010001), CONST64(0x0001014000010001), CONST64(0x0001010001010001), CONST64(0x0001014001010001), + CONST64(0x0001010000000101), CONST64(0x0001014000000101), CONST64(0x0001010001000101), CONST64(0x0001014001000101), + CONST64(0x0001010000010101), CONST64(0x0001014000010101), CONST64(0x0001010001010101), CONST64(0x0001014001010101), + CONST64(0x0101010000000000), CONST64(0x0101014000000000), CONST64(0x0101010001000000), CONST64(0x0101014001000000), + CONST64(0x0101010000010000), CONST64(0x0101014000010000), CONST64(0x0101010001010000), CONST64(0x0101014001010000), + CONST64(0x0101010000000100), CONST64(0x0101014000000100), CONST64(0x0101010001000100), CONST64(0x0101014001000100), + CONST64(0x0101010000010100), CONST64(0x0101014000010100), CONST64(0x0101010001010100), CONST64(0x0101014001010100), + CONST64(0x0101010000000001), CONST64(0x0101014000000001), CONST64(0x0101010001000001), CONST64(0x0101014001000001), + CONST64(0x0101010000010001), CONST64(0x0101014000010001), CONST64(0x0101010001010001), CONST64(0x0101014001010001), + CONST64(0x0101010000000101), CONST64(0x0101014000000101), CONST64(0x0101010001000101), CONST64(0x0101014001000101), + CONST64(0x0101010000010101), CONST64(0x0101014000010101), CONST64(0x0101010001010101), CONST64(0x0101014001010101) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000000100000000), CONST64(0x0000000004000000), CONST64(0x0000000104000000), + CONST64(0x0000000000040000), CONST64(0x0000000100040000), CONST64(0x0000000004040000), CONST64(0x0000000104040000), + CONST64(0x0000000000000400), CONST64(0x0000000100000400), CONST64(0x0000000004000400), CONST64(0x0000000104000400), + CONST64(0x0000000000040400), CONST64(0x0000000100040400), CONST64(0x0000000004040400), CONST64(0x0000000104040400), + CONST64(0x0000000000000004), CONST64(0x0000000100000004), CONST64(0x0000000004000004), CONST64(0x0000000104000004), + CONST64(0x0000000000040004), CONST64(0x0000000100040004), CONST64(0x0000000004040004), CONST64(0x0000000104040004), + CONST64(0x0000000000000404), CONST64(0x0000000100000404), CONST64(0x0000000004000404), CONST64(0x0000000104000404), + CONST64(0x0000000000040404), CONST64(0x0000000100040404), CONST64(0x0000000004040404), CONST64(0x0000000104040404), + CONST64(0x0400000000000000), CONST64(0x0400000100000000), CONST64(0x0400000004000000), CONST64(0x0400000104000000), + CONST64(0x0400000000040000), CONST64(0x0400000100040000), CONST64(0x0400000004040000), CONST64(0x0400000104040000), + CONST64(0x0400000000000400), CONST64(0x0400000100000400), CONST64(0x0400000004000400), CONST64(0x0400000104000400), + CONST64(0x0400000000040400), CONST64(0x0400000100040400), CONST64(0x0400000004040400), CONST64(0x0400000104040400), + CONST64(0x0400000000000004), CONST64(0x0400000100000004), CONST64(0x0400000004000004), CONST64(0x0400000104000004), + CONST64(0x0400000000040004), CONST64(0x0400000100040004), CONST64(0x0400000004040004), CONST64(0x0400000104040004), + CONST64(0x0400000000000404), CONST64(0x0400000100000404), CONST64(0x0400000004000404), CONST64(0x0400000104000404), + CONST64(0x0400000000040404), CONST64(0x0400000100040404), CONST64(0x0400000004040404), CONST64(0x0400000104040404), + CONST64(0x0004000000000000), CONST64(0x0004000100000000), CONST64(0x0004000004000000), CONST64(0x0004000104000000), + CONST64(0x0004000000040000), CONST64(0x0004000100040000), CONST64(0x0004000004040000), CONST64(0x0004000104040000), + CONST64(0x0004000000000400), CONST64(0x0004000100000400), CONST64(0x0004000004000400), CONST64(0x0004000104000400), + CONST64(0x0004000000040400), CONST64(0x0004000100040400), CONST64(0x0004000004040400), CONST64(0x0004000104040400), + CONST64(0x0004000000000004), CONST64(0x0004000100000004), CONST64(0x0004000004000004), CONST64(0x0004000104000004), + CONST64(0x0004000000040004), CONST64(0x0004000100040004), CONST64(0x0004000004040004), CONST64(0x0004000104040004), + CONST64(0x0004000000000404), CONST64(0x0004000100000404), CONST64(0x0004000004000404), CONST64(0x0004000104000404), + CONST64(0x0004000000040404), CONST64(0x0004000100040404), CONST64(0x0004000004040404), CONST64(0x0004000104040404), + CONST64(0x0404000000000000), CONST64(0x0404000100000000), CONST64(0x0404000004000000), CONST64(0x0404000104000000), + CONST64(0x0404000000040000), CONST64(0x0404000100040000), CONST64(0x0404000004040000), CONST64(0x0404000104040000), + CONST64(0x0404000000000400), CONST64(0x0404000100000400), CONST64(0x0404000004000400), CONST64(0x0404000104000400), + CONST64(0x0404000000040400), CONST64(0x0404000100040400), CONST64(0x0404000004040400), CONST64(0x0404000104040400), + CONST64(0x0404000000000004), CONST64(0x0404000100000004), CONST64(0x0404000004000004), CONST64(0x0404000104000004), + CONST64(0x0404000000040004), CONST64(0x0404000100040004), CONST64(0x0404000004040004), CONST64(0x0404000104040004), + CONST64(0x0404000000000404), CONST64(0x0404000100000404), CONST64(0x0404000004000404), CONST64(0x0404000104000404), + CONST64(0x0404000000040404), CONST64(0x0404000100040404), CONST64(0x0404000004040404), CONST64(0x0404000104040404), + CONST64(0x0000040000000000), CONST64(0x0000040100000000), CONST64(0x0000040004000000), CONST64(0x0000040104000000), + CONST64(0x0000040000040000), CONST64(0x0000040100040000), CONST64(0x0000040004040000), CONST64(0x0000040104040000), + CONST64(0x0000040000000400), CONST64(0x0000040100000400), CONST64(0x0000040004000400), CONST64(0x0000040104000400), + CONST64(0x0000040000040400), CONST64(0x0000040100040400), CONST64(0x0000040004040400), CONST64(0x0000040104040400), + CONST64(0x0000040000000004), CONST64(0x0000040100000004), CONST64(0x0000040004000004), CONST64(0x0000040104000004), + CONST64(0x0000040000040004), CONST64(0x0000040100040004), CONST64(0x0000040004040004), CONST64(0x0000040104040004), + CONST64(0x0000040000000404), CONST64(0x0000040100000404), CONST64(0x0000040004000404), CONST64(0x0000040104000404), + CONST64(0x0000040000040404), CONST64(0x0000040100040404), CONST64(0x0000040004040404), CONST64(0x0000040104040404), + CONST64(0x0400040000000000), CONST64(0x0400040100000000), CONST64(0x0400040004000000), CONST64(0x0400040104000000), + CONST64(0x0400040000040000), CONST64(0x0400040100040000), CONST64(0x0400040004040000), CONST64(0x0400040104040000), + CONST64(0x0400040000000400), CONST64(0x0400040100000400), CONST64(0x0400040004000400), CONST64(0x0400040104000400), + CONST64(0x0400040000040400), CONST64(0x0400040100040400), CONST64(0x0400040004040400), CONST64(0x0400040104040400), + CONST64(0x0400040000000004), CONST64(0x0400040100000004), CONST64(0x0400040004000004), CONST64(0x0400040104000004), + CONST64(0x0400040000040004), CONST64(0x0400040100040004), CONST64(0x0400040004040004), CONST64(0x0400040104040004), + CONST64(0x0400040000000404), CONST64(0x0400040100000404), CONST64(0x0400040004000404), CONST64(0x0400040104000404), + CONST64(0x0400040000040404), CONST64(0x0400040100040404), CONST64(0x0400040004040404), CONST64(0x0400040104040404), + CONST64(0x0004040000000000), CONST64(0x0004040100000000), CONST64(0x0004040004000000), CONST64(0x0004040104000000), + CONST64(0x0004040000040000), CONST64(0x0004040100040000), CONST64(0x0004040004040000), CONST64(0x0004040104040000), + CONST64(0x0004040000000400), CONST64(0x0004040100000400), CONST64(0x0004040004000400), CONST64(0x0004040104000400), + CONST64(0x0004040000040400), CONST64(0x0004040100040400), CONST64(0x0004040004040400), CONST64(0x0004040104040400), + CONST64(0x0004040000000004), CONST64(0x0004040100000004), CONST64(0x0004040004000004), CONST64(0x0004040104000004), + CONST64(0x0004040000040004), CONST64(0x0004040100040004), CONST64(0x0004040004040004), CONST64(0x0004040104040004), + CONST64(0x0004040000000404), CONST64(0x0004040100000404), CONST64(0x0004040004000404), CONST64(0x0004040104000404), + CONST64(0x0004040000040404), CONST64(0x0004040100040404), CONST64(0x0004040004040404), CONST64(0x0004040104040404), + CONST64(0x0404040000000000), CONST64(0x0404040100000000), CONST64(0x0404040004000000), CONST64(0x0404040104000000), + CONST64(0x0404040000040000), CONST64(0x0404040100040000), CONST64(0x0404040004040000), CONST64(0x0404040104040000), + CONST64(0x0404040000000400), CONST64(0x0404040100000400), CONST64(0x0404040004000400), CONST64(0x0404040104000400), + CONST64(0x0404040000040400), CONST64(0x0404040100040400), CONST64(0x0404040004040400), CONST64(0x0404040104040400), + CONST64(0x0404040000000004), CONST64(0x0404040100000004), CONST64(0x0404040004000004), CONST64(0x0404040104000004), + CONST64(0x0404040000040004), CONST64(0x0404040100040004), CONST64(0x0404040004040004), CONST64(0x0404040104040004), + CONST64(0x0404040000000404), CONST64(0x0404040100000404), CONST64(0x0404040004000404), CONST64(0x0404040104000404), + CONST64(0x0404040000040404), CONST64(0x0404040100040404), CONST64(0x0404040004040404), CONST64(0x0404040104040404) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000000400000000), CONST64(0x0000000010000000), CONST64(0x0000000410000000), + CONST64(0x0000000000100000), CONST64(0x0000000400100000), CONST64(0x0000000010100000), CONST64(0x0000000410100000), + CONST64(0x0000000000001000), CONST64(0x0000000400001000), CONST64(0x0000000010001000), CONST64(0x0000000410001000), + CONST64(0x0000000000101000), CONST64(0x0000000400101000), CONST64(0x0000000010101000), CONST64(0x0000000410101000), + CONST64(0x0000000000000010), CONST64(0x0000000400000010), CONST64(0x0000000010000010), CONST64(0x0000000410000010), + CONST64(0x0000000000100010), CONST64(0x0000000400100010), CONST64(0x0000000010100010), CONST64(0x0000000410100010), + CONST64(0x0000000000001010), CONST64(0x0000000400001010), CONST64(0x0000000010001010), CONST64(0x0000000410001010), + CONST64(0x0000000000101010), CONST64(0x0000000400101010), CONST64(0x0000000010101010), CONST64(0x0000000410101010), + CONST64(0x1000000000000000), CONST64(0x1000000400000000), CONST64(0x1000000010000000), CONST64(0x1000000410000000), + CONST64(0x1000000000100000), CONST64(0x1000000400100000), CONST64(0x1000000010100000), CONST64(0x1000000410100000), + CONST64(0x1000000000001000), CONST64(0x1000000400001000), CONST64(0x1000000010001000), CONST64(0x1000000410001000), + CONST64(0x1000000000101000), CONST64(0x1000000400101000), CONST64(0x1000000010101000), CONST64(0x1000000410101000), + CONST64(0x1000000000000010), CONST64(0x1000000400000010), CONST64(0x1000000010000010), CONST64(0x1000000410000010), + CONST64(0x1000000000100010), CONST64(0x1000000400100010), CONST64(0x1000000010100010), CONST64(0x1000000410100010), + CONST64(0x1000000000001010), CONST64(0x1000000400001010), CONST64(0x1000000010001010), CONST64(0x1000000410001010), + CONST64(0x1000000000101010), CONST64(0x1000000400101010), CONST64(0x1000000010101010), CONST64(0x1000000410101010), + CONST64(0x0010000000000000), CONST64(0x0010000400000000), CONST64(0x0010000010000000), CONST64(0x0010000410000000), + CONST64(0x0010000000100000), CONST64(0x0010000400100000), CONST64(0x0010000010100000), CONST64(0x0010000410100000), + CONST64(0x0010000000001000), CONST64(0x0010000400001000), CONST64(0x0010000010001000), CONST64(0x0010000410001000), + CONST64(0x0010000000101000), CONST64(0x0010000400101000), CONST64(0x0010000010101000), CONST64(0x0010000410101000), + CONST64(0x0010000000000010), CONST64(0x0010000400000010), CONST64(0x0010000010000010), CONST64(0x0010000410000010), + CONST64(0x0010000000100010), CONST64(0x0010000400100010), CONST64(0x0010000010100010), CONST64(0x0010000410100010), + CONST64(0x0010000000001010), CONST64(0x0010000400001010), CONST64(0x0010000010001010), CONST64(0x0010000410001010), + CONST64(0x0010000000101010), CONST64(0x0010000400101010), CONST64(0x0010000010101010), CONST64(0x0010000410101010), + CONST64(0x1010000000000000), CONST64(0x1010000400000000), CONST64(0x1010000010000000), CONST64(0x1010000410000000), + CONST64(0x1010000000100000), CONST64(0x1010000400100000), CONST64(0x1010000010100000), CONST64(0x1010000410100000), + CONST64(0x1010000000001000), CONST64(0x1010000400001000), CONST64(0x1010000010001000), CONST64(0x1010000410001000), + CONST64(0x1010000000101000), CONST64(0x1010000400101000), CONST64(0x1010000010101000), CONST64(0x1010000410101000), + CONST64(0x1010000000000010), CONST64(0x1010000400000010), CONST64(0x1010000010000010), CONST64(0x1010000410000010), + CONST64(0x1010000000100010), CONST64(0x1010000400100010), CONST64(0x1010000010100010), CONST64(0x1010000410100010), + CONST64(0x1010000000001010), CONST64(0x1010000400001010), CONST64(0x1010000010001010), CONST64(0x1010000410001010), + CONST64(0x1010000000101010), CONST64(0x1010000400101010), CONST64(0x1010000010101010), CONST64(0x1010000410101010), + CONST64(0x0000100000000000), CONST64(0x0000100400000000), CONST64(0x0000100010000000), CONST64(0x0000100410000000), + CONST64(0x0000100000100000), CONST64(0x0000100400100000), CONST64(0x0000100010100000), CONST64(0x0000100410100000), + CONST64(0x0000100000001000), CONST64(0x0000100400001000), CONST64(0x0000100010001000), CONST64(0x0000100410001000), + CONST64(0x0000100000101000), CONST64(0x0000100400101000), CONST64(0x0000100010101000), CONST64(0x0000100410101000), + CONST64(0x0000100000000010), CONST64(0x0000100400000010), CONST64(0x0000100010000010), CONST64(0x0000100410000010), + CONST64(0x0000100000100010), CONST64(0x0000100400100010), CONST64(0x0000100010100010), CONST64(0x0000100410100010), + CONST64(0x0000100000001010), CONST64(0x0000100400001010), CONST64(0x0000100010001010), CONST64(0x0000100410001010), + CONST64(0x0000100000101010), CONST64(0x0000100400101010), CONST64(0x0000100010101010), CONST64(0x0000100410101010), + CONST64(0x1000100000000000), CONST64(0x1000100400000000), CONST64(0x1000100010000000), CONST64(0x1000100410000000), + CONST64(0x1000100000100000), CONST64(0x1000100400100000), CONST64(0x1000100010100000), CONST64(0x1000100410100000), + CONST64(0x1000100000001000), CONST64(0x1000100400001000), CONST64(0x1000100010001000), CONST64(0x1000100410001000), + CONST64(0x1000100000101000), CONST64(0x1000100400101000), CONST64(0x1000100010101000), CONST64(0x1000100410101000), + CONST64(0x1000100000000010), CONST64(0x1000100400000010), CONST64(0x1000100010000010), CONST64(0x1000100410000010), + CONST64(0x1000100000100010), CONST64(0x1000100400100010), CONST64(0x1000100010100010), CONST64(0x1000100410100010), + CONST64(0x1000100000001010), CONST64(0x1000100400001010), CONST64(0x1000100010001010), CONST64(0x1000100410001010), + CONST64(0x1000100000101010), CONST64(0x1000100400101010), CONST64(0x1000100010101010), CONST64(0x1000100410101010), + CONST64(0x0010100000000000), CONST64(0x0010100400000000), CONST64(0x0010100010000000), CONST64(0x0010100410000000), + CONST64(0x0010100000100000), CONST64(0x0010100400100000), CONST64(0x0010100010100000), CONST64(0x0010100410100000), + CONST64(0x0010100000001000), CONST64(0x0010100400001000), CONST64(0x0010100010001000), CONST64(0x0010100410001000), + CONST64(0x0010100000101000), CONST64(0x0010100400101000), CONST64(0x0010100010101000), CONST64(0x0010100410101000), + CONST64(0x0010100000000010), CONST64(0x0010100400000010), CONST64(0x0010100010000010), CONST64(0x0010100410000010), + CONST64(0x0010100000100010), CONST64(0x0010100400100010), CONST64(0x0010100010100010), CONST64(0x0010100410100010), + CONST64(0x0010100000001010), CONST64(0x0010100400001010), CONST64(0x0010100010001010), CONST64(0x0010100410001010), + CONST64(0x0010100000101010), CONST64(0x0010100400101010), CONST64(0x0010100010101010), CONST64(0x0010100410101010), + CONST64(0x1010100000000000), CONST64(0x1010100400000000), CONST64(0x1010100010000000), CONST64(0x1010100410000000), + CONST64(0x1010100000100000), CONST64(0x1010100400100000), CONST64(0x1010100010100000), CONST64(0x1010100410100000), + CONST64(0x1010100000001000), CONST64(0x1010100400001000), CONST64(0x1010100010001000), CONST64(0x1010100410001000), + CONST64(0x1010100000101000), CONST64(0x1010100400101000), CONST64(0x1010100010101000), CONST64(0x1010100410101000), + CONST64(0x1010100000000010), CONST64(0x1010100400000010), CONST64(0x1010100010000010), CONST64(0x1010100410000010), + CONST64(0x1010100000100010), CONST64(0x1010100400100010), CONST64(0x1010100010100010), CONST64(0x1010100410100010), + CONST64(0x1010100000001010), CONST64(0x1010100400001010), CONST64(0x1010100010001010), CONST64(0x1010100410001010), + CONST64(0x1010100000101010), CONST64(0x1010100400101010), CONST64(0x1010100010101010), CONST64(0x1010100410101010) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000001000000000), CONST64(0x0000000040000000), CONST64(0x0000001040000000), + CONST64(0x0000000000400000), CONST64(0x0000001000400000), CONST64(0x0000000040400000), CONST64(0x0000001040400000), + CONST64(0x0000000000004000), CONST64(0x0000001000004000), CONST64(0x0000000040004000), CONST64(0x0000001040004000), + CONST64(0x0000000000404000), CONST64(0x0000001000404000), CONST64(0x0000000040404000), CONST64(0x0000001040404000), + CONST64(0x0000000000000040), CONST64(0x0000001000000040), CONST64(0x0000000040000040), CONST64(0x0000001040000040), + CONST64(0x0000000000400040), CONST64(0x0000001000400040), CONST64(0x0000000040400040), CONST64(0x0000001040400040), + CONST64(0x0000000000004040), CONST64(0x0000001000004040), CONST64(0x0000000040004040), CONST64(0x0000001040004040), + CONST64(0x0000000000404040), CONST64(0x0000001000404040), CONST64(0x0000000040404040), CONST64(0x0000001040404040), + CONST64(0x4000000000000000), CONST64(0x4000001000000000), CONST64(0x4000000040000000), CONST64(0x4000001040000000), + CONST64(0x4000000000400000), CONST64(0x4000001000400000), CONST64(0x4000000040400000), CONST64(0x4000001040400000), + CONST64(0x4000000000004000), CONST64(0x4000001000004000), CONST64(0x4000000040004000), CONST64(0x4000001040004000), + CONST64(0x4000000000404000), CONST64(0x4000001000404000), CONST64(0x4000000040404000), CONST64(0x4000001040404000), + CONST64(0x4000000000000040), CONST64(0x4000001000000040), CONST64(0x4000000040000040), CONST64(0x4000001040000040), + CONST64(0x4000000000400040), CONST64(0x4000001000400040), CONST64(0x4000000040400040), CONST64(0x4000001040400040), + CONST64(0x4000000000004040), CONST64(0x4000001000004040), CONST64(0x4000000040004040), CONST64(0x4000001040004040), + CONST64(0x4000000000404040), CONST64(0x4000001000404040), CONST64(0x4000000040404040), CONST64(0x4000001040404040), + CONST64(0x0040000000000000), CONST64(0x0040001000000000), CONST64(0x0040000040000000), CONST64(0x0040001040000000), + CONST64(0x0040000000400000), CONST64(0x0040001000400000), CONST64(0x0040000040400000), CONST64(0x0040001040400000), + CONST64(0x0040000000004000), CONST64(0x0040001000004000), CONST64(0x0040000040004000), CONST64(0x0040001040004000), + CONST64(0x0040000000404000), CONST64(0x0040001000404000), CONST64(0x0040000040404000), CONST64(0x0040001040404000), + CONST64(0x0040000000000040), CONST64(0x0040001000000040), CONST64(0x0040000040000040), CONST64(0x0040001040000040), + CONST64(0x0040000000400040), CONST64(0x0040001000400040), CONST64(0x0040000040400040), CONST64(0x0040001040400040), + CONST64(0x0040000000004040), CONST64(0x0040001000004040), CONST64(0x0040000040004040), CONST64(0x0040001040004040), + CONST64(0x0040000000404040), CONST64(0x0040001000404040), CONST64(0x0040000040404040), CONST64(0x0040001040404040), + CONST64(0x4040000000000000), CONST64(0x4040001000000000), CONST64(0x4040000040000000), CONST64(0x4040001040000000), + CONST64(0x4040000000400000), CONST64(0x4040001000400000), CONST64(0x4040000040400000), CONST64(0x4040001040400000), + CONST64(0x4040000000004000), CONST64(0x4040001000004000), CONST64(0x4040000040004000), CONST64(0x4040001040004000), + CONST64(0x4040000000404000), CONST64(0x4040001000404000), CONST64(0x4040000040404000), CONST64(0x4040001040404000), + CONST64(0x4040000000000040), CONST64(0x4040001000000040), CONST64(0x4040000040000040), CONST64(0x4040001040000040), + CONST64(0x4040000000400040), CONST64(0x4040001000400040), CONST64(0x4040000040400040), CONST64(0x4040001040400040), + CONST64(0x4040000000004040), CONST64(0x4040001000004040), CONST64(0x4040000040004040), CONST64(0x4040001040004040), + CONST64(0x4040000000404040), CONST64(0x4040001000404040), CONST64(0x4040000040404040), CONST64(0x4040001040404040), + CONST64(0x0000400000000000), CONST64(0x0000401000000000), CONST64(0x0000400040000000), CONST64(0x0000401040000000), + CONST64(0x0000400000400000), CONST64(0x0000401000400000), CONST64(0x0000400040400000), CONST64(0x0000401040400000), + CONST64(0x0000400000004000), CONST64(0x0000401000004000), CONST64(0x0000400040004000), CONST64(0x0000401040004000), + CONST64(0x0000400000404000), CONST64(0x0000401000404000), CONST64(0x0000400040404000), CONST64(0x0000401040404000), + CONST64(0x0000400000000040), CONST64(0x0000401000000040), CONST64(0x0000400040000040), CONST64(0x0000401040000040), + CONST64(0x0000400000400040), CONST64(0x0000401000400040), CONST64(0x0000400040400040), CONST64(0x0000401040400040), + CONST64(0x0000400000004040), CONST64(0x0000401000004040), CONST64(0x0000400040004040), CONST64(0x0000401040004040), + CONST64(0x0000400000404040), CONST64(0x0000401000404040), CONST64(0x0000400040404040), CONST64(0x0000401040404040), + CONST64(0x4000400000000000), CONST64(0x4000401000000000), CONST64(0x4000400040000000), CONST64(0x4000401040000000), + CONST64(0x4000400000400000), CONST64(0x4000401000400000), CONST64(0x4000400040400000), CONST64(0x4000401040400000), + CONST64(0x4000400000004000), CONST64(0x4000401000004000), CONST64(0x4000400040004000), CONST64(0x4000401040004000), + CONST64(0x4000400000404000), CONST64(0x4000401000404000), CONST64(0x4000400040404000), CONST64(0x4000401040404000), + CONST64(0x4000400000000040), CONST64(0x4000401000000040), CONST64(0x4000400040000040), CONST64(0x4000401040000040), + CONST64(0x4000400000400040), CONST64(0x4000401000400040), CONST64(0x4000400040400040), CONST64(0x4000401040400040), + CONST64(0x4000400000004040), CONST64(0x4000401000004040), CONST64(0x4000400040004040), CONST64(0x4000401040004040), + CONST64(0x4000400000404040), CONST64(0x4000401000404040), CONST64(0x4000400040404040), CONST64(0x4000401040404040), + CONST64(0x0040400000000000), CONST64(0x0040401000000000), CONST64(0x0040400040000000), CONST64(0x0040401040000000), + CONST64(0x0040400000400000), CONST64(0x0040401000400000), CONST64(0x0040400040400000), CONST64(0x0040401040400000), + CONST64(0x0040400000004000), CONST64(0x0040401000004000), CONST64(0x0040400040004000), CONST64(0x0040401040004000), + CONST64(0x0040400000404000), CONST64(0x0040401000404000), CONST64(0x0040400040404000), CONST64(0x0040401040404000), + CONST64(0x0040400000000040), CONST64(0x0040401000000040), CONST64(0x0040400040000040), CONST64(0x0040401040000040), + CONST64(0x0040400000400040), CONST64(0x0040401000400040), CONST64(0x0040400040400040), CONST64(0x0040401040400040), + CONST64(0x0040400000004040), CONST64(0x0040401000004040), CONST64(0x0040400040004040), CONST64(0x0040401040004040), + CONST64(0x0040400000404040), CONST64(0x0040401000404040), CONST64(0x0040400040404040), CONST64(0x0040401040404040), + CONST64(0x4040400000000000), CONST64(0x4040401000000000), CONST64(0x4040400040000000), CONST64(0x4040401040000000), + CONST64(0x4040400000400000), CONST64(0x4040401000400000), CONST64(0x4040400040400000), CONST64(0x4040401040400000), + CONST64(0x4040400000004000), CONST64(0x4040401000004000), CONST64(0x4040400040004000), CONST64(0x4040401040004000), + CONST64(0x4040400000404000), CONST64(0x4040401000404000), CONST64(0x4040400040404000), CONST64(0x4040401040404000), + CONST64(0x4040400000000040), CONST64(0x4040401000000040), CONST64(0x4040400040000040), CONST64(0x4040401040000040), + CONST64(0x4040400000400040), CONST64(0x4040401000400040), CONST64(0x4040400040400040), CONST64(0x4040401040400040), + CONST64(0x4040400000004040), CONST64(0x4040401000004040), CONST64(0x4040400040004040), CONST64(0x4040401040004040), + CONST64(0x4040400000404040), CONST64(0x4040401000404040), CONST64(0x4040400040404040), CONST64(0x4040401040404040) + }}; + +#endif + + +static void cookey(const ulong32 *raw1, ulong32 *keyout); + +#ifdef LTC_CLEAN_STACK +static void _deskey(const unsigned char *key, short edf, ulong32 *keyout) +#else +static void deskey(const unsigned char *key, short edf, ulong32 *keyout) +#endif +{ + ulong32 i, j, l, m, n, kn[32]; + unsigned char pc1m[56], pcr[56]; + + for (j=0; j < 56; j++) { + l = (ulong32)pc1[j]; + m = l & 7; + pc1m[j] = (unsigned char)((key[l >> 3U] & bytebit[m]) == bytebit[m] ? 1 : 0); + } + + for (i=0; i < 16; i++) { + if (edf == DE1) { + m = (15 - i) << 1; + } else { + m = i << 1; + } + n = m + 1; + kn[m] = kn[n] = 0L; + for (j=0; j < 28; j++) { + l = j + (ulong32)totrot[i]; + if (l < 28) { + pcr[j] = pc1m[l]; + } else { + pcr[j] = pc1m[l - 28]; + } + } + for (/*j = 28*/; j < 56; j++) { + l = j + (ulong32)totrot[i]; + if (l < 56) { + pcr[j] = pc1m[l]; + } else { + pcr[j] = pc1m[l - 28]; + } + } + for (j=0; j < 24; j++) { + if ((int)pcr[(int)pc2[j]] != 0) { + kn[m] |= bigbyte[j]; + } + if ((int)pcr[(int)pc2[j+24]] != 0) { + kn[n] |= bigbyte[j]; + } + } + } + + cookey(kn, keyout); +} + +#ifdef LTC_CLEAN_STACK +static void deskey(const unsigned char *key, short edf, ulong32 *keyout) +{ + _deskey(key, edf, keyout); + burn_stack(sizeof(int)*5 + sizeof(ulong32)*32 + sizeof(unsigned char)*112); +} +#endif + +#ifdef LTC_CLEAN_STACK +static void _cookey(const ulong32 *raw1, ulong32 *keyout) +#else +static void cookey(const ulong32 *raw1, ulong32 *keyout) +#endif +{ + ulong32 *cook; + const ulong32 *raw0; + ulong32 dough[32]; + int i; + + cook = dough; + for(i=0; i < 16; i++, raw1++) + { + raw0 = raw1++; + *cook = (*raw0 & 0x00fc0000L) << 6; + *cook |= (*raw0 & 0x00000fc0L) << 10; + *cook |= (*raw1 & 0x00fc0000L) >> 10; + *cook++ |= (*raw1 & 0x00000fc0L) >> 6; + *cook = (*raw0 & 0x0003f000L) << 12; + *cook |= (*raw0 & 0x0000003fL) << 16; + *cook |= (*raw1 & 0x0003f000L) >> 4; + *cook++ |= (*raw1 & 0x0000003fL); + } + + XMEMCPY(keyout, dough, sizeof dough); +} + +#ifdef LTC_CLEAN_STACK +static void cookey(const ulong32 *raw1, ulong32 *keyout) +{ + _cookey(raw1, keyout); + burn_stack(sizeof(ulong32 *) * 2 + sizeof(ulong32)*32 + sizeof(int)); +} +#endif + +#ifndef LTC_CLEAN_STACK +static void desfunc(ulong32 *block, const ulong32 *keys) +#else +static void _desfunc(ulong32 *block, const ulong32 *keys) +#endif +{ + ulong32 work, right, leftt; + int cur_round; + + leftt = block[0]; + right = block[1]; + +#ifdef LTC_SMALL_CODE + work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL; + right ^= work; + leftt ^= (work << 4); + + work = ((leftt >> 16) ^ right) & 0x0000ffffL; + right ^= work; + leftt ^= (work << 16); + + work = ((right >> 2) ^ leftt) & 0x33333333L; + leftt ^= work; + right ^= (work << 2); + + work = ((right >> 8) ^ leftt) & 0x00ff00ffL; + leftt ^= work; + right ^= (work << 8); + + right = ROLc(right, 1); + work = (leftt ^ right) & 0xaaaaaaaaL; + + leftt ^= work; + right ^= work; + leftt = ROLc(leftt, 1); +#else + { + ulong64 tmp; + tmp = des_ip[0][byte(leftt, 0)] ^ + des_ip[1][byte(leftt, 1)] ^ + des_ip[2][byte(leftt, 2)] ^ + des_ip[3][byte(leftt, 3)] ^ + des_ip[4][byte(right, 0)] ^ + des_ip[5][byte(right, 1)] ^ + des_ip[6][byte(right, 2)] ^ + des_ip[7][byte(right, 3)]; + leftt = (ulong32)(tmp >> 32); + right = (ulong32)(tmp & 0xFFFFFFFFUL); + } +#endif + + for (cur_round = 0; cur_round < 8; cur_round++) { + work = RORc(right, 4) ^ *keys++; + leftt ^= SP7[work & 0x3fL] + ^ SP5[(work >> 8) & 0x3fL] + ^ SP3[(work >> 16) & 0x3fL] + ^ SP1[(work >> 24) & 0x3fL]; + work = right ^ *keys++; + leftt ^= SP8[ work & 0x3fL] + ^ SP6[(work >> 8) & 0x3fL] + ^ SP4[(work >> 16) & 0x3fL] + ^ SP2[(work >> 24) & 0x3fL]; + + work = RORc(leftt, 4) ^ *keys++; + right ^= SP7[ work & 0x3fL] + ^ SP5[(work >> 8) & 0x3fL] + ^ SP3[(work >> 16) & 0x3fL] + ^ SP1[(work >> 24) & 0x3fL]; + work = leftt ^ *keys++; + right ^= SP8[ work & 0x3fL] + ^ SP6[(work >> 8) & 0x3fL] + ^ SP4[(work >> 16) & 0x3fL] + ^ SP2[(work >> 24) & 0x3fL]; + } + +#ifdef LTC_SMALL_CODE + right = RORc(right, 1); + work = (leftt ^ right) & 0xaaaaaaaaL; + leftt ^= work; + right ^= work; + leftt = RORc(leftt, 1); + work = ((leftt >> 8) ^ right) & 0x00ff00ffL; + right ^= work; + leftt ^= (work << 8); + /* -- */ + work = ((leftt >> 2) ^ right) & 0x33333333L; + right ^= work; + leftt ^= (work << 2); + work = ((right >> 16) ^ leftt) & 0x0000ffffL; + leftt ^= work; + right ^= (work << 16); + work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL; + leftt ^= work; + right ^= (work << 4); +#else + { + ulong64 tmp; + tmp = des_fp[0][byte(leftt, 0)] ^ + des_fp[1][byte(leftt, 1)] ^ + des_fp[2][byte(leftt, 2)] ^ + des_fp[3][byte(leftt, 3)] ^ + des_fp[4][byte(right, 0)] ^ + des_fp[5][byte(right, 1)] ^ + des_fp[6][byte(right, 2)] ^ + des_fp[7][byte(right, 3)]; + leftt = (ulong32)(tmp >> 32); + right = (ulong32)(tmp & 0xFFFFFFFFUL); + } +#endif + + block[0] = right; + block[1] = leftt; +} + +#ifdef LTC_CLEAN_STACK +static void desfunc(ulong32 *block, const ulong32 *keys) +{ + _desfunc(block, keys); + burn_stack(sizeof(ulong32) * 4 + sizeof(int)); +} +#endif + + /** + Initialize the LTC_DES block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + if (num_rounds != 0 && num_rounds != 16) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen != 8) { + return CRYPT_INVALID_KEYSIZE; + } + + deskey(key, EN0, skey->des.ek); + deskey(key, DE1, skey->des.dk); + + return CRYPT_OK; +} + + /** + Initialize the 3LTC_DES-EDE block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + if(num_rounds != 0 && num_rounds != 16) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen != 24 && keylen != 16) { + return CRYPT_INVALID_KEYSIZE; + } + + deskey(key, EN0, skey->des3.ek[0]); + deskey(key+8, DE1, skey->des3.ek[1]); + if (keylen == 24) { + deskey(key+16, EN0, skey->des3.ek[2]); + } else { + /* two-key 3DES: K3=K1 */ + deskey(key, EN0, skey->des3.ek[2]); + } + + deskey(key, DE1, skey->des3.dk[2]); + deskey(key+8, EN0, skey->des3.dk[1]); + if (keylen == 24) { + deskey(key+16, DE1, skey->des3.dk[0]); + } else { + /* two-key 3DES: K3=K1 */ + deskey(key, DE1, skey->des3.dk[0]); + } + + return CRYPT_OK; +} + +/** + Encrypts a block of text with LTC_DES + @param pt The input plaintext (8 bytes) + @param ct The output ciphertext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + ulong32 work[2]; + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + LOAD32H(work[0], pt+0); + LOAD32H(work[1], pt+4); + desfunc(work, skey->des.ek); + STORE32H(work[0],ct+0); + STORE32H(work[1],ct+4); + return CRYPT_OK; +} + +/** + Decrypts a block of text with LTC_DES + @param ct The input ciphertext (8 bytes) + @param pt The output plaintext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + ulong32 work[2]; + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + LOAD32H(work[0], ct+0); + LOAD32H(work[1], ct+4); + desfunc(work, skey->des.dk); + STORE32H(work[0],pt+0); + STORE32H(work[1],pt+4); + return CRYPT_OK; +} + +/** + Encrypts a block of text with 3LTC_DES-EDE + @param pt The input plaintext (8 bytes) + @param ct The output ciphertext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + ulong32 work[2]; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + LOAD32H(work[0], pt+0); + LOAD32H(work[1], pt+4); + desfunc(work, skey->des3.ek[0]); + desfunc(work, skey->des3.ek[1]); + desfunc(work, skey->des3.ek[2]); + STORE32H(work[0],ct+0); + STORE32H(work[1],ct+4); + return CRYPT_OK; +} + +/** + Decrypts a block of text with 3LTC_DES-EDE + @param ct The input ciphertext (8 bytes) + @param pt The output plaintext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + ulong32 work[2]; + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + LOAD32H(work[0], ct+0); + LOAD32H(work[1], ct+4); + desfunc(work, skey->des3.dk[0]); + desfunc(work, skey->des3.dk[1]); + desfunc(work, skey->des3.dk[2]); + STORE32H(work[0],pt+0); + STORE32H(work[1],pt+4); + return CRYPT_OK; +} + +/** + Performs a self-test of the LTC_DES block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int des_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + int err; + static const struct des_test_case { + int num, mode; /* mode 1 = encrypt */ + unsigned char key[8], txt[8], out[8]; + } cases[] = { + { 1, 1, { 0x10, 0x31, 0x6E, 0x02, 0x8C, 0x8F, 0x3B, 0x4A }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x82, 0xDC, 0xBA, 0xFB, 0xDE, 0xAB, 0x66, 0x02 } }, + { 2, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 3, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0xDD, 0x7F, 0x12, 0x1C, 0xA5, 0x01, 0x56, 0x19 }, + { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 4, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x2E, 0x86, 0x53, 0x10, 0x4F, 0x38, 0x34, 0xEA }, + { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 5, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x4B, 0xD3, 0x88, 0xFF, 0x6C, 0xD8, 0x1D, 0x4F }, + { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 6, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x20, 0xB9, 0xE7, 0x67, 0xB2, 0xFB, 0x14, 0x56 }, + { 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 7, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x55, 0x57, 0x93, 0x80, 0xD7, 0x71, 0x38, 0xEF }, + { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 8, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x6C, 0xC5, 0xDE, 0xFA, 0xAF, 0x04, 0x51, 0x2F }, + { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 9, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x0D, 0x9F, 0x27, 0x9B, 0xA5, 0xD8, 0x72, 0x60 }, + { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + {10, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0xD9, 0x03, 0x1B, 0x02, 0x71, 0xBD, 0x5A, 0x0A }, + { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + + { 1, 0, { 0x10, 0x31, 0x6E, 0x02, 0x8C, 0x8F, 0x3B, 0x4A }, + { 0x82, 0xDC, 0xBA, 0xFB, 0xDE, 0xAB, 0x66, 0x02 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 2, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00 } }, + { 3, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xDD, 0x7F, 0x12, 0x1C, 0xA5, 0x01, 0x56, 0x19 } }, + { 4, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x2E, 0x86, 0x53, 0x10, 0x4F, 0x38, 0x34, 0xEA } }, + { 5, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x4B, 0xD3, 0x88, 0xFF, 0x6C, 0xD8, 0x1D, 0x4F } }, + { 6, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x20, 0xB9, 0xE7, 0x67, 0xB2, 0xFB, 0x14, 0x56 } }, + { 7, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x55, 0x57, 0x93, 0x80, 0xD7, 0x71, 0x38, 0xEF } }, + { 8, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x6C, 0xC5, 0xDE, 0xFA, 0xAF, 0x04, 0x51, 0x2F } }, + { 9, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x0D, 0x9F, 0x27, 0x9B, 0xA5, 0xD8, 0x72, 0x60 } }, + {10, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xD9, 0x03, 0x1B, 0x02, 0x71, 0xBD, 0x5A, 0x0A } }, + +#ifdef LTC_TEST_EXT + { 0+11, 0, { 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x95, 0xA8, 0xD7, 0x28, 0x13, 0xDA, 0xA9, 0x4D } }, + { 1+11, 0, { 0x40, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x0E, 0xEC, 0x14, 0x87, 0xDD, 0x8C, 0x26, 0xD5 } }, + { 2+11, 0, { 0x20, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x7A, 0xD1, 0x6F, 0xFB, 0x79, 0xC4, 0x59, 0x26 } }, + { 3+11, 0, { 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xD3, 0x74, 0x62, 0x94, 0xCA, 0x6A, 0x6C, 0xF3 } }, + { 4+11, 0, { 0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x80, 0x9F, 0x5F, 0x87, 0x3C, 0x1F, 0xD7, 0x61 } }, + { 5+11, 0, { 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xC0, 0x2F, 0xAF, 0xFE, 0xC9, 0x89, 0xD1, 0xFC } }, + { 6+11, 0, { 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x46, 0x15, 0xAA, 0x1D, 0x33, 0xE7, 0x2F, 0x10 } }, + { 7+11, 0, { 0x01, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x20, 0x55, 0x12, 0x33, 0x50, 0xC0, 0x08, 0x58 } }, + { 8+11, 0, { 0x01, 0x40, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xDF, 0x3B, 0x99, 0xD6, 0x57, 0x73, 0x97, 0xC8 } }, + { 9+11, 0, { 0x01, 0x20, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x31, 0xFE, 0x17, 0x36, 0x9B, 0x52, 0x88, 0xC9 } }, + {10+11, 0, { 0x01, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xDF, 0xDD, 0x3C, 0xC6, 0x4D, 0xAE, 0x16, 0x42 } }, + {11+11, 0, { 0x01, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x17, 0x8C, 0x83, 0xCE, 0x2B, 0x39, 0x9D, 0x94 } }, + {12+11, 0, { 0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x50, 0xF6, 0x36, 0x32, 0x4A, 0x9B, 0x7F, 0x80 } }, + {13+11, 0, { 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xA8, 0x46, 0x8E, 0xE3, 0xBC, 0x18, 0xF0, 0x6D } }, + {14+11, 0, { 0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xA2, 0xDC, 0x9E, 0x92, 0xFD, 0x3C, 0xDE, 0x92 } }, + {15+11, 0, { 0x01, 0x01, 0x40, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xCA, 0xC0, 0x9F, 0x79, 0x7D, 0x03, 0x12, 0x87 } }, + {16+11, 0, { 0x01, 0x01, 0x20, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x90, 0xBA, 0x68, 0x0B, 0x22, 0xAE, 0xB5, 0x25 } }, + {17+11, 0, { 0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xCE, 0x7A, 0x24, 0xF3, 0x50, 0xE2, 0x80, 0xB6 } }, + {18+11, 0, { 0x01, 0x01, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x88, 0x2B, 0xFF, 0x0A, 0xA0, 0x1A, 0x0B, 0x87 } }, + {19+11, 0, { 0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x25, 0x61, 0x02, 0x88, 0x92, 0x45, 0x11, 0xC2 } }, + {20+11, 0, { 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xC7, 0x15, 0x16, 0xC2, 0x9C, 0x75, 0xD1, 0x70 } }, + {21+11, 0, { 0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x51, 0x99, 0xC2, 0x9A, 0x52, 0xC9, 0xF0, 0x59 } }, + {22+11, 0, { 0x01, 0x01, 0x01, 0x40, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xC2, 0x2F, 0x0A, 0x29, 0x4A, 0x71, 0xF2, 0x9F } }, + {23+11, 0, { 0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xEE, 0x37, 0x14, 0x83, 0x71, 0x4C, 0x02, 0xEA } }, + {24+11, 0, { 0x01, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xA8, 0x1F, 0xBD, 0x44, 0x8F, 0x9E, 0x52, 0x2F } }, + {25+11, 0, { 0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x4F, 0x64, 0x4C, 0x92, 0xE1, 0x92, 0xDF, 0xED } }, + {26+11, 0, { 0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x1A, 0xFA, 0x9A, 0x66, 0xA6, 0xDF, 0x92, 0xAE } }, + {27+11, 0, { 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xB3, 0xC1, 0xCC, 0x71, 0x5C, 0xB8, 0x79, 0xD8 } }, + {28+11, 0, { 0x01, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x19, 0xD0, 0x32, 0xE6, 0x4A, 0xB0, 0xBD, 0x8B } }, + {29+11, 0, { 0x01, 0x01, 0x01, 0x01, 0x40, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x3C, 0xFA, 0xA7, 0xA7, 0xDC, 0x87, 0x20, 0xDC } }, + {30+11, 0, { 0x01, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xB7, 0x26, 0x5F, 0x7F, 0x44, 0x7A, 0xC6, 0xF3 } }, + {31+11, 0, { 0x01, 0x01, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x9D, 0xB7, 0x3B, 0x3C, 0x0D, 0x16, 0x3F, 0x54 } }, + {32+11, 0, { 0x01, 0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x81, 0x81, 0xB6, 0x5B, 0xAB, 0xF4, 0xA9, 0x75 } }, + {33+11, 0, { 0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x93, 0xC9, 0xB6, 0x40, 0x42, 0xEA, 0xA2, 0x40 } }, + {34+11, 0, { 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x55, 0x70, 0x53, 0x08, 0x29, 0x70, 0x55, 0x92 } }, + {35+11, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x86, 0x38, 0x80, 0x9E, 0x87, 0x87, 0x87, 0xA0 } }, + {36+11, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x40, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x41, 0xB9, 0xA7, 0x9A, 0xF7, 0x9A, 0xC2, 0x08 } }, + {37+11, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x7A, 0x9B, 0xE4, 0x2F, 0x20, 0x09, 0xA8, 0x92 } }, + {38+11, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x10, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x29, 0x03, 0x8D, 0x56, 0xBA, 0x6D, 0x27, 0x45 } }, + {39+11, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x54, 0x95, 0xC6, 0xAB, 0xF1, 0xE5, 0xDF, 0x51 } }, + {40+11, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xAE, 0x13, 0xDB, 0xD5, 0x61, 0x48, 0x89, 0x33 } }, + {41+11, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x02, 0x4D, 0x1F, 0xFA, 0x89, 0x04, 0xE3, 0x89 } }, + {42+11, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xD1, 0x39, 0x97, 0x12, 0xF9, 0x9B, 0xF0, 0x2E } }, + {43+11, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x40, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x14, 0xC1, 0xD7, 0xC1, 0xCF, 0xFE, 0xC7, 0x9E } }, + {44+11, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x20, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x1D, 0xE5, 0x27, 0x9D, 0xAE, 0x3B, 0xED, 0x6F } }, + {45+11, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xE9, 0x41, 0xA3, 0x3F, 0x85, 0x50, 0x13, 0x03 } }, + {46+11, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xDA, 0x99, 0xDB, 0xBC, 0x9A, 0x03, 0xF3, 0x79 } }, + {47+11, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xB7, 0xFC, 0x92, 0xF9, 0x1D, 0x8E, 0x92, 0xE9 } }, + {48+11, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xAE, 0x8E, 0x5C, 0xAA, 0x3C, 0xA0, 0x4E, 0x85 } }, + {49+11, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x9C, 0xC6, 0x2D, 0xF4, 0x3B, 0x6E, 0xED, 0x74 } }, + {50+11, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x40 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xD8, 0x63, 0xDB, 0xB5, 0xC5, 0x9A, 0x91, 0xA0 } }, + {51+11, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x20 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xA1, 0xAB, 0x21, 0x90, 0x54, 0x5B, 0x91, 0xD7 } }, + {52+11, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x08, 0x75, 0x04, 0x1E, 0x64, 0xC5, 0x70, 0xF7 } }, + {53+11, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x5A, 0x59, 0x45, 0x28, 0xBE, 0xBE, 0xF1, 0xCC } }, + {54+11, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xFC, 0xDB, 0x32, 0x91, 0xDE, 0x21, 0xF0, 0xC0 } }, + {55+11, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x86, 0x9E, 0xFD, 0x7F, 0x9F, 0x26, 0x5A, 0x09 } }, +#endif /* LTC_TEST_EXT */ + + /*** more test cases you could add if you are not convinced (the above test cases aren't really too good): + + key plaintext ciphertext + 0000000000000000 0000000000000000 8CA64DE9C1B123A7 + FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF 7359B2163E4EDC58 + 3000000000000000 1000000000000001 958E6E627A05557B + 1111111111111111 1111111111111111 F40379AB9E0EC533 + 0123456789ABCDEF 1111111111111111 17668DFC7292532D + 1111111111111111 0123456789ABCDEF 8A5AE1F81AB8F2DD + 0000000000000000 0000000000000000 8CA64DE9C1B123A7 + FEDCBA9876543210 0123456789ABCDEF ED39D950FA74BCC4 + 7CA110454A1A6E57 01A1D6D039776742 690F5B0D9A26939B + 0131D9619DC1376E 5CD54CA83DEF57DA 7A389D10354BD271 + 07A1133E4A0B2686 0248D43806F67172 868EBB51CAB4599A + 3849674C2602319E 51454B582DDF440A 7178876E01F19B2A + 04B915BA43FEB5B6 42FD443059577FA2 AF37FB421F8C4095 + 0113B970FD34F2CE 059B5E0851CF143A 86A560F10EC6D85B + 0170F175468FB5E6 0756D8E0774761D2 0CD3DA020021DC09 + 43297FAD38E373FE 762514B829BF486A EA676B2CB7DB2B7A + 07A7137045DA2A16 3BDD119049372802 DFD64A815CAF1A0F + 04689104C2FD3B2F 26955F6835AF609A 5C513C9C4886C088 + 37D06BB516CB7546 164D5E404F275232 0A2AEEAE3FF4AB77 + 1F08260D1AC2465E 6B056E18759F5CCA EF1BF03E5DFA575A + 584023641ABA6176 004BD6EF09176062 88BF0DB6D70DEE56 + 025816164629B007 480D39006EE762F2 A1F9915541020B56 + 49793EBC79B3258F 437540C8698F3CFA 6FBF1CAFCFFD0556 + 4FB05E1515AB73A7 072D43A077075292 2F22E49BAB7CA1AC + 49E95D6D4CA229BF 02FE55778117F12A 5A6B612CC26CCE4A + 018310DC409B26D6 1D9D5C5018F728C2 5F4C038ED12B2E41 + 1C587F1C13924FEF 305532286D6F295A 63FAC0D034D9F793 + 0101010101010101 0123456789ABCDEF 617B3A0CE8F07100 + 1F1F1F1F0E0E0E0E 0123456789ABCDEF DB958605F8C8C606 + E0FEE0FEF1FEF1FE 0123456789ABCDEF EDBFD1C66C29CCC7 + 0000000000000000 FFFFFFFFFFFFFFFF 355550B2150E2451 + FFFFFFFFFFFFFFFF 0000000000000000 CAAAAF4DEAF1DBAE + 0123456789ABCDEF 0000000000000000 D5D44FF720683D0D + FEDCBA9876543210 FFFFFFFFFFFFFFFF 2A2BB008DF97C2F2 + + http://www.ecs.soton.ac.uk/~prw99r/ez438/vectors.txt + ***/ + }; + int i, y; + unsigned char tmp[8]; + symmetric_key des; + + for(i=0; i < (int)(sizeof(cases)/sizeof(cases[0])); i++) + { + if ((err = des_setup(cases[i].key, 8, 0, &des)) != CRYPT_OK) { + return err; + } + if (cases[i].mode != 0) { + des_ecb_encrypt(cases[i].txt, tmp, &des); + } else { + des_ecb_decrypt(cases[i].txt, tmp, &des); + } + + if (XMEMCMP(cases[i].out, tmp, sizeof(tmp)) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) tmp[y] = 0; + for (y = 0; y < 1000; y++) des_ecb_encrypt(tmp, tmp, &des); + for (y = 0; y < 1000; y++) des_ecb_decrypt(tmp, tmp, &des); + for (y = 0; y < 8; y++) if (tmp[y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; + #endif +} + +int des3_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + unsigned char key[24], pt[8], ct[8], tmp[8]; + symmetric_key skey; + int x, err; + + if ((err = des_test()) != CRYPT_OK) { + return err; + } + + for (x = 0; x < 8; x++) { + pt[x] = x; + } + + for (x = 0; x < 24; x++) { + key[x] = x; + } + + if ((err = des3_setup(key, 24, 0, &skey)) != CRYPT_OK) { + return err; + } + + des3_ecb_encrypt(pt, ct, &skey); + des3_ecb_decrypt(ct, tmp, &skey); + + if (XMEMCMP(pt, tmp, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; + #endif +} + +/** Terminate the context + @param skey The scheduled key +*/ +void des_done(symmetric_key *skey) +{ + LTC_UNUSED_PARAM(skey); +} + +/** Terminate the context + @param skey The scheduled key +*/ +void des3_done(symmetric_key *skey) +{ + LTC_UNUSED_PARAM(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. + @return CRYPT_OK if the input key size is acceptable. +*/ +int des_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if(*keysize < 8) { + return CRYPT_INVALID_KEYSIZE; + } + *keysize = 8; + return CRYPT_OK; +} + +/** + 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. + @return CRYPT_OK if the input key size is acceptable. +*/ +int des3_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if(*keysize < 24) { + return CRYPT_INVALID_KEYSIZE; + } + *keysize = 24; + return CRYPT_OK; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/ciphers/kasumi.c b/src/ltc/ciphers/kasumi.c new file mode 100644 index 0000000..61369e0 --- /dev/null +++ b/src/ltc/ciphers/kasumi.c @@ -0,0 +1,319 @@ +/* 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://libtom.org + */ + +/** + @file kasumi.c + Implementation of the 3GPP Kasumi block cipher + Derived from the 3GPP standard source code +*/ + +#include "tomcrypt.h" + +#ifdef LTC_KASUMI + +typedef unsigned u16; + +#define ROL16(x, y) ((((x)<<(y)) | ((x)>>(16-(y)))) & 0xFFFF) + +const struct ltc_cipher_descriptor kasumi_desc = { + "kasumi", + 21, + 16, 16, 8, 8, + &kasumi_setup, + &kasumi_ecb_encrypt, + &kasumi_ecb_decrypt, + &kasumi_test, + &kasumi_done, + &kasumi_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +static u16 FI( u16 in, u16 subkey ) +{ + u16 nine, seven; + static const u16 S7[128] = { + 54, 50, 62, 56, 22, 34, 94, 96, 38, 6, 63, 93, 2, 18,123, 33, + 55,113, 39,114, 21, 67, 65, 12, 47, 73, 46, 27, 25,111,124, 81, + 53, 9,121, 79, 52, 60, 58, 48,101,127, 40,120,104, 70, 71, 43, + 20,122, 72, 61, 23,109, 13,100, 77, 1, 16, 7, 82, 10,105, 98, + 117,116, 76, 11, 89,106, 0,125,118, 99, 86, 69, 30, 57,126, 87, + 112, 51, 17, 5, 95, 14, 90, 84, 91, 8, 35,103, 32, 97, 28, 66, + 102, 31, 26, 45, 75, 4, 85, 92, 37, 74, 80, 49, 68, 29,115, 44, + 64,107,108, 24,110, 83, 36, 78, 42, 19, 15, 41, 88,119, 59, 3 }; + static const u16 S9[512] = { + 167,239,161,379,391,334, 9,338, 38,226, 48,358,452,385, 90,397, + 183,253,147,331,415,340, 51,362,306,500,262, 82,216,159,356,177, + 175,241,489, 37,206, 17, 0,333, 44,254,378, 58,143,220, 81,400, + 95, 3,315,245, 54,235,218,405,472,264,172,494,371,290,399, 76, + 165,197,395,121,257,480,423,212,240, 28,462,176,406,507,288,223, + 501,407,249,265, 89,186,221,428,164, 74,440,196,458,421,350,163, + 232,158,134,354, 13,250,491,142,191, 69,193,425,152,227,366,135, + 344,300,276,242,437,320,113,278, 11,243, 87,317, 36, 93,496, 27, + 487,446,482, 41, 68,156,457,131,326,403,339, 20, 39,115,442,124, + 475,384,508, 53,112,170,479,151,126,169, 73,268,279,321,168,364, + 363,292, 46,499,393,327,324, 24,456,267,157,460,488,426,309,229, + 439,506,208,271,349,401,434,236, 16,209,359, 52, 56,120,199,277, + 465,416,252,287,246, 6, 83,305,420,345,153,502, 65, 61,244,282, + 173,222,418, 67,386,368,261,101,476,291,195,430, 49, 79,166,330, + 280,383,373,128,382,408,155,495,367,388,274,107,459,417, 62,454, + 132,225,203,316,234, 14,301, 91,503,286,424,211,347,307,140,374, + 35,103,125,427, 19,214,453,146,498,314,444,230,256,329,198,285, + 50,116, 78,410, 10,205,510,171,231, 45,139,467, 29, 86,505, 32, + 72, 26,342,150,313,490,431,238,411,325,149,473, 40,119,174,355, + 185,233,389, 71,448,273,372, 55,110,178,322, 12,469,392,369,190, + 1,109,375,137,181, 88, 75,308,260,484, 98,272,370,275,412,111, + 336,318, 4,504,492,259,304, 77,337,435, 21,357,303,332,483, 18, + 47, 85, 25,497,474,289,100,269,296,478,270,106, 31,104,433, 84, + 414,486,394, 96, 99,154,511,148,413,361,409,255,162,215,302,201, + 266,351,343,144,441,365,108,298,251, 34,182,509,138,210,335,133, + 311,352,328,141,396,346,123,319,450,281,429,228,443,481, 92,404, + 485,422,248,297, 23,213,130,466, 22,217,283, 70,294,360,419,127, + 312,377, 7,468,194, 2,117,295,463,258,224,447,247,187, 80,398, + 284,353,105,390,299,471,470,184, 57,200,348, 63,204,188, 33,451, + 97, 30,310,219, 94,160,129,493, 64,179,263,102,189,207,114,402, + 438,477,387,122,192, 42,381, 5,145,118,180,449,293,323,136,380, + 43, 66, 60,455,341,445,202,432, 8,237, 15,376,436,464, 59,461}; + + /* The sixteen bit input is split into two unequal halves, * + * nine bits and seven bits - as is the subkey */ + + nine = (u16)(in>>7)&0x1FF; + seven = (u16)(in&0x7F); + + /* Now run the various operations */ + nine = (u16)(S9[nine] ^ seven); + seven = (u16)(S7[seven] ^ (nine & 0x7F)); + seven ^= (subkey>>9); + nine ^= (subkey&0x1FF); + nine = (u16)(S9[nine] ^ seven); + seven = (u16)(S7[seven] ^ (nine & 0x7F)); + return (u16)(seven<<9) + nine; +} + +static ulong32 FO( ulong32 in, int round_no, symmetric_key *key) +{ + u16 left, right; + + /* Split the input into two 16-bit words */ + left = (u16)(in>>16); + right = (u16) in&0xFFFF; + + /* Now apply the same basic transformation three times */ + left ^= key->kasumi.KOi1[round_no]; + left = FI( left, key->kasumi.KIi1[round_no] ); + left ^= right; + + right ^= key->kasumi.KOi2[round_no]; + right = FI( right, key->kasumi.KIi2[round_no] ); + right ^= left; + + left ^= key->kasumi.KOi3[round_no]; + left = FI( left, key->kasumi.KIi3[round_no] ); + left ^= right; + + return (((ulong32)right)<<16)+left; +} + +static ulong32 FL( ulong32 in, int round_no, symmetric_key *key ) +{ + u16 l, r, a, b; + /* split out the left and right halves */ + l = (u16)(in>>16); + r = (u16)(in)&0xFFFF; + /* do the FL() operations */ + a = (u16) (l & key->kasumi.KLi1[round_no]); + r ^= ROL16(a,1); + b = (u16)(r | key->kasumi.KLi2[round_no]); + l ^= ROL16(b,1); + /* put the two halves back together */ + + return (((ulong32)l)<<16) + r; +} + +int kasumi_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + ulong32 left, right, temp; + int n; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + + LOAD32H(left, pt); + LOAD32H(right, pt+4); + + for (n = 0; n <= 7; ) { + temp = FL(left, n, skey); + temp = FO(temp, n++, skey); + right ^= temp; + temp = FO(right, n, skey); + temp = FL(temp, n++, skey); + left ^= temp; + } + + STORE32H(left, ct); + STORE32H(right, ct+4); + + return CRYPT_OK; +} + +int kasumi_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + ulong32 left, right, temp; + int n; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + + LOAD32H(left, ct); + LOAD32H(right, ct+4); + + for (n = 7; n >= 0; ) { + temp = FO(right, n, skey); + temp = FL(temp, n--, skey); + left ^= temp; + temp = FL(left, n, skey); + temp = FO(temp, n--, skey); + right ^= temp; + } + + STORE32H(left, pt); + STORE32H(right, pt+4); + + return CRYPT_OK; +} + +int kasumi_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + static const u16 C[8] = { 0x0123,0x4567,0x89AB,0xCDEF, 0xFEDC,0xBA98,0x7654,0x3210 }; + u16 ukey[8], Kprime[8]; + int n; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + if (keylen != 16) { + return CRYPT_INVALID_KEYSIZE; + } + + if (num_rounds != 0 && num_rounds != 8) { + return CRYPT_INVALID_ROUNDS; + } + + /* Start by ensuring the subkeys are endian correct on a 16-bit basis */ + for (n = 0; n < 8; n++ ) { + ukey[n] = (((u16)key[2*n]) << 8) | key[2*n+1]; + } + + /* Now build the K'[] keys */ + for (n = 0; n < 8; n++) { + Kprime[n] = ukey[n] ^ C[n]; + } + + /* Finally construct the various sub keys */ + for(n = 0; n < 8; n++) { + skey->kasumi.KLi1[n] = ROL16(ukey[n],1); + skey->kasumi.KLi2[n] = Kprime[(n+2)&0x7]; + skey->kasumi.KOi1[n] = ROL16(ukey[(n+1)&0x7],5); + skey->kasumi.KOi2[n] = ROL16(ukey[(n+5)&0x7],8); + skey->kasumi.KOi3[n] = ROL16(ukey[(n+6)&0x7],13); + skey->kasumi.KIi1[n] = Kprime[(n+4)&0x7]; + skey->kasumi.KIi2[n] = Kprime[(n+3)&0x7]; + skey->kasumi.KIi3[n] = Kprime[(n+7)&0x7]; + } + + return CRYPT_OK; +} + +void kasumi_done(symmetric_key *skey) +{ + LTC_UNUSED_PARAM(skey); +} + +int kasumi_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if (*keysize >= 16) { + *keysize = 16; + return CRYPT_OK; + } else { + return CRYPT_INVALID_KEYSIZE; + } +} + +int kasumi_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + unsigned char key[16], pt[8], ct[8]; + } tests[] = { + +{ + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x4B, 0x58, 0xA7, 0x71, 0xAF, 0xC7, 0xE5, 0xE8 } +}, + +{ + { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x7E, 0xEF, 0x11, 0x3C, 0x95, 0xBB, 0x5A, 0x77 } +}, + +{ + { 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x5F, 0x14, 0x06, 0x86, 0xD7, 0xAD, 0x5A, 0x39 }, +}, + +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x2E, 0x14, 0x91, 0xCF, 0x70, 0xAA, 0x46, 0x5D } +}, + +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xB5, 0x45, 0x86, 0xF4, 0xAB, 0x9A, 0xE5, 0x46 } +}, + +}; + unsigned char buf[2][8]; + symmetric_key key; + int err, x; + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + if ((err = kasumi_setup(tests[x].key, 16, 0, &key)) != CRYPT_OK) { + return err; + } + if ((err = kasumi_ecb_encrypt(tests[x].pt, buf[0], &key)) != CRYPT_OK) { + return err; + } + if ((err = kasumi_ecb_decrypt(tests[x].ct, buf[1], &key)) != CRYPT_OK) { + return err; + } + if (XMEMCMP(tests[x].pt, buf[1], 8) || XMEMCMP(tests[x].ct, buf[0], 8)) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +#endif +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/ciphers/khazad.c b/src/ltc/ciphers/khazad.c new file mode 100644 index 0000000..1cea03c --- /dev/null +++ b/src/ltc/ciphers/khazad.c @@ -0,0 +1,856 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file khazad.c + Khazad implementation derived from public domain source + Authors: Paulo S.L.M. Barreto and Vincent Rijmen. +*/ + +#ifdef LTC_KHAZAD + +const struct ltc_cipher_descriptor khazad_desc = { + "khazad", + 18, + 16, 16, 8, 8, + &khazad_setup, + &khazad_ecb_encrypt, + &khazad_ecb_decrypt, + &khazad_test, + &khazad_done, + &khazad_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +#define R 8 +#define KEYSIZE 128 +#define KEYSIZEB (KEYSIZE/8) +#define BLOCKSIZE 64 +#define BLOCKSIZEB (BLOCKSIZE/8) + +static const ulong64 T0[256] = { + CONST64(0xbad3d268bbb96a01), CONST64(0x54fc4d19e59a66b1), CONST64(0x2f71bc93e26514cd), CONST64(0x749ccdb925871b51), + CONST64(0x53f55102f7a257a4), CONST64(0xd3686bb8d0d6be03), CONST64(0xd26b6fbdd6deb504), CONST64(0x4dd72964b35285fe), + CONST64(0x50f05d0dfdba4aad), CONST64(0xace98a26cf09e063), CONST64(0x8d8a0e83091c9684), CONST64(0xbfdcc679a5914d1a), + CONST64(0x7090ddad3da7374d), CONST64(0x52f65507f1aa5ca3), CONST64(0x9ab352c87ba417e1), CONST64(0x4cd42d61b55a8ef9), + CONST64(0xea238f65460320ac), CONST64(0xd56273a6c4e68411), CONST64(0x97a466f155cc68c2), CONST64(0xd16e63b2dcc6a80d), + CONST64(0x3355ccffaa85d099), CONST64(0x51f35908fbb241aa), CONST64(0x5bed712ac7e20f9c), CONST64(0xa6f7a204f359ae55), + CONST64(0xde7f5f81febec120), CONST64(0x48d83d75ad7aa2e5), CONST64(0xa8e59a32d729cc7f), CONST64(0x99b65ec771bc0ae8), + CONST64(0xdb704b90e096e63b), CONST64(0x3256c8faac8ddb9e), CONST64(0xb7c4e65195d11522), CONST64(0xfc19d72b32b3aace), + CONST64(0xe338ab48704b7393), CONST64(0x9ebf42dc63843bfd), CONST64(0x91ae7eef41fc52d0), CONST64(0x9bb056cd7dac1ce6), + CONST64(0xe23baf4d76437894), CONST64(0xbbd0d66dbdb16106), CONST64(0x41c319589b32f1da), CONST64(0x6eb2a5cb7957e517), + CONST64(0xa5f2ae0bf941b35c), CONST64(0xcb400bc08016564b), CONST64(0x6bbdb1da677fc20c), CONST64(0x95a26efb59dc7ecc), + CONST64(0xa1febe1fe1619f40), CONST64(0xf308eb1810cbc3e3), CONST64(0xb1cefe4f81e12f30), CONST64(0x0206080a0c10160e), + CONST64(0xcc4917db922e675e), CONST64(0xc45137f3a26e3f66), CONST64(0x1d2774694ee8cf53), CONST64(0x143c504478a09c6c), + CONST64(0xc3582be8b0560e73), CONST64(0x63a591f2573f9a34), CONST64(0xda734f95e69eed3c), CONST64(0x5de76934d3d2358e), + CONST64(0x5fe1613edfc22380), CONST64(0xdc79578bf2aed72e), CONST64(0x7d87e99413cf486e), CONST64(0xcd4a13de94266c59), + CONST64(0x7f81e19e1fdf5e60), CONST64(0x5aee752fc1ea049b), CONST64(0x6cb4adc17547f319), CONST64(0x5ce46d31d5da3e89), + CONST64(0xf704fb0c08ebefff), CONST64(0x266a98bed42d47f2), CONST64(0xff1cdb2438abb7c7), CONST64(0xed2a937e543b11b9), + CONST64(0xe825876f4a1336a2), CONST64(0x9dba4ed3699c26f4), CONST64(0x6fb1a1ce7f5fee10), CONST64(0x8e8f028c03048b8d), + CONST64(0x192b647d56c8e34f), CONST64(0xa0fdba1ae7699447), CONST64(0xf00de7171ad3deea), CONST64(0x89861e97113cba98), + CONST64(0x0f113c332278692d), CONST64(0x07091c1b12383115), CONST64(0xafec8629c511fd6a), CONST64(0xfb10cb30208b9bdb), + CONST64(0x0818202830405838), CONST64(0x153f54417ea8976b), CONST64(0x0d1734392e687f23), CONST64(0x040c101418202c1c), + CONST64(0x0103040506080b07), CONST64(0x64ac8de94507ab21), CONST64(0xdf7c5b84f8b6ca27), CONST64(0x769ac5b329970d5f), + CONST64(0x798bf9800bef6472), CONST64(0xdd7a538ef4a6dc29), CONST64(0x3d47f4c98ef5b2b3), CONST64(0x163a584e74b08a62), + CONST64(0x3f41fcc382e5a4bd), CONST64(0x3759dcebb2a5fc85), CONST64(0x6db7a9c4734ff81e), CONST64(0x3848e0d890dd95a8), + CONST64(0xb9d6de67b1a17708), CONST64(0x7395d1a237bf2a44), CONST64(0xe926836a4c1b3da5), CONST64(0x355fd4e1beb5ea8b), + CONST64(0x55ff491ce3926db6), CONST64(0x7193d9a83baf3c4a), CONST64(0x7b8df18a07ff727c), CONST64(0x8c890a860f149d83), + CONST64(0x7296d5a731b72143), CONST64(0x88851a921734b19f), CONST64(0xf607ff090ee3e4f8), CONST64(0x2a7ea882fc4d33d6), + CONST64(0x3e42f8c684edafba), CONST64(0x5ee2653bd9ca2887), CONST64(0x27699cbbd2254cf5), CONST64(0x46ca0543890ac0cf), + CONST64(0x0c14303c28607424), CONST64(0x65af89ec430fa026), CONST64(0x68b8bdd56d67df05), CONST64(0x61a399f85b2f8c3a), + CONST64(0x03050c0f0a181d09), CONST64(0xc15e23e2bc46187d), CONST64(0x57f94116ef827bb8), CONST64(0xd6677fa9cefe9918), + CONST64(0xd976439aec86f035), CONST64(0x58e87d25cdfa1295), CONST64(0xd875479fea8efb32), CONST64(0x66aa85e34917bd2f), + CONST64(0xd7647bacc8f6921f), CONST64(0x3a4ee8d29ccd83a6), CONST64(0xc84507cf8a0e4b42), CONST64(0x3c44f0cc88fdb9b4), + CONST64(0xfa13cf35268390dc), CONST64(0x96a762f453c463c5), CONST64(0xa7f4a601f551a552), CONST64(0x98b55ac277b401ef), + CONST64(0xec29977b52331abe), CONST64(0xb8d5da62b7a97c0f), CONST64(0xc7543bfca876226f), CONST64(0xaeef822cc319f66d), + CONST64(0x69bbb9d06b6fd402), CONST64(0x4bdd317aa762bfec), CONST64(0xabe0963ddd31d176), CONST64(0xa9e69e37d121c778), + CONST64(0x67a981e64f1fb628), CONST64(0x0a1e28223c504e36), CONST64(0x47c901468f02cbc8), CONST64(0xf20bef1d16c3c8e4), + CONST64(0xb5c2ee5b99c1032c), CONST64(0x226688aacc0d6bee), CONST64(0xe532b356647b4981), CONST64(0xee2f9f715e230cb0), + CONST64(0xbedfc27ca399461d), CONST64(0x2b7dac87fa4538d1), CONST64(0x819e3ebf217ce2a0), CONST64(0x1236485a6c90a67e), + CONST64(0x839836b52d6cf4ae), CONST64(0x1b2d6c775ad8f541), CONST64(0x0e1238362470622a), CONST64(0x23658cafca0560e9), + CONST64(0xf502f30604fbf9f1), CONST64(0x45cf094c8312ddc6), CONST64(0x216384a5c61576e7), CONST64(0xce4f1fd19e3e7150), + CONST64(0x49db3970ab72a9e2), CONST64(0x2c74b09ce87d09c4), CONST64(0xf916c33a2c9b8dd5), CONST64(0xe637bf596e635488), + CONST64(0xb6c7e25493d91e25), CONST64(0x2878a088f05d25d8), CONST64(0x17395c4b72b88165), CONST64(0x829b32b02b64ffa9), + CONST64(0x1a2e68725cd0fe46), CONST64(0x8b80169d1d2cac96), CONST64(0xfe1fdf213ea3bcc0), CONST64(0x8a8312981b24a791), + CONST64(0x091b242d3648533f), CONST64(0xc94603ca8c064045), CONST64(0x879426a1354cd8b2), CONST64(0x4ed2256bb94a98f7), + CONST64(0xe13ea3427c5b659d), CONST64(0x2e72b896e46d1fca), CONST64(0xe431b75362734286), CONST64(0xe03da7477a536e9a), + CONST64(0xeb208b60400b2bab), CONST64(0x90ad7aea47f459d7), CONST64(0xa4f1aa0eff49b85b), CONST64(0x1e22786644f0d25a), + CONST64(0x85922eab395ccebc), CONST64(0x60a09dfd5d27873d), CONST64(0x0000000000000000), CONST64(0x256f94b1de355afb), + CONST64(0xf401f70302f3f2f6), CONST64(0xf10ee3121cdbd5ed), CONST64(0x94a16afe5fd475cb), CONST64(0x0b1d2c273a584531), + CONST64(0xe734bb5c686b5f8f), CONST64(0x759fc9bc238f1056), CONST64(0xef2c9b74582b07b7), CONST64(0x345cd0e4b8bde18c), + CONST64(0x3153c4f5a695c697), CONST64(0xd46177a3c2ee8f16), CONST64(0xd06d67b7dacea30a), CONST64(0x869722a43344d3b5), + CONST64(0x7e82e59b19d75567), CONST64(0xadea8e23c901eb64), CONST64(0xfd1ad32e34bba1c9), CONST64(0x297ba48df6552edf), + CONST64(0x3050c0f0a09dcd90), CONST64(0x3b4decd79ac588a1), CONST64(0x9fbc46d9658c30fa), CONST64(0xf815c73f2a9386d2), + CONST64(0xc6573ff9ae7e2968), CONST64(0x13354c5f6a98ad79), CONST64(0x060a181e14303a12), CONST64(0x050f14111e28271b), + CONST64(0xc55233f6a4663461), CONST64(0x113344556688bb77), CONST64(0x7799c1b62f9f0658), CONST64(0x7c84ed9115c74369), + CONST64(0x7a8ef58f01f7797b), CONST64(0x7888fd850de76f75), CONST64(0x365ad8eeb4adf782), CONST64(0x1c24706c48e0c454), + CONST64(0x394be4dd96d59eaf), CONST64(0x59eb7920cbf21992), CONST64(0x1828607850c0e848), CONST64(0x56fa4513e98a70bf), + CONST64(0xb3c8f6458df1393e), CONST64(0xb0cdfa4a87e92437), CONST64(0x246c90b4d83d51fc), CONST64(0x206080a0c01d7de0), + CONST64(0xb2cbf2408bf93239), CONST64(0x92ab72e04be44fd9), CONST64(0xa3f8b615ed71894e), CONST64(0xc05d27e7ba4e137a), + CONST64(0x44cc0d49851ad6c1), CONST64(0x62a695f751379133), CONST64(0x103040506080b070), CONST64(0xb4c1ea5e9fc9082b), + CONST64(0x84912aae3f54c5bb), CONST64(0x43c511529722e7d4), CONST64(0x93a876e54dec44de), CONST64(0xc25b2fedb65e0574), + CONST64(0x4ade357fa16ab4eb), CONST64(0xbddace73a9815b14), CONST64(0x8f8c0689050c808a), CONST64(0x2d77b499ee7502c3), + CONST64(0xbcd9ca76af895013), CONST64(0x9cb94ad66f942df3), CONST64(0x6abeb5df6177c90b), CONST64(0x40c01d5d9d3afadd), + CONST64(0xcf4c1bd498367a57), CONST64(0xa2fbb210eb798249), CONST64(0x809d3aba2774e9a7), CONST64(0x4fd1216ebf4293f0), + CONST64(0x1f217c6342f8d95d), CONST64(0xca430fc5861e5d4c), CONST64(0xaae39238db39da71), CONST64(0x42c61557912aecd3), +}; + +static const ulong64 T1[256] = { + CONST64(0xd3ba68d2b9bb016a), CONST64(0xfc54194d9ae5b166), CONST64(0x712f93bc65e2cd14), CONST64(0x9c74b9cd8725511b), + CONST64(0xf5530251a2f7a457), CONST64(0x68d3b86bd6d003be), CONST64(0x6bd2bd6fded604b5), CONST64(0xd74d642952b3fe85), + CONST64(0xf0500d5dbafdad4a), CONST64(0xe9ac268a09cf63e0), CONST64(0x8a8d830e1c098496), CONST64(0xdcbf79c691a51a4d), + CONST64(0x9070addda73d4d37), CONST64(0xf6520755aaf1a35c), CONST64(0xb39ac852a47be117), CONST64(0xd44c612d5ab5f98e), + CONST64(0x23ea658f0346ac20), CONST64(0x62d5a673e6c41184), CONST64(0xa497f166cc55c268), CONST64(0x6ed1b263c6dc0da8), + CONST64(0x5533ffcc85aa99d0), CONST64(0xf3510859b2fbaa41), CONST64(0xed5b2a71e2c79c0f), CONST64(0xf7a604a259f355ae), + CONST64(0x7fde815fbefe20c1), CONST64(0xd848753d7aade5a2), CONST64(0xe5a8329a29d77fcc), CONST64(0xb699c75ebc71e80a), + CONST64(0x70db904b96e03be6), CONST64(0x5632fac88dac9edb), CONST64(0xc4b751e6d1952215), CONST64(0x19fc2bd7b332ceaa), + CONST64(0x38e348ab4b709373), CONST64(0xbf9edc428463fd3b), CONST64(0xae91ef7efc41d052), CONST64(0xb09bcd56ac7de61c), + CONST64(0x3be24daf43769478), CONST64(0xd0bb6dd6b1bd0661), CONST64(0xc3415819329bdaf1), CONST64(0xb26ecba5577917e5), + CONST64(0xf2a50bae41f95cb3), CONST64(0x40cbc00b16804b56), CONST64(0xbd6bdab17f670cc2), CONST64(0xa295fb6edc59cc7e), + CONST64(0xfea11fbe61e1409f), CONST64(0x08f318ebcb10e3c3), CONST64(0xceb14ffee181302f), CONST64(0x06020a08100c0e16), + CONST64(0x49ccdb172e925e67), CONST64(0x51c4f3376ea2663f), CONST64(0x271d6974e84e53cf), CONST64(0x3c144450a0786c9c), + CONST64(0x58c3e82b56b0730e), CONST64(0xa563f2913f57349a), CONST64(0x73da954f9ee63ced), CONST64(0xe75d3469d2d38e35), + CONST64(0xe15f3e61c2df8023), CONST64(0x79dc8b57aef22ed7), CONST64(0x877d94e9cf136e48), CONST64(0x4acdde132694596c), + CONST64(0x817f9ee1df1f605e), CONST64(0xee5a2f75eac19b04), CONST64(0xb46cc1ad477519f3), CONST64(0xe45c316ddad5893e), + CONST64(0x04f70cfbeb08ffef), CONST64(0x6a26be982dd4f247), CONST64(0x1cff24dbab38c7b7), CONST64(0x2aed7e933b54b911), + CONST64(0x25e86f87134aa236), CONST64(0xba9dd34e9c69f426), CONST64(0xb16fcea15f7f10ee), CONST64(0x8f8e8c0204038d8b), + CONST64(0x2b197d64c8564fe3), CONST64(0xfda01aba69e74794), CONST64(0x0df017e7d31aeade), CONST64(0x8689971e3c1198ba), + CONST64(0x110f333c78222d69), CONST64(0x09071b1c38121531), CONST64(0xecaf298611c56afd), CONST64(0x10fb30cb8b20db9b), + CONST64(0x1808282040303858), CONST64(0x3f154154a87e6b97), CONST64(0x170d3934682e237f), CONST64(0x0c04141020181c2c), + CONST64(0x030105040806070b), CONST64(0xac64e98d074521ab), CONST64(0x7cdf845bb6f827ca), CONST64(0x9a76b3c597295f0d), + CONST64(0x8b7980f9ef0b7264), CONST64(0x7add8e53a6f429dc), CONST64(0x473dc9f4f58eb3b2), CONST64(0x3a164e58b074628a), + CONST64(0x413fc3fce582bda4), CONST64(0x5937ebdca5b285fc), CONST64(0xb76dc4a94f731ef8), CONST64(0x4838d8e0dd90a895), + CONST64(0xd6b967dea1b10877), CONST64(0x9573a2d1bf37442a), CONST64(0x26e96a831b4ca53d), CONST64(0x5f35e1d4b5be8bea), + CONST64(0xff551c4992e3b66d), CONST64(0x9371a8d9af3b4a3c), CONST64(0x8d7b8af1ff077c72), CONST64(0x898c860a140f839d), + CONST64(0x9672a7d5b7314321), CONST64(0x8588921a34179fb1), CONST64(0x07f609ffe30ef8e4), CONST64(0x7e2a82a84dfcd633), + CONST64(0x423ec6f8ed84baaf), CONST64(0xe25e3b65cad98728), CONST64(0x6927bb9c25d2f54c), CONST64(0xca4643050a89cfc0), + CONST64(0x140c3c3060282474), CONST64(0xaf65ec890f4326a0), CONST64(0xb868d5bd676d05df), CONST64(0xa361f8992f5b3a8c), + CONST64(0x05030f0c180a091d), CONST64(0x5ec1e22346bc7d18), CONST64(0xf957164182efb87b), CONST64(0x67d6a97ffece1899), + CONST64(0x76d99a4386ec35f0), CONST64(0xe858257dfacd9512), CONST64(0x75d89f478eea32fb), CONST64(0xaa66e38517492fbd), + CONST64(0x64d7ac7bf6c81f92), CONST64(0x4e3ad2e8cd9ca683), CONST64(0x45c8cf070e8a424b), CONST64(0x443cccf0fd88b4b9), + CONST64(0x13fa35cf8326dc90), CONST64(0xa796f462c453c563), CONST64(0xf4a701a651f552a5), CONST64(0xb598c25ab477ef01), + CONST64(0x29ec7b973352be1a), CONST64(0xd5b862daa9b70f7c), CONST64(0x54c7fc3b76a86f22), CONST64(0xefae2c8219c36df6), + CONST64(0xbb69d0b96f6b02d4), CONST64(0xdd4b7a3162a7ecbf), CONST64(0xe0ab3d9631dd76d1), CONST64(0xe6a9379e21d178c7), + CONST64(0xa967e6811f4f28b6), CONST64(0x1e0a2228503c364e), CONST64(0xc9474601028fc8cb), CONST64(0x0bf21defc316e4c8), + CONST64(0xc2b55beec1992c03), CONST64(0x6622aa880dccee6b), CONST64(0x32e556b37b648149), CONST64(0x2fee719f235eb00c), + CONST64(0xdfbe7cc299a31d46), CONST64(0x7d2b87ac45fad138), CONST64(0x9e81bf3e7c21a0e2), CONST64(0x36125a48906c7ea6), + CONST64(0x9883b5366c2daef4), CONST64(0x2d1b776cd85a41f5), CONST64(0x120e363870242a62), CONST64(0x6523af8c05cae960), + CONST64(0x02f506f3fb04f1f9), CONST64(0xcf454c091283c6dd), CONST64(0x6321a58415c6e776), CONST64(0x4fced11f3e9e5071), + CONST64(0xdb49703972abe2a9), CONST64(0x742c9cb07de8c409), CONST64(0x16f93ac39b2cd58d), CONST64(0x37e659bf636e8854), + CONST64(0xc7b654e2d993251e), CONST64(0x782888a05df0d825), CONST64(0x39174b5cb8726581), CONST64(0x9b82b032642ba9ff), + CONST64(0x2e1a7268d05c46fe), CONST64(0x808b9d162c1d96ac), CONST64(0x1ffe21dfa33ec0bc), CONST64(0x838a9812241b91a7), + CONST64(0x1b092d2448363f53), CONST64(0x46c9ca03068c4540), CONST64(0x9487a1264c35b2d8), CONST64(0xd24e6b254ab9f798), + CONST64(0x3ee142a35b7c9d65), CONST64(0x722e96b86de4ca1f), CONST64(0x31e453b773628642), CONST64(0x3de047a7537a9a6e), + CONST64(0x20eb608b0b40ab2b), CONST64(0xad90ea7af447d759), CONST64(0xf1a40eaa49ff5bb8), CONST64(0x221e6678f0445ad2), + CONST64(0x9285ab2e5c39bcce), CONST64(0xa060fd9d275d3d87), CONST64(0x0000000000000000), CONST64(0x6f25b19435defb5a), + CONST64(0x01f403f7f302f6f2), CONST64(0x0ef112e3db1cedd5), CONST64(0xa194fe6ad45fcb75), CONST64(0x1d0b272c583a3145), + CONST64(0x34e75cbb6b688f5f), CONST64(0x9f75bcc98f235610), CONST64(0x2cef749b2b58b707), CONST64(0x5c34e4d0bdb88ce1), + CONST64(0x5331f5c495a697c6), CONST64(0x61d4a377eec2168f), CONST64(0x6dd0b767ceda0aa3), CONST64(0x9786a4224433b5d3), + CONST64(0x827e9be5d7196755), CONST64(0xeaad238e01c964eb), CONST64(0x1afd2ed3bb34c9a1), CONST64(0x7b298da455f6df2e), + CONST64(0x5030f0c09da090cd), CONST64(0x4d3bd7ecc59aa188), CONST64(0xbc9fd9468c65fa30), CONST64(0x15f83fc7932ad286), + CONST64(0x57c6f93f7eae6829), CONST64(0x35135f4c986a79ad), CONST64(0x0a061e183014123a), CONST64(0x0f051114281e1b27), + CONST64(0x52c5f63366a46134), CONST64(0x33115544886677bb), CONST64(0x9977b6c19f2f5806), CONST64(0x847c91edc7156943), + CONST64(0x8e7a8ff5f7017b79), CONST64(0x887885fde70d756f), CONST64(0x5a36eed8adb482f7), CONST64(0x241c6c70e04854c4), + CONST64(0x4b39dde4d596af9e), CONST64(0xeb592079f2cb9219), CONST64(0x28187860c05048e8), CONST64(0xfa5613458ae9bf70), + CONST64(0xc8b345f6f18d3e39), CONST64(0xcdb04afae9873724), CONST64(0x6c24b4903dd8fc51), CONST64(0x6020a0801dc0e07d), + CONST64(0xcbb240f2f98b3932), CONST64(0xab92e072e44bd94f), CONST64(0xf8a315b671ed4e89), CONST64(0x5dc0e7274eba7a13), + CONST64(0xcc44490d1a85c1d6), CONST64(0xa662f79537513391), CONST64(0x30105040806070b0), CONST64(0xc1b45eeac99f2b08), + CONST64(0x9184ae2a543fbbc5), CONST64(0xc54352112297d4e7), CONST64(0xa893e576ec4dde44), CONST64(0x5bc2ed2f5eb67405), + CONST64(0xde4a7f356aa1ebb4), CONST64(0xdabd73ce81a9145b), CONST64(0x8c8f89060c058a80), CONST64(0x772d99b475eec302), + CONST64(0xd9bc76ca89af1350), CONST64(0xb99cd64a946ff32d), CONST64(0xbe6adfb577610bc9), CONST64(0xc0405d1d3a9dddfa), + CONST64(0x4ccfd41b3698577a), CONST64(0xfba210b279eb4982), CONST64(0x9d80ba3a7427a7e9), CONST64(0xd14f6e2142bff093), + CONST64(0x211f637cf8425dd9), CONST64(0x43cac50f1e864c5d), CONST64(0xe3aa389239db71da), CONST64(0xc64257152a91d3ec), +}; + +static const ulong64 T2[256] = { + CONST64(0xd268bad36a01bbb9), CONST64(0x4d1954fc66b1e59a), CONST64(0xbc932f7114cde265), CONST64(0xcdb9749c1b512587), + CONST64(0x510253f557a4f7a2), CONST64(0x6bb8d368be03d0d6), CONST64(0x6fbdd26bb504d6de), CONST64(0x29644dd785feb352), + CONST64(0x5d0d50f04aadfdba), CONST64(0x8a26ace9e063cf09), CONST64(0x0e838d8a9684091c), CONST64(0xc679bfdc4d1aa591), + CONST64(0xddad7090374d3da7), CONST64(0x550752f65ca3f1aa), CONST64(0x52c89ab317e17ba4), CONST64(0x2d614cd48ef9b55a), + CONST64(0x8f65ea2320ac4603), CONST64(0x73a6d5628411c4e6), CONST64(0x66f197a468c255cc), CONST64(0x63b2d16ea80ddcc6), + CONST64(0xccff3355d099aa85), CONST64(0x590851f341aafbb2), CONST64(0x712a5bed0f9cc7e2), CONST64(0xa204a6f7ae55f359), + CONST64(0x5f81de7fc120febe), CONST64(0x3d7548d8a2e5ad7a), CONST64(0x9a32a8e5cc7fd729), CONST64(0x5ec799b60ae871bc), + CONST64(0x4b90db70e63be096), CONST64(0xc8fa3256db9eac8d), CONST64(0xe651b7c4152295d1), CONST64(0xd72bfc19aace32b3), + CONST64(0xab48e3387393704b), CONST64(0x42dc9ebf3bfd6384), CONST64(0x7eef91ae52d041fc), CONST64(0x56cd9bb01ce67dac), + CONST64(0xaf4de23b78947643), CONST64(0xd66dbbd06106bdb1), CONST64(0x195841c3f1da9b32), CONST64(0xa5cb6eb2e5177957), + CONST64(0xae0ba5f2b35cf941), CONST64(0x0bc0cb40564b8016), CONST64(0xb1da6bbdc20c677f), CONST64(0x6efb95a27ecc59dc), + CONST64(0xbe1fa1fe9f40e161), CONST64(0xeb18f308c3e310cb), CONST64(0xfe4fb1ce2f3081e1), CONST64(0x080a0206160e0c10), + CONST64(0x17dbcc49675e922e), CONST64(0x37f3c4513f66a26e), CONST64(0x74691d27cf534ee8), CONST64(0x5044143c9c6c78a0), + CONST64(0x2be8c3580e73b056), CONST64(0x91f263a59a34573f), CONST64(0x4f95da73ed3ce69e), CONST64(0x69345de7358ed3d2), + CONST64(0x613e5fe12380dfc2), CONST64(0x578bdc79d72ef2ae), CONST64(0xe9947d87486e13cf), CONST64(0x13decd4a6c599426), + CONST64(0xe19e7f815e601fdf), CONST64(0x752f5aee049bc1ea), CONST64(0xadc16cb4f3197547), CONST64(0x6d315ce43e89d5da), + CONST64(0xfb0cf704efff08eb), CONST64(0x98be266a47f2d42d), CONST64(0xdb24ff1cb7c738ab), CONST64(0x937eed2a11b9543b), + CONST64(0x876fe82536a24a13), CONST64(0x4ed39dba26f4699c), CONST64(0xa1ce6fb1ee107f5f), CONST64(0x028c8e8f8b8d0304), + CONST64(0x647d192be34f56c8), CONST64(0xba1aa0fd9447e769), CONST64(0xe717f00ddeea1ad3), CONST64(0x1e978986ba98113c), + CONST64(0x3c330f11692d2278), CONST64(0x1c1b070931151238), CONST64(0x8629afecfd6ac511), CONST64(0xcb30fb109bdb208b), + CONST64(0x2028081858383040), CONST64(0x5441153f976b7ea8), CONST64(0x34390d177f232e68), CONST64(0x1014040c2c1c1820), + CONST64(0x040501030b070608), CONST64(0x8de964acab214507), CONST64(0x5b84df7cca27f8b6), CONST64(0xc5b3769a0d5f2997), + CONST64(0xf980798b64720bef), CONST64(0x538edd7adc29f4a6), CONST64(0xf4c93d47b2b38ef5), CONST64(0x584e163a8a6274b0), + CONST64(0xfcc33f41a4bd82e5), CONST64(0xdceb3759fc85b2a5), CONST64(0xa9c46db7f81e734f), CONST64(0xe0d8384895a890dd), + CONST64(0xde67b9d67708b1a1), CONST64(0xd1a273952a4437bf), CONST64(0x836ae9263da54c1b), CONST64(0xd4e1355fea8bbeb5), + CONST64(0x491c55ff6db6e392), CONST64(0xd9a871933c4a3baf), CONST64(0xf18a7b8d727c07ff), CONST64(0x0a868c899d830f14), + CONST64(0xd5a77296214331b7), CONST64(0x1a928885b19f1734), CONST64(0xff09f607e4f80ee3), CONST64(0xa8822a7e33d6fc4d), + CONST64(0xf8c63e42afba84ed), CONST64(0x653b5ee22887d9ca), CONST64(0x9cbb27694cf5d225), CONST64(0x054346cac0cf890a), + CONST64(0x303c0c1474242860), CONST64(0x89ec65afa026430f), CONST64(0xbdd568b8df056d67), CONST64(0x99f861a38c3a5b2f), + CONST64(0x0c0f03051d090a18), CONST64(0x23e2c15e187dbc46), CONST64(0x411657f97bb8ef82), CONST64(0x7fa9d6679918cefe), + CONST64(0x439ad976f035ec86), CONST64(0x7d2558e81295cdfa), CONST64(0x479fd875fb32ea8e), CONST64(0x85e366aabd2f4917), + CONST64(0x7bacd764921fc8f6), CONST64(0xe8d23a4e83a69ccd), CONST64(0x07cfc8454b428a0e), CONST64(0xf0cc3c44b9b488fd), + CONST64(0xcf35fa1390dc2683), CONST64(0x62f496a763c553c4), CONST64(0xa601a7f4a552f551), CONST64(0x5ac298b501ef77b4), + CONST64(0x977bec291abe5233), CONST64(0xda62b8d57c0fb7a9), CONST64(0x3bfcc754226fa876), CONST64(0x822caeeff66dc319), + CONST64(0xb9d069bbd4026b6f), CONST64(0x317a4bddbfeca762), CONST64(0x963dabe0d176dd31), CONST64(0x9e37a9e6c778d121), + CONST64(0x81e667a9b6284f1f), CONST64(0x28220a1e4e363c50), CONST64(0x014647c9cbc88f02), CONST64(0xef1df20bc8e416c3), + CONST64(0xee5bb5c2032c99c1), CONST64(0x88aa22666beecc0d), CONST64(0xb356e5324981647b), CONST64(0x9f71ee2f0cb05e23), + CONST64(0xc27cbedf461da399), CONST64(0xac872b7d38d1fa45), CONST64(0x3ebf819ee2a0217c), CONST64(0x485a1236a67e6c90), + CONST64(0x36b58398f4ae2d6c), CONST64(0x6c771b2df5415ad8), CONST64(0x38360e12622a2470), CONST64(0x8caf236560e9ca05), + CONST64(0xf306f502f9f104fb), CONST64(0x094c45cfddc68312), CONST64(0x84a5216376e7c615), CONST64(0x1fd1ce4f71509e3e), + CONST64(0x397049dba9e2ab72), CONST64(0xb09c2c7409c4e87d), CONST64(0xc33af9168dd52c9b), CONST64(0xbf59e63754886e63), + CONST64(0xe254b6c71e2593d9), CONST64(0xa088287825d8f05d), CONST64(0x5c4b1739816572b8), CONST64(0x32b0829bffa92b64), + CONST64(0x68721a2efe465cd0), CONST64(0x169d8b80ac961d2c), CONST64(0xdf21fe1fbcc03ea3), CONST64(0x12988a83a7911b24), + CONST64(0x242d091b533f3648), CONST64(0x03cac94640458c06), CONST64(0x26a18794d8b2354c), CONST64(0x256b4ed298f7b94a), + CONST64(0xa342e13e659d7c5b), CONST64(0xb8962e721fcae46d), CONST64(0xb753e43142866273), CONST64(0xa747e03d6e9a7a53), + CONST64(0x8b60eb202bab400b), CONST64(0x7aea90ad59d747f4), CONST64(0xaa0ea4f1b85bff49), CONST64(0x78661e22d25a44f0), + CONST64(0x2eab8592cebc395c), CONST64(0x9dfd60a0873d5d27), CONST64(0x0000000000000000), CONST64(0x94b1256f5afbde35), + CONST64(0xf703f401f2f602f3), CONST64(0xe312f10ed5ed1cdb), CONST64(0x6afe94a175cb5fd4), CONST64(0x2c270b1d45313a58), + CONST64(0xbb5ce7345f8f686b), CONST64(0xc9bc759f1056238f), CONST64(0x9b74ef2c07b7582b), CONST64(0xd0e4345ce18cb8bd), + CONST64(0xc4f53153c697a695), CONST64(0x77a3d4618f16c2ee), CONST64(0x67b7d06da30adace), CONST64(0x22a48697d3b53344), + CONST64(0xe59b7e82556719d7), CONST64(0x8e23adeaeb64c901), CONST64(0xd32efd1aa1c934bb), CONST64(0xa48d297b2edff655), + CONST64(0xc0f03050cd90a09d), CONST64(0xecd73b4d88a19ac5), CONST64(0x46d99fbc30fa658c), CONST64(0xc73ff81586d22a93), + CONST64(0x3ff9c6572968ae7e), CONST64(0x4c5f1335ad796a98), CONST64(0x181e060a3a121430), CONST64(0x1411050f271b1e28), + CONST64(0x33f6c5523461a466), CONST64(0x44551133bb776688), CONST64(0xc1b6779906582f9f), CONST64(0xed917c84436915c7), + CONST64(0xf58f7a8e797b01f7), CONST64(0xfd8578886f750de7), CONST64(0xd8ee365af782b4ad), CONST64(0x706c1c24c45448e0), + CONST64(0xe4dd394b9eaf96d5), CONST64(0x792059eb1992cbf2), CONST64(0x60781828e84850c0), CONST64(0x451356fa70bfe98a), + CONST64(0xf645b3c8393e8df1), CONST64(0xfa4ab0cd243787e9), CONST64(0x90b4246c51fcd83d), CONST64(0x80a020607de0c01d), + CONST64(0xf240b2cb32398bf9), CONST64(0x72e092ab4fd94be4), CONST64(0xb615a3f8894eed71), CONST64(0x27e7c05d137aba4e), + CONST64(0x0d4944ccd6c1851a), CONST64(0x95f762a691335137), CONST64(0x40501030b0706080), CONST64(0xea5eb4c1082b9fc9), + CONST64(0x2aae8491c5bb3f54), CONST64(0x115243c5e7d49722), CONST64(0x76e593a844de4dec), CONST64(0x2fedc25b0574b65e), + CONST64(0x357f4adeb4eba16a), CONST64(0xce73bdda5b14a981), CONST64(0x06898f8c808a050c), CONST64(0xb4992d7702c3ee75), + CONST64(0xca76bcd95013af89), CONST64(0x4ad69cb92df36f94), CONST64(0xb5df6abec90b6177), CONST64(0x1d5d40c0fadd9d3a), + CONST64(0x1bd4cf4c7a579836), CONST64(0xb210a2fb8249eb79), CONST64(0x3aba809de9a72774), CONST64(0x216e4fd193f0bf42), + CONST64(0x7c631f21d95d42f8), CONST64(0x0fc5ca435d4c861e), CONST64(0x9238aae3da71db39), CONST64(0x155742c6ecd3912a), +}; + +static const ulong64 T3[256] = { + CONST64(0x68d2d3ba016ab9bb), CONST64(0x194dfc54b1669ae5), CONST64(0x93bc712fcd1465e2), CONST64(0xb9cd9c74511b8725), + CONST64(0x0251f553a457a2f7), CONST64(0xb86b68d303bed6d0), CONST64(0xbd6f6bd204b5ded6), CONST64(0x6429d74dfe8552b3), + CONST64(0x0d5df050ad4abafd), CONST64(0x268ae9ac63e009cf), CONST64(0x830e8a8d84961c09), CONST64(0x79c6dcbf1a4d91a5), + CONST64(0xaddd90704d37a73d), CONST64(0x0755f652a35caaf1), CONST64(0xc852b39ae117a47b), CONST64(0x612dd44cf98e5ab5), + CONST64(0x658f23eaac200346), CONST64(0xa67362d51184e6c4), CONST64(0xf166a497c268cc55), CONST64(0xb2636ed10da8c6dc), + CONST64(0xffcc553399d085aa), CONST64(0x0859f351aa41b2fb), CONST64(0x2a71ed5b9c0fe2c7), CONST64(0x04a2f7a655ae59f3), + CONST64(0x815f7fde20c1befe), CONST64(0x753dd848e5a27aad), CONST64(0x329ae5a87fcc29d7), CONST64(0xc75eb699e80abc71), + CONST64(0x904b70db3be696e0), CONST64(0xfac856329edb8dac), CONST64(0x51e6c4b72215d195), CONST64(0x2bd719fcceaab332), + CONST64(0x48ab38e393734b70), CONST64(0xdc42bf9efd3b8463), CONST64(0xef7eae91d052fc41), CONST64(0xcd56b09be61cac7d), + CONST64(0x4daf3be294784376), CONST64(0x6dd6d0bb0661b1bd), CONST64(0x5819c341daf1329b), CONST64(0xcba5b26e17e55779), + CONST64(0x0baef2a55cb341f9), CONST64(0xc00b40cb4b561680), CONST64(0xdab1bd6b0cc27f67), CONST64(0xfb6ea295cc7edc59), + CONST64(0x1fbefea1409f61e1), CONST64(0x18eb08f3e3c3cb10), CONST64(0x4ffeceb1302fe181), CONST64(0x0a0806020e16100c), + CONST64(0xdb1749cc5e672e92), CONST64(0xf33751c4663f6ea2), CONST64(0x6974271d53cfe84e), CONST64(0x44503c146c9ca078), + CONST64(0xe82b58c3730e56b0), CONST64(0xf291a563349a3f57), CONST64(0x954f73da3ced9ee6), CONST64(0x3469e75d8e35d2d3), + CONST64(0x3e61e15f8023c2df), CONST64(0x8b5779dc2ed7aef2), CONST64(0x94e9877d6e48cf13), CONST64(0xde134acd596c2694), + CONST64(0x9ee1817f605edf1f), CONST64(0x2f75ee5a9b04eac1), CONST64(0xc1adb46c19f34775), CONST64(0x316de45c893edad5), + CONST64(0x0cfb04f7ffefeb08), CONST64(0xbe986a26f2472dd4), CONST64(0x24db1cffc7b7ab38), CONST64(0x7e932aedb9113b54), + CONST64(0x6f8725e8a236134a), CONST64(0xd34eba9df4269c69), CONST64(0xcea1b16f10ee5f7f), CONST64(0x8c028f8e8d8b0403), + CONST64(0x7d642b194fe3c856), CONST64(0x1abafda0479469e7), CONST64(0x17e70df0eaded31a), CONST64(0x971e868998ba3c11), + CONST64(0x333c110f2d697822), CONST64(0x1b1c090715313812), CONST64(0x2986ecaf6afd11c5), CONST64(0x30cb10fbdb9b8b20), + CONST64(0x2820180838584030), CONST64(0x41543f156b97a87e), CONST64(0x3934170d237f682e), CONST64(0x14100c041c2c2018), + CONST64(0x05040301070b0806), CONST64(0xe98dac6421ab0745), CONST64(0x845b7cdf27cab6f8), CONST64(0xb3c59a765f0d9729), + CONST64(0x80f98b797264ef0b), CONST64(0x8e537add29dca6f4), CONST64(0xc9f4473db3b2f58e), CONST64(0x4e583a16628ab074), + CONST64(0xc3fc413fbda4e582), CONST64(0xebdc593785fca5b2), CONST64(0xc4a9b76d1ef84f73), CONST64(0xd8e04838a895dd90), + CONST64(0x67ded6b90877a1b1), CONST64(0xa2d19573442abf37), CONST64(0x6a8326e9a53d1b4c), CONST64(0xe1d45f358beab5be), + CONST64(0x1c49ff55b66d92e3), CONST64(0xa8d993714a3caf3b), CONST64(0x8af18d7b7c72ff07), CONST64(0x860a898c839d140f), + CONST64(0xa7d596724321b731), CONST64(0x921a85889fb13417), CONST64(0x09ff07f6f8e4e30e), CONST64(0x82a87e2ad6334dfc), + CONST64(0xc6f8423ebaafed84), CONST64(0x3b65e25e8728cad9), CONST64(0xbb9c6927f54c25d2), CONST64(0x4305ca46cfc00a89), + CONST64(0x3c30140c24746028), CONST64(0xec89af6526a00f43), CONST64(0xd5bdb86805df676d), CONST64(0xf899a3613a8c2f5b), + CONST64(0x0f0c0503091d180a), CONST64(0xe2235ec17d1846bc), CONST64(0x1641f957b87b82ef), CONST64(0xa97f67d61899fece), + CONST64(0x9a4376d935f086ec), CONST64(0x257de8589512facd), CONST64(0x9f4775d832fb8eea), CONST64(0xe385aa662fbd1749), + CONST64(0xac7b64d71f92f6c8), CONST64(0xd2e84e3aa683cd9c), CONST64(0xcf0745c8424b0e8a), CONST64(0xccf0443cb4b9fd88), + CONST64(0x35cf13fadc908326), CONST64(0xf462a796c563c453), CONST64(0x01a6f4a752a551f5), CONST64(0xc25ab598ef01b477), + CONST64(0x7b9729ecbe1a3352), CONST64(0x62dad5b80f7ca9b7), CONST64(0xfc3b54c76f2276a8), CONST64(0x2c82efae6df619c3), + CONST64(0xd0b9bb6902d46f6b), CONST64(0x7a31dd4becbf62a7), CONST64(0x3d96e0ab76d131dd), CONST64(0x379ee6a978c721d1), + CONST64(0xe681a96728b61f4f), CONST64(0x22281e0a364e503c), CONST64(0x4601c947c8cb028f), CONST64(0x1def0bf2e4c8c316), + CONST64(0x5beec2b52c03c199), CONST64(0xaa886622ee6b0dcc), CONST64(0x56b332e581497b64), CONST64(0x719f2feeb00c235e), + CONST64(0x7cc2dfbe1d4699a3), CONST64(0x87ac7d2bd13845fa), CONST64(0xbf3e9e81a0e27c21), CONST64(0x5a4836127ea6906c), + CONST64(0xb5369883aef46c2d), CONST64(0x776c2d1b41f5d85a), CONST64(0x3638120e2a627024), CONST64(0xaf8c6523e96005ca), + CONST64(0x06f302f5f1f9fb04), CONST64(0x4c09cf45c6dd1283), CONST64(0xa5846321e77615c6), CONST64(0xd11f4fce50713e9e), + CONST64(0x7039db49e2a972ab), CONST64(0x9cb0742cc4097de8), CONST64(0x3ac316f9d58d9b2c), CONST64(0x59bf37e68854636e), + CONST64(0x54e2c7b6251ed993), CONST64(0x88a07828d8255df0), CONST64(0x4b5c39176581b872), CONST64(0xb0329b82a9ff642b), + CONST64(0x72682e1a46fed05c), CONST64(0x9d16808b96ac2c1d), CONST64(0x21df1ffec0bca33e), CONST64(0x9812838a91a7241b), + CONST64(0x2d241b093f534836), CONST64(0xca0346c94540068c), CONST64(0xa1269487b2d84c35), CONST64(0x6b25d24ef7984ab9), + CONST64(0x42a33ee19d655b7c), CONST64(0x96b8722eca1f6de4), CONST64(0x53b731e486427362), CONST64(0x47a73de09a6e537a), + CONST64(0x608b20ebab2b0b40), CONST64(0xea7aad90d759f447), CONST64(0x0eaaf1a45bb849ff), CONST64(0x6678221e5ad2f044), + CONST64(0xab2e9285bcce5c39), CONST64(0xfd9da0603d87275d), CONST64(0x0000000000000000), CONST64(0xb1946f25fb5a35de), + CONST64(0x03f701f4f6f2f302), CONST64(0x12e30ef1edd5db1c), CONST64(0xfe6aa194cb75d45f), CONST64(0x272c1d0b3145583a), + CONST64(0x5cbb34e78f5f6b68), CONST64(0xbcc99f7556108f23), CONST64(0x749b2cefb7072b58), CONST64(0xe4d05c348ce1bdb8), + CONST64(0xf5c4533197c695a6), CONST64(0xa37761d4168feec2), CONST64(0xb7676dd00aa3ceda), CONST64(0xa4229786b5d34433), + CONST64(0x9be5827e6755d719), CONST64(0x238eeaad64eb01c9), CONST64(0x2ed31afdc9a1bb34), CONST64(0x8da47b29df2e55f6), + CONST64(0xf0c0503090cd9da0), CONST64(0xd7ec4d3ba188c59a), CONST64(0xd946bc9ffa308c65), CONST64(0x3fc715f8d286932a), + CONST64(0xf93f57c668297eae), CONST64(0x5f4c351379ad986a), CONST64(0x1e180a06123a3014), CONST64(0x11140f051b27281e), + CONST64(0xf63352c5613466a4), CONST64(0x5544331177bb8866), CONST64(0xb6c1997758069f2f), CONST64(0x91ed847c6943c715), + CONST64(0x8ff58e7a7b79f701), CONST64(0x85fd8878756fe70d), CONST64(0xeed85a3682f7adb4), CONST64(0x6c70241c54c4e048), + CONST64(0xdde44b39af9ed596), CONST64(0x2079eb599219f2cb), CONST64(0x7860281848e8c050), CONST64(0x1345fa56bf708ae9), + CONST64(0x45f6c8b33e39f18d), CONST64(0x4afacdb03724e987), CONST64(0xb4906c24fc513dd8), CONST64(0xa0806020e07d1dc0), + CONST64(0x40f2cbb23932f98b), CONST64(0xe072ab92d94fe44b), CONST64(0x15b6f8a34e8971ed), CONST64(0xe7275dc07a134eba), + CONST64(0x490dcc44c1d61a85), CONST64(0xf795a66233913751), CONST64(0x5040301070b08060), CONST64(0x5eeac1b42b08c99f), + CONST64(0xae2a9184bbc5543f), CONST64(0x5211c543d4e72297), CONST64(0xe576a893de44ec4d), CONST64(0xed2f5bc274055eb6), + CONST64(0x7f35de4aebb46aa1), CONST64(0x73cedabd145b81a9), CONST64(0x89068c8f8a800c05), CONST64(0x99b4772dc30275ee), + CONST64(0x76cad9bc135089af), CONST64(0xd64ab99cf32d946f), CONST64(0xdfb5be6a0bc97761), CONST64(0x5d1dc040ddfa3a9d), + CONST64(0xd41b4ccf577a3698), CONST64(0x10b2fba2498279eb), CONST64(0xba3a9d80a7e97427), CONST64(0x6e21d14ff09342bf), + CONST64(0x637c211f5dd9f842), CONST64(0xc50f43ca4c5d1e86), CONST64(0x3892e3aa71da39db), CONST64(0x5715c642d3ec2a91), +}; + +static const ulong64 T4[256] = { + CONST64(0xbbb96a01bad3d268), CONST64(0xe59a66b154fc4d19), CONST64(0xe26514cd2f71bc93), CONST64(0x25871b51749ccdb9), + CONST64(0xf7a257a453f55102), CONST64(0xd0d6be03d3686bb8), CONST64(0xd6deb504d26b6fbd), CONST64(0xb35285fe4dd72964), + CONST64(0xfdba4aad50f05d0d), CONST64(0xcf09e063ace98a26), CONST64(0x091c96848d8a0e83), CONST64(0xa5914d1abfdcc679), + CONST64(0x3da7374d7090ddad), CONST64(0xf1aa5ca352f65507), CONST64(0x7ba417e19ab352c8), CONST64(0xb55a8ef94cd42d61), + CONST64(0x460320acea238f65), CONST64(0xc4e68411d56273a6), CONST64(0x55cc68c297a466f1), CONST64(0xdcc6a80dd16e63b2), + CONST64(0xaa85d0993355ccff), CONST64(0xfbb241aa51f35908), CONST64(0xc7e20f9c5bed712a), CONST64(0xf359ae55a6f7a204), + CONST64(0xfebec120de7f5f81), CONST64(0xad7aa2e548d83d75), CONST64(0xd729cc7fa8e59a32), CONST64(0x71bc0ae899b65ec7), + CONST64(0xe096e63bdb704b90), CONST64(0xac8ddb9e3256c8fa), CONST64(0x95d11522b7c4e651), CONST64(0x32b3aacefc19d72b), + CONST64(0x704b7393e338ab48), CONST64(0x63843bfd9ebf42dc), CONST64(0x41fc52d091ae7eef), CONST64(0x7dac1ce69bb056cd), + CONST64(0x76437894e23baf4d), CONST64(0xbdb16106bbd0d66d), CONST64(0x9b32f1da41c31958), CONST64(0x7957e5176eb2a5cb), + CONST64(0xf941b35ca5f2ae0b), CONST64(0x8016564bcb400bc0), CONST64(0x677fc20c6bbdb1da), CONST64(0x59dc7ecc95a26efb), + CONST64(0xe1619f40a1febe1f), CONST64(0x10cbc3e3f308eb18), CONST64(0x81e12f30b1cefe4f), CONST64(0x0c10160e0206080a), + CONST64(0x922e675ecc4917db), CONST64(0xa26e3f66c45137f3), CONST64(0x4ee8cf531d277469), CONST64(0x78a09c6c143c5044), + CONST64(0xb0560e73c3582be8), CONST64(0x573f9a3463a591f2), CONST64(0xe69eed3cda734f95), CONST64(0xd3d2358e5de76934), + CONST64(0xdfc223805fe1613e), CONST64(0xf2aed72edc79578b), CONST64(0x13cf486e7d87e994), CONST64(0x94266c59cd4a13de), + CONST64(0x1fdf5e607f81e19e), CONST64(0xc1ea049b5aee752f), CONST64(0x7547f3196cb4adc1), CONST64(0xd5da3e895ce46d31), + CONST64(0x08ebeffff704fb0c), CONST64(0xd42d47f2266a98be), CONST64(0x38abb7c7ff1cdb24), CONST64(0x543b11b9ed2a937e), + CONST64(0x4a1336a2e825876f), CONST64(0x699c26f49dba4ed3), CONST64(0x7f5fee106fb1a1ce), CONST64(0x03048b8d8e8f028c), + CONST64(0x56c8e34f192b647d), CONST64(0xe7699447a0fdba1a), CONST64(0x1ad3deeaf00de717), CONST64(0x113cba9889861e97), + CONST64(0x2278692d0f113c33), CONST64(0x1238311507091c1b), CONST64(0xc511fd6aafec8629), CONST64(0x208b9bdbfb10cb30), + CONST64(0x3040583808182028), CONST64(0x7ea8976b153f5441), CONST64(0x2e687f230d173439), CONST64(0x18202c1c040c1014), + CONST64(0x06080b0701030405), CONST64(0x4507ab2164ac8de9), CONST64(0xf8b6ca27df7c5b84), CONST64(0x29970d5f769ac5b3), + CONST64(0x0bef6472798bf980), CONST64(0xf4a6dc29dd7a538e), CONST64(0x8ef5b2b33d47f4c9), CONST64(0x74b08a62163a584e), + CONST64(0x82e5a4bd3f41fcc3), CONST64(0xb2a5fc853759dceb), CONST64(0x734ff81e6db7a9c4), CONST64(0x90dd95a83848e0d8), + CONST64(0xb1a17708b9d6de67), CONST64(0x37bf2a447395d1a2), CONST64(0x4c1b3da5e926836a), CONST64(0xbeb5ea8b355fd4e1), + CONST64(0xe3926db655ff491c), CONST64(0x3baf3c4a7193d9a8), CONST64(0x07ff727c7b8df18a), CONST64(0x0f149d838c890a86), + CONST64(0x31b721437296d5a7), CONST64(0x1734b19f88851a92), CONST64(0x0ee3e4f8f607ff09), CONST64(0xfc4d33d62a7ea882), + CONST64(0x84edafba3e42f8c6), CONST64(0xd9ca28875ee2653b), CONST64(0xd2254cf527699cbb), CONST64(0x890ac0cf46ca0543), + CONST64(0x286074240c14303c), CONST64(0x430fa02665af89ec), CONST64(0x6d67df0568b8bdd5), CONST64(0x5b2f8c3a61a399f8), + CONST64(0x0a181d0903050c0f), CONST64(0xbc46187dc15e23e2), CONST64(0xef827bb857f94116), CONST64(0xcefe9918d6677fa9), + CONST64(0xec86f035d976439a), CONST64(0xcdfa129558e87d25), CONST64(0xea8efb32d875479f), CONST64(0x4917bd2f66aa85e3), + CONST64(0xc8f6921fd7647bac), CONST64(0x9ccd83a63a4ee8d2), CONST64(0x8a0e4b42c84507cf), CONST64(0x88fdb9b43c44f0cc), + CONST64(0x268390dcfa13cf35), CONST64(0x53c463c596a762f4), CONST64(0xf551a552a7f4a601), CONST64(0x77b401ef98b55ac2), + CONST64(0x52331abeec29977b), CONST64(0xb7a97c0fb8d5da62), CONST64(0xa876226fc7543bfc), CONST64(0xc319f66daeef822c), + CONST64(0x6b6fd40269bbb9d0), CONST64(0xa762bfec4bdd317a), CONST64(0xdd31d176abe0963d), CONST64(0xd121c778a9e69e37), + CONST64(0x4f1fb62867a981e6), CONST64(0x3c504e360a1e2822), CONST64(0x8f02cbc847c90146), CONST64(0x16c3c8e4f20bef1d), + CONST64(0x99c1032cb5c2ee5b), CONST64(0xcc0d6bee226688aa), CONST64(0x647b4981e532b356), CONST64(0x5e230cb0ee2f9f71), + CONST64(0xa399461dbedfc27c), CONST64(0xfa4538d12b7dac87), CONST64(0x217ce2a0819e3ebf), CONST64(0x6c90a67e1236485a), + CONST64(0x2d6cf4ae839836b5), CONST64(0x5ad8f5411b2d6c77), CONST64(0x2470622a0e123836), CONST64(0xca0560e923658caf), + CONST64(0x04fbf9f1f502f306), CONST64(0x8312ddc645cf094c), CONST64(0xc61576e7216384a5), CONST64(0x9e3e7150ce4f1fd1), + CONST64(0xab72a9e249db3970), CONST64(0xe87d09c42c74b09c), CONST64(0x2c9b8dd5f916c33a), CONST64(0x6e635488e637bf59), + CONST64(0x93d91e25b6c7e254), CONST64(0xf05d25d82878a088), CONST64(0x72b8816517395c4b), CONST64(0x2b64ffa9829b32b0), + CONST64(0x5cd0fe461a2e6872), CONST64(0x1d2cac968b80169d), CONST64(0x3ea3bcc0fe1fdf21), CONST64(0x1b24a7918a831298), + CONST64(0x3648533f091b242d), CONST64(0x8c064045c94603ca), CONST64(0x354cd8b2879426a1), CONST64(0xb94a98f74ed2256b), + CONST64(0x7c5b659de13ea342), CONST64(0xe46d1fca2e72b896), CONST64(0x62734286e431b753), CONST64(0x7a536e9ae03da747), + CONST64(0x400b2babeb208b60), CONST64(0x47f459d790ad7aea), CONST64(0xff49b85ba4f1aa0e), CONST64(0x44f0d25a1e227866), + CONST64(0x395ccebc85922eab), CONST64(0x5d27873d60a09dfd), CONST64(0x0000000000000000), CONST64(0xde355afb256f94b1), + CONST64(0x02f3f2f6f401f703), CONST64(0x1cdbd5edf10ee312), CONST64(0x5fd475cb94a16afe), CONST64(0x3a5845310b1d2c27), + CONST64(0x686b5f8fe734bb5c), CONST64(0x238f1056759fc9bc), CONST64(0x582b07b7ef2c9b74), CONST64(0xb8bde18c345cd0e4), + CONST64(0xa695c6973153c4f5), CONST64(0xc2ee8f16d46177a3), CONST64(0xdacea30ad06d67b7), CONST64(0x3344d3b5869722a4), + CONST64(0x19d755677e82e59b), CONST64(0xc901eb64adea8e23), CONST64(0x34bba1c9fd1ad32e), CONST64(0xf6552edf297ba48d), + CONST64(0xa09dcd903050c0f0), CONST64(0x9ac588a13b4decd7), CONST64(0x658c30fa9fbc46d9), CONST64(0x2a9386d2f815c73f), + CONST64(0xae7e2968c6573ff9), CONST64(0x6a98ad7913354c5f), CONST64(0x14303a12060a181e), CONST64(0x1e28271b050f1411), + CONST64(0xa4663461c55233f6), CONST64(0x6688bb7711334455), CONST64(0x2f9f06587799c1b6), CONST64(0x15c743697c84ed91), + CONST64(0x01f7797b7a8ef58f), CONST64(0x0de76f757888fd85), CONST64(0xb4adf782365ad8ee), CONST64(0x48e0c4541c24706c), + CONST64(0x96d59eaf394be4dd), CONST64(0xcbf2199259eb7920), CONST64(0x50c0e84818286078), CONST64(0xe98a70bf56fa4513), + CONST64(0x8df1393eb3c8f645), CONST64(0x87e92437b0cdfa4a), CONST64(0xd83d51fc246c90b4), CONST64(0xc01d7de0206080a0), + CONST64(0x8bf93239b2cbf240), CONST64(0x4be44fd992ab72e0), CONST64(0xed71894ea3f8b615), CONST64(0xba4e137ac05d27e7), + CONST64(0x851ad6c144cc0d49), CONST64(0x5137913362a695f7), CONST64(0x6080b07010304050), CONST64(0x9fc9082bb4c1ea5e), + CONST64(0x3f54c5bb84912aae), CONST64(0x9722e7d443c51152), CONST64(0x4dec44de93a876e5), CONST64(0xb65e0574c25b2fed), + CONST64(0xa16ab4eb4ade357f), CONST64(0xa9815b14bddace73), CONST64(0x050c808a8f8c0689), CONST64(0xee7502c32d77b499), + CONST64(0xaf895013bcd9ca76), CONST64(0x6f942df39cb94ad6), CONST64(0x6177c90b6abeb5df), CONST64(0x9d3afadd40c01d5d), + CONST64(0x98367a57cf4c1bd4), CONST64(0xeb798249a2fbb210), CONST64(0x2774e9a7809d3aba), CONST64(0xbf4293f04fd1216e), + CONST64(0x42f8d95d1f217c63), CONST64(0x861e5d4cca430fc5), CONST64(0xdb39da71aae39238), CONST64(0x912aecd342c61557), +}; + +static const ulong64 T5[256] = { + CONST64(0xb9bb016ad3ba68d2), CONST64(0x9ae5b166fc54194d), CONST64(0x65e2cd14712f93bc), CONST64(0x8725511b9c74b9cd), + CONST64(0xa2f7a457f5530251), CONST64(0xd6d003be68d3b86b), CONST64(0xded604b56bd2bd6f), CONST64(0x52b3fe85d74d6429), + CONST64(0xbafdad4af0500d5d), CONST64(0x09cf63e0e9ac268a), CONST64(0x1c0984968a8d830e), CONST64(0x91a51a4ddcbf79c6), + CONST64(0xa73d4d379070addd), CONST64(0xaaf1a35cf6520755), CONST64(0xa47be117b39ac852), CONST64(0x5ab5f98ed44c612d), + CONST64(0x0346ac2023ea658f), CONST64(0xe6c4118462d5a673), CONST64(0xcc55c268a497f166), CONST64(0xc6dc0da86ed1b263), + CONST64(0x85aa99d05533ffcc), CONST64(0xb2fbaa41f3510859), CONST64(0xe2c79c0fed5b2a71), CONST64(0x59f355aef7a604a2), + CONST64(0xbefe20c17fde815f), CONST64(0x7aade5a2d848753d), CONST64(0x29d77fcce5a8329a), CONST64(0xbc71e80ab699c75e), + CONST64(0x96e03be670db904b), CONST64(0x8dac9edb5632fac8), CONST64(0xd1952215c4b751e6), CONST64(0xb332ceaa19fc2bd7), + CONST64(0x4b70937338e348ab), CONST64(0x8463fd3bbf9edc42), CONST64(0xfc41d052ae91ef7e), CONST64(0xac7de61cb09bcd56), + CONST64(0x437694783be24daf), CONST64(0xb1bd0661d0bb6dd6), CONST64(0x329bdaf1c3415819), CONST64(0x577917e5b26ecba5), + CONST64(0x41f95cb3f2a50bae), CONST64(0x16804b5640cbc00b), CONST64(0x7f670cc2bd6bdab1), CONST64(0xdc59cc7ea295fb6e), + CONST64(0x61e1409ffea11fbe), CONST64(0xcb10e3c308f318eb), CONST64(0xe181302fceb14ffe), CONST64(0x100c0e1606020a08), + CONST64(0x2e925e6749ccdb17), CONST64(0x6ea2663f51c4f337), CONST64(0xe84e53cf271d6974), CONST64(0xa0786c9c3c144450), + CONST64(0x56b0730e58c3e82b), CONST64(0x3f57349aa563f291), CONST64(0x9ee63ced73da954f), CONST64(0xd2d38e35e75d3469), + CONST64(0xc2df8023e15f3e61), CONST64(0xaef22ed779dc8b57), CONST64(0xcf136e48877d94e9), CONST64(0x2694596c4acdde13), + CONST64(0xdf1f605e817f9ee1), CONST64(0xeac19b04ee5a2f75), CONST64(0x477519f3b46cc1ad), CONST64(0xdad5893ee45c316d), + CONST64(0xeb08ffef04f70cfb), CONST64(0x2dd4f2476a26be98), CONST64(0xab38c7b71cff24db), CONST64(0x3b54b9112aed7e93), + CONST64(0x134aa23625e86f87), CONST64(0x9c69f426ba9dd34e), CONST64(0x5f7f10eeb16fcea1), CONST64(0x04038d8b8f8e8c02), + CONST64(0xc8564fe32b197d64), CONST64(0x69e74794fda01aba), CONST64(0xd31aeade0df017e7), CONST64(0x3c1198ba8689971e), + CONST64(0x78222d69110f333c), CONST64(0x3812153109071b1c), CONST64(0x11c56afdecaf2986), CONST64(0x8b20db9b10fb30cb), + CONST64(0x4030385818082820), CONST64(0xa87e6b973f154154), CONST64(0x682e237f170d3934), CONST64(0x20181c2c0c041410), + CONST64(0x0806070b03010504), CONST64(0x074521abac64e98d), CONST64(0xb6f827ca7cdf845b), CONST64(0x97295f0d9a76b3c5), + CONST64(0xef0b72648b7980f9), CONST64(0xa6f429dc7add8e53), CONST64(0xf58eb3b2473dc9f4), CONST64(0xb074628a3a164e58), + CONST64(0xe582bda4413fc3fc), CONST64(0xa5b285fc5937ebdc), CONST64(0x4f731ef8b76dc4a9), CONST64(0xdd90a8954838d8e0), + CONST64(0xa1b10877d6b967de), CONST64(0xbf37442a9573a2d1), CONST64(0x1b4ca53d26e96a83), CONST64(0xb5be8bea5f35e1d4), + CONST64(0x92e3b66dff551c49), CONST64(0xaf3b4a3c9371a8d9), CONST64(0xff077c728d7b8af1), CONST64(0x140f839d898c860a), + CONST64(0xb73143219672a7d5), CONST64(0x34179fb18588921a), CONST64(0xe30ef8e407f609ff), CONST64(0x4dfcd6337e2a82a8), + CONST64(0xed84baaf423ec6f8), CONST64(0xcad98728e25e3b65), CONST64(0x25d2f54c6927bb9c), CONST64(0x0a89cfc0ca464305), + CONST64(0x60282474140c3c30), CONST64(0x0f4326a0af65ec89), CONST64(0x676d05dfb868d5bd), CONST64(0x2f5b3a8ca361f899), + CONST64(0x180a091d05030f0c), CONST64(0x46bc7d185ec1e223), CONST64(0x82efb87bf9571641), CONST64(0xfece189967d6a97f), + CONST64(0x86ec35f076d99a43), CONST64(0xfacd9512e858257d), CONST64(0x8eea32fb75d89f47), CONST64(0x17492fbdaa66e385), + CONST64(0xf6c81f9264d7ac7b), CONST64(0xcd9ca6834e3ad2e8), CONST64(0x0e8a424b45c8cf07), CONST64(0xfd88b4b9443cccf0), + CONST64(0x8326dc9013fa35cf), CONST64(0xc453c563a796f462), CONST64(0x51f552a5f4a701a6), CONST64(0xb477ef01b598c25a), + CONST64(0x3352be1a29ec7b97), CONST64(0xa9b70f7cd5b862da), CONST64(0x76a86f2254c7fc3b), CONST64(0x19c36df6efae2c82), + CONST64(0x6f6b02d4bb69d0b9), CONST64(0x62a7ecbfdd4b7a31), CONST64(0x31dd76d1e0ab3d96), CONST64(0x21d178c7e6a9379e), + CONST64(0x1f4f28b6a967e681), CONST64(0x503c364e1e0a2228), CONST64(0x028fc8cbc9474601), CONST64(0xc316e4c80bf21def), + CONST64(0xc1992c03c2b55bee), CONST64(0x0dccee6b6622aa88), CONST64(0x7b64814932e556b3), CONST64(0x235eb00c2fee719f), + CONST64(0x99a31d46dfbe7cc2), CONST64(0x45fad1387d2b87ac), CONST64(0x7c21a0e29e81bf3e), CONST64(0x906c7ea636125a48), + CONST64(0x6c2daef49883b536), CONST64(0xd85a41f52d1b776c), CONST64(0x70242a62120e3638), CONST64(0x05cae9606523af8c), + CONST64(0xfb04f1f902f506f3), CONST64(0x1283c6ddcf454c09), CONST64(0x15c6e7766321a584), CONST64(0x3e9e50714fced11f), + CONST64(0x72abe2a9db497039), CONST64(0x7de8c409742c9cb0), CONST64(0x9b2cd58d16f93ac3), CONST64(0x636e885437e659bf), + CONST64(0xd993251ec7b654e2), CONST64(0x5df0d825782888a0), CONST64(0xb872658139174b5c), CONST64(0x642ba9ff9b82b032), + CONST64(0xd05c46fe2e1a7268), CONST64(0x2c1d96ac808b9d16), CONST64(0xa33ec0bc1ffe21df), CONST64(0x241b91a7838a9812), + CONST64(0x48363f531b092d24), CONST64(0x068c454046c9ca03), CONST64(0x4c35b2d89487a126), CONST64(0x4ab9f798d24e6b25), + CONST64(0x5b7c9d653ee142a3), CONST64(0x6de4ca1f722e96b8), CONST64(0x7362864231e453b7), CONST64(0x537a9a6e3de047a7), + CONST64(0x0b40ab2b20eb608b), CONST64(0xf447d759ad90ea7a), CONST64(0x49ff5bb8f1a40eaa), CONST64(0xf0445ad2221e6678), + CONST64(0x5c39bcce9285ab2e), CONST64(0x275d3d87a060fd9d), CONST64(0x0000000000000000), CONST64(0x35defb5a6f25b194), + CONST64(0xf302f6f201f403f7), CONST64(0xdb1cedd50ef112e3), CONST64(0xd45fcb75a194fe6a), CONST64(0x583a31451d0b272c), + CONST64(0x6b688f5f34e75cbb), CONST64(0x8f2356109f75bcc9), CONST64(0x2b58b7072cef749b), CONST64(0xbdb88ce15c34e4d0), + CONST64(0x95a697c65331f5c4), CONST64(0xeec2168f61d4a377), CONST64(0xceda0aa36dd0b767), CONST64(0x4433b5d39786a422), + CONST64(0xd7196755827e9be5), CONST64(0x01c964ebeaad238e), CONST64(0xbb34c9a11afd2ed3), CONST64(0x55f6df2e7b298da4), + CONST64(0x9da090cd5030f0c0), CONST64(0xc59aa1884d3bd7ec), CONST64(0x8c65fa30bc9fd946), CONST64(0x932ad28615f83fc7), + CONST64(0x7eae682957c6f93f), CONST64(0x986a79ad35135f4c), CONST64(0x3014123a0a061e18), CONST64(0x281e1b270f051114), + CONST64(0x66a4613452c5f633), CONST64(0x886677bb33115544), CONST64(0x9f2f58069977b6c1), CONST64(0xc7156943847c91ed), + CONST64(0xf7017b798e7a8ff5), CONST64(0xe70d756f887885fd), CONST64(0xadb482f75a36eed8), CONST64(0xe04854c4241c6c70), + CONST64(0xd596af9e4b39dde4), CONST64(0xf2cb9219eb592079), CONST64(0xc05048e828187860), CONST64(0x8ae9bf70fa561345), + CONST64(0xf18d3e39c8b345f6), CONST64(0xe9873724cdb04afa), CONST64(0x3dd8fc516c24b490), CONST64(0x1dc0e07d6020a080), + CONST64(0xf98b3932cbb240f2), CONST64(0xe44bd94fab92e072), CONST64(0x71ed4e89f8a315b6), CONST64(0x4eba7a135dc0e727), + CONST64(0x1a85c1d6cc44490d), CONST64(0x37513391a662f795), CONST64(0x806070b030105040), CONST64(0xc99f2b08c1b45eea), + CONST64(0x543fbbc59184ae2a), CONST64(0x2297d4e7c5435211), CONST64(0xec4dde44a893e576), CONST64(0x5eb674055bc2ed2f), + CONST64(0x6aa1ebb4de4a7f35), CONST64(0x81a9145bdabd73ce), CONST64(0x0c058a808c8f8906), CONST64(0x75eec302772d99b4), + CONST64(0x89af1350d9bc76ca), CONST64(0x946ff32db99cd64a), CONST64(0x77610bc9be6adfb5), CONST64(0x3a9dddfac0405d1d), + CONST64(0x3698577a4ccfd41b), CONST64(0x79eb4982fba210b2), CONST64(0x7427a7e99d80ba3a), CONST64(0x42bff093d14f6e21), + CONST64(0xf8425dd9211f637c), CONST64(0x1e864c5d43cac50f), CONST64(0x39db71dae3aa3892), CONST64(0x2a91d3ecc6425715), +}; + +static const ulong64 T6[256] = { + CONST64(0x6a01bbb9d268bad3), CONST64(0x66b1e59a4d1954fc), CONST64(0x14cde265bc932f71), CONST64(0x1b512587cdb9749c), + CONST64(0x57a4f7a2510253f5), CONST64(0xbe03d0d66bb8d368), CONST64(0xb504d6de6fbdd26b), CONST64(0x85feb35229644dd7), + CONST64(0x4aadfdba5d0d50f0), CONST64(0xe063cf098a26ace9), CONST64(0x9684091c0e838d8a), CONST64(0x4d1aa591c679bfdc), + CONST64(0x374d3da7ddad7090), CONST64(0x5ca3f1aa550752f6), CONST64(0x17e17ba452c89ab3), CONST64(0x8ef9b55a2d614cd4), + CONST64(0x20ac46038f65ea23), CONST64(0x8411c4e673a6d562), CONST64(0x68c255cc66f197a4), CONST64(0xa80ddcc663b2d16e), + CONST64(0xd099aa85ccff3355), CONST64(0x41aafbb2590851f3), CONST64(0x0f9cc7e2712a5bed), CONST64(0xae55f359a204a6f7), + CONST64(0xc120febe5f81de7f), CONST64(0xa2e5ad7a3d7548d8), CONST64(0xcc7fd7299a32a8e5), CONST64(0x0ae871bc5ec799b6), + CONST64(0xe63be0964b90db70), CONST64(0xdb9eac8dc8fa3256), CONST64(0x152295d1e651b7c4), CONST64(0xaace32b3d72bfc19), + CONST64(0x7393704bab48e338), CONST64(0x3bfd638442dc9ebf), CONST64(0x52d041fc7eef91ae), CONST64(0x1ce67dac56cd9bb0), + CONST64(0x78947643af4de23b), CONST64(0x6106bdb1d66dbbd0), CONST64(0xf1da9b32195841c3), CONST64(0xe5177957a5cb6eb2), + CONST64(0xb35cf941ae0ba5f2), CONST64(0x564b80160bc0cb40), CONST64(0xc20c677fb1da6bbd), CONST64(0x7ecc59dc6efb95a2), + CONST64(0x9f40e161be1fa1fe), CONST64(0xc3e310cbeb18f308), CONST64(0x2f3081e1fe4fb1ce), CONST64(0x160e0c10080a0206), + CONST64(0x675e922e17dbcc49), CONST64(0x3f66a26e37f3c451), CONST64(0xcf534ee874691d27), CONST64(0x9c6c78a05044143c), + CONST64(0x0e73b0562be8c358), CONST64(0x9a34573f91f263a5), CONST64(0xed3ce69e4f95da73), CONST64(0x358ed3d269345de7), + CONST64(0x2380dfc2613e5fe1), CONST64(0xd72ef2ae578bdc79), CONST64(0x486e13cfe9947d87), CONST64(0x6c59942613decd4a), + CONST64(0x5e601fdfe19e7f81), CONST64(0x049bc1ea752f5aee), CONST64(0xf3197547adc16cb4), CONST64(0x3e89d5da6d315ce4), + CONST64(0xefff08ebfb0cf704), CONST64(0x47f2d42d98be266a), CONST64(0xb7c738abdb24ff1c), CONST64(0x11b9543b937eed2a), + CONST64(0x36a24a13876fe825), CONST64(0x26f4699c4ed39dba), CONST64(0xee107f5fa1ce6fb1), CONST64(0x8b8d0304028c8e8f), + CONST64(0xe34f56c8647d192b), CONST64(0x9447e769ba1aa0fd), CONST64(0xdeea1ad3e717f00d), CONST64(0xba98113c1e978986), + CONST64(0x692d22783c330f11), CONST64(0x311512381c1b0709), CONST64(0xfd6ac5118629afec), CONST64(0x9bdb208bcb30fb10), + CONST64(0x5838304020280818), CONST64(0x976b7ea85441153f), CONST64(0x7f232e6834390d17), CONST64(0x2c1c18201014040c), + CONST64(0x0b07060804050103), CONST64(0xab2145078de964ac), CONST64(0xca27f8b65b84df7c), CONST64(0x0d5f2997c5b3769a), + CONST64(0x64720beff980798b), CONST64(0xdc29f4a6538edd7a), CONST64(0xb2b38ef5f4c93d47), CONST64(0x8a6274b0584e163a), + CONST64(0xa4bd82e5fcc33f41), CONST64(0xfc85b2a5dceb3759), CONST64(0xf81e734fa9c46db7), CONST64(0x95a890dde0d83848), + CONST64(0x7708b1a1de67b9d6), CONST64(0x2a4437bfd1a27395), CONST64(0x3da54c1b836ae926), CONST64(0xea8bbeb5d4e1355f), + CONST64(0x6db6e392491c55ff), CONST64(0x3c4a3bafd9a87193), CONST64(0x727c07fff18a7b8d), CONST64(0x9d830f140a868c89), + CONST64(0x214331b7d5a77296), CONST64(0xb19f17341a928885), CONST64(0xe4f80ee3ff09f607), CONST64(0x33d6fc4da8822a7e), + CONST64(0xafba84edf8c63e42), CONST64(0x2887d9ca653b5ee2), CONST64(0x4cf5d2259cbb2769), CONST64(0xc0cf890a054346ca), + CONST64(0x74242860303c0c14), CONST64(0xa026430f89ec65af), CONST64(0xdf056d67bdd568b8), CONST64(0x8c3a5b2f99f861a3), + CONST64(0x1d090a180c0f0305), CONST64(0x187dbc4623e2c15e), CONST64(0x7bb8ef82411657f9), CONST64(0x9918cefe7fa9d667), + CONST64(0xf035ec86439ad976), CONST64(0x1295cdfa7d2558e8), CONST64(0xfb32ea8e479fd875), CONST64(0xbd2f491785e366aa), + CONST64(0x921fc8f67bacd764), CONST64(0x83a69ccde8d23a4e), CONST64(0x4b428a0e07cfc845), CONST64(0xb9b488fdf0cc3c44), + CONST64(0x90dc2683cf35fa13), CONST64(0x63c553c462f496a7), CONST64(0xa552f551a601a7f4), CONST64(0x01ef77b45ac298b5), + CONST64(0x1abe5233977bec29), CONST64(0x7c0fb7a9da62b8d5), CONST64(0x226fa8763bfcc754), CONST64(0xf66dc319822caeef), + CONST64(0xd4026b6fb9d069bb), CONST64(0xbfeca762317a4bdd), CONST64(0xd176dd31963dabe0), CONST64(0xc778d1219e37a9e6), + CONST64(0xb6284f1f81e667a9), CONST64(0x4e363c5028220a1e), CONST64(0xcbc88f02014647c9), CONST64(0xc8e416c3ef1df20b), + CONST64(0x032c99c1ee5bb5c2), CONST64(0x6beecc0d88aa2266), CONST64(0x4981647bb356e532), CONST64(0x0cb05e239f71ee2f), + CONST64(0x461da399c27cbedf), CONST64(0x38d1fa45ac872b7d), CONST64(0xe2a0217c3ebf819e), CONST64(0xa67e6c90485a1236), + CONST64(0xf4ae2d6c36b58398), CONST64(0xf5415ad86c771b2d), CONST64(0x622a247038360e12), CONST64(0x60e9ca058caf2365), + CONST64(0xf9f104fbf306f502), CONST64(0xddc68312094c45cf), CONST64(0x76e7c61584a52163), CONST64(0x71509e3e1fd1ce4f), + CONST64(0xa9e2ab72397049db), CONST64(0x09c4e87db09c2c74), CONST64(0x8dd52c9bc33af916), CONST64(0x54886e63bf59e637), + CONST64(0x1e2593d9e254b6c7), CONST64(0x25d8f05da0882878), CONST64(0x816572b85c4b1739), CONST64(0xffa92b6432b0829b), + CONST64(0xfe465cd068721a2e), CONST64(0xac961d2c169d8b80), CONST64(0xbcc03ea3df21fe1f), CONST64(0xa7911b2412988a83), + CONST64(0x533f3648242d091b), CONST64(0x40458c0603cac946), CONST64(0xd8b2354c26a18794), CONST64(0x98f7b94a256b4ed2), + CONST64(0x659d7c5ba342e13e), CONST64(0x1fcae46db8962e72), CONST64(0x42866273b753e431), CONST64(0x6e9a7a53a747e03d), + CONST64(0x2bab400b8b60eb20), CONST64(0x59d747f47aea90ad), CONST64(0xb85bff49aa0ea4f1), CONST64(0xd25a44f078661e22), + CONST64(0xcebc395c2eab8592), CONST64(0x873d5d279dfd60a0), CONST64(0x0000000000000000), CONST64(0x5afbde3594b1256f), + CONST64(0xf2f602f3f703f401), CONST64(0xd5ed1cdbe312f10e), CONST64(0x75cb5fd46afe94a1), CONST64(0x45313a582c270b1d), + CONST64(0x5f8f686bbb5ce734), CONST64(0x1056238fc9bc759f), CONST64(0x07b7582b9b74ef2c), CONST64(0xe18cb8bdd0e4345c), + CONST64(0xc697a695c4f53153), CONST64(0x8f16c2ee77a3d461), CONST64(0xa30adace67b7d06d), CONST64(0xd3b5334422a48697), + CONST64(0x556719d7e59b7e82), CONST64(0xeb64c9018e23adea), CONST64(0xa1c934bbd32efd1a), CONST64(0x2edff655a48d297b), + CONST64(0xcd90a09dc0f03050), CONST64(0x88a19ac5ecd73b4d), CONST64(0x30fa658c46d99fbc), CONST64(0x86d22a93c73ff815), + CONST64(0x2968ae7e3ff9c657), CONST64(0xad796a984c5f1335), CONST64(0x3a121430181e060a), CONST64(0x271b1e281411050f), + CONST64(0x3461a46633f6c552), CONST64(0xbb77668844551133), CONST64(0x06582f9fc1b67799), CONST64(0x436915c7ed917c84), + CONST64(0x797b01f7f58f7a8e), CONST64(0x6f750de7fd857888), CONST64(0xf782b4add8ee365a), CONST64(0xc45448e0706c1c24), + CONST64(0x9eaf96d5e4dd394b), CONST64(0x1992cbf2792059eb), CONST64(0xe84850c060781828), CONST64(0x70bfe98a451356fa), + CONST64(0x393e8df1f645b3c8), CONST64(0x243787e9fa4ab0cd), CONST64(0x51fcd83d90b4246c), CONST64(0x7de0c01d80a02060), + CONST64(0x32398bf9f240b2cb), CONST64(0x4fd94be472e092ab), CONST64(0x894eed71b615a3f8), CONST64(0x137aba4e27e7c05d), + CONST64(0xd6c1851a0d4944cc), CONST64(0x9133513795f762a6), CONST64(0xb070608040501030), CONST64(0x082b9fc9ea5eb4c1), + CONST64(0xc5bb3f542aae8491), CONST64(0xe7d49722115243c5), CONST64(0x44de4dec76e593a8), CONST64(0x0574b65e2fedc25b), + CONST64(0xb4eba16a357f4ade), CONST64(0x5b14a981ce73bdda), CONST64(0x808a050c06898f8c), CONST64(0x02c3ee75b4992d77), + CONST64(0x5013af89ca76bcd9), CONST64(0x2df36f944ad69cb9), CONST64(0xc90b6177b5df6abe), CONST64(0xfadd9d3a1d5d40c0), + CONST64(0x7a5798361bd4cf4c), CONST64(0x8249eb79b210a2fb), CONST64(0xe9a727743aba809d), CONST64(0x93f0bf42216e4fd1), + CONST64(0xd95d42f87c631f21), CONST64(0x5d4c861e0fc5ca43), CONST64(0xda71db399238aae3), CONST64(0xecd3912a155742c6), +}; + +static const ulong64 T7[256] = { + CONST64(0x016ab9bb68d2d3ba), CONST64(0xb1669ae5194dfc54), CONST64(0xcd1465e293bc712f), CONST64(0x511b8725b9cd9c74), + CONST64(0xa457a2f70251f553), CONST64(0x03bed6d0b86b68d3), CONST64(0x04b5ded6bd6f6bd2), CONST64(0xfe8552b36429d74d), + CONST64(0xad4abafd0d5df050), CONST64(0x63e009cf268ae9ac), CONST64(0x84961c09830e8a8d), CONST64(0x1a4d91a579c6dcbf), + CONST64(0x4d37a73daddd9070), CONST64(0xa35caaf10755f652), CONST64(0xe117a47bc852b39a), CONST64(0xf98e5ab5612dd44c), + CONST64(0xac200346658f23ea), CONST64(0x1184e6c4a67362d5), CONST64(0xc268cc55f166a497), CONST64(0x0da8c6dcb2636ed1), + CONST64(0x99d085aaffcc5533), CONST64(0xaa41b2fb0859f351), CONST64(0x9c0fe2c72a71ed5b), CONST64(0x55ae59f304a2f7a6), + CONST64(0x20c1befe815f7fde), CONST64(0xe5a27aad753dd848), CONST64(0x7fcc29d7329ae5a8), CONST64(0xe80abc71c75eb699), + CONST64(0x3be696e0904b70db), CONST64(0x9edb8dacfac85632), CONST64(0x2215d19551e6c4b7), CONST64(0xceaab3322bd719fc), + CONST64(0x93734b7048ab38e3), CONST64(0xfd3b8463dc42bf9e), CONST64(0xd052fc41ef7eae91), CONST64(0xe61cac7dcd56b09b), + CONST64(0x947843764daf3be2), CONST64(0x0661b1bd6dd6d0bb), CONST64(0xdaf1329b5819c341), CONST64(0x17e55779cba5b26e), + CONST64(0x5cb341f90baef2a5), CONST64(0x4b561680c00b40cb), CONST64(0x0cc27f67dab1bd6b), CONST64(0xcc7edc59fb6ea295), + CONST64(0x409f61e11fbefea1), CONST64(0xe3c3cb1018eb08f3), CONST64(0x302fe1814ffeceb1), CONST64(0x0e16100c0a080602), + CONST64(0x5e672e92db1749cc), CONST64(0x663f6ea2f33751c4), CONST64(0x53cfe84e6974271d), CONST64(0x6c9ca07844503c14), + CONST64(0x730e56b0e82b58c3), CONST64(0x349a3f57f291a563), CONST64(0x3ced9ee6954f73da), CONST64(0x8e35d2d33469e75d), + CONST64(0x8023c2df3e61e15f), CONST64(0x2ed7aef28b5779dc), CONST64(0x6e48cf1394e9877d), CONST64(0x596c2694de134acd), + CONST64(0x605edf1f9ee1817f), CONST64(0x9b04eac12f75ee5a), CONST64(0x19f34775c1adb46c), CONST64(0x893edad5316de45c), + CONST64(0xffefeb080cfb04f7), CONST64(0xf2472dd4be986a26), CONST64(0xc7b7ab3824db1cff), CONST64(0xb9113b547e932aed), + CONST64(0xa236134a6f8725e8), CONST64(0xf4269c69d34eba9d), CONST64(0x10ee5f7fcea1b16f), CONST64(0x8d8b04038c028f8e), + CONST64(0x4fe3c8567d642b19), CONST64(0x479469e71abafda0), CONST64(0xeaded31a17e70df0), CONST64(0x98ba3c11971e8689), + CONST64(0x2d697822333c110f), CONST64(0x153138121b1c0907), CONST64(0x6afd11c52986ecaf), CONST64(0xdb9b8b2030cb10fb), + CONST64(0x3858403028201808), CONST64(0x6b97a87e41543f15), CONST64(0x237f682e3934170d), CONST64(0x1c2c201814100c04), + CONST64(0x070b080605040301), CONST64(0x21ab0745e98dac64), CONST64(0x27cab6f8845b7cdf), CONST64(0x5f0d9729b3c59a76), + CONST64(0x7264ef0b80f98b79), CONST64(0x29dca6f48e537add), CONST64(0xb3b2f58ec9f4473d), CONST64(0x628ab0744e583a16), + CONST64(0xbda4e582c3fc413f), CONST64(0x85fca5b2ebdc5937), CONST64(0x1ef84f73c4a9b76d), CONST64(0xa895dd90d8e04838), + CONST64(0x0877a1b167ded6b9), CONST64(0x442abf37a2d19573), CONST64(0xa53d1b4c6a8326e9), CONST64(0x8beab5bee1d45f35), + CONST64(0xb66d92e31c49ff55), CONST64(0x4a3caf3ba8d99371), CONST64(0x7c72ff078af18d7b), CONST64(0x839d140f860a898c), + CONST64(0x4321b731a7d59672), CONST64(0x9fb13417921a8588), CONST64(0xf8e4e30e09ff07f6), CONST64(0xd6334dfc82a87e2a), + CONST64(0xbaafed84c6f8423e), CONST64(0x8728cad93b65e25e), CONST64(0xf54c25d2bb9c6927), CONST64(0xcfc00a894305ca46), + CONST64(0x247460283c30140c), CONST64(0x26a00f43ec89af65), CONST64(0x05df676dd5bdb868), CONST64(0x3a8c2f5bf899a361), + CONST64(0x091d180a0f0c0503), CONST64(0x7d1846bce2235ec1), CONST64(0xb87b82ef1641f957), CONST64(0x1899fecea97f67d6), + CONST64(0x35f086ec9a4376d9), CONST64(0x9512facd257de858), CONST64(0x32fb8eea9f4775d8), CONST64(0x2fbd1749e385aa66), + CONST64(0x1f92f6c8ac7b64d7), CONST64(0xa683cd9cd2e84e3a), CONST64(0x424b0e8acf0745c8), CONST64(0xb4b9fd88ccf0443c), + CONST64(0xdc90832635cf13fa), CONST64(0xc563c453f462a796), CONST64(0x52a551f501a6f4a7), CONST64(0xef01b477c25ab598), + CONST64(0xbe1a33527b9729ec), CONST64(0x0f7ca9b762dad5b8), CONST64(0x6f2276a8fc3b54c7), CONST64(0x6df619c32c82efae), + CONST64(0x02d46f6bd0b9bb69), CONST64(0xecbf62a77a31dd4b), CONST64(0x76d131dd3d96e0ab), CONST64(0x78c721d1379ee6a9), + CONST64(0x28b61f4fe681a967), CONST64(0x364e503c22281e0a), CONST64(0xc8cb028f4601c947), CONST64(0xe4c8c3161def0bf2), + CONST64(0x2c03c1995beec2b5), CONST64(0xee6b0dccaa886622), CONST64(0x81497b6456b332e5), CONST64(0xb00c235e719f2fee), + CONST64(0x1d4699a37cc2dfbe), CONST64(0xd13845fa87ac7d2b), CONST64(0xa0e27c21bf3e9e81), CONST64(0x7ea6906c5a483612), + CONST64(0xaef46c2db5369883), CONST64(0x41f5d85a776c2d1b), CONST64(0x2a6270243638120e), CONST64(0xe96005caaf8c6523), + CONST64(0xf1f9fb0406f302f5), CONST64(0xc6dd12834c09cf45), CONST64(0xe77615c6a5846321), CONST64(0x50713e9ed11f4fce), + CONST64(0xe2a972ab7039db49), CONST64(0xc4097de89cb0742c), CONST64(0xd58d9b2c3ac316f9), CONST64(0x8854636e59bf37e6), + CONST64(0x251ed99354e2c7b6), CONST64(0xd8255df088a07828), CONST64(0x6581b8724b5c3917), CONST64(0xa9ff642bb0329b82), + CONST64(0x46fed05c72682e1a), CONST64(0x96ac2c1d9d16808b), CONST64(0xc0bca33e21df1ffe), CONST64(0x91a7241b9812838a), + CONST64(0x3f5348362d241b09), CONST64(0x4540068cca0346c9), CONST64(0xb2d84c35a1269487), CONST64(0xf7984ab96b25d24e), + CONST64(0x9d655b7c42a33ee1), CONST64(0xca1f6de496b8722e), CONST64(0x8642736253b731e4), CONST64(0x9a6e537a47a73de0), + CONST64(0xab2b0b40608b20eb), CONST64(0xd759f447ea7aad90), CONST64(0x5bb849ff0eaaf1a4), CONST64(0x5ad2f0446678221e), + CONST64(0xbcce5c39ab2e9285), CONST64(0x3d87275dfd9da060), CONST64(0x0000000000000000), CONST64(0xfb5a35deb1946f25), + CONST64(0xf6f2f30203f701f4), CONST64(0xedd5db1c12e30ef1), CONST64(0xcb75d45ffe6aa194), CONST64(0x3145583a272c1d0b), + CONST64(0x8f5f6b685cbb34e7), CONST64(0x56108f23bcc99f75), CONST64(0xb7072b58749b2cef), CONST64(0x8ce1bdb8e4d05c34), + CONST64(0x97c695a6f5c45331), CONST64(0x168feec2a37761d4), CONST64(0x0aa3cedab7676dd0), CONST64(0xb5d34433a4229786), + CONST64(0x6755d7199be5827e), CONST64(0x64eb01c9238eeaad), CONST64(0xc9a1bb342ed31afd), CONST64(0xdf2e55f68da47b29), + CONST64(0x90cd9da0f0c05030), CONST64(0xa188c59ad7ec4d3b), CONST64(0xfa308c65d946bc9f), CONST64(0xd286932a3fc715f8), + CONST64(0x68297eaef93f57c6), CONST64(0x79ad986a5f4c3513), CONST64(0x123a30141e180a06), CONST64(0x1b27281e11140f05), + CONST64(0x613466a4f63352c5), CONST64(0x77bb886655443311), CONST64(0x58069f2fb6c19977), CONST64(0x6943c71591ed847c), + CONST64(0x7b79f7018ff58e7a), CONST64(0x756fe70d85fd8878), CONST64(0x82f7adb4eed85a36), CONST64(0x54c4e0486c70241c), + CONST64(0xaf9ed596dde44b39), CONST64(0x9219f2cb2079eb59), CONST64(0x48e8c05078602818), CONST64(0xbf708ae91345fa56), + CONST64(0x3e39f18d45f6c8b3), CONST64(0x3724e9874afacdb0), CONST64(0xfc513dd8b4906c24), CONST64(0xe07d1dc0a0806020), + CONST64(0x3932f98b40f2cbb2), CONST64(0xd94fe44be072ab92), CONST64(0x4e8971ed15b6f8a3), CONST64(0x7a134ebae7275dc0), + CONST64(0xc1d61a85490dcc44), CONST64(0x33913751f795a662), CONST64(0x70b0806050403010), CONST64(0x2b08c99f5eeac1b4), + CONST64(0xbbc5543fae2a9184), CONST64(0xd4e722975211c543), CONST64(0xde44ec4de576a893), CONST64(0x74055eb6ed2f5bc2), + CONST64(0xebb46aa17f35de4a), CONST64(0x145b81a973cedabd), CONST64(0x8a800c0589068c8f), CONST64(0xc30275ee99b4772d), + CONST64(0x135089af76cad9bc), CONST64(0xf32d946fd64ab99c), CONST64(0x0bc97761dfb5be6a), CONST64(0xddfa3a9d5d1dc040), + CONST64(0x577a3698d41b4ccf), CONST64(0x498279eb10b2fba2), CONST64(0xa7e97427ba3a9d80), CONST64(0xf09342bf6e21d14f), + CONST64(0x5dd9f842637c211f), CONST64(0x4c5d1e86c50f43ca), CONST64(0x71da39db3892e3aa), CONST64(0xd3ec2a915715c642), +}; + +static const ulong64 c[R + 1] = { + CONST64(0xba542f7453d3d24d), + CONST64(0x50ac8dbf70529a4c), + CONST64(0xead597d133515ba6), + CONST64(0xde48a899db32b7fc), + CONST64(0xe39e919be2bb416e), + CONST64(0xa5cb6b95a1f3b102), + CONST64(0xccc41d14c363da5d), + CONST64(0x5fdc7dcd7f5a6c5c), + CONST64(0xf726ffede89d6f8e), +}; + + /** + Initialize the Khazad block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +int khazad_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int r; + const ulong64 *S; + ulong64 K2, K1; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + if (keylen != 16) { + return CRYPT_INVALID_KEYSIZE; + } + if (num_rounds != 8 && num_rounds != 0) { + return CRYPT_INVALID_ROUNDS; + } + + /* use 7th table */ + S = T7; + + /* + * map unsigned char array cipher key to initial key state (mu): + */ + K2 = + ((ulong64)key[ 0] << 56) ^ + ((ulong64)key[ 1] << 48) ^ + ((ulong64)key[ 2] << 40) ^ + ((ulong64)key[ 3] << 32) ^ + ((ulong64)key[ 4] << 24) ^ + ((ulong64)key[ 5] << 16) ^ + ((ulong64)key[ 6] << 8) ^ + ((ulong64)key[ 7] ); + K1 = + ((ulong64)key[ 8] << 56) ^ + ((ulong64)key[ 9] << 48) ^ + ((ulong64)key[10] << 40) ^ + ((ulong64)key[11] << 32) ^ + ((ulong64)key[12] << 24) ^ + ((ulong64)key[13] << 16) ^ + ((ulong64)key[14] << 8) ^ + ((ulong64)key[15] ); + + /* + * compute the round keys: + */ + for (r = 0; r <= R; r++) { + /* + * K[r] = rho(c[r], K1) ^ K2; + */ + skey->khazad.roundKeyEnc[r] = + T0[(int)(K1 >> 56) ] ^ + T1[(int)(K1 >> 48) & 0xff] ^ + T2[(int)(K1 >> 40) & 0xff] ^ + T3[(int)(K1 >> 32) & 0xff] ^ + T4[(int)(K1 >> 24) & 0xff] ^ + T5[(int)(K1 >> 16) & 0xff] ^ + T6[(int)(K1 >> 8) & 0xff] ^ + T7[(int)(K1 ) & 0xff] ^ + c[r] ^ K2; + K2 = K1; K1 = skey->khazad.roundKeyEnc[r]; + } + /* + * compute the inverse key schedule: + * K'^0 = K^R, K'^R = K^0, K'^r = theta(K^{R-r}) + */ + skey->khazad.roundKeyDec[0] = skey->khazad.roundKeyEnc[R]; + for (r = 1; r < R; r++) { + K1 = skey->khazad.roundKeyEnc[R - r]; + skey->khazad.roundKeyDec[r] = + T0[(int)S[(int)(K1 >> 56) ] & 0xff] ^ + T1[(int)S[(int)(K1 >> 48) & 0xff] & 0xff] ^ + T2[(int)S[(int)(K1 >> 40) & 0xff] & 0xff] ^ + T3[(int)S[(int)(K1 >> 32) & 0xff] & 0xff] ^ + T4[(int)S[(int)(K1 >> 24) & 0xff] & 0xff] ^ + T5[(int)S[(int)(K1 >> 16) & 0xff] & 0xff] ^ + T6[(int)S[(int)(K1 >> 8) & 0xff] & 0xff] ^ + T7[(int)S[(int)(K1 ) & 0xff] & 0xff]; + } + skey->khazad.roundKeyDec[R] = skey->khazad.roundKeyEnc[0]; + + return CRYPT_OK; +} + +static void khazad_crypt(const unsigned char *plaintext, unsigned char *ciphertext, + const ulong64 *roundKey) { + int r; + ulong64 state; + /* + * map plaintext block to cipher state (mu) + * and add initial round key (sigma[K^0]): + */ + state = + ((ulong64)plaintext[0] << 56) ^ + ((ulong64)plaintext[1] << 48) ^ + ((ulong64)plaintext[2] << 40) ^ + ((ulong64)plaintext[3] << 32) ^ + ((ulong64)plaintext[4] << 24) ^ + ((ulong64)plaintext[5] << 16) ^ + ((ulong64)plaintext[6] << 8) ^ + ((ulong64)plaintext[7] ) ^ + roundKey[0]; + + /* + * R - 1 full rounds: + */ + for (r = 1; r < R; r++) { + state = + T0[(int)(state >> 56) ] ^ + T1[(int)(state >> 48) & 0xff] ^ + T2[(int)(state >> 40) & 0xff] ^ + T3[(int)(state >> 32) & 0xff] ^ + T4[(int)(state >> 24) & 0xff] ^ + T5[(int)(state >> 16) & 0xff] ^ + T6[(int)(state >> 8) & 0xff] ^ + T7[(int)(state ) & 0xff] ^ + roundKey[r]; + } + + /* + * last round: + */ + state = + (T0[(int)(state >> 56) ] & CONST64(0xff00000000000000)) ^ + (T1[(int)(state >> 48) & 0xff] & CONST64(0x00ff000000000000)) ^ + (T2[(int)(state >> 40) & 0xff] & CONST64(0x0000ff0000000000)) ^ + (T3[(int)(state >> 32) & 0xff] & CONST64(0x000000ff00000000)) ^ + (T4[(int)(state >> 24) & 0xff] & CONST64(0x00000000ff000000)) ^ + (T5[(int)(state >> 16) & 0xff] & CONST64(0x0000000000ff0000)) ^ + (T6[(int)(state >> 8) & 0xff] & CONST64(0x000000000000ff00)) ^ + (T7[(int)(state ) & 0xff] & CONST64(0x00000000000000ff)) ^ + roundKey[R]; + + /* + * map cipher state to ciphertext block (mu^{-1}): + */ + ciphertext[0] = (unsigned char)(state >> 56); + ciphertext[1] = (unsigned char)(state >> 48); + ciphertext[2] = (unsigned char)(state >> 40); + ciphertext[3] = (unsigned char)(state >> 32); + ciphertext[4] = (unsigned char)(state >> 24); + ciphertext[5] = (unsigned char)(state >> 16); + ciphertext[6] = (unsigned char)(state >> 8); + ciphertext[7] = (unsigned char)(state ); +} + +/** + Encrypts a block of text with Khazad + @param pt The input plaintext (8 bytes) + @param ct The output ciphertext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + khazad_crypt(pt, ct, skey->khazad.roundKeyEnc); + return CRYPT_OK; +} + +/** + Decrypts a block of text with Khazad + @param ct The input ciphertext (8 bytes) + @param pt The output plaintext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + khazad_crypt(ct, pt, skey->khazad.roundKeyDec); + return CRYPT_OK; +} + +/** + Performs a self-test of the Khazad block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int khazad_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct test { + unsigned char pt[8], ct[8], key[16]; + } tests[] = { +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x49, 0xA4, 0xCE, 0x32, 0xAC, 0x19, 0x0E, 0x3F }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}, { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x64, 0x5D, 0x77, 0x3E, 0x40, 0xAB, 0xDD, 0x53 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } +}, { + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x9E, 0x39, 0x98, 0x64, 0xF7, 0x8E, 0xCA, 0x02 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}, { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + { 0xA9, 0xDF, 0x3D, 0x2C, 0x64, 0xD3, 0xEA, 0x28 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +} +}; + int x, y; + unsigned char buf[2][8]; + symmetric_key skey; + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + khazad_setup(tests[x].key, 16, 0, &skey); + khazad_ecb_encrypt(tests[x].pt, buf[0], &skey); + khazad_ecb_decrypt(buf[0], buf[1], &skey); + if (XMEMCMP(buf[0], tests[x].ct, 8) || XMEMCMP(buf[1], tests[x].pt, 8)) { + return CRYPT_FAIL_TESTVECTOR; + } + + for (y = 0; y < 1000; y++) khazad_ecb_encrypt(buf[0], buf[0], &skey); + for (y = 0; y < 1000; y++) khazad_ecb_decrypt(buf[0], buf[0], &skey); + if (XMEMCMP(buf[0], tests[x].ct, 8)) { + return CRYPT_FAIL_TESTVECTOR; + } + + } + return CRYPT_OK; +#endif +} + +/** Terminate the context + @param skey The scheduled key +*/ +void khazad_done(symmetric_key *skey) +{ + LTC_UNUSED_PARAM(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. + @return CRYPT_OK if the input key size is acceptable. +*/ +int khazad_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if (*keysize >= 16) { + *keysize = 16; + return CRYPT_OK; + } else { + return CRYPT_INVALID_KEYSIZE; + } +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/ciphers/kseed.c b/src/ltc/ciphers/kseed.c new file mode 100644 index 0000000..85b4f8a --- /dev/null +++ b/src/ltc/ciphers/kseed.c @@ -0,0 +1,392 @@ +/* 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://libtom.org + */ + +/** + @file kseed.c + seed implementation of SEED derived from RFC4269 + Tom St Denis +*/ + +#include "tomcrypt.h" + +#ifdef LTC_KSEED + +const struct ltc_cipher_descriptor kseed_desc = { + "seed", + 20, + 16, 16, 16, 16, + &kseed_setup, + &kseed_ecb_encrypt, + &kseed_ecb_decrypt, + &kseed_test, + &kseed_done, + &kseed_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +static const ulong32 SS0[256] = { +0x2989A1A8UL,0x05858184UL,0x16C6D2D4UL,0x13C3D3D0UL,0x14445054UL,0x1D0D111CUL,0x2C8CA0ACUL,0x25052124UL, +0x1D4D515CUL,0x03434340UL,0x18081018UL,0x1E0E121CUL,0x11415150UL,0x3CCCF0FCUL,0x0ACAC2C8UL,0x23436360UL, +0x28082028UL,0x04444044UL,0x20002020UL,0x1D8D919CUL,0x20C0E0E0UL,0x22C2E2E0UL,0x08C8C0C8UL,0x17071314UL, +0x2585A1A4UL,0x0F8F838CUL,0x03030300UL,0x3B4B7378UL,0x3B8BB3B8UL,0x13031310UL,0x12C2D2D0UL,0x2ECEE2ECUL, +0x30407070UL,0x0C8C808CUL,0x3F0F333CUL,0x2888A0A8UL,0x32023230UL,0x1DCDD1DCUL,0x36C6F2F4UL,0x34447074UL, +0x2CCCE0ECUL,0x15859194UL,0x0B0B0308UL,0x17475354UL,0x1C4C505CUL,0x1B4B5358UL,0x3D8DB1BCUL,0x01010100UL, +0x24042024UL,0x1C0C101CUL,0x33437370UL,0x18889098UL,0x10001010UL,0x0CCCC0CCUL,0x32C2F2F0UL,0x19C9D1D8UL, +0x2C0C202CUL,0x27C7E3E4UL,0x32427270UL,0x03838380UL,0x1B8B9398UL,0x11C1D1D0UL,0x06868284UL,0x09C9C1C8UL, +0x20406060UL,0x10405050UL,0x2383A3A0UL,0x2BCBE3E8UL,0x0D0D010CUL,0x3686B2B4UL,0x1E8E929CUL,0x0F4F434CUL, +0x3787B3B4UL,0x1A4A5258UL,0x06C6C2C4UL,0x38487078UL,0x2686A2A4UL,0x12021210UL,0x2F8FA3ACUL,0x15C5D1D4UL, +0x21416160UL,0x03C3C3C0UL,0x3484B0B4UL,0x01414140UL,0x12425250UL,0x3D4D717CUL,0x0D8D818CUL,0x08080008UL, +0x1F0F131CUL,0x19899198UL,0x00000000UL,0x19091118UL,0x04040004UL,0x13435350UL,0x37C7F3F4UL,0x21C1E1E0UL, +0x3DCDF1FCUL,0x36467274UL,0x2F0F232CUL,0x27072324UL,0x3080B0B0UL,0x0B8B8388UL,0x0E0E020CUL,0x2B8BA3A8UL, +0x2282A2A0UL,0x2E4E626CUL,0x13839390UL,0x0D4D414CUL,0x29496168UL,0x3C4C707CUL,0x09090108UL,0x0A0A0208UL, +0x3F8FB3BCUL,0x2FCFE3ECUL,0x33C3F3F0UL,0x05C5C1C4UL,0x07878384UL,0x14041014UL,0x3ECEF2FCUL,0x24446064UL, +0x1ECED2DCUL,0x2E0E222CUL,0x0B4B4348UL,0x1A0A1218UL,0x06060204UL,0x21012120UL,0x2B4B6368UL,0x26466264UL, +0x02020200UL,0x35C5F1F4UL,0x12829290UL,0x0A8A8288UL,0x0C0C000CUL,0x3383B3B0UL,0x3E4E727CUL,0x10C0D0D0UL, +0x3A4A7278UL,0x07474344UL,0x16869294UL,0x25C5E1E4UL,0x26062224UL,0x00808080UL,0x2D8DA1ACUL,0x1FCFD3DCUL, +0x2181A1A0UL,0x30003030UL,0x37073334UL,0x2E8EA2ACUL,0x36063234UL,0x15051114UL,0x22022220UL,0x38083038UL, +0x34C4F0F4UL,0x2787A3A4UL,0x05454144UL,0x0C4C404CUL,0x01818180UL,0x29C9E1E8UL,0x04848084UL,0x17879394UL, +0x35053134UL,0x0BCBC3C8UL,0x0ECEC2CCUL,0x3C0C303CUL,0x31417170UL,0x11011110UL,0x07C7C3C4UL,0x09898188UL, +0x35457174UL,0x3BCBF3F8UL,0x1ACAD2D8UL,0x38C8F0F8UL,0x14849094UL,0x19495158UL,0x02828280UL,0x04C4C0C4UL, +0x3FCFF3FCUL,0x09494148UL,0x39093138UL,0x27476364UL,0x00C0C0C0UL,0x0FCFC3CCUL,0x17C7D3D4UL,0x3888B0B8UL, +0x0F0F030CUL,0x0E8E828CUL,0x02424240UL,0x23032320UL,0x11819190UL,0x2C4C606CUL,0x1BCBD3D8UL,0x2484A0A4UL, +0x34043034UL,0x31C1F1F0UL,0x08484048UL,0x02C2C2C0UL,0x2F4F636CUL,0x3D0D313CUL,0x2D0D212CUL,0x00404040UL, +0x3E8EB2BCUL,0x3E0E323CUL,0x3C8CB0BCUL,0x01C1C1C0UL,0x2A8AA2A8UL,0x3A8AB2B8UL,0x0E4E424CUL,0x15455154UL, +0x3B0B3338UL,0x1CCCD0DCUL,0x28486068UL,0x3F4F737CUL,0x1C8C909CUL,0x18C8D0D8UL,0x0A4A4248UL,0x16465254UL, +0x37477374UL,0x2080A0A0UL,0x2DCDE1ECUL,0x06464244UL,0x3585B1B4UL,0x2B0B2328UL,0x25456164UL,0x3ACAF2F8UL, +0x23C3E3E0UL,0x3989B1B8UL,0x3181B1B0UL,0x1F8F939CUL,0x1E4E525CUL,0x39C9F1F8UL,0x26C6E2E4UL,0x3282B2B0UL, +0x31013130UL,0x2ACAE2E8UL,0x2D4D616CUL,0x1F4F535CUL,0x24C4E0E4UL,0x30C0F0F0UL,0x0DCDC1CCUL,0x08888088UL, +0x16061214UL,0x3A0A3238UL,0x18485058UL,0x14C4D0D4UL,0x22426260UL,0x29092128UL,0x07070304UL,0x33033330UL, +0x28C8E0E8UL,0x1B0B1318UL,0x05050104UL,0x39497178UL,0x10809090UL,0x2A4A6268UL,0x2A0A2228UL,0x1A8A9298UL +}; + +static const ulong32 SS1[256] = { +0x38380830UL,0xE828C8E0UL,0x2C2D0D21UL,0xA42686A2UL,0xCC0FCFC3UL,0xDC1ECED2UL,0xB03383B3UL,0xB83888B0UL, +0xAC2F8FA3UL,0x60204060UL,0x54154551UL,0xC407C7C3UL,0x44044440UL,0x6C2F4F63UL,0x682B4B63UL,0x581B4B53UL, +0xC003C3C3UL,0x60224262UL,0x30330333UL,0xB43585B1UL,0x28290921UL,0xA02080A0UL,0xE022C2E2UL,0xA42787A3UL, +0xD013C3D3UL,0x90118191UL,0x10110111UL,0x04060602UL,0x1C1C0C10UL,0xBC3C8CB0UL,0x34360632UL,0x480B4B43UL, +0xEC2FCFE3UL,0x88088880UL,0x6C2C4C60UL,0xA82888A0UL,0x14170713UL,0xC404C4C0UL,0x14160612UL,0xF434C4F0UL, +0xC002C2C2UL,0x44054541UL,0xE021C1E1UL,0xD416C6D2UL,0x3C3F0F33UL,0x3C3D0D31UL,0x8C0E8E82UL,0x98188890UL, +0x28280820UL,0x4C0E4E42UL,0xF436C6F2UL,0x3C3E0E32UL,0xA42585A1UL,0xF839C9F1UL,0x0C0D0D01UL,0xDC1FCFD3UL, +0xD818C8D0UL,0x282B0B23UL,0x64264662UL,0x783A4A72UL,0x24270723UL,0x2C2F0F23UL,0xF031C1F1UL,0x70324272UL, +0x40024242UL,0xD414C4D0UL,0x40014141UL,0xC000C0C0UL,0x70334373UL,0x64274763UL,0xAC2C8CA0UL,0x880B8B83UL, +0xF437C7F3UL,0xAC2D8DA1UL,0x80008080UL,0x1C1F0F13UL,0xC80ACAC2UL,0x2C2C0C20UL,0xA82A8AA2UL,0x34340430UL, +0xD012C2D2UL,0x080B0B03UL,0xEC2ECEE2UL,0xE829C9E1UL,0x5C1D4D51UL,0x94148490UL,0x18180810UL,0xF838C8F0UL, +0x54174753UL,0xAC2E8EA2UL,0x08080800UL,0xC405C5C1UL,0x10130313UL,0xCC0DCDC1UL,0x84068682UL,0xB83989B1UL, +0xFC3FCFF3UL,0x7C3D4D71UL,0xC001C1C1UL,0x30310131UL,0xF435C5F1UL,0x880A8A82UL,0x682A4A62UL,0xB03181B1UL, +0xD011C1D1UL,0x20200020UL,0xD417C7D3UL,0x00020202UL,0x20220222UL,0x04040400UL,0x68284860UL,0x70314171UL, +0x04070703UL,0xD81BCBD3UL,0x9C1D8D91UL,0x98198991UL,0x60214161UL,0xBC3E8EB2UL,0xE426C6E2UL,0x58194951UL, +0xDC1DCDD1UL,0x50114151UL,0x90108090UL,0xDC1CCCD0UL,0x981A8A92UL,0xA02383A3UL,0xA82B8BA3UL,0xD010C0D0UL, +0x80018181UL,0x0C0F0F03UL,0x44074743UL,0x181A0A12UL,0xE023C3E3UL,0xEC2CCCE0UL,0x8C0D8D81UL,0xBC3F8FB3UL, +0x94168692UL,0x783B4B73UL,0x5C1C4C50UL,0xA02282A2UL,0xA02181A1UL,0x60234363UL,0x20230323UL,0x4C0D4D41UL, +0xC808C8C0UL,0x9C1E8E92UL,0x9C1C8C90UL,0x383A0A32UL,0x0C0C0C00UL,0x2C2E0E22UL,0xB83A8AB2UL,0x6C2E4E62UL, +0x9C1F8F93UL,0x581A4A52UL,0xF032C2F2UL,0x90128292UL,0xF033C3F3UL,0x48094941UL,0x78384870UL,0xCC0CCCC0UL, +0x14150511UL,0xF83BCBF3UL,0x70304070UL,0x74354571UL,0x7C3F4F73UL,0x34350531UL,0x10100010UL,0x00030303UL, +0x64244460UL,0x6C2D4D61UL,0xC406C6C2UL,0x74344470UL,0xD415C5D1UL,0xB43484B0UL,0xE82ACAE2UL,0x08090901UL, +0x74364672UL,0x18190911UL,0xFC3ECEF2UL,0x40004040UL,0x10120212UL,0xE020C0E0UL,0xBC3D8DB1UL,0x04050501UL, +0xF83ACAF2UL,0x00010101UL,0xF030C0F0UL,0x282A0A22UL,0x5C1E4E52UL,0xA82989A1UL,0x54164652UL,0x40034343UL, +0x84058581UL,0x14140410UL,0x88098981UL,0x981B8B93UL,0xB03080B0UL,0xE425C5E1UL,0x48084840UL,0x78394971UL, +0x94178793UL,0xFC3CCCF0UL,0x1C1E0E12UL,0x80028282UL,0x20210121UL,0x8C0C8C80UL,0x181B0B13UL,0x5C1F4F53UL, +0x74374773UL,0x54144450UL,0xB03282B2UL,0x1C1D0D11UL,0x24250521UL,0x4C0F4F43UL,0x00000000UL,0x44064642UL, +0xEC2DCDE1UL,0x58184850UL,0x50124252UL,0xE82BCBE3UL,0x7C3E4E72UL,0xD81ACAD2UL,0xC809C9C1UL,0xFC3DCDF1UL, +0x30300030UL,0x94158591UL,0x64254561UL,0x3C3C0C30UL,0xB43686B2UL,0xE424C4E0UL,0xB83B8BB3UL,0x7C3C4C70UL, +0x0C0E0E02UL,0x50104050UL,0x38390931UL,0x24260622UL,0x30320232UL,0x84048480UL,0x68294961UL,0x90138393UL, +0x34370733UL,0xE427C7E3UL,0x24240420UL,0xA42484A0UL,0xC80BCBC3UL,0x50134353UL,0x080A0A02UL,0x84078783UL, +0xD819C9D1UL,0x4C0C4C40UL,0x80038383UL,0x8C0F8F83UL,0xCC0ECEC2UL,0x383B0B33UL,0x480A4A42UL,0xB43787B3UL +}; + +static const ulong32 SS2[256] = { +0xA1A82989UL,0x81840585UL,0xD2D416C6UL,0xD3D013C3UL,0x50541444UL,0x111C1D0DUL,0xA0AC2C8CUL,0x21242505UL, +0x515C1D4DUL,0x43400343UL,0x10181808UL,0x121C1E0EUL,0x51501141UL,0xF0FC3CCCUL,0xC2C80ACAUL,0x63602343UL, +0x20282808UL,0x40440444UL,0x20202000UL,0x919C1D8DUL,0xE0E020C0UL,0xE2E022C2UL,0xC0C808C8UL,0x13141707UL, +0xA1A42585UL,0x838C0F8FUL,0x03000303UL,0x73783B4BUL,0xB3B83B8BUL,0x13101303UL,0xD2D012C2UL,0xE2EC2ECEUL, +0x70703040UL,0x808C0C8CUL,0x333C3F0FUL,0xA0A82888UL,0x32303202UL,0xD1DC1DCDUL,0xF2F436C6UL,0x70743444UL, +0xE0EC2CCCUL,0x91941585UL,0x03080B0BUL,0x53541747UL,0x505C1C4CUL,0x53581B4BUL,0xB1BC3D8DUL,0x01000101UL, +0x20242404UL,0x101C1C0CUL,0x73703343UL,0x90981888UL,0x10101000UL,0xC0CC0CCCUL,0xF2F032C2UL,0xD1D819C9UL, +0x202C2C0CUL,0xE3E427C7UL,0x72703242UL,0x83800383UL,0x93981B8BUL,0xD1D011C1UL,0x82840686UL,0xC1C809C9UL, +0x60602040UL,0x50501040UL,0xA3A02383UL,0xE3E82BCBUL,0x010C0D0DUL,0xB2B43686UL,0x929C1E8EUL,0x434C0F4FUL, +0xB3B43787UL,0x52581A4AUL,0xC2C406C6UL,0x70783848UL,0xA2A42686UL,0x12101202UL,0xA3AC2F8FUL,0xD1D415C5UL, +0x61602141UL,0xC3C003C3UL,0xB0B43484UL,0x41400141UL,0x52501242UL,0x717C3D4DUL,0x818C0D8DUL,0x00080808UL, +0x131C1F0FUL,0x91981989UL,0x00000000UL,0x11181909UL,0x00040404UL,0x53501343UL,0xF3F437C7UL,0xE1E021C1UL, +0xF1FC3DCDUL,0x72743646UL,0x232C2F0FUL,0x23242707UL,0xB0B03080UL,0x83880B8BUL,0x020C0E0EUL,0xA3A82B8BUL, +0xA2A02282UL,0x626C2E4EUL,0x93901383UL,0x414C0D4DUL,0x61682949UL,0x707C3C4CUL,0x01080909UL,0x02080A0AUL, +0xB3BC3F8FUL,0xE3EC2FCFUL,0xF3F033C3UL,0xC1C405C5UL,0x83840787UL,0x10141404UL,0xF2FC3ECEUL,0x60642444UL, +0xD2DC1ECEUL,0x222C2E0EUL,0x43480B4BUL,0x12181A0AUL,0x02040606UL,0x21202101UL,0x63682B4BUL,0x62642646UL, +0x02000202UL,0xF1F435C5UL,0x92901282UL,0x82880A8AUL,0x000C0C0CUL,0xB3B03383UL,0x727C3E4EUL,0xD0D010C0UL, +0x72783A4AUL,0x43440747UL,0x92941686UL,0xE1E425C5UL,0x22242606UL,0x80800080UL,0xA1AC2D8DUL,0xD3DC1FCFUL, +0xA1A02181UL,0x30303000UL,0x33343707UL,0xA2AC2E8EUL,0x32343606UL,0x11141505UL,0x22202202UL,0x30383808UL, +0xF0F434C4UL,0xA3A42787UL,0x41440545UL,0x404C0C4CUL,0x81800181UL,0xE1E829C9UL,0x80840484UL,0x93941787UL, +0x31343505UL,0xC3C80BCBUL,0xC2CC0ECEUL,0x303C3C0CUL,0x71703141UL,0x11101101UL,0xC3C407C7UL,0x81880989UL, +0x71743545UL,0xF3F83BCBUL,0xD2D81ACAUL,0xF0F838C8UL,0x90941484UL,0x51581949UL,0x82800282UL,0xC0C404C4UL, +0xF3FC3FCFUL,0x41480949UL,0x31383909UL,0x63642747UL,0xC0C000C0UL,0xC3CC0FCFUL,0xD3D417C7UL,0xB0B83888UL, +0x030C0F0FUL,0x828C0E8EUL,0x42400242UL,0x23202303UL,0x91901181UL,0x606C2C4CUL,0xD3D81BCBUL,0xA0A42484UL, +0x30343404UL,0xF1F031C1UL,0x40480848UL,0xC2C002C2UL,0x636C2F4FUL,0x313C3D0DUL,0x212C2D0DUL,0x40400040UL, +0xB2BC3E8EUL,0x323C3E0EUL,0xB0BC3C8CUL,0xC1C001C1UL,0xA2A82A8AUL,0xB2B83A8AUL,0x424C0E4EUL,0x51541545UL, +0x33383B0BUL,0xD0DC1CCCUL,0x60682848UL,0x737C3F4FUL,0x909C1C8CUL,0xD0D818C8UL,0x42480A4AUL,0x52541646UL, +0x73743747UL,0xA0A02080UL,0xE1EC2DCDUL,0x42440646UL,0xB1B43585UL,0x23282B0BUL,0x61642545UL,0xF2F83ACAUL, +0xE3E023C3UL,0xB1B83989UL,0xB1B03181UL,0x939C1F8FUL,0x525C1E4EUL,0xF1F839C9UL,0xE2E426C6UL,0xB2B03282UL, +0x31303101UL,0xE2E82ACAUL,0x616C2D4DUL,0x535C1F4FUL,0xE0E424C4UL,0xF0F030C0UL,0xC1CC0DCDUL,0x80880888UL, +0x12141606UL,0x32383A0AUL,0x50581848UL,0xD0D414C4UL,0x62602242UL,0x21282909UL,0x03040707UL,0x33303303UL, +0xE0E828C8UL,0x13181B0BUL,0x01040505UL,0x71783949UL,0x90901080UL,0x62682A4AUL,0x22282A0AUL,0x92981A8AUL +}; + +static const ulong32 SS3[256] = { +0x08303838UL,0xC8E0E828UL,0x0D212C2DUL,0x86A2A426UL,0xCFC3CC0FUL,0xCED2DC1EUL,0x83B3B033UL,0x88B0B838UL, +0x8FA3AC2FUL,0x40606020UL,0x45515415UL,0xC7C3C407UL,0x44404404UL,0x4F636C2FUL,0x4B63682BUL,0x4B53581BUL, +0xC3C3C003UL,0x42626022UL,0x03333033UL,0x85B1B435UL,0x09212829UL,0x80A0A020UL,0xC2E2E022UL,0x87A3A427UL, +0xC3D3D013UL,0x81919011UL,0x01111011UL,0x06020406UL,0x0C101C1CUL,0x8CB0BC3CUL,0x06323436UL,0x4B43480BUL, +0xCFE3EC2FUL,0x88808808UL,0x4C606C2CUL,0x88A0A828UL,0x07131417UL,0xC4C0C404UL,0x06121416UL,0xC4F0F434UL, +0xC2C2C002UL,0x45414405UL,0xC1E1E021UL,0xC6D2D416UL,0x0F333C3FUL,0x0D313C3DUL,0x8E828C0EUL,0x88909818UL, +0x08202828UL,0x4E424C0EUL,0xC6F2F436UL,0x0E323C3EUL,0x85A1A425UL,0xC9F1F839UL,0x0D010C0DUL,0xCFD3DC1FUL, +0xC8D0D818UL,0x0B23282BUL,0x46626426UL,0x4A72783AUL,0x07232427UL,0x0F232C2FUL,0xC1F1F031UL,0x42727032UL, +0x42424002UL,0xC4D0D414UL,0x41414001UL,0xC0C0C000UL,0x43737033UL,0x47636427UL,0x8CA0AC2CUL,0x8B83880BUL, +0xC7F3F437UL,0x8DA1AC2DUL,0x80808000UL,0x0F131C1FUL,0xCAC2C80AUL,0x0C202C2CUL,0x8AA2A82AUL,0x04303434UL, +0xC2D2D012UL,0x0B03080BUL,0xCEE2EC2EUL,0xC9E1E829UL,0x4D515C1DUL,0x84909414UL,0x08101818UL,0xC8F0F838UL, +0x47535417UL,0x8EA2AC2EUL,0x08000808UL,0xC5C1C405UL,0x03131013UL,0xCDC1CC0DUL,0x86828406UL,0x89B1B839UL, +0xCFF3FC3FUL,0x4D717C3DUL,0xC1C1C001UL,0x01313031UL,0xC5F1F435UL,0x8A82880AUL,0x4A62682AUL,0x81B1B031UL, +0xC1D1D011UL,0x00202020UL,0xC7D3D417UL,0x02020002UL,0x02222022UL,0x04000404UL,0x48606828UL,0x41717031UL, +0x07030407UL,0xCBD3D81BUL,0x8D919C1DUL,0x89919819UL,0x41616021UL,0x8EB2BC3EUL,0xC6E2E426UL,0x49515819UL, +0xCDD1DC1DUL,0x41515011UL,0x80909010UL,0xCCD0DC1CUL,0x8A92981AUL,0x83A3A023UL,0x8BA3A82BUL,0xC0D0D010UL, +0x81818001UL,0x0F030C0FUL,0x47434407UL,0x0A12181AUL,0xC3E3E023UL,0xCCE0EC2CUL,0x8D818C0DUL,0x8FB3BC3FUL, +0x86929416UL,0x4B73783BUL,0x4C505C1CUL,0x82A2A022UL,0x81A1A021UL,0x43636023UL,0x03232023UL,0x4D414C0DUL, +0xC8C0C808UL,0x8E929C1EUL,0x8C909C1CUL,0x0A32383AUL,0x0C000C0CUL,0x0E222C2EUL,0x8AB2B83AUL,0x4E626C2EUL, +0x8F939C1FUL,0x4A52581AUL,0xC2F2F032UL,0x82929012UL,0xC3F3F033UL,0x49414809UL,0x48707838UL,0xCCC0CC0CUL, +0x05111415UL,0xCBF3F83BUL,0x40707030UL,0x45717435UL,0x4F737C3FUL,0x05313435UL,0x00101010UL,0x03030003UL, +0x44606424UL,0x4D616C2DUL,0xC6C2C406UL,0x44707434UL,0xC5D1D415UL,0x84B0B434UL,0xCAE2E82AUL,0x09010809UL, +0x46727436UL,0x09111819UL,0xCEF2FC3EUL,0x40404000UL,0x02121012UL,0xC0E0E020UL,0x8DB1BC3DUL,0x05010405UL, +0xCAF2F83AUL,0x01010001UL,0xC0F0F030UL,0x0A22282AUL,0x4E525C1EUL,0x89A1A829UL,0x46525416UL,0x43434003UL, +0x85818405UL,0x04101414UL,0x89818809UL,0x8B93981BUL,0x80B0B030UL,0xC5E1E425UL,0x48404808UL,0x49717839UL, +0x87939417UL,0xCCF0FC3CUL,0x0E121C1EUL,0x82828002UL,0x01212021UL,0x8C808C0CUL,0x0B13181BUL,0x4F535C1FUL, +0x47737437UL,0x44505414UL,0x82B2B032UL,0x0D111C1DUL,0x05212425UL,0x4F434C0FUL,0x00000000UL,0x46424406UL, +0xCDE1EC2DUL,0x48505818UL,0x42525012UL,0xCBE3E82BUL,0x4E727C3EUL,0xCAD2D81AUL,0xC9C1C809UL,0xCDF1FC3DUL, +0x00303030UL,0x85919415UL,0x45616425UL,0x0C303C3CUL,0x86B2B436UL,0xC4E0E424UL,0x8BB3B83BUL,0x4C707C3CUL, +0x0E020C0EUL,0x40505010UL,0x09313839UL,0x06222426UL,0x02323032UL,0x84808404UL,0x49616829UL,0x83939013UL, +0x07333437UL,0xC7E3E427UL,0x04202424UL,0x84A0A424UL,0xCBC3C80BUL,0x43535013UL,0x0A02080AUL,0x87838407UL, +0xC9D1D819UL,0x4C404C0CUL,0x83838003UL,0x8F838C0FUL,0xCEC2CC0EUL,0x0B33383BUL,0x4A42480AUL,0x87B3B437UL +}; + +static const ulong32 KCi[16] = { +0x9E3779B9,0x3C6EF373, +0x78DDE6E6,0xF1BBCDCC, +0xE3779B99,0xC6EF3733, +0x8DDE6E67,0x1BBCDCCF, +0x3779B99E,0x6EF3733C, +0xDDE6E678,0xBBCDCCF1, +0x779B99E3,0xEF3733C6, +0xDE6E678D,0xBCDCCF1B +}; + +#define G(x) (SS3[((x)>>24)&255] ^ SS2[((x)>>16)&255] ^ SS1[((x)>>8)&255] ^ SS0[(x)&255]) + +#define F(L1, L2, R1, R2, K1, K2) \ + T2 = G((R1 ^ K1) ^ (R2 ^ K2)); \ + T = G( G(T2 + (R1 ^ K1)) + T2); \ + L2 ^= T; \ + L1 ^= (T + G(T2 + (R1 ^ K1))); \ + + /** + Initialize the SEED block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +int kseed_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int i; + ulong32 tmp, k1, k2, k3, k4; + + if (keylen != 16) { + return CRYPT_INVALID_KEYSIZE; + } + + if (num_rounds != 16 && num_rounds != 0) { + return CRYPT_INVALID_ROUNDS; + } + + /* load key */ + LOAD32H(k1, key); + LOAD32H(k2, key+4); + LOAD32H(k3, key+8); + LOAD32H(k4, key+12); + + for (i = 0; i < 16; i++) { + skey->kseed.K[2*i+0] = G(k1 + k3 - KCi[i]); + skey->kseed.K[2*i+1] = G(k2 - k4 + KCi[i]); + if (i&1) { + tmp = k3; + k3 = ((k3 << 8) | (k4 >> 24)) & 0xFFFFFFFF; + k4 = ((k4 << 8) | (tmp >> 24)) & 0xFFFFFFFF; + } else { + tmp = k1; + k1 = ((k1 >> 8) | (k2 << 24)) & 0xFFFFFFFF; + k2 = ((k2 >> 8) | (tmp << 24)) & 0xFFFFFFFF; + } + /* reverse keys for decrypt */ + skey->kseed.dK[2*(15-i)+0] = skey->kseed.K[2*i+0]; + skey->kseed.dK[2*(15-i)+1] = skey->kseed.K[2*i+1]; + } + + return CRYPT_OK; +} + +static void rounds(ulong32 *P, ulong32 *K) +{ + ulong32 T, T2; + int i; + for (i = 0; i < 16; i += 2) { + F(P[0], P[1], P[2], P[3], K[0], K[1]); + F(P[2], P[3], P[0], P[1], K[2], K[3]); + K += 4; + } +} + +/** + Encrypts a block of text with SEED + @param pt The input plaintext (16 bytes) + @param ct The output ciphertext (16 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int kseed_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + ulong32 P[4]; + LOAD32H(P[0], pt); + LOAD32H(P[1], pt+4); + LOAD32H(P[2], pt+8); + LOAD32H(P[3], pt+12); + rounds(P, skey->kseed.K); + STORE32H(P[2], ct); + STORE32H(P[3], ct+4); + STORE32H(P[0], ct+8); + STORE32H(P[1], ct+12); + return CRYPT_OK; +} + +/** + Decrypts a block of text with SEED + @param ct The input ciphertext (16 bytes) + @param pt The output plaintext (16 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int kseed_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + ulong32 P[4]; + LOAD32H(P[0], ct); + LOAD32H(P[1], ct+4); + LOAD32H(P[2], ct+8); + LOAD32H(P[3], ct+12); + rounds(P, skey->kseed.dK); + STORE32H(P[2], pt); + STORE32H(P[3], pt+4); + STORE32H(P[0], pt+8); + STORE32H(P[1], pt+12); + return CRYPT_OK; +} + +/** Terminate the context + @param skey The scheduled key +*/ +void kseed_done(symmetric_key *skey) +{ + LTC_UNUSED_PARAM(skey); +} + +/** + Performs a self-test of the SEED block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int kseed_test(void) +{ +#if !defined(LTC_TEST) + return CRYPT_NOP; +#else + static const struct test { + unsigned char pt[16], ct[16], key[16]; + } tests[] = { + +{ + { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F }, + { 0x5E,0xBA,0xC6,0xE0,0x05,0x4E,0x16,0x68,0x19,0xAF,0xF1,0xCC,0x6D,0x34,0x6C,0xDB }, + { 0 }, +}, + +{ + { 0 }, + { 0xC1,0x1F,0x22,0xF2,0x01,0x40,0x50,0x50,0x84,0x48,0x35,0x97,0xE4,0x37,0x0F,0x43 }, + { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F }, +}, + +{ + { 0x83,0xA2,0xF8,0xA2,0x88,0x64,0x1F,0xB9,0xA4,0xE9,0xA5,0xCC,0x2F,0x13,0x1C,0x7D }, + { 0xEE,0x54,0xD1,0x3E,0xBC,0xAE,0x70,0x6D,0x22,0x6B,0xC3,0x14,0x2C,0xD4,0x0D,0x4A }, + { 0x47,0x06,0x48,0x08,0x51,0xE6,0x1B,0xE8,0x5D,0x74,0xBF,0xB3,0xFD,0x95,0x61,0x85 }, +}, + +{ + { 0xB4,0x1E,0x6B,0xE2,0xEB,0xA8,0x4A,0x14,0x8E,0x2E,0xED,0x84,0x59,0x3C,0x5E,0xC7 }, + { 0x9B,0x9B,0x7B,0xFC,0xD1,0x81,0x3C,0xB9,0x5D,0x0B,0x36,0x18,0xF4,0x0F,0x51,0x22 }, + { 0x28,0xDB,0xC3,0xBC,0x49,0xFF,0xD8,0x7D,0xCF,0xA5,0x09,0xB1,0x1D,0x42,0x2B,0xE7 }, +} +}; + int x; + unsigned char buf[2][16]; + symmetric_key skey; + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + kseed_setup(tests[x].key, 16, 0, &skey); + kseed_ecb_encrypt(tests[x].pt, buf[0], &skey); + kseed_ecb_decrypt(buf[0], buf[1], &skey); + if (XMEMCMP(buf[0], tests[x].ct, 16) || XMEMCMP(buf[1], tests[x].pt, 16)) { +#if 0 + int i, j; + printf ("\n\nLTC_KSEED failed for x=%d, I got:\n", x); + for (i = 0; i < 2; i++) { + const unsigned char *expected, *actual; + expected = (i ? tests[x].pt : tests[x].ct); + actual = buf[i]; + printf ("expected actual (%s)\n", (i ? "plaintext" : "ciphertext")); + for (j = 0; j < 16; j++) { + const char *eq = (expected[j] == actual[j] ? "==" : "!="); + printf (" %02x %s %02x\n", expected[j], eq, actual[j]); + } + printf ("\n"); + } +#endif + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +#endif +} + +/** + 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. + @return CRYPT_OK if the input key size is acceptable. +*/ +int kseed_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if (*keysize >= 16) { + *keysize = 16; + } else { + return CRYPT_INVALID_KEYSIZE; + } + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/ciphers/multi2.c b/src/ltc/ciphers/multi2.c new file mode 100644 index 0000000..d77c9a6 --- /dev/null +++ b/src/ltc/ciphers/multi2.c @@ -0,0 +1,321 @@ +/* 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://libtom.org + */ + +/** + @file multi2.c + Multi-2 implementation (not public domain, hence the default disable) +*/ +#include "tomcrypt.h" + +#ifdef LTC_MULTI2 + +static void pi1(ulong32 *p) +{ + p[1] ^= p[0]; +} + +static void pi2(ulong32 *p, ulong32 *k) +{ + ulong32 t; + t = (p[1] + k[0]) & 0xFFFFFFFFUL; + t = (ROL(t, 1) + t - 1) & 0xFFFFFFFFUL; + t = (ROL(t, 4) ^ t) & 0xFFFFFFFFUL; + p[0] ^= t; +} + +static void pi3(ulong32 *p, ulong32 *k) +{ + ulong32 t; + t = p[0] + k[1]; + t = (ROL(t, 2) + t + 1) & 0xFFFFFFFFUL; + t = (ROL(t, 8) ^ t) & 0xFFFFFFFFUL; + t = (t + k[2]) & 0xFFFFFFFFUL; + t = (ROL(t, 1) - t) & 0xFFFFFFFFUL; + t = ROL(t, 16) ^ (p[0] | t); + p[1] ^= t; +} + +static void pi4(ulong32 *p, ulong32 *k) +{ + ulong32 t; + t = (p[1] + k[3]) & 0xFFFFFFFFUL; + t = (ROL(t, 2) + t + 1) & 0xFFFFFFFFUL; + p[0] ^= t; +} + +static void setup(ulong32 *dk, ulong32 *k, ulong32 *uk) +{ + int n, t; + ulong32 p[2]; + + p[0] = dk[0]; p[1] = dk[1]; + + t = 4; + n = 0; + pi1(p); + pi2(p, k); + uk[n++] = p[0]; + pi3(p, k); + uk[n++] = p[1]; + pi4(p, k); + uk[n++] = p[0]; + pi1(p); + uk[n++] = p[1]; + pi2(p, k+t); + uk[n++] = p[0]; + pi3(p, k+t); + uk[n++] = p[1]; + pi4(p, k+t); + uk[n++] = p[0]; + pi1(p); + uk[n++] = p[1]; +} + +static void encrypt(ulong32 *p, int N, ulong32 *uk) +{ + int n, t; + for (t = n = 0; ; ) { + pi1(p); if (++n == N) break; + pi2(p, uk+t); if (++n == N) break; + pi3(p, uk+t); if (++n == N) break; + pi4(p, uk+t); if (++n == N) break; + t ^= 4; + } +} + +static void decrypt(ulong32 *p, int N, ulong32 *uk) +{ + int n, t; + for (t = 4*(((N-1)>>2)&1), n = N; ; ) { + switch (n<=4 ? n : ((n-1)%4)+1) { + case 4: pi4(p, uk+t); --n; /* FALLTHROUGH */ + case 3: pi3(p, uk+t); --n; /* FALLTHROUGH */ + case 2: pi2(p, uk+t); --n; /* FALLTHROUGH */ + case 1: pi1(p); --n; break; + case 0: return; + } + t ^= 4; + } +} + +const struct ltc_cipher_descriptor multi2_desc = { + "multi2", + 22, + 40, 40, 8, 128, + &multi2_setup, + &multi2_ecb_encrypt, + &multi2_ecb_decrypt, + &multi2_test, + &multi2_done, + &multi2_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +int multi2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + ulong32 sk[8], dk[2]; + int x; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + if (keylen != 40) return CRYPT_INVALID_KEYSIZE; + if (num_rounds == 0) num_rounds = 128; + + skey->multi2.N = num_rounds; + for (x = 0; x < 8; x++) { + LOAD32H(sk[x], key + x*4); + } + LOAD32H(dk[0], key + 32); + LOAD32H(dk[1], key + 36); + setup(dk, sk, skey->multi2.uk); + + zeromem(sk, sizeof(sk)); + zeromem(dk, sizeof(dk)); + return CRYPT_OK; +} + +/** + Encrypts a block of text with multi2 + @param pt The input plaintext (8 bytes) + @param ct The output ciphertext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int multi2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + ulong32 p[2]; + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + LOAD32H(p[0], pt); + LOAD32H(p[1], pt+4); + encrypt(p, skey->multi2.N, skey->multi2.uk); + STORE32H(p[0], ct); + STORE32H(p[1], ct+4); + return CRYPT_OK; +} + +/** + Decrypts a block of text with multi2 + @param ct The input ciphertext (8 bytes) + @param pt The output plaintext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int multi2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + ulong32 p[2]; + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + LOAD32H(p[0], ct); + LOAD32H(p[1], ct+4); + decrypt(p, skey->multi2.N, skey->multi2.uk); + STORE32H(p[0], pt); + STORE32H(p[1], pt+4); + return CRYPT_OK; +} + +/** + Performs a self-test of the multi2 block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int multi2_test(void) +{ + static const struct { + unsigned char key[40]; + unsigned char pt[8], ct[8]; + int rounds; + } tests[] = { +{ + { + 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, 0x23, 0x45, 0x67, + 0x89, 0xAB, 0xCD, 0xEF + }, + { + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + }, + { + 0xf8, 0x94, 0x40, 0x84, + 0x5e, 0x11, 0xcf, 0x89 + }, + 128, +}, +{ + { + 0x35, 0x91, 0x9d, 0x96, + 0x07, 0x02, 0xe2, 0xce, + 0x8d, 0x0b, 0x58, 0x3c, + 0xc9, 0xc8, 0x9d, 0x59, + 0xa2, 0xae, 0x96, 0x4e, + 0x87, 0x82, 0x45, 0xed, + 0x3f, 0x2e, 0x62, 0xd6, + 0x36, 0x35, 0xd0, 0x67, + + 0xb1, 0x27, 0xb9, 0x06, + 0xe7, 0x56, 0x22, 0x38, + }, + { + 0x1f, 0xb4, 0x60, 0x60, + 0xd0, 0xb3, 0x4f, 0xa5 + }, + { + 0xca, 0x84, 0xa9, 0x34, + 0x75, 0xc8, 0x60, 0xe5 + }, + 216, +} +}; + unsigned char buf[8]; + symmetric_key skey; + int err, x; + + for (x = 1; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + if ((err = multi2_setup(tests[x].key, 40, tests[x].rounds, &skey)) != CRYPT_OK) { + return err; + } + if ((err = multi2_ecb_encrypt(tests[x].pt, buf, &skey)) != CRYPT_OK) { + return err; + } + + if (XMEMCMP(buf, tests[x].ct, 8)) { + return CRYPT_FAIL_TESTVECTOR; + } + + if ((err = multi2_ecb_decrypt(buf, buf, &skey)) != CRYPT_OK) { + return err; + } + if (XMEMCMP(buf, tests[x].pt, 8)) { + return CRYPT_FAIL_TESTVECTOR; + } + } + + for (x = 128; x < 256; ++x) { + unsigned char ct[8]; + + if ((err = multi2_setup(tests[0].key, 40, x, &skey)) != CRYPT_OK) { + return err; + } + if ((err = multi2_ecb_encrypt(tests[0].pt, ct, &skey)) != CRYPT_OK) { + return err; + } + if ((err = multi2_ecb_decrypt(ct, buf, &skey)) != CRYPT_OK) { + return err; + } + if (XMEMCMP(buf, tests[0].pt, 8)) { + return CRYPT_FAIL_TESTVECTOR; + } + } + + return CRYPT_OK; +} + +/** Terminate the context + @param skey The scheduled key +*/ +void multi2_done(symmetric_key *skey) +{ + LTC_UNUSED_PARAM(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. + @return CRYPT_OK if the input key size is acceptable. +*/ +int multi2_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if (*keysize >= 40) { + *keysize = 40; + } else { + return CRYPT_INVALID_KEYSIZE; + } + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/ciphers/noekeon.c b/src/ltc/ciphers/noekeon.c new file mode 100644 index 0000000..5b8d1c8 --- /dev/null +++ b/src/ltc/ciphers/noekeon.c @@ -0,0 +1,345 @@ +/* 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://libtom.org + */ +/** + @file noekeon.c + Implementation of the Noekeon block cipher by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_NOEKEON + +const struct ltc_cipher_descriptor noekeon_desc = +{ + "noekeon", + 16, + 16, 16, 16, 16, + &noekeon_setup, + &noekeon_ecb_encrypt, + &noekeon_ecb_decrypt, + &noekeon_test, + &noekeon_done, + &noekeon_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +static const ulong32 RC[] = { + 0x00000080UL, 0x0000001bUL, 0x00000036UL, 0x0000006cUL, + 0x000000d8UL, 0x000000abUL, 0x0000004dUL, 0x0000009aUL, + 0x0000002fUL, 0x0000005eUL, 0x000000bcUL, 0x00000063UL, + 0x000000c6UL, 0x00000097UL, 0x00000035UL, 0x0000006aUL, + 0x000000d4UL +}; + +#define kTHETA(a, b, c, d) \ + temp = a^c; temp = temp ^ ROLc(temp, 8) ^ RORc(temp, 8); \ + b ^= temp; d ^= temp; \ + temp = b^d; temp = temp ^ ROLc(temp, 8) ^ RORc(temp, 8); \ + a ^= temp; c ^= temp; + +#define THETA(k, a, b, c, d) \ + temp = a^c; temp = temp ^ ROLc(temp, 8) ^ RORc(temp, 8); \ + b ^= temp ^ k[1]; d ^= temp ^ k[3]; \ + temp = b^d; temp = temp ^ ROLc(temp, 8) ^ RORc(temp, 8); \ + a ^= temp ^ k[0]; c ^= temp ^ k[2]; + +#define GAMMA(a, b, c, d) \ + b ^= ~(d|c); \ + a ^= c&b; \ + temp = d; d = a; a = temp;\ + c ^= a ^ b ^ d; \ + b ^= ~(d|c); \ + a ^= c&b; + +#define PI1(a, b, c, d) \ + b = ROLc(b, 1); c = ROLc(c, 5); d = ROLc(d, 2); + +#define PI2(a, b, c, d) \ + b = RORc(b, 1); c = RORc(c, 5); d = RORc(d, 2); + + /** + Initialize the Noekeon block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + ulong32 temp; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + if (keylen != 16) { + return CRYPT_INVALID_KEYSIZE; + } + + if (num_rounds != 16 && num_rounds != 0) { + return CRYPT_INVALID_ROUNDS; + } + + LOAD32H(skey->noekeon.K[0],&key[0]); + LOAD32H(skey->noekeon.K[1],&key[4]); + LOAD32H(skey->noekeon.K[2],&key[8]); + LOAD32H(skey->noekeon.K[3],&key[12]); + + LOAD32H(skey->noekeon.dK[0],&key[0]); + LOAD32H(skey->noekeon.dK[1],&key[4]); + LOAD32H(skey->noekeon.dK[2],&key[8]); + LOAD32H(skey->noekeon.dK[3],&key[12]); + + kTHETA(skey->noekeon.dK[0], skey->noekeon.dK[1], skey->noekeon.dK[2], skey->noekeon.dK[3]); + + return CRYPT_OK; +} + +/** + Encrypts a block of text with Noekeon + @param pt The input plaintext (16 bytes) + @param ct The output ciphertext (16 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +#ifdef LTC_CLEAN_STACK +static int _noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#else +int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#endif +{ + ulong32 a,b,c,d,temp; + int r; + + LTC_ARGCHK(skey != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + + LOAD32H(a,&pt[0]); LOAD32H(b,&pt[4]); + LOAD32H(c,&pt[8]); LOAD32H(d,&pt[12]); + +#define ROUND(i) \ + a ^= RC[i]; \ + THETA(skey->noekeon.K, a,b,c,d); \ + PI1(a,b,c,d); \ + GAMMA(a,b,c,d); \ + PI2(a,b,c,d); + + for (r = 0; r < 16; ++r) { + ROUND(r); + } + +#undef ROUND + + a ^= RC[16]; + THETA(skey->noekeon.K, a, b, c, d); + + STORE32H(a,&ct[0]); STORE32H(b,&ct[4]); + STORE32H(c,&ct[8]); STORE32H(d,&ct[12]); + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + int err = _noekeon_ecb_encrypt(pt, ct, skey); + burn_stack(sizeof(ulong32) * 5 + sizeof(int)); + return err; +} +#endif + +/** + Decrypts a block of text with Noekeon + @param ct The input ciphertext (16 bytes) + @param pt The output plaintext (16 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +#ifdef LTC_CLEAN_STACK +static int _noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#else +int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#endif +{ + ulong32 a,b,c,d, temp; + int r; + + LTC_ARGCHK(skey != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + + LOAD32H(a,&ct[0]); LOAD32H(b,&ct[4]); + LOAD32H(c,&ct[8]); LOAD32H(d,&ct[12]); + + +#define ROUND(i) \ + THETA(skey->noekeon.dK, a,b,c,d); \ + a ^= RC[i]; \ + PI1(a,b,c,d); \ + GAMMA(a,b,c,d); \ + PI2(a,b,c,d); + + for (r = 16; r > 0; --r) { + ROUND(r); + } + +#undef ROUND + + THETA(skey->noekeon.dK, a,b,c,d); + a ^= RC[0]; + STORE32H(a,&pt[0]); STORE32H(b, &pt[4]); + STORE32H(c,&pt[8]); STORE32H(d, &pt[12]); + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + int err = _noekeon_ecb_decrypt(ct, pt, skey); + burn_stack(sizeof(ulong32) * 5 + sizeof(int)); + return err; +} +#endif + +/** + Performs a self-test of the Noekeon block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int noekeon_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + int keylen; + unsigned char key[16], pt[16], ct[16]; + } tests[] = { + { + 16, + { 0xAA, 0x3C, 0x8C, 0x86, 0xD9, 0x8B, 0xF8, 0xBE, 0x21, 0xE0, 0x36, 0x09, 0x78, 0xFB, 0xE4, 0x90 }, + { 0xE4, 0x96, 0x6C, 0xD3, 0x13, 0xA0, 0x6C, 0xAF, 0xD0, 0x23, 0xC9, 0xFD, 0x45, 0x32, 0x23, 0x16 }, + { 0xA6, 0xEC, 0xB8, 0xA8, 0x61, 0xFD, 0x62, 0xD9, 0x13, 0x02, 0xFE, 0x9E, 0x47, 0x01, 0x3F, 0xC3 } + }, + { + 16, + { 0xED, 0x43, 0xD1, 0x87, 0x21, 0x7E, 0xE0, 0x97, 0x3D, 0x76, 0xC3, 0x37, 0x2E, 0x7D, 0xAE, 0xD3 }, + { 0xE3, 0x38, 0x32, 0xCC, 0xF2, 0x2F, 0x2F, 0x0A, 0x4A, 0x8B, 0x8F, 0x18, 0x12, 0x20, 0x17, 0xD3 }, + { 0x94, 0xA5, 0xDF, 0xF5, 0xAE, 0x1C, 0xBB, 0x22, 0xAD, 0xEB, 0xA7, 0x0D, 0xB7, 0x82, 0x90, 0xA0 } + }, + { + 16, + { 0x6F, 0xDC, 0x23, 0x38, 0xF2, 0x10, 0xFB, 0xD3, 0xC1, 0x8C, 0x02, 0xF6, 0xB4, 0x6A, 0xD5, 0xA8 }, + { 0xDB, 0x29, 0xED, 0xB5, 0x5F, 0xB3, 0x60, 0x3A, 0x92, 0xA8, 0xEB, 0x9C, 0x6D, 0x9D, 0x3E, 0x8F }, + { 0x78, 0xF3, 0x6F, 0xF8, 0x9E, 0xBB, 0x8C, 0x6A, 0xE8, 0x10, 0xF7, 0x00, 0x22, 0x15, 0x30, 0x3D } + }, + { + 16, + { 0x2C, 0x0C, 0x02, 0xEF, 0x6B, 0xC4, 0xF2, 0x0B, 0x2E, 0xB9, 0xE0, 0xBF, 0xD9, 0x36, 0xC2, 0x4E }, + { 0x84, 0xE2, 0xFE, 0x64, 0xB1, 0xB9, 0xFE, 0x76, 0xA8, 0x3F, 0x45, 0xC7, 0x40, 0x7A, 0xAF, 0xEE }, + { 0x2A, 0x08, 0xD6, 0xA2, 0x1C, 0x63, 0x08, 0xB0, 0xF8, 0xBC, 0xB3, 0xA1, 0x66, 0xF7, 0xAE, 0xCF } + }, + { + 16, + { 0x6F, 0x30, 0xF8, 0x9F, 0xDA, 0x6E, 0xA0, 0x91, 0x04, 0x0F, 0x6C, 0x8B, 0x7D, 0xF7, 0x2A, 0x4B }, + { 0x65, 0xB6, 0xA6, 0xD0, 0x42, 0x14, 0x08, 0x60, 0x34, 0x8D, 0x37, 0x2F, 0x01, 0xF0, 0x46, 0xBE }, + { 0x66, 0xAC, 0x0B, 0x62, 0x1D, 0x68, 0x11, 0xF5, 0x27, 0xB1, 0x13, 0x5D, 0xF3, 0x2A, 0xE9, 0x18 } + }, + { + 16, + { 0xCA, 0xA4, 0x16, 0xB7, 0x1C, 0x92, 0x2E, 0xAD, 0xEB, 0xA7, 0xDB, 0x69, 0x92, 0xCB, 0x35, 0xEF }, + { 0x81, 0x6F, 0x8E, 0x4D, 0x96, 0xC6, 0xB3, 0x67, 0x83, 0xF5, 0x63, 0xC7, 0x20, 0x6D, 0x40, 0x23 }, + { 0x44, 0xF7, 0x63, 0x62, 0xF0, 0x43, 0xBB, 0x67, 0x4A, 0x75, 0x12, 0x42, 0x46, 0x29, 0x28, 0x19 } + }, + { + 16, + { 0x6B, 0xCF, 0x22, 0x2F, 0xE0, 0x1B, 0xB0, 0xAA, 0xD8, 0x3C, 0x91, 0x99, 0x18, 0xB2, 0x28, 0xE8 }, + { 0x7C, 0x37, 0xC7, 0xD0, 0xAC, 0x92, 0x29, 0xF1, 0x60, 0x82, 0x93, 0x89, 0xAA, 0x61, 0xAA, 0xA9 }, + { 0xE5, 0x89, 0x1B, 0xB3, 0xFE, 0x8B, 0x0C, 0xA1, 0xA6, 0xC7, 0xBE, 0x12, 0x73, 0x0F, 0xC1, 0x19 } + }, + { + 16, + { 0xE6, 0xD0, 0xF1, 0x03, 0x2E, 0xDE, 0x70, 0x8D, 0xD8, 0x9E, 0x36, 0x5C, 0x05, 0x52, 0xE7, 0x0D }, + { 0xE2, 0x42, 0xE7, 0x92, 0x0E, 0xF7, 0x82, 0xA2, 0xB8, 0x21, 0x8D, 0x26, 0xBA, 0x2D, 0xE6, 0x32 }, + { 0x1E, 0xDD, 0x75, 0x22, 0xB9, 0x36, 0x8A, 0x0F, 0x32, 0xFD, 0xD4, 0x48, 0x65, 0x12, 0x5A, 0x2F } + } + }; + symmetric_key key; + unsigned char tmp[2][16]; + int err, i, y; + + for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { + zeromem(&key, sizeof(key)); + if ((err = noekeon_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { + return err; + } + + noekeon_ecb_encrypt(tests[i].pt, tmp[0], &key); + noekeon_ecb_decrypt(tmp[0], tmp[1], &key); + if (XMEMCMP(tmp[0], tests[i].ct, 16) || XMEMCMP(tmp[1], tests[i].pt, 16)) { +#if 0 + printf("\n\nTest %d failed\n", i); + if (XMEMCMP(tmp[0], tests[i].ct, 16)) { + printf("CT: "); + for (i = 0; i < 16; i++) { + printf("%02x ", tmp[0][i]); + } + printf("\n"); + } else { + printf("PT: "); + for (i = 0; i < 16; i++) { + printf("%02x ", tmp[1][i]); + } + printf("\n"); + } +#endif + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 16; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) noekeon_ecb_encrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) noekeon_ecb_decrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; + #endif +} + +/** Terminate the context + @param skey The scheduled key +*/ +void noekeon_done(symmetric_key *skey) +{ + LTC_UNUSED_PARAM(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. + @return CRYPT_OK if the input key size is acceptable. +*/ +int noekeon_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if (*keysize < 16) { + return CRYPT_INVALID_KEYSIZE; + } else { + *keysize = 16; + return CRYPT_OK; + } +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/ciphers/rc2.c b/src/ltc/ciphers/rc2.c new file mode 100644 index 0000000..e0e05d1 --- /dev/null +++ b/src/ltc/ciphers/rc2.c @@ -0,0 +1,419 @@ +/* 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://libtom.org + */ +/**********************************************************************\ +* To commemorate the 1996 RSA Data Security Conference, the following * +* code is released into the public domain by its author. Prost! * +* * +* This cipher uses 16-bit words and little-endian byte ordering. * +* I wonder which processor it was optimized for? * +* * +* Thanks to CodeView, SoftIce, and D86 for helping bring this code to * +* the public. * +\**********************************************************************/ +#include + +/** + @file rc2.c + Implementation of RC2 with fixed effective key length of 64bits +*/ + +#ifdef LTC_RC2 + +const struct ltc_cipher_descriptor rc2_desc = { + "rc2", + 12, 8, 128, 8, 16, + &rc2_setup, + &rc2_ecb_encrypt, + &rc2_ecb_decrypt, + &rc2_test, + &rc2_done, + &rc2_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +/* 256-entry permutation table, probably derived somehow from pi */ +static const unsigned char permute[256] = { + 217,120,249,196, 25,221,181,237, 40,233,253,121, 74,160,216,157, + 198,126, 55,131, 43,118, 83,142, 98, 76,100,136, 68,139,251,162, + 23,154, 89,245,135,179, 79, 19, 97, 69,109,141, 9,129,125, 50, + 189,143, 64,235,134,183,123, 11,240,149, 33, 34, 92,107, 78,130, + 84,214,101,147,206, 96,178, 28,115, 86,192, 20,167,140,241,220, + 18,117,202, 31, 59,190,228,209, 66, 61,212, 48,163, 60,182, 38, + 111,191, 14,218, 70,105, 7, 87, 39,242, 29,155,188,148, 67, 3, + 248, 17,199,246,144,239, 62,231, 6,195,213, 47,200,102, 30,215, + 8,232,234,222,128, 82,238,247,132,170,114,172, 53, 77,106, 42, + 150, 26,210,113, 90, 21, 73,116, 75,159,208, 94, 4, 24,164,236, + 194,224, 65,110, 15, 81,203,204, 36,145,175, 80,161,244,112, 57, + 153,124, 58,133, 35,184,180,122,252, 2, 54, 91, 37, 85,151, 49, + 45, 93,250,152,227,138,146,174, 5,223, 41, 16,103,108,186,201, + 211, 0,230,207,225,158,168, 44, 99, 22, 1, 63, 88,226,137,169, + 13, 56, 52, 27,171, 51,255,176,187, 72, 12, 95,185,177,205, 46, + 197,243,219, 71,229,165,156,119, 10,166, 32,104,254,127,193,173 +}; + + /** + Initialize the RC2 block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param bits The effective key length in bits + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +int rc2_setup_ex(const unsigned char *key, int keylen, int bits, int num_rounds, symmetric_key *skey) +{ + unsigned *xkey = skey->rc2.xkey; + unsigned char tmp[128]; + unsigned T8, TM; + int i; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + if (keylen == 0 || keylen > 128 || bits > 1024) { + return CRYPT_INVALID_KEYSIZE; + } + if (bits == 0) { + bits = 1024; + } + + if (num_rounds != 0 && num_rounds != 16) { + return CRYPT_INVALID_ROUNDS; + } + + for (i = 0; i < keylen; i++) { + tmp[i] = key[i] & 255; + } + + /* Phase 1: Expand input key to 128 bytes */ + if (keylen < 128) { + for (i = keylen; i < 128; i++) { + tmp[i] = permute[(tmp[i - 1] + tmp[i - keylen]) & 255]; + } + } + + /* Phase 2 - reduce effective key size to "bits" */ + T8 = (unsigned)(bits+7)>>3; + TM = (255 >> (unsigned)(7 & -bits)); + tmp[128 - T8] = permute[tmp[128 - T8] & TM]; + for (i = 127 - T8; i >= 0; i--) { + tmp[i] = permute[tmp[i + 1] ^ tmp[i + T8]]; + } + + /* Phase 3 - copy to xkey in little-endian order */ + for (i = 0; i < 64; i++) { + xkey[i] = (unsigned)tmp[2*i] + ((unsigned)tmp[2*i+1] << 8); + } + +#ifdef LTC_CLEAN_STACK + zeromem(tmp, sizeof(tmp)); +#endif + + return CRYPT_OK; +} + +/** + Initialize the RC2 block cipher + + The effective key length is here always keylen * 8 + + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful +*/ +int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + return rc2_setup_ex(key, keylen, keylen * 8, num_rounds, skey); +} + +/**********************************************************************\ +* Encrypt an 8-byte block of plaintext using the given key. * +\**********************************************************************/ +/** + Encrypts a block of text with RC2 + @param pt The input plaintext (8 bytes) + @param ct The output ciphertext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +#ifdef LTC_CLEAN_STACK +static int _rc2_ecb_encrypt( const unsigned char *pt, + unsigned char *ct, + symmetric_key *skey) +#else +int rc2_ecb_encrypt( const unsigned char *pt, + unsigned char *ct, + symmetric_key *skey) +#endif +{ + unsigned *xkey; + unsigned x76, x54, x32, x10, i; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + + xkey = skey->rc2.xkey; + + x76 = ((unsigned)pt[7] << 8) + (unsigned)pt[6]; + x54 = ((unsigned)pt[5] << 8) + (unsigned)pt[4]; + x32 = ((unsigned)pt[3] << 8) + (unsigned)pt[2]; + x10 = ((unsigned)pt[1] << 8) + (unsigned)pt[0]; + + for (i = 0; i < 16; i++) { + x10 = (x10 + (x32 & ~x76) + (x54 & x76) + xkey[4*i+0]) & 0xFFFF; + x10 = ((x10 << 1) | (x10 >> 15)); + + x32 = (x32 + (x54 & ~x10) + (x76 & x10) + xkey[4*i+1]) & 0xFFFF; + x32 = ((x32 << 2) | (x32 >> 14)); + + x54 = (x54 + (x76 & ~x32) + (x10 & x32) + xkey[4*i+2]) & 0xFFFF; + x54 = ((x54 << 3) | (x54 >> 13)); + + x76 = (x76 + (x10 & ~x54) + (x32 & x54) + xkey[4*i+3]) & 0xFFFF; + x76 = ((x76 << 5) | (x76 >> 11)); + + if (i == 4 || i == 10) { + x10 = (x10 + xkey[x76 & 63]) & 0xFFFF; + x32 = (x32 + xkey[x10 & 63]) & 0xFFFF; + x54 = (x54 + xkey[x32 & 63]) & 0xFFFF; + x76 = (x76 + xkey[x54 & 63]) & 0xFFFF; + } + } + + ct[0] = (unsigned char)x10; + ct[1] = (unsigned char)(x10 >> 8); + ct[2] = (unsigned char)x32; + ct[3] = (unsigned char)(x32 >> 8); + ct[4] = (unsigned char)x54; + ct[5] = (unsigned char)(x54 >> 8); + ct[6] = (unsigned char)x76; + ct[7] = (unsigned char)(x76 >> 8); + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int rc2_ecb_encrypt( const unsigned char *pt, + unsigned char *ct, + symmetric_key *skey) +{ + int err = _rc2_ecb_encrypt(pt, ct, skey); + burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 5); + return err; +} +#endif + +/**********************************************************************\ +* Decrypt an 8-byte block of ciphertext using the given key. * +\**********************************************************************/ +/** + Decrypts a block of text with RC2 + @param ct The input ciphertext (8 bytes) + @param pt The output plaintext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +#ifdef LTC_CLEAN_STACK +static int _rc2_ecb_decrypt( const unsigned char *ct, + unsigned char *pt, + symmetric_key *skey) +#else +int rc2_ecb_decrypt( const unsigned char *ct, + unsigned char *pt, + symmetric_key *skey) +#endif +{ + unsigned x76, x54, x32, x10; + unsigned *xkey; + int i; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + + xkey = skey->rc2.xkey; + + x76 = ((unsigned)ct[7] << 8) + (unsigned)ct[6]; + x54 = ((unsigned)ct[5] << 8) + (unsigned)ct[4]; + x32 = ((unsigned)ct[3] << 8) + (unsigned)ct[2]; + x10 = ((unsigned)ct[1] << 8) + (unsigned)ct[0]; + + for (i = 15; i >= 0; i--) { + if (i == 4 || i == 10) { + x76 = (x76 - xkey[x54 & 63]) & 0xFFFF; + x54 = (x54 - xkey[x32 & 63]) & 0xFFFF; + x32 = (x32 - xkey[x10 & 63]) & 0xFFFF; + x10 = (x10 - xkey[x76 & 63]) & 0xFFFF; + } + + x76 = ((x76 << 11) | (x76 >> 5)); + x76 = (x76 - ((x10 & ~x54) + (x32 & x54) + xkey[4*i+3])) & 0xFFFF; + + x54 = ((x54 << 13) | (x54 >> 3)); + x54 = (x54 - ((x76 & ~x32) + (x10 & x32) + xkey[4*i+2])) & 0xFFFF; + + x32 = ((x32 << 14) | (x32 >> 2)); + x32 = (x32 - ((x54 & ~x10) + (x76 & x10) + xkey[4*i+1])) & 0xFFFF; + + x10 = ((x10 << 15) | (x10 >> 1)); + x10 = (x10 - ((x32 & ~x76) + (x54 & x76) + xkey[4*i+0])) & 0xFFFF; + } + + pt[0] = (unsigned char)x10; + pt[1] = (unsigned char)(x10 >> 8); + pt[2] = (unsigned char)x32; + pt[3] = (unsigned char)(x32 >> 8); + pt[4] = (unsigned char)x54; + pt[5] = (unsigned char)(x54 >> 8); + pt[6] = (unsigned char)x76; + pt[7] = (unsigned char)(x76 >> 8); + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int rc2_ecb_decrypt( const unsigned char *ct, + unsigned char *pt, + symmetric_key *skey) +{ + int err = _rc2_ecb_decrypt(ct, pt, skey); + burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 4 + sizeof(int)); + return err; +} +#endif + +/** + Performs a self-test of the RC2 block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int rc2_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + int keylen, bits; + unsigned char key[16], pt[8], ct[8]; + } tests[] = { + + { 8, 63, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xeb, 0xb7, 0x73, 0xf9, 0x93, 0x27, 0x8e, 0xff } + }, + { 8, 64, + { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, + { 0x27, 0x8b, 0x27, 0xe4, 0x2e, 0x2f, 0x0d, 0x49 } + }, + { 8, 64, + { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + { 0x30, 0x64, 0x9e, 0xdf, 0x9b, 0xe7, 0xd2, 0xc2 } + }, + { 1, 64, + { 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x61, 0xa8, 0xa2, 0x44, 0xad, 0xac, 0xcc, 0xf0 } + }, + { 7, 64, + { 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x6c, 0xcf, 0x43, 0x08, 0x97, 0x4c, 0x26, 0x7f } + }, + { 16, 64, + { 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x7f, + 0x0f, 0x79, 0xc3, 0x84, 0x62, 0x7b, 0xaf, 0xb2 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x1a, 0x80, 0x7d, 0x27, 0x2b, 0xbe, 0x5d, 0xb1 } + }, + { 16, 128, + { 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x7f, + 0x0f, 0x79, 0xc3, 0x84, 0x62, 0x7b, 0xaf, 0xb2 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x22, 0x69, 0x55, 0x2a, 0xb0, 0xf8, 0x5c, 0xa6 } + } + }; + int x, y, err; + symmetric_key skey; + unsigned char tmp[2][8]; + + for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) { + zeromem(tmp, sizeof(tmp)); + if (tests[x].bits == (tests[x].keylen * 8)) { + if ((err = rc2_setup(tests[x].key, tests[x].keylen, 0, &skey)) != CRYPT_OK) { + return err; + } + } + else { + if ((err = rc2_setup_ex(tests[x].key, tests[x].keylen, tests[x].bits, 0, &skey)) != CRYPT_OK) { + return err; + } + } + + rc2_ecb_encrypt(tests[x].pt, tmp[0], &skey); + rc2_ecb_decrypt(tmp[0], tmp[1], &skey); + + if (compare_testvector(tmp[0], 8, tests[x].ct, 8, "RC2 CT", x) || + compare_testvector(tmp[1], 8, tests[x].pt, 8, "RC2 PT", x)) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) rc2_ecb_encrypt(tmp[0], tmp[0], &skey); + for (y = 0; y < 1000; y++) rc2_ecb_decrypt(tmp[0], tmp[0], &skey); + for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; + #endif +} + +/** Terminate the context + @param skey The scheduled key +*/ +void rc2_done(symmetric_key *skey) +{ + LTC_UNUSED_PARAM(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. + @return CRYPT_OK if the input key size is acceptable. +*/ +int rc2_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if (*keysize < 1) { + return CRYPT_INVALID_KEYSIZE; + } else if (*keysize > 128) { + *keysize = 128; + } + return CRYPT_OK; +} + +#endif + + + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/ciphers/rc5.c b/src/ltc/ciphers/rc5.c new file mode 100644 index 0000000..bd964e2 --- /dev/null +++ b/src/ltc/ciphers/rc5.c @@ -0,0 +1,323 @@ +/* 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://libtom.org + */ + +/** + @file rc5.c + LTC_RC5 code by Tom St Denis +*/ + +#include "tomcrypt.h" + +#ifdef LTC_RC5 + +const struct ltc_cipher_descriptor rc5_desc = +{ + "rc5", + 2, + 8, 128, 8, 12, + &rc5_setup, + &rc5_ecb_encrypt, + &rc5_ecb_decrypt, + &rc5_test, + &rc5_done, + &rc5_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +static const ulong32 stab[50] = { +0xb7e15163UL, 0x5618cb1cUL, 0xf45044d5UL, 0x9287be8eUL, 0x30bf3847UL, 0xcef6b200UL, 0x6d2e2bb9UL, 0x0b65a572UL, +0xa99d1f2bUL, 0x47d498e4UL, 0xe60c129dUL, 0x84438c56UL, 0x227b060fUL, 0xc0b27fc8UL, 0x5ee9f981UL, 0xfd21733aUL, +0x9b58ecf3UL, 0x399066acUL, 0xd7c7e065UL, 0x75ff5a1eUL, 0x1436d3d7UL, 0xb26e4d90UL, 0x50a5c749UL, 0xeedd4102UL, +0x8d14babbUL, 0x2b4c3474UL, 0xc983ae2dUL, 0x67bb27e6UL, 0x05f2a19fUL, 0xa42a1b58UL, 0x42619511UL, 0xe0990ecaUL, +0x7ed08883UL, 0x1d08023cUL, 0xbb3f7bf5UL, 0x5976f5aeUL, 0xf7ae6f67UL, 0x95e5e920UL, 0x341d62d9UL, 0xd254dc92UL, +0x708c564bUL, 0x0ec3d004UL, 0xacfb49bdUL, 0x4b32c376UL, 0xe96a3d2fUL, 0x87a1b6e8UL, 0x25d930a1UL, 0xc410aa5aUL, +0x62482413UL, 0x007f9dccUL +}; + + /** + Initialize the LTC_RC5 block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +#ifdef LTC_CLEAN_STACK +static int _rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#else +int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#endif +{ + ulong32 L[64], *S, A, B, i, j, v, s, t, l; + + LTC_ARGCHK(skey != NULL); + LTC_ARGCHK(key != NULL); + + /* test parameters */ + if (num_rounds == 0) { + num_rounds = rc5_desc.default_rounds; + } + + if (num_rounds < 12 || num_rounds > 24) { + return CRYPT_INVALID_ROUNDS; + } + + /* key must be between 64 and 1024 bits */ + if (keylen < 8 || keylen > 128) { + return CRYPT_INVALID_KEYSIZE; + } + + skey->rc5.rounds = num_rounds; + S = skey->rc5.K; + + /* copy the key into the L array */ + for (A = i = j = 0; i < (ulong32)keylen; ) { + A = (A << 8) | ((ulong32)(key[i++] & 255)); + if ((i & 3) == 0) { + L[j++] = BSWAP(A); + A = 0; + } + } + + if ((keylen & 3) != 0) { + A <<= (ulong32)((8 * (4 - (keylen&3)))); + L[j++] = BSWAP(A); + } + + /* setup the S array */ + t = (ulong32)(2 * (num_rounds + 1)); + XMEMCPY(S, stab, t * sizeof(*S)); + + /* mix buffer */ + s = 3 * MAX(t, j); + l = j; + for (A = B = i = j = v = 0; v < s; v++) { + A = S[i] = ROLc(S[i] + A + B, 3); + B = L[j] = ROL(L[j] + A + B, (A+B)); + if (++i == t) { i = 0; } + if (++j == l) { j = 0; } + } + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int x; + x = _rc5_setup(key, keylen, num_rounds, skey); + burn_stack(sizeof(ulong32) * 122 + sizeof(int)); + return x; +} +#endif + +/** + Encrypts a block of text with LTC_RC5 + @param pt The input plaintext (8 bytes) + @param ct The output ciphertext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +#ifdef LTC_CLEAN_STACK +static int _rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#else +int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#endif +{ + ulong32 A, B, *K; + int r; + LTC_ARGCHK(skey != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + + LOAD32L(A, &pt[0]); + LOAD32L(B, &pt[4]); + A += skey->rc5.K[0]; + B += skey->rc5.K[1]; + K = skey->rc5.K + 2; + + if ((skey->rc5.rounds & 1) == 0) { + for (r = 0; r < skey->rc5.rounds; r += 2) { + A = ROL(A ^ B, B) + K[0]; + B = ROL(B ^ A, A) + K[1]; + A = ROL(A ^ B, B) + K[2]; + B = ROL(B ^ A, A) + K[3]; + K += 4; + } + } else { + for (r = 0; r < skey->rc5.rounds; r++) { + A = ROL(A ^ B, B) + K[0]; + B = ROL(B ^ A, A) + K[1]; + K += 2; + } + } + STORE32L(A, &ct[0]); + STORE32L(B, &ct[4]); + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + int err = _rc5_ecb_encrypt(pt, ct, skey); + burn_stack(sizeof(ulong32) * 2 + sizeof(int)); + return err; +} +#endif + +/** + Decrypts a block of text with LTC_RC5 + @param ct The input ciphertext (8 bytes) + @param pt The output plaintext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +#ifdef LTC_CLEAN_STACK +static int _rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#else +int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#endif +{ + ulong32 A, B, *K; + int r; + LTC_ARGCHK(skey != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + + LOAD32L(A, &ct[0]); + LOAD32L(B, &ct[4]); + K = skey->rc5.K + (skey->rc5.rounds << 1); + + if ((skey->rc5.rounds & 1) == 0) { + K -= 2; + for (r = skey->rc5.rounds - 1; r >= 0; r -= 2) { + B = ROR(B - K[3], A) ^ A; + A = ROR(A - K[2], B) ^ B; + B = ROR(B - K[1], A) ^ A; + A = ROR(A - K[0], B) ^ B; + K -= 4; + } + } else { + for (r = skey->rc5.rounds - 1; r >= 0; r--) { + B = ROR(B - K[1], A) ^ A; + A = ROR(A - K[0], B) ^ B; + K -= 2; + } + } + A -= skey->rc5.K[0]; + B -= skey->rc5.K[1]; + STORE32L(A, &pt[0]); + STORE32L(B, &pt[4]); + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + int err = _rc5_ecb_decrypt(ct, pt, skey); + burn_stack(sizeof(ulong32) * 2 + sizeof(int)); + return err; +} +#endif + +/** + Performs a self-test of the LTC_RC5 block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int rc5_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + unsigned char key[16], pt[8], ct[8]; + } tests[] = { + { + { 0x91, 0x5f, 0x46, 0x19, 0xbe, 0x41, 0xb2, 0x51, + 0x63, 0x55, 0xa5, 0x01, 0x10, 0xa9, 0xce, 0x91 }, + { 0x21, 0xa5, 0xdb, 0xee, 0x15, 0x4b, 0x8f, 0x6d }, + { 0xf7, 0xc0, 0x13, 0xac, 0x5b, 0x2b, 0x89, 0x52 } + }, + { + { 0x78, 0x33, 0x48, 0xe7, 0x5a, 0xeb, 0x0f, 0x2f, + 0xd7, 0xb1, 0x69, 0xbb, 0x8d, 0xc1, 0x67, 0x87 }, + { 0xF7, 0xC0, 0x13, 0xAC, 0x5B, 0x2B, 0x89, 0x52 }, + { 0x2F, 0x42, 0xB3, 0xB7, 0x03, 0x69, 0xFC, 0x92 } + }, + { + { 0xDC, 0x49, 0xdb, 0x13, 0x75, 0xa5, 0x58, 0x4f, + 0x64, 0x85, 0xb4, 0x13, 0xb5, 0xf1, 0x2b, 0xaf }, + { 0x2F, 0x42, 0xB3, 0xB7, 0x03, 0x69, 0xFC, 0x92 }, + { 0x65, 0xc1, 0x78, 0xb2, 0x84, 0xd1, 0x97, 0xcc } + } + }; + unsigned char tmp[2][8]; + int x, y, err; + symmetric_key key; + + for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) { + /* setup key */ + if ((err = rc5_setup(tests[x].key, 16, 12, &key)) != CRYPT_OK) { + return err; + } + + /* encrypt and decrypt */ + rc5_ecb_encrypt(tests[x].pt, tmp[0], &key); + rc5_ecb_decrypt(tmp[0], tmp[1], &key); + + /* compare */ + if (XMEMCMP(tmp[0], tests[x].ct, 8) != 0 || XMEMCMP(tmp[1], tests[x].pt, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) rc5_ecb_encrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) rc5_ecb_decrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; + #endif +} + +/** Terminate the context + @param skey The scheduled key +*/ +void rc5_done(symmetric_key *skey) +{ + LTC_UNUSED_PARAM(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. + @return CRYPT_OK if the input key size is acceptable. +*/ +int rc5_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if (*keysize < 8) { + return CRYPT_INVALID_KEYSIZE; + } else if (*keysize > 128) { + *keysize = 128; + } + return CRYPT_OK; +} + +#endif + + + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/ciphers/rc6.c b/src/ltc/ciphers/rc6.c new file mode 100644 index 0000000..48d413d --- /dev/null +++ b/src/ltc/ciphers/rc6.c @@ -0,0 +1,349 @@ +/* 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://libtom.org + */ + +/** + @file rc6.c + LTC_RC6 code by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_RC6 + +const struct ltc_cipher_descriptor rc6_desc = +{ + "rc6", + 3, + 8, 128, 16, 20, + &rc6_setup, + &rc6_ecb_encrypt, + &rc6_ecb_decrypt, + &rc6_test, + &rc6_done, + &rc6_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +static const ulong32 stab[44] = { +0xb7e15163UL, 0x5618cb1cUL, 0xf45044d5UL, 0x9287be8eUL, 0x30bf3847UL, 0xcef6b200UL, 0x6d2e2bb9UL, 0x0b65a572UL, +0xa99d1f2bUL, 0x47d498e4UL, 0xe60c129dUL, 0x84438c56UL, 0x227b060fUL, 0xc0b27fc8UL, 0x5ee9f981UL, 0xfd21733aUL, +0x9b58ecf3UL, 0x399066acUL, 0xd7c7e065UL, 0x75ff5a1eUL, 0x1436d3d7UL, 0xb26e4d90UL, 0x50a5c749UL, 0xeedd4102UL, +0x8d14babbUL, 0x2b4c3474UL, 0xc983ae2dUL, 0x67bb27e6UL, 0x05f2a19fUL, 0xa42a1b58UL, 0x42619511UL, 0xe0990ecaUL, +0x7ed08883UL, 0x1d08023cUL, 0xbb3f7bf5UL, 0x5976f5aeUL, 0xf7ae6f67UL, 0x95e5e920UL, 0x341d62d9UL, 0xd254dc92UL, +0x708c564bUL, 0x0ec3d004UL, 0xacfb49bdUL, 0x4b32c376UL }; + + /** + Initialize the LTC_RC6 block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +#ifdef LTC_CLEAN_STACK +static int _rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#else +int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#endif +{ + ulong32 L[64], S[50], A, B, i, j, v, s, l; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + /* test parameters */ + if (num_rounds != 0 && num_rounds != 20) { + return CRYPT_INVALID_ROUNDS; + } + + /* key must be between 64 and 1024 bits */ + if (keylen < 8 || keylen > 128) { + return CRYPT_INVALID_KEYSIZE; + } + + /* copy the key into the L array */ + for (A = i = j = 0; i < (ulong32)keylen; ) { + A = (A << 8) | ((ulong32)(key[i++] & 255)); + if (!(i & 3)) { + L[j++] = BSWAP(A); + A = 0; + } + } + + /* handle odd sized keys */ + if (keylen & 3) { + A <<= (8 * (4 - (keylen&3))); + L[j++] = BSWAP(A); + } + + /* setup the S array */ + XMEMCPY(S, stab, 44 * sizeof(stab[0])); + + /* mix buffer */ + s = 3 * MAX(44, j); + l = j; + for (A = B = i = j = v = 0; v < s; v++) { + A = S[i] = ROLc(S[i] + A + B, 3); + B = L[j] = ROL(L[j] + A + B, (A+B)); + if (++i == 44) { i = 0; } + if (++j == l) { j = 0; } + } + + /* copy to key */ + for (i = 0; i < 44; i++) { + skey->rc6.K[i] = S[i]; + } + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int x; + x = _rc6_setup(key, keylen, num_rounds, skey); + burn_stack(sizeof(ulong32) * 122); + return x; +} +#endif + +/** + Encrypts a block of text with LTC_RC6 + @param pt The input plaintext (16 bytes) + @param ct The output ciphertext (16 bytes) + @param skey The key as scheduled +*/ +#ifdef LTC_CLEAN_STACK +static int _rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#else +int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#endif +{ + ulong32 a,b,c,d,t,u, *K; + int r; + + LTC_ARGCHK(skey != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LOAD32L(a,&pt[0]);LOAD32L(b,&pt[4]);LOAD32L(c,&pt[8]);LOAD32L(d,&pt[12]); + + b += skey->rc6.K[0]; + d += skey->rc6.K[1]; + +#define RND(a,b,c,d) \ + t = (b * (b + b + 1)); t = ROLc(t, 5); \ + u = (d * (d + d + 1)); u = ROLc(u, 5); \ + a = ROL(a^t,u) + K[0]; \ + c = ROL(c^u,t) + K[1]; K += 2; + + K = skey->rc6.K + 2; + for (r = 0; r < 20; r += 4) { + RND(a,b,c,d); + RND(b,c,d,a); + RND(c,d,a,b); + RND(d,a,b,c); + } + +#undef RND + + a += skey->rc6.K[42]; + c += skey->rc6.K[43]; + STORE32L(a,&ct[0]);STORE32L(b,&ct[4]);STORE32L(c,&ct[8]);STORE32L(d,&ct[12]); + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + int err = _rc6_ecb_encrypt(pt, ct, skey); + burn_stack(sizeof(ulong32) * 6 + sizeof(int)); + return err; +} +#endif + +/** + Decrypts a block of text with LTC_RC6 + @param ct The input ciphertext (16 bytes) + @param pt The output plaintext (16 bytes) + @param skey The key as scheduled +*/ +#ifdef LTC_CLEAN_STACK +static int _rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#else +int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#endif +{ + ulong32 a,b,c,d,t,u, *K; + int r; + + LTC_ARGCHK(skey != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + + LOAD32L(a,&ct[0]);LOAD32L(b,&ct[4]);LOAD32L(c,&ct[8]);LOAD32L(d,&ct[12]); + a -= skey->rc6.K[42]; + c -= skey->rc6.K[43]; + +#define RND(a,b,c,d) \ + t = (b * (b + b + 1)); t = ROLc(t, 5); \ + u = (d * (d + d + 1)); u = ROLc(u, 5); \ + c = ROR(c - K[1], t) ^ u; \ + a = ROR(a - K[0], u) ^ t; K -= 2; + + K = skey->rc6.K + 40; + + for (r = 0; r < 20; r += 4) { + RND(d,a,b,c); + RND(c,d,a,b); + RND(b,c,d,a); + RND(a,b,c,d); + } + +#undef RND + + b -= skey->rc6.K[0]; + d -= skey->rc6.K[1]; + STORE32L(a,&pt[0]);STORE32L(b,&pt[4]);STORE32L(c,&pt[8]);STORE32L(d,&pt[12]); + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + int err = _rc6_ecb_decrypt(ct, pt, skey); + burn_stack(sizeof(ulong32) * 6 + sizeof(int)); + return err; +} +#endif + +/** + Performs a self-test of the LTC_RC6 block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int rc6_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + int keylen; + unsigned char key[32], pt[16], ct[16]; + } tests[] = { + { + 16, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79, + 0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 }, + { 0x52, 0x4e, 0x19, 0x2f, 0x47, 0x15, 0xc6, 0x23, + 0x1f, 0x51, 0xf6, 0x36, 0x7e, 0xa4, 0x3f, 0x18 } + }, + { + 24, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, + 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79, + 0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 }, + { 0x68, 0x83, 0x29, 0xd0, 0x19, 0xe5, 0x05, 0x04, + 0x1e, 0x52, 0xe9, 0x2a, 0xf9, 0x52, 0x91, 0xd4 } + }, + { + 32, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, + 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0, + 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe }, + { 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79, + 0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 }, + { 0xc8, 0x24, 0x18, 0x16, 0xf0, 0xd7, 0xe4, 0x89, + 0x20, 0xad, 0x16, 0xa1, 0x67, 0x4e, 0x5d, 0x48 } + } + }; + unsigned char tmp[2][16]; + int x, y, err; + symmetric_key key; + + for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) { + /* setup key */ + if ((err = rc6_setup(tests[x].key, tests[x].keylen, 0, &key)) != CRYPT_OK) { + return err; + } + + /* encrypt and decrypt */ + rc6_ecb_encrypt(tests[x].pt, tmp[0], &key); + rc6_ecb_decrypt(tmp[0], tmp[1], &key); + + /* compare */ + if (XMEMCMP(tmp[0], tests[x].ct, 16) || XMEMCMP(tmp[1], tests[x].pt, 16)) { +#if 0 + printf("\n\nFailed test %d\n", x); + if (XMEMCMP(tmp[0], tests[x].ct, 16)) { + printf("Ciphertext: "); + for (y = 0; y < 16; y++) printf("%02x ", tmp[0][y]); + printf("\nExpected : "); + for (y = 0; y < 16; y++) printf("%02x ", tests[x].ct[y]); + printf("\n"); + } + if (XMEMCMP(tmp[1], tests[x].pt, 16)) { + printf("Plaintext: "); + for (y = 0; y < 16; y++) printf("%02x ", tmp[0][y]); + printf("\nExpected : "); + for (y = 0; y < 16; y++) printf("%02x ", tests[x].pt[y]); + printf("\n"); + } +#endif + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 16; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) rc6_ecb_encrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) rc6_ecb_decrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; + #endif +} + +/** Terminate the context + @param skey The scheduled key +*/ +void rc6_done(symmetric_key *skey) +{ + LTC_UNUSED_PARAM(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. + @return CRYPT_OK if the input key size is acceptable. +*/ +int rc6_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if (*keysize < 8) { + return CRYPT_INVALID_KEYSIZE; + } else if (*keysize > 128) { + *keysize = 128; + } + return CRYPT_OK; +} + +#endif /*LTC_RC6*/ + + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/ciphers/safer/safer.c b/src/ltc/ciphers/safer/safer.c new file mode 100644 index 0000000..85af1f2 --- /dev/null +++ b/src/ltc/ciphers/safer/safer.c @@ -0,0 +1,495 @@ +/* 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://libtom.org + */ + +/******************************************************************************* +* +* FILE: safer.c +* +* LTC_DESCRIPTION: block-cipher algorithm LTC_SAFER (Secure And Fast Encryption +* Routine) in its four versions: LTC_SAFER K-64, LTC_SAFER K-128, +* LTC_SAFER SK-64 and LTC_SAFER SK-128. +* +* AUTHOR: Richard De Moliner (demoliner@isi.ee.ethz.ch) +* Signal and Information Processing Laboratory +* Swiss Federal Institute of Technology +* CH-8092 Zuerich, Switzerland +* +* DATE: September 9, 1995 +* +* CHANGE HISTORY: +* +*******************************************************************************/ + +#include + +#ifdef LTC_SAFER + +#define __LTC_SAFER_TAB_C__ +#include "safer_tab.c" + +const struct ltc_cipher_descriptor + safer_k64_desc = { + "safer-k64", + 8, 8, 8, 8, LTC_SAFER_K64_DEFAULT_NOF_ROUNDS, + &safer_k64_setup, + &safer_ecb_encrypt, + &safer_ecb_decrypt, + &safer_k64_test, + &safer_done, + &safer_64_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + }, + + safer_sk64_desc = { + "safer-sk64", + 9, 8, 8, 8, LTC_SAFER_SK64_DEFAULT_NOF_ROUNDS, + &safer_sk64_setup, + &safer_ecb_encrypt, + &safer_ecb_decrypt, + &safer_sk64_test, + &safer_done, + &safer_64_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + }, + + safer_k128_desc = { + "safer-k128", + 10, 16, 16, 8, LTC_SAFER_K128_DEFAULT_NOF_ROUNDS, + &safer_k128_setup, + &safer_ecb_encrypt, + &safer_ecb_decrypt, + &safer_sk128_test, + &safer_done, + &safer_128_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + }, + + safer_sk128_desc = { + "safer-sk128", + 11, 16, 16, 8, LTC_SAFER_SK128_DEFAULT_NOF_ROUNDS, + &safer_sk128_setup, + &safer_ecb_encrypt, + &safer_ecb_decrypt, + &safer_sk128_test, + &safer_done, + &safer_128_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + }; + +/******************* Constants ************************************************/ +/* #define TAB_LEN 256 */ + +/******************* Assertions ***********************************************/ + +/******************* Macros ***************************************************/ +#define ROL8(x, n) ((unsigned char)((unsigned int)(x) << (n)\ + |(unsigned int)((x) & 0xFF) >> (8 - (n)))) +#define EXP(x) safer_ebox[(x) & 0xFF] +#define LOG(x) safer_lbox[(x) & 0xFF] +#define PHT(x, y) { y += x; x += y; } +#define IPHT(x, y) { x -= y; y -= x; } + +/******************* Types ****************************************************/ + +#ifdef LTC_CLEAN_STACK +static void _Safer_Expand_Userkey(const unsigned char *userkey_1, + const unsigned char *userkey_2, + unsigned int nof_rounds, + int strengthened, + safer_key_t key) +#else +static void Safer_Expand_Userkey(const unsigned char *userkey_1, + const unsigned char *userkey_2, + unsigned int nof_rounds, + int strengthened, + safer_key_t key) +#endif +{ unsigned int i, j, k; + unsigned char ka[LTC_SAFER_BLOCK_LEN + 1]; + unsigned char kb[LTC_SAFER_BLOCK_LEN + 1]; + + if (LTC_SAFER_MAX_NOF_ROUNDS < nof_rounds) + nof_rounds = LTC_SAFER_MAX_NOF_ROUNDS; + *key++ = (unsigned char)nof_rounds; + ka[LTC_SAFER_BLOCK_LEN] = (unsigned char)0; + kb[LTC_SAFER_BLOCK_LEN] = (unsigned char)0; + k = 0; + for (j = 0; j < LTC_SAFER_BLOCK_LEN; j++) { + ka[j] = ROL8(userkey_1[j], 5); + ka[LTC_SAFER_BLOCK_LEN] ^= ka[j]; + kb[j] = *key++ = userkey_2[j]; + kb[LTC_SAFER_BLOCK_LEN] ^= kb[j]; + } + for (i = 1; i <= nof_rounds; i++) { + for (j = 0; j < LTC_SAFER_BLOCK_LEN + 1; j++) { + ka[j] = ROL8(ka[j], 6); + kb[j] = ROL8(kb[j], 6); + } + if (strengthened) { + k = 2 * i - 1; + while (k >= (LTC_SAFER_BLOCK_LEN + 1)) { k -= LTC_SAFER_BLOCK_LEN + 1; } + } + for (j = 0; j < LTC_SAFER_BLOCK_LEN; j++) { + if (strengthened) { + *key++ = (ka[k] + + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 1)&0xFF)]]) & 0xFF; + if (++k == (LTC_SAFER_BLOCK_LEN + 1)) { k = 0; } + } else { + *key++ = (ka[j] + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 1)&0xFF)]]) & 0xFF; + } + } + if (strengthened) { + k = 2 * i; + while (k >= (LTC_SAFER_BLOCK_LEN + 1)) { k -= LTC_SAFER_BLOCK_LEN + 1; } + } + for (j = 0; j < LTC_SAFER_BLOCK_LEN; j++) { + if (strengthened) { + *key++ = (kb[k] + + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 10)&0xFF)]]) & 0xFF; + if (++k == (LTC_SAFER_BLOCK_LEN + 1)) { k = 0; } + } else { + *key++ = (kb[j] + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 10)&0xFF)]]) & 0xFF; + } + } + } + +#ifdef LTC_CLEAN_STACK + zeromem(ka, sizeof(ka)); + zeromem(kb, sizeof(kb)); +#endif +} + +#ifdef LTC_CLEAN_STACK +static void Safer_Expand_Userkey(const unsigned char *userkey_1, + const unsigned char *userkey_2, + unsigned int nof_rounds, + int strengthened, + safer_key_t key) +{ + _Safer_Expand_Userkey(userkey_1, userkey_2, nof_rounds, strengthened, key); + burn_stack(sizeof(unsigned char) * (2 * (LTC_SAFER_BLOCK_LEN + 1)) + sizeof(unsigned int)*2); +} +#endif + +int safer_k64_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) +{ + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + if (numrounds != 0 && (numrounds < 6 || numrounds > LTC_SAFER_MAX_NOF_ROUNDS)) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen != 8) { + return CRYPT_INVALID_KEYSIZE; + } + + Safer_Expand_Userkey(key, key, (unsigned int)(numrounds != 0 ?numrounds:LTC_SAFER_K64_DEFAULT_NOF_ROUNDS), 0, skey->safer.key); + return CRYPT_OK; +} + +int safer_sk64_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) +{ + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + if (numrounds != 0 && (numrounds < 6 || numrounds > LTC_SAFER_MAX_NOF_ROUNDS)) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen != 8) { + return CRYPT_INVALID_KEYSIZE; + } + + Safer_Expand_Userkey(key, key, (unsigned int)(numrounds != 0 ?numrounds:LTC_SAFER_SK64_DEFAULT_NOF_ROUNDS), 1, skey->safer.key); + return CRYPT_OK; +} + +int safer_k128_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) +{ + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + if (numrounds != 0 && (numrounds < 6 || numrounds > LTC_SAFER_MAX_NOF_ROUNDS)) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen != 16) { + return CRYPT_INVALID_KEYSIZE; + } + + Safer_Expand_Userkey(key, key+8, (unsigned int)(numrounds != 0 ?numrounds:LTC_SAFER_K128_DEFAULT_NOF_ROUNDS), 0, skey->safer.key); + return CRYPT_OK; +} + +int safer_sk128_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) +{ + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + if (numrounds != 0 && (numrounds < 6 || numrounds > LTC_SAFER_MAX_NOF_ROUNDS)) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen != 16) { + return CRYPT_INVALID_KEYSIZE; + } + + Safer_Expand_Userkey(key, key+8, (unsigned int)(numrounds != 0?numrounds:LTC_SAFER_SK128_DEFAULT_NOF_ROUNDS), 1, skey->safer.key); + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +static int _safer_ecb_encrypt(const unsigned char *block_in, + unsigned char *block_out, + symmetric_key *skey) +#else +int safer_ecb_encrypt(const unsigned char *block_in, + unsigned char *block_out, + symmetric_key *skey) +#endif +{ unsigned char a, b, c, d, e, f, g, h, t; + unsigned int round; + unsigned char *key; + + LTC_ARGCHK(block_in != NULL); + LTC_ARGCHK(block_out != NULL); + LTC_ARGCHK(skey != NULL); + + key = skey->safer.key; + a = block_in[0]; b = block_in[1]; c = block_in[2]; d = block_in[3]; + e = block_in[4]; f = block_in[5]; g = block_in[6]; h = block_in[7]; + if (LTC_SAFER_MAX_NOF_ROUNDS < (round = *key)) round = LTC_SAFER_MAX_NOF_ROUNDS; + while(round-- > 0) + { + a ^= *++key; b += *++key; c += *++key; d ^= *++key; + e ^= *++key; f += *++key; g += *++key; h ^= *++key; + a = EXP(a) + *++key; b = LOG(b) ^ *++key; + c = LOG(c) ^ *++key; d = EXP(d) + *++key; + e = EXP(e) + *++key; f = LOG(f) ^ *++key; + g = LOG(g) ^ *++key; h = EXP(h) + *++key; + PHT(a, b); PHT(c, d); PHT(e, f); PHT(g, h); + PHT(a, c); PHT(e, g); PHT(b, d); PHT(f, h); + PHT(a, e); PHT(b, f); PHT(c, g); PHT(d, h); + t = b; b = e; e = c; c = t; t = d; d = f; f = g; g = t; + } + a ^= *++key; b += *++key; c += *++key; d ^= *++key; + e ^= *++key; f += *++key; g += *++key; h ^= *++key; + block_out[0] = a & 0xFF; block_out[1] = b & 0xFF; + block_out[2] = c & 0xFF; block_out[3] = d & 0xFF; + block_out[4] = e & 0xFF; block_out[5] = f & 0xFF; + block_out[6] = g & 0xFF; block_out[7] = h & 0xFF; + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int safer_ecb_encrypt(const unsigned char *block_in, + unsigned char *block_out, + symmetric_key *skey) +{ + int err = _safer_ecb_encrypt(block_in, block_out, skey); + burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *)); + return err; +} +#endif + +#ifdef LTC_CLEAN_STACK +static int _safer_ecb_decrypt(const unsigned char *block_in, + unsigned char *block_out, + symmetric_key *skey) +#else +int safer_ecb_decrypt(const unsigned char *block_in, + unsigned char *block_out, + symmetric_key *skey) +#endif +{ unsigned char a, b, c, d, e, f, g, h, t; + unsigned int round; + unsigned char *key; + + LTC_ARGCHK(block_in != NULL); + LTC_ARGCHK(block_out != NULL); + LTC_ARGCHK(skey != NULL); + + key = skey->safer.key; + a = block_in[0]; b = block_in[1]; c = block_in[2]; d = block_in[3]; + e = block_in[4]; f = block_in[5]; g = block_in[6]; h = block_in[7]; + if (LTC_SAFER_MAX_NOF_ROUNDS < (round = *key)) round = LTC_SAFER_MAX_NOF_ROUNDS; + key += LTC_SAFER_BLOCK_LEN * (1 + 2 * round); + h ^= *key; g -= *--key; f -= *--key; e ^= *--key; + d ^= *--key; c -= *--key; b -= *--key; a ^= *--key; + while (round--) + { + t = e; e = b; b = c; c = t; t = f; f = d; d = g; g = t; + IPHT(a, e); IPHT(b, f); IPHT(c, g); IPHT(d, h); + IPHT(a, c); IPHT(e, g); IPHT(b, d); IPHT(f, h); + IPHT(a, b); IPHT(c, d); IPHT(e, f); IPHT(g, h); + h -= *--key; g ^= *--key; f ^= *--key; e -= *--key; + d -= *--key; c ^= *--key; b ^= *--key; a -= *--key; + h = LOG(h) ^ *--key; g = EXP(g) - *--key; + f = EXP(f) - *--key; e = LOG(e) ^ *--key; + d = LOG(d) ^ *--key; c = EXP(c) - *--key; + b = EXP(b) - *--key; a = LOG(a) ^ *--key; + } + block_out[0] = a & 0xFF; block_out[1] = b & 0xFF; + block_out[2] = c & 0xFF; block_out[3] = d & 0xFF; + block_out[4] = e & 0xFF; block_out[5] = f & 0xFF; + block_out[6] = g & 0xFF; block_out[7] = h & 0xFF; + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int safer_ecb_decrypt(const unsigned char *block_in, + unsigned char *block_out, + symmetric_key *skey) +{ + int err = _safer_ecb_decrypt(block_in, block_out, skey); + burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *)); + return err; +} +#endif + +int safer_64_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if (*keysize < 8) { + return CRYPT_INVALID_KEYSIZE; + } else { + *keysize = 8; + return CRYPT_OK; + } +} + +int safer_128_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if (*keysize < 16) { + return CRYPT_INVALID_KEYSIZE; + } else { + *keysize = 16; + return CRYPT_OK; + } +} + +int safer_k64_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const unsigned char k64_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, + k64_key[] = { 8, 7, 6, 5, 4, 3, 2, 1 }, + k64_ct[] = { 200, 242, 156, 221, 135, 120, 62, 217 }; + + symmetric_key skey; + unsigned char buf[2][8]; + int err; + + /* test K64 */ + if ((err = safer_k64_setup(k64_key, 8, 6, &skey)) != CRYPT_OK) { + return err; + } + safer_ecb_encrypt(k64_pt, buf[0], &skey); + safer_ecb_decrypt(buf[0], buf[1], &skey); + + if (XMEMCMP(buf[0], k64_ct, 8) != 0 || XMEMCMP(buf[1], k64_pt, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; + #endif +} + + +int safer_sk64_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const unsigned char sk64_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, + sk64_key[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, + sk64_ct[] = { 95, 206, 155, 162, 5, 132, 56, 199 }; + + symmetric_key skey; + unsigned char buf[2][8]; + int err, y; + + /* test SK64 */ + if ((err = safer_sk64_setup(sk64_key, 8, 6, &skey)) != CRYPT_OK) { + return err; + } + + safer_ecb_encrypt(sk64_pt, buf[0], &skey); + safer_ecb_decrypt(buf[0], buf[1], &skey); + + if (XMEMCMP(buf[0], sk64_ct, 8) != 0 || XMEMCMP(buf[1], sk64_pt, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) buf[0][y] = 0; + for (y = 0; y < 1000; y++) safer_ecb_encrypt(buf[0], buf[0], &skey); + for (y = 0; y < 1000; y++) safer_ecb_decrypt(buf[0], buf[0], &skey); + for (y = 0; y < 8; y++) if (buf[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + + return CRYPT_OK; + #endif +} + +/** Terminate the context + @param skey The scheduled key +*/ +void safer_done(symmetric_key *skey) +{ + LTC_UNUSED_PARAM(skey); +} + +int safer_sk128_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const unsigned char sk128_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, + sk128_key[] = { 1, 2, 3, 4, 5, 6, 7, 8, + 0, 0, 0, 0, 0, 0, 0, 0 }, + sk128_ct[] = { 255, 120, 17, 228, 179, 167, 46, 113 }; + + symmetric_key skey; + unsigned char buf[2][8]; + int err, y; + + /* test SK128 */ + if ((err = safer_sk128_setup(sk128_key, 16, 0, &skey)) != CRYPT_OK) { + return err; + } + safer_ecb_encrypt(sk128_pt, buf[0], &skey); + safer_ecb_decrypt(buf[0], buf[1], &skey); + + if (XMEMCMP(buf[0], sk128_ct, 8) != 0 || XMEMCMP(buf[1], sk128_pt, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) buf[0][y] = 0; + for (y = 0; y < 1000; y++) safer_ecb_encrypt(buf[0], buf[0], &skey); + for (y = 0; y < 1000; y++) safer_ecb_decrypt(buf[0], buf[0], &skey); + for (y = 0; y < 8; y++) if (buf[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + + return CRYPT_OK; + #endif +} + +#endif + + + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/ciphers/safer/safer_tab.c b/src/ltc/ciphers/safer/safer_tab.c new file mode 100644 index 0000000..308fe55 --- /dev/null +++ b/src/ltc/ciphers/safer/safer_tab.c @@ -0,0 +1,66 @@ +/* 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://libtom.org + */ + +/** + @file safer_tab.c + Tables for LTC_SAFER block ciphers +*/ + +#ifdef __LTC_SAFER_TAB_C__ + +/* This is the box defined by ebox[x] = 45^x mod 257. + * Its assumed that the value "256" corresponds to zero. */ +static const unsigned char safer_ebox[256] = { + 1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207, 63, + 8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247, + 64, 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141, 177, +255, 167, 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, +241, 51, 239, 218, 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, 20, +129, 151, 113, 202, 95, 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160, + 4, 180, 133, 74, 246, 19, 84, 182, 223, 12, 26, 142, 222, 224, 57, 252, + 32, 155, 36, 78, 169, 152, 158, 171, 242, 96, 208, 108, 234, 250, 199, 217, + 0, 212, 31, 110, 67, 188, 236, 83, 137, 254, 122, 93, 73, 201, 50, 194, +249, 154, 248, 109, 22, 219, 89, 150, 68, 233, 205, 230, 70, 66, 143, 10, +193, 204, 185, 101, 176, 210, 198, 172, 30, 65, 98, 41, 46, 14, 116, 80, + 2, 90, 195, 37, 123, 138, 42, 91, 240, 6, 13, 71, 111, 112, 157, 126, + 16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104, 54, 117, 125, 228, 237, +128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175, 165, 229, 25, 97, +253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35, 33, 200, 5, +225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7, 58, 40 +}; + +/* This is the inverse of ebox or the base 45 logarithm */ +static const unsigned char safer_lbox[256] = { +128, 0, 176, 9, 96, 239, 185, 253, 16, 18, 159, 228, 105, 186, 173, 248, +192, 56, 194, 101, 79, 6, 148, 252, 25, 222, 106, 27, 93, 78, 168, 130, +112, 237, 232, 236, 114, 179, 21, 195, 255, 171, 182, 71, 68, 1, 172, 37, +201, 250, 142, 65, 26, 33, 203, 211, 13, 110, 254, 38, 88, 218, 50, 15, + 32, 169, 157, 132, 152, 5, 156, 187, 34, 140, 99, 231, 197, 225, 115, 198, +175, 36, 91, 135, 102, 39, 247, 87, 244, 150, 177, 183, 92, 139, 213, 84, +121, 223, 170, 246, 62, 163, 241, 17, 202, 245, 209, 23, 123, 147, 131, 188, +189, 82, 30, 235, 174, 204, 214, 53, 8, 200, 138, 180, 226, 205, 191, 217, +208, 80, 89, 63, 77, 98, 52, 10, 72, 136, 181, 86, 76, 46, 107, 158, +210, 61, 60, 3, 19, 251, 151, 81, 117, 74, 145, 113, 35, 190, 118, 42, + 95, 249, 212, 85, 11, 220, 55, 49, 22, 116, 215, 119, 167, 230, 7, 219, +164, 47, 70, 243, 97, 69, 103, 227, 12, 162, 59, 28, 133, 24, 4, 29, + 41, 160, 143, 178, 90, 216, 166, 126, 238, 141, 83, 75, 161, 154, 193, 14, +122, 73, 165, 44, 129, 196, 199, 54, 43, 127, 67, 149, 51, 242, 108, 104, +109, 240, 2, 40, 206, 221, 155, 234, 94, 153, 124, 20, 134, 207, 229, 66, +184, 64, 120, 45, 58, 233, 100, 31, 146, 144, 125, 57, 111, 224, 137, 48 +}; + +#endif /* __LTC_SAFER_TAB_C__ */ + + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/ciphers/safer/saferp.c b/src/ltc/ciphers/safer/saferp.c new file mode 100644 index 0000000..e5f8bf3 --- /dev/null +++ b/src/ltc/ciphers/safer/saferp.c @@ -0,0 +1,569 @@ +/* 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://libtom.org + */ + +/** + @file saferp.c + LTC_SAFER+ Implementation by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_SAFERP + +#define __LTC_SAFER_TAB_C__ +#include "safer_tab.c" + +const struct ltc_cipher_descriptor saferp_desc = +{ + "safer+", + 4, + 16, 32, 16, 8, + &saferp_setup, + &saferp_ecb_encrypt, + &saferp_ecb_decrypt, + &saferp_test, + &saferp_done, + &saferp_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +/* ROUND(b,i) + * + * This is one forward key application. Note the basic form is + * key addition, substitution, key addition. The safer_ebox and safer_lbox + * are the exponentiation box and logarithm boxes respectively. + * The value of 'i' is the current round number which allows this + * function to be unrolled massively. Most of LTC_SAFER+'s speed + * comes from not having to compute indirect accesses into the + * array of 16 bytes b[0..15] which is the block of data +*/ + +#define ROUND(b, i) do { \ + b[0] = (safer_ebox[(b[0] ^ skey->saferp.K[i][0]) & 255] + skey->saferp.K[i+1][0]) & 255; \ + b[1] = safer_lbox[(b[1] + skey->saferp.K[i][1]) & 255] ^ skey->saferp.K[i+1][1]; \ + b[2] = safer_lbox[(b[2] + skey->saferp.K[i][2]) & 255] ^ skey->saferp.K[i+1][2]; \ + b[3] = (safer_ebox[(b[3] ^ skey->saferp.K[i][3]) & 255] + skey->saferp.K[i+1][3]) & 255; \ + b[4] = (safer_ebox[(b[4] ^ skey->saferp.K[i][4]) & 255] + skey->saferp.K[i+1][4]) & 255; \ + b[5] = safer_lbox[(b[5] + skey->saferp.K[i][5]) & 255] ^ skey->saferp.K[i+1][5]; \ + b[6] = safer_lbox[(b[6] + skey->saferp.K[i][6]) & 255] ^ skey->saferp.K[i+1][6]; \ + b[7] = (safer_ebox[(b[7] ^ skey->saferp.K[i][7]) & 255] + skey->saferp.K[i+1][7]) & 255; \ + b[8] = (safer_ebox[(b[8] ^ skey->saferp.K[i][8]) & 255] + skey->saferp.K[i+1][8]) & 255; \ + b[9] = safer_lbox[(b[9] + skey->saferp.K[i][9]) & 255] ^ skey->saferp.K[i+1][9]; \ + b[10] = safer_lbox[(b[10] + skey->saferp.K[i][10]) & 255] ^ skey->saferp.K[i+1][10]; \ + b[11] = (safer_ebox[(b[11] ^ skey->saferp.K[i][11]) & 255] + skey->saferp.K[i+1][11]) & 255; \ + b[12] = (safer_ebox[(b[12] ^ skey->saferp.K[i][12]) & 255] + skey->saferp.K[i+1][12]) & 255; \ + b[13] = safer_lbox[(b[13] + skey->saferp.K[i][13]) & 255] ^ skey->saferp.K[i+1][13]; \ + b[14] = safer_lbox[(b[14] + skey->saferp.K[i][14]) & 255] ^ skey->saferp.K[i+1][14]; \ + b[15] = (safer_ebox[(b[15] ^ skey->saferp.K[i][15]) & 255] + skey->saferp.K[i+1][15]) & 255; \ +} while (0) + +/* This is one inverse key application */ +#define iROUND(b, i) do { \ + b[0] = safer_lbox[(b[0] - skey->saferp.K[i+1][0]) & 255] ^ skey->saferp.K[i][0]; \ + b[1] = (safer_ebox[(b[1] ^ skey->saferp.K[i+1][1]) & 255] - skey->saferp.K[i][1]) & 255; \ + b[2] = (safer_ebox[(b[2] ^ skey->saferp.K[i+1][2]) & 255] - skey->saferp.K[i][2]) & 255; \ + b[3] = safer_lbox[(b[3] - skey->saferp.K[i+1][3]) & 255] ^ skey->saferp.K[i][3]; \ + b[4] = safer_lbox[(b[4] - skey->saferp.K[i+1][4]) & 255] ^ skey->saferp.K[i][4]; \ + b[5] = (safer_ebox[(b[5] ^ skey->saferp.K[i+1][5]) & 255] - skey->saferp.K[i][5]) & 255; \ + b[6] = (safer_ebox[(b[6] ^ skey->saferp.K[i+1][6]) & 255] - skey->saferp.K[i][6]) & 255; \ + b[7] = safer_lbox[(b[7] - skey->saferp.K[i+1][7]) & 255] ^ skey->saferp.K[i][7]; \ + b[8] = safer_lbox[(b[8] - skey->saferp.K[i+1][8]) & 255] ^ skey->saferp.K[i][8]; \ + b[9] = (safer_ebox[(b[9] ^ skey->saferp.K[i+1][9]) & 255] - skey->saferp.K[i][9]) & 255; \ + b[10] = (safer_ebox[(b[10] ^ skey->saferp.K[i+1][10]) & 255] - skey->saferp.K[i][10]) & 255; \ + b[11] = safer_lbox[(b[11] - skey->saferp.K[i+1][11]) & 255] ^ skey->saferp.K[i][11]; \ + b[12] = safer_lbox[(b[12] - skey->saferp.K[i+1][12]) & 255] ^ skey->saferp.K[i][12]; \ + b[13] = (safer_ebox[(b[13] ^ skey->saferp.K[i+1][13]) & 255] - skey->saferp.K[i][13]) & 255; \ + b[14] = (safer_ebox[(b[14] ^ skey->saferp.K[i+1][14]) & 255] - skey->saferp.K[i][14]) & 255; \ + b[15] = safer_lbox[(b[15] - skey->saferp.K[i+1][15]) & 255] ^ skey->saferp.K[i][15]; \ +} while (0) + +/* This is a forward single layer PHT transform. */ +#define PHT(b) do { \ + b[0] = (b[0] + (b[1] = (b[0] + b[1]) & 255)) & 255; \ + b[2] = (b[2] + (b[3] = (b[3] + b[2]) & 255)) & 255; \ + b[4] = (b[4] + (b[5] = (b[5] + b[4]) & 255)) & 255; \ + b[6] = (b[6] + (b[7] = (b[7] + b[6]) & 255)) & 255; \ + b[8] = (b[8] + (b[9] = (b[9] + b[8]) & 255)) & 255; \ + b[10] = (b[10] + (b[11] = (b[11] + b[10]) & 255)) & 255; \ + b[12] = (b[12] + (b[13] = (b[13] + b[12]) & 255)) & 255; \ + b[14] = (b[14] + (b[15] = (b[15] + b[14]) & 255)) & 255; \ +} while (0) + +/* This is an inverse single layer PHT transform */ +#define iPHT(b) do { \ + b[15] = (b[15] - (b[14] = (b[14] - b[15]) & 255)) & 255; \ + b[13] = (b[13] - (b[12] = (b[12] - b[13]) & 255)) & 255; \ + b[11] = (b[11] - (b[10] = (b[10] - b[11]) & 255)) & 255; \ + b[9] = (b[9] - (b[8] = (b[8] - b[9]) & 255)) & 255; \ + b[7] = (b[7] - (b[6] = (b[6] - b[7]) & 255)) & 255; \ + b[5] = (b[5] - (b[4] = (b[4] - b[5]) & 255)) & 255; \ + b[3] = (b[3] - (b[2] = (b[2] - b[3]) & 255)) & 255; \ + b[1] = (b[1] - (b[0] = (b[0] - b[1]) & 255)) & 255; \ + } while (0) + +/* This is the "Armenian" Shuffle. It takes the input from b and stores it in b2 */ +#define SHUF(b, b2) do { \ + b2[0] = b[8]; b2[1] = b[11]; b2[2] = b[12]; b2[3] = b[15]; \ + b2[4] = b[2]; b2[5] = b[1]; b2[6] = b[6]; b2[7] = b[5]; \ + b2[8] = b[10]; b2[9] = b[9]; b2[10] = b[14]; b2[11] = b[13]; \ + b2[12] = b[0]; b2[13] = b[7]; b2[14] = b[4]; b2[15] = b[3]; \ +} while (0) + +/* This is the inverse shuffle. It takes from b and gives to b2 */ +#define iSHUF(b, b2) do { \ + b2[0] = b[12]; b2[1] = b[5]; b2[2] = b[4]; b2[3] = b[15]; \ + b2[4] = b[14]; b2[5] = b[7]; b2[6] = b[6]; b2[7] = b[13]; \ + b2[8] = b[0]; b2[9] = b[9]; b2[10] = b[8]; b2[11] = b[1]; \ + b2[12] = b[2]; b2[13] = b[11]; b2[14] = b[10]; b2[15] = b[3]; \ +} while (0) + +/* The complete forward Linear Transform layer. + * Note that alternating usage of b and b2. + * Each round of LT starts in 'b' and ends in 'b2'. + */ +#define LT(b, b2) do { \ + PHT(b); SHUF(b, b2); \ + PHT(b2); SHUF(b2, b); \ + PHT(b); SHUF(b, b2); \ + PHT(b2); \ +} while (0) + +/* This is the inverse linear transform layer. */ +#define iLT(b, b2) do { \ + iPHT(b); \ + iSHUF(b, b2); iPHT(b2); \ + iSHUF(b2, b); iPHT(b); \ + iSHUF(b, b2); iPHT(b2); \ +} while (0) + +#ifdef LTC_SMALL_CODE + +static void _round(unsigned char *b, int i, symmetric_key *skey) +{ + ROUND(b, i); +} + +static void _iround(unsigned char *b, int i, symmetric_key *skey) +{ + iROUND(b, i); +} + +static void _lt(unsigned char *b, unsigned char *b2) +{ + LT(b, b2); +} + +static void _ilt(unsigned char *b, unsigned char *b2) +{ + iLT(b, b2); +} + +#undef ROUND +#define ROUND(b, i) _round(b, i, skey) + +#undef iROUND +#define iROUND(b, i) _iround(b, i, skey) + +#undef LT +#define LT(b, b2) _lt(b, b2) + +#undef iLT +#define iLT(b, b2) _ilt(b, b2) + +#endif + +/* These are the 33, 128-bit bias words for the key schedule */ +static const unsigned char safer_bias[33][16] = { +{ 70, 151, 177, 186, 163, 183, 16, 10, 197, 55, 179, 201, 90, 40, 172, 100}, +{ 236, 171, 170, 198, 103, 149, 88, 13, 248, 154, 246, 110, 102, 220, 5, 61}, +{ 138, 195, 216, 137, 106, 233, 54, 73, 67, 191, 235, 212, 150, 155, 104, 160}, +{ 93, 87, 146, 31, 213, 113, 92, 187, 34, 193, 190, 123, 188, 153, 99, 148}, +{ 42, 97, 184, 52, 50, 25, 253, 251, 23, 64, 230, 81, 29, 65, 68, 143}, +{ 221, 4, 128, 222, 231, 49, 214, 127, 1, 162, 247, 57, 218, 111, 35, 202}, +{ 58, 208, 28, 209, 48, 62, 18, 161, 205, 15, 224, 168, 175, 130, 89, 44}, +{ 125, 173, 178, 239, 194, 135, 206, 117, 6, 19, 2, 144, 79, 46, 114, 51}, +{ 192, 141, 207, 169, 129, 226, 196, 39, 47, 108, 122, 159, 82, 225, 21, 56}, +{ 252, 32, 66, 199, 8, 228, 9, 85, 94, 140, 20, 118, 96, 255, 223, 215}, +{ 250, 11, 33, 0, 26, 249, 166, 185, 232, 158, 98, 76, 217, 145, 80, 210}, +{ 24, 180, 7, 132, 234, 91, 164, 200, 14, 203, 72, 105, 75, 78, 156, 53}, +{ 69, 77, 84, 229, 37, 60, 12, 74, 139, 63, 204, 167, 219, 107, 174, 244}, +{ 45, 243, 124, 109, 157, 181, 38, 116, 242, 147, 83, 176, 240, 17, 237, 131}, +{ 182, 3, 22, 115, 59, 30, 142, 112, 189, 134, 27, 71, 126, 36, 86, 241}, +{ 136, 70, 151, 177, 186, 163, 183, 16, 10, 197, 55, 179, 201, 90, 40, 172}, +{ 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, 241, 51, 239}, +{ 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, 20, 129, 151, 113, 202}, +{ 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160, 4, 180, 133, 74, 246}, +{ 84, 182, 223, 12, 26, 142, 222, 224, 57, 252, 32, 155, 36, 78, 169, 152}, +{ 171, 242, 96, 208, 108, 234, 250, 199, 217, 0, 212, 31, 110, 67, 188, 236}, +{ 137, 254, 122, 93, 73, 201, 50, 194, 249, 154, 248, 109, 22, 219, 89, 150}, +{ 233, 205, 230, 70, 66, 143, 10, 193, 204, 185, 101, 176, 210, 198, 172, 30}, +{ 98, 41, 46, 14, 116, 80, 2, 90, 195, 37, 123, 138, 42, 91, 240, 6}, +{ 71, 111, 112, 157, 126, 16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104}, +{ 117, 125, 228, 237, 128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175}, +{ 229, 25, 97, 253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35}, +{ 200, 5, 225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7}, +{ 40, 1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207}, +{ 8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247}, +{ 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141, 177, 255}, +{ 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, 241, 51}}; + + /** + Initialize the LTC_SAFER+ block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + unsigned x, y, z; + unsigned char t[33]; + static const int rounds[3] = { 8, 12, 16 }; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + /* check arguments */ + if (keylen != 16 && keylen != 24 && keylen != 32) { + return CRYPT_INVALID_KEYSIZE; + } + + /* Is the number of rounds valid? Either use zero for default or + * 8,12,16 rounds for 16,24,32 byte keys + */ + if (num_rounds != 0 && num_rounds != rounds[(keylen/8)-2]) { + return CRYPT_INVALID_ROUNDS; + } + + /* 128 bit key version */ + if (keylen == 16) { + /* copy key into t */ + for (x = y = 0; x < 16; x++) { + t[x] = key[x]; + y ^= key[x]; + } + t[16] = y; + + /* make round keys */ + for (x = 0; x < 16; x++) { + skey->saferp.K[0][x] = t[x]; + } + + /* make the 16 other keys as a transformation of the first key */ + for (x = 1; x < 17; x++) { + /* rotate 3 bits each */ + for (y = 0; y < 17; y++) { + t[y] = ((t[y]<<3)|(t[y]>>5)) & 255; + } + + /* select and add */ + z = x; + for (y = 0; y < 16; y++) { + skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255; + if (++z == 17) { z = 0; } + } + } + skey->saferp.rounds = 8; + } else if (keylen == 24) { + /* copy key into t */ + for (x = y = 0; x < 24; x++) { + t[x] = key[x]; + y ^= key[x]; + } + t[24] = y; + + /* make round keys */ + for (x = 0; x < 16; x++) { + skey->saferp.K[0][x] = t[x]; + } + + for (x = 1; x < 25; x++) { + /* rotate 3 bits each */ + for (y = 0; y < 25; y++) { + t[y] = ((t[y]<<3)|(t[y]>>5)) & 255; + } + + /* select and add */ + z = x; + for (y = 0; y < 16; y++) { + skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255; + if (++z == 25) { z = 0; } + } + } + skey->saferp.rounds = 12; + } else { + /* copy key into t */ + for (x = y = 0; x < 32; x++) { + t[x] = key[x]; + y ^= key[x]; + } + t[32] = y; + + /* make round keys */ + for (x = 0; x < 16; x++) { + skey->saferp.K[0][x] = t[x]; + } + + for (x = 1; x < 33; x++) { + /* rotate 3 bits each */ + for (y = 0; y < 33; y++) { + t[y] = ((t[y]<<3)|(t[y]>>5)) & 255; + } + + /* select and add */ + z = x; + for (y = 0; y < 16; y++) { + skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255; + if (++z == 33) { z = 0; } + } + } + skey->saferp.rounds = 16; + } +#ifdef LTC_CLEAN_STACK + zeromem(t, sizeof(t)); +#endif + return CRYPT_OK; +} + +/** + Encrypts a block of text with LTC_SAFER+ + @param pt The input plaintext (16 bytes) + @param ct The output ciphertext (16 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + unsigned char b[16]; + int x; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + + /* do eight rounds */ + for (x = 0; x < 16; x++) { + b[x] = pt[x]; + } + ROUND(b, 0); LT(b, ct); + ROUND(ct, 2); LT(ct, b); + ROUND(b, 4); LT(b, ct); + ROUND(ct, 6); LT(ct, b); + ROUND(b, 8); LT(b, ct); + ROUND(ct, 10); LT(ct, b); + ROUND(b, 12); LT(b, ct); + ROUND(ct, 14); LT(ct, b); + /* 192-bit key? */ + if (skey->saferp.rounds > 8) { + ROUND(b, 16); LT(b, ct); + ROUND(ct, 18); LT(ct, b); + ROUND(b, 20); LT(b, ct); + ROUND(ct, 22); LT(ct, b); + } + /* 256-bit key? */ + if (skey->saferp.rounds > 12) { + ROUND(b, 24); LT(b, ct); + ROUND(ct, 26); LT(ct, b); + ROUND(b, 28); LT(b, ct); + ROUND(ct, 30); LT(ct, b); + } + ct[0] = b[0] ^ skey->saferp.K[skey->saferp.rounds*2][0]; + ct[1] = (b[1] + skey->saferp.K[skey->saferp.rounds*2][1]) & 255; + ct[2] = (b[2] + skey->saferp.K[skey->saferp.rounds*2][2]) & 255; + ct[3] = b[3] ^ skey->saferp.K[skey->saferp.rounds*2][3]; + ct[4] = b[4] ^ skey->saferp.K[skey->saferp.rounds*2][4]; + ct[5] = (b[5] + skey->saferp.K[skey->saferp.rounds*2][5]) & 255; + ct[6] = (b[6] + skey->saferp.K[skey->saferp.rounds*2][6]) & 255; + ct[7] = b[7] ^ skey->saferp.K[skey->saferp.rounds*2][7]; + ct[8] = b[8] ^ skey->saferp.K[skey->saferp.rounds*2][8]; + ct[9] = (b[9] + skey->saferp.K[skey->saferp.rounds*2][9]) & 255; + ct[10] = (b[10] + skey->saferp.K[skey->saferp.rounds*2][10]) & 255; + ct[11] = b[11] ^ skey->saferp.K[skey->saferp.rounds*2][11]; + ct[12] = b[12] ^ skey->saferp.K[skey->saferp.rounds*2][12]; + ct[13] = (b[13] + skey->saferp.K[skey->saferp.rounds*2][13]) & 255; + ct[14] = (b[14] + skey->saferp.K[skey->saferp.rounds*2][14]) & 255; + ct[15] = b[15] ^ skey->saferp.K[skey->saferp.rounds*2][15]; +#ifdef LTC_CLEAN_STACK + zeromem(b, sizeof(b)); +#endif + return CRYPT_OK; +} + +/** + Decrypts a block of text with LTC_SAFER+ + @param ct The input ciphertext (16 bytes) + @param pt The output plaintext (16 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + unsigned char b[16]; + int x; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + + /* do eight rounds */ + b[0] = ct[0] ^ skey->saferp.K[skey->saferp.rounds*2][0]; + b[1] = (ct[1] - skey->saferp.K[skey->saferp.rounds*2][1]) & 255; + b[2] = (ct[2] - skey->saferp.K[skey->saferp.rounds*2][2]) & 255; + b[3] = ct[3] ^ skey->saferp.K[skey->saferp.rounds*2][3]; + b[4] = ct[4] ^ skey->saferp.K[skey->saferp.rounds*2][4]; + b[5] = (ct[5] - skey->saferp.K[skey->saferp.rounds*2][5]) & 255; + b[6] = (ct[6] - skey->saferp.K[skey->saferp.rounds*2][6]) & 255; + b[7] = ct[7] ^ skey->saferp.K[skey->saferp.rounds*2][7]; + b[8] = ct[8] ^ skey->saferp.K[skey->saferp.rounds*2][8]; + b[9] = (ct[9] - skey->saferp.K[skey->saferp.rounds*2][9]) & 255; + b[10] = (ct[10] - skey->saferp.K[skey->saferp.rounds*2][10]) & 255; + b[11] = ct[11] ^ skey->saferp.K[skey->saferp.rounds*2][11]; + b[12] = ct[12] ^ skey->saferp.K[skey->saferp.rounds*2][12]; + b[13] = (ct[13] - skey->saferp.K[skey->saferp.rounds*2][13]) & 255; + b[14] = (ct[14] - skey->saferp.K[skey->saferp.rounds*2][14]) & 255; + b[15] = ct[15] ^ skey->saferp.K[skey->saferp.rounds*2][15]; + /* 256-bit key? */ + if (skey->saferp.rounds > 12) { + iLT(b, pt); iROUND(pt, 30); + iLT(pt, b); iROUND(b, 28); + iLT(b, pt); iROUND(pt, 26); + iLT(pt, b); iROUND(b, 24); + } + /* 192-bit key? */ + if (skey->saferp.rounds > 8) { + iLT(b, pt); iROUND(pt, 22); + iLT(pt, b); iROUND(b, 20); + iLT(b, pt); iROUND(pt, 18); + iLT(pt, b); iROUND(b, 16); + } + iLT(b, pt); iROUND(pt, 14); + iLT(pt, b); iROUND(b, 12); + iLT(b, pt); iROUND(pt,10); + iLT(pt, b); iROUND(b, 8); + iLT(b, pt); iROUND(pt,6); + iLT(pt, b); iROUND(b, 4); + iLT(b, pt); iROUND(pt,2); + iLT(pt, b); iROUND(b, 0); + for (x = 0; x < 16; x++) { + pt[x] = b[x]; + } +#ifdef LTC_CLEAN_STACK + zeromem(b, sizeof(b)); +#endif + return CRYPT_OK; +} + +/** + Performs a self-test of the LTC_SAFER+ block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int saferp_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + int keylen; + unsigned char key[32], pt[16], ct[16]; + } tests[] = { + { + 16, + { 41, 35, 190, 132, 225, 108, 214, 174, + 82, 144, 73, 241, 241, 187, 233, 235 }, + { 179, 166, 219, 60, 135, 12, 62, 153, + 36, 94, 13, 28, 6, 183, 71, 222 }, + { 224, 31, 182, 10, 12, 255, 84, 70, + 127, 13, 89, 249, 9, 57, 165, 220 } + }, { + 24, + { 72, 211, 143, 117, 230, 217, 29, 42, + 229, 192, 247, 43, 120, 129, 135, 68, + 14, 95, 80, 0, 212, 97, 141, 190 }, + { 123, 5, 21, 7, 59, 51, 130, 31, + 24, 112, 146, 218, 100, 84, 206, 177 }, + { 92, 136, 4, 63, 57, 95, 100, 0, + 150, 130, 130, 16, 193, 111, 219, 133 } + }, { + 32, + { 243, 168, 141, 254, 190, 242, 235, 113, + 255, 160, 208, 59, 117, 6, 140, 126, + 135, 120, 115, 77, 208, 190, 130, 190, + 219, 194, 70, 65, 43, 140, 250, 48 }, + { 127, 112, 240, 167, 84, 134, 50, 149, + 170, 91, 104, 19, 11, 230, 252, 245 }, + { 88, 11, 25, 36, 172, 229, 202, 213, + 170, 65, 105, 153, 220, 104, 153, 138 } + } + }; + + unsigned char tmp[2][16]; + symmetric_key skey; + int err, i, y; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + if ((err = saferp_setup(tests[i].key, tests[i].keylen, 0, &skey)) != CRYPT_OK) { + return err; + } + saferp_ecb_encrypt(tests[i].pt, tmp[0], &skey); + saferp_ecb_decrypt(tmp[0], tmp[1], &skey); + + /* compare */ + if (XMEMCMP(tmp[0], tests[i].ct, 16) || XMEMCMP(tmp[1], tests[i].pt, 16)) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 16; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) saferp_ecb_encrypt(tmp[0], tmp[0], &skey); + for (y = 0; y < 1000; y++) saferp_ecb_decrypt(tmp[0], tmp[0], &skey); + for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; + #endif +} + +/** Terminate the context + @param skey The scheduled key +*/ +void saferp_done(symmetric_key *skey) +{ + LTC_UNUSED_PARAM(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. + @return CRYPT_OK if the input key size is acceptable. +*/ +int saferp_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + + if (*keysize < 16) + return CRYPT_INVALID_KEYSIZE; + if (*keysize < 24) { + *keysize = 16; + } else if (*keysize < 32) { + *keysize = 24; + } else { + *keysize = 32; + } + return CRYPT_OK; +} + +#endif + + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/ciphers/skipjack.c b/src/ltc/ciphers/skipjack.c new file mode 100644 index 0000000..4333a9f --- /dev/null +++ b/src/ltc/ciphers/skipjack.c @@ -0,0 +1,344 @@ +/* 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://libtom.org + */ + +/** + @file skipjack.c + Skipjack Implementation by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_SKIPJACK + +const struct ltc_cipher_descriptor skipjack_desc = +{ + "skipjack", + 17, + 10, 10, 8, 32, + &skipjack_setup, + &skipjack_ecb_encrypt, + &skipjack_ecb_decrypt, + &skipjack_test, + &skipjack_done, + &skipjack_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +static const unsigned char sbox[256] = { + 0xa3,0xd7,0x09,0x83,0xf8,0x48,0xf6,0xf4,0xb3,0x21,0x15,0x78,0x99,0xb1,0xaf,0xf9, + 0xe7,0x2d,0x4d,0x8a,0xce,0x4c,0xca,0x2e,0x52,0x95,0xd9,0x1e,0x4e,0x38,0x44,0x28, + 0x0a,0xdf,0x02,0xa0,0x17,0xf1,0x60,0x68,0x12,0xb7,0x7a,0xc3,0xe9,0xfa,0x3d,0x53, + 0x96,0x84,0x6b,0xba,0xf2,0x63,0x9a,0x19,0x7c,0xae,0xe5,0xf5,0xf7,0x16,0x6a,0xa2, + 0x39,0xb6,0x7b,0x0f,0xc1,0x93,0x81,0x1b,0xee,0xb4,0x1a,0xea,0xd0,0x91,0x2f,0xb8, + 0x55,0xb9,0xda,0x85,0x3f,0x41,0xbf,0xe0,0x5a,0x58,0x80,0x5f,0x66,0x0b,0xd8,0x90, + 0x35,0xd5,0xc0,0xa7,0x33,0x06,0x65,0x69,0x45,0x00,0x94,0x56,0x6d,0x98,0x9b,0x76, + 0x97,0xfc,0xb2,0xc2,0xb0,0xfe,0xdb,0x20,0xe1,0xeb,0xd6,0xe4,0xdd,0x47,0x4a,0x1d, + 0x42,0xed,0x9e,0x6e,0x49,0x3c,0xcd,0x43,0x27,0xd2,0x07,0xd4,0xde,0xc7,0x67,0x18, + 0x89,0xcb,0x30,0x1f,0x8d,0xc6,0x8f,0xaa,0xc8,0x74,0xdc,0xc9,0x5d,0x5c,0x31,0xa4, + 0x70,0x88,0x61,0x2c,0x9f,0x0d,0x2b,0x87,0x50,0x82,0x54,0x64,0x26,0x7d,0x03,0x40, + 0x34,0x4b,0x1c,0x73,0xd1,0xc4,0xfd,0x3b,0xcc,0xfb,0x7f,0xab,0xe6,0x3e,0x5b,0xa5, + 0xad,0x04,0x23,0x9c,0x14,0x51,0x22,0xf0,0x29,0x79,0x71,0x7e,0xff,0x8c,0x0e,0xe2, + 0x0c,0xef,0xbc,0x72,0x75,0x6f,0x37,0xa1,0xec,0xd3,0x8e,0x62,0x8b,0x86,0x10,0xe8, + 0x08,0x77,0x11,0xbe,0x92,0x4f,0x24,0xc5,0x32,0x36,0x9d,0xcf,0xf3,0xa6,0xbb,0xac, + 0x5e,0x6c,0xa9,0x13,0x57,0x25,0xb5,0xe3,0xbd,0xa8,0x3a,0x01,0x05,0x59,0x2a,0x46 +}; + +/* simple x + 1 (mod 10) in one step. */ +static const int keystep[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; + +/* simple x - 1 (mod 10) in one step */ +static const int ikeystep[] = { 9, 0, 1, 2, 3, 4, 5, 6, 7, 8 }; + + /** + Initialize the Skipjack block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int x; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + if (keylen != 10) { + return CRYPT_INVALID_KEYSIZE; + } + + if (num_rounds != 32 && num_rounds != 0) { + return CRYPT_INVALID_ROUNDS; + } + + /* make sure the key is in range for platforms where CHAR_BIT != 8 */ + for (x = 0; x < 10; x++) { + skey->skipjack.key[x] = key[x] & 255; + } + + return CRYPT_OK; +} + +#define RULE_A \ + tmp = g_func(w1, &kp, skey->skipjack.key); \ + w1 = tmp ^ w4 ^ x; \ + w4 = w3; w3 = w2; \ + w2 = tmp; + +#define RULE_B \ + tmp = g_func(w1, &kp, skey->skipjack.key); \ + tmp1 = w4; w4 = w3; \ + w3 = w1 ^ w2 ^ x; \ + w1 = tmp1; w2 = tmp; + +#define RULE_A1 \ + tmp = w1 ^ w2 ^ x; \ + w1 = ig_func(w2, &kp, skey->skipjack.key); \ + w2 = w3; w3 = w4; w4 = tmp; + +#define RULE_B1 \ + tmp = ig_func(w2, &kp, skey->skipjack.key); \ + w2 = tmp ^ w3 ^ x; \ + w3 = w4; w4 = w1; w1 = tmp; + +static unsigned g_func(unsigned w, int *kp, unsigned char *key) +{ + unsigned char g1,g2; + + g1 = (w >> 8) & 255; g2 = w & 255; + g1 ^= sbox[g2^key[*kp]]; *kp = keystep[*kp]; + g2 ^= sbox[g1^key[*kp]]; *kp = keystep[*kp]; + g1 ^= sbox[g2^key[*kp]]; *kp = keystep[*kp]; + g2 ^= sbox[g1^key[*kp]]; *kp = keystep[*kp]; + return ((unsigned)g1<<8)|(unsigned)g2; +} + +static unsigned ig_func(unsigned w, int *kp, unsigned char *key) +{ + unsigned char g1,g2; + + g1 = (w >> 8) & 255; g2 = w & 255; + *kp = ikeystep[*kp]; g2 ^= sbox[g1^key[*kp]]; + *kp = ikeystep[*kp]; g1 ^= sbox[g2^key[*kp]]; + *kp = ikeystep[*kp]; g2 ^= sbox[g1^key[*kp]]; + *kp = ikeystep[*kp]; g1 ^= sbox[g2^key[*kp]]; + return ((unsigned)g1<<8)|(unsigned)g2; +} + +/** + Encrypts a block of text with Skipjack + @param pt The input plaintext (8 bytes) + @param ct The output ciphertext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +#ifdef LTC_CLEAN_STACK +static int _skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#else +int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#endif +{ + unsigned w1,w2,w3,w4,tmp,tmp1; + int x, kp; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + + /* load block */ + w1 = ((unsigned)pt[0]<<8)|pt[1]; + w2 = ((unsigned)pt[2]<<8)|pt[3]; + w3 = ((unsigned)pt[4]<<8)|pt[5]; + w4 = ((unsigned)pt[6]<<8)|pt[7]; + + /* 8 rounds of RULE A */ + for (x = 1, kp = 0; x < 9; x++) { + RULE_A; + } + + /* 8 rounds of RULE B */ + for (; x < 17; x++) { + RULE_B; + } + + /* 8 rounds of RULE A */ + for (; x < 25; x++) { + RULE_A; + } + + /* 8 rounds of RULE B */ + for (; x < 33; x++) { + RULE_B; + } + + /* store block */ + ct[0] = (w1>>8)&255; ct[1] = w1&255; + ct[2] = (w2>>8)&255; ct[3] = w2&255; + ct[4] = (w3>>8)&255; ct[5] = w3&255; + ct[6] = (w4>>8)&255; ct[7] = w4&255; + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + int err = _skipjack_ecb_encrypt(pt, ct, skey); + burn_stack(sizeof(unsigned) * 8 + sizeof(int) * 2); + return err; +} +#endif + +/** + Decrypts a block of text with Skipjack + @param ct The input ciphertext (8 bytes) + @param pt The output plaintext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +#ifdef LTC_CLEAN_STACK +static int _skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#else +int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#endif +{ + unsigned w1,w2,w3,w4,tmp; + int x, kp; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + + /* load block */ + w1 = ((unsigned)ct[0]<<8)|ct[1]; + w2 = ((unsigned)ct[2]<<8)|ct[3]; + w3 = ((unsigned)ct[4]<<8)|ct[5]; + w4 = ((unsigned)ct[6]<<8)|ct[7]; + + /* 8 rounds of RULE B^-1 + + Note the value "kp = 8" comes from "kp = (32 * 4) mod 10" where 32*4 is 128 which mod 10 is 8 + */ + for (x = 32, kp = 8; x > 24; x--) { + RULE_B1; + } + + /* 8 rounds of RULE A^-1 */ + for (; x > 16; x--) { + RULE_A1; + } + + + /* 8 rounds of RULE B^-1 */ + for (; x > 8; x--) { + RULE_B1; + } + + /* 8 rounds of RULE A^-1 */ + for (; x > 0; x--) { + RULE_A1; + } + + /* store block */ + pt[0] = (w1>>8)&255; pt[1] = w1&255; + pt[2] = (w2>>8)&255; pt[3] = w2&255; + pt[4] = (w3>>8)&255; pt[5] = w3&255; + pt[6] = (w4>>8)&255; pt[7] = w4&255; + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + int err = _skipjack_ecb_decrypt(ct, pt, skey); + burn_stack(sizeof(unsigned) * 7 + sizeof(int) * 2); + return err; +} +#endif + +/** + Performs a self-test of the Skipjack block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int skipjack_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + unsigned char key[10], pt[8], ct[8]; + } tests[] = { + { + { 0x00, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }, + { 0x33, 0x22, 0x11, 0x00, 0xdd, 0xcc, 0xbb, 0xaa }, + { 0x25, 0x87, 0xca, 0xe2, 0x7a, 0x12, 0xd3, 0x00 } + } + }; + unsigned char buf[2][8]; + int x, y, err; + symmetric_key key; + + for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) { + /* setup key */ + if ((err = skipjack_setup(tests[x].key, 10, 0, &key)) != CRYPT_OK) { + return err; + } + + /* encrypt and decrypt */ + skipjack_ecb_encrypt(tests[x].pt, buf[0], &key); + skipjack_ecb_decrypt(buf[0], buf[1], &key); + + /* compare */ + if (XMEMCMP(buf[0], tests[x].ct, 8) != 0 || XMEMCMP(buf[1], tests[x].pt, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) buf[0][y] = 0; + for (y = 0; y < 1000; y++) skipjack_ecb_encrypt(buf[0], buf[0], &key); + for (y = 0; y < 1000; y++) skipjack_ecb_decrypt(buf[0], buf[0], &key); + for (y = 0; y < 8; y++) if (buf[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; + #endif +} + +/** Terminate the context + @param skey The scheduled key +*/ +void skipjack_done(symmetric_key *skey) +{ + LTC_UNUSED_PARAM(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. + @return CRYPT_OK if the input key size is acceptable. +*/ +int skipjack_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if (*keysize < 10) { + return CRYPT_INVALID_KEYSIZE; + } else if (*keysize > 10) { + *keysize = 10; + } + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/ciphers/twofish/twofish.c b/src/ltc/ciphers/twofish/twofish.c new file mode 100644 index 0000000..b2b41bb --- /dev/null +++ b/src/ltc/ciphers/twofish/twofish.c @@ -0,0 +1,715 @@ +/* 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://libtom.org + */ + + /** + @file twofish.c + Implementation of Twofish by Tom St Denis + */ +#include "tomcrypt.h" + +#ifdef LTC_TWOFISH + +/* first LTC_TWOFISH_ALL_TABLES must ensure LTC_TWOFISH_TABLES is defined */ +#ifdef LTC_TWOFISH_ALL_TABLES +#ifndef LTC_TWOFISH_TABLES +#define LTC_TWOFISH_TABLES +#endif +#endif + +const struct ltc_cipher_descriptor twofish_desc = +{ + "twofish", + 7, + 16, 32, 16, 16, + &twofish_setup, + &twofish_ecb_encrypt, + &twofish_ecb_decrypt, + &twofish_test, + &twofish_done, + &twofish_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +/* the two polynomials */ +#define MDS_POLY 0x169 +#define RS_POLY 0x14D + +/* The 4x8 RS Linear Transform */ +static const unsigned char RS[4][8] = { + { 0x01, 0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E }, + { 0xA4, 0x56, 0x82, 0xF3, 0X1E, 0XC6, 0X68, 0XE5 }, + { 0X02, 0XA1, 0XFC, 0XC1, 0X47, 0XAE, 0X3D, 0X19 }, + { 0XA4, 0X55, 0X87, 0X5A, 0X58, 0XDB, 0X9E, 0X03 } +}; + +#ifdef LTC_TWOFISH_SMALL +/* sbox usage orderings */ +static const unsigned char qord[4][5] = { + { 1, 1, 0, 0, 1 }, + { 0, 1, 1, 0, 0 }, + { 0, 0, 0, 1, 1 }, + { 1, 0, 1, 1, 0 } +}; +#endif /* LTC_TWOFISH_SMALL */ + +#ifdef LTC_TWOFISH_TABLES + +#define __LTC_TWOFISH_TAB_C__ +#include "twofish_tab.c" + +#define sbox(i, x) ((ulong32)SBOX[i][(x)&255]) + +#else + +/* The Q-box tables */ +static const unsigned char qbox[2][4][16] = { +{ + { 0x8, 0x1, 0x7, 0xD, 0x6, 0xF, 0x3, 0x2, 0x0, 0xB, 0x5, 0x9, 0xE, 0xC, 0xA, 0x4 }, + { 0xE, 0XC, 0XB, 0X8, 0X1, 0X2, 0X3, 0X5, 0XF, 0X4, 0XA, 0X6, 0X7, 0X0, 0X9, 0XD }, + { 0XB, 0XA, 0X5, 0XE, 0X6, 0XD, 0X9, 0X0, 0XC, 0X8, 0XF, 0X3, 0X2, 0X4, 0X7, 0X1 }, + { 0XD, 0X7, 0XF, 0X4, 0X1, 0X2, 0X6, 0XE, 0X9, 0XB, 0X3, 0X0, 0X8, 0X5, 0XC, 0XA } +}, +{ + { 0X2, 0X8, 0XB, 0XD, 0XF, 0X7, 0X6, 0XE, 0X3, 0X1, 0X9, 0X4, 0X0, 0XA, 0XC, 0X5 }, + { 0X1, 0XE, 0X2, 0XB, 0X4, 0XC, 0X3, 0X7, 0X6, 0XD, 0XA, 0X5, 0XF, 0X9, 0X0, 0X8 }, + { 0X4, 0XC, 0X7, 0X5, 0X1, 0X6, 0X9, 0XA, 0X0, 0XE, 0XD, 0X8, 0X2, 0XB, 0X3, 0XF }, + { 0xB, 0X9, 0X5, 0X1, 0XC, 0X3, 0XD, 0XE, 0X6, 0X4, 0X7, 0XF, 0X2, 0X0, 0X8, 0XA } +} +}; + +/* computes S_i[x] */ +#ifdef LTC_CLEAN_STACK +static ulong32 _sbox(int i, ulong32 x) +#else +static ulong32 sbox(int i, ulong32 x) +#endif +{ + unsigned char a0,b0,a1,b1,a2,b2,a3,b3,a4,b4,y; + + /* a0,b0 = [x/16], x mod 16 */ + a0 = (unsigned char)((x>>4)&15); + b0 = (unsigned char)((x)&15); + + /* a1 = a0 ^ b0 */ + a1 = a0 ^ b0; + + /* b1 = a0 ^ ROR(b0, 1) ^ 8a0 */ + b1 = (a0 ^ ((b0<<3)|(b0>>1)) ^ (a0<<3)) & 15; + + /* a2,b2 = t0[a1], t1[b1] */ + a2 = qbox[i][0][(int)a1]; + b2 = qbox[i][1][(int)b1]; + + /* a3 = a2 ^ b2 */ + a3 = a2 ^ b2; + + /* b3 = a2 ^ ROR(b2, 1) ^ 8a2 */ + b3 = (a2 ^ ((b2<<3)|(b2>>1)) ^ (a2<<3)) & 15; + + /* a4,b4 = t2[a3], t3[b3] */ + a4 = qbox[i][2][(int)a3]; + b4 = qbox[i][3][(int)b3]; + + /* y = 16b4 + a4 */ + y = (b4 << 4) + a4; + + /* return result */ + return (ulong32)y; +} + +#ifdef LTC_CLEAN_STACK +static ulong32 sbox(int i, ulong32 x) +{ + ulong32 y; + y = _sbox(i, x); + burn_stack(sizeof(unsigned char) * 11); + return y; +} +#endif /* LTC_CLEAN_STACK */ + +#endif /* LTC_TWOFISH_TABLES */ + +/* computes ab mod p */ +static ulong32 gf_mult(ulong32 a, ulong32 b, ulong32 p) +{ + ulong32 result, B[2], P[2]; + + P[1] = p; + B[1] = b; + result = P[0] = B[0] = 0; + + /* unrolled branchless GF multiplier */ + result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); + result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); + result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); + result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); + result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); + result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); + result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); + result ^= B[a&1]; + + return result; +} + +/* computes [y0 y1 y2 y3] = MDS . [x0] */ +#ifndef LTC_TWOFISH_TABLES +static ulong32 mds_column_mult(unsigned char in, int col) +{ + ulong32 x01, x5B, xEF; + + x01 = in; + x5B = gf_mult(in, 0x5B, MDS_POLY); + xEF = gf_mult(in, 0xEF, MDS_POLY); + + switch (col) { + case 0: + return (x01 << 0 ) | + (x5B << 8 ) | + (xEF << 16) | + (xEF << 24); + case 1: + return (xEF << 0 ) | + (xEF << 8 ) | + (x5B << 16) | + (x01 << 24); + case 2: + return (x5B << 0 ) | + (xEF << 8 ) | + (x01 << 16) | + (xEF << 24); + case 3: + return (x5B << 0 ) | + (x01 << 8 ) | + (xEF << 16) | + (x5B << 24); + } + /* avoid warnings, we'd never get here normally but just to calm compiler warnings... */ + return 0; +} + +#else /* !LTC_TWOFISH_TABLES */ + +#define mds_column_mult(x, i) mds_tab[i][x] + +#endif /* LTC_TWOFISH_TABLES */ + +/* Computes [y0 y1 y2 y3] = MDS . [x0 x1 x2 x3] */ +static void mds_mult(const unsigned char *in, unsigned char *out) +{ + int x; + ulong32 tmp; + for (tmp = x = 0; x < 4; x++) { + tmp ^= mds_column_mult(in[x], x); + } + STORE32L(tmp, out); +} + +#ifdef LTC_TWOFISH_ALL_TABLES +/* computes [y0 y1 y2 y3] = RS . [x0 x1 x2 x3 x4 x5 x6 x7] */ +static void rs_mult(const unsigned char *in, unsigned char *out) +{ + ulong32 tmp; + tmp = rs_tab0[in[0]] ^ rs_tab1[in[1]] ^ rs_tab2[in[2]] ^ rs_tab3[in[3]] ^ + rs_tab4[in[4]] ^ rs_tab5[in[5]] ^ rs_tab6[in[6]] ^ rs_tab7[in[7]]; + STORE32L(tmp, out); +} + +#else /* !LTC_TWOFISH_ALL_TABLES */ + +/* computes [y0 y1 y2 y3] = RS . [x0 x1 x2 x3 x4 x5 x6 x7] */ +static void rs_mult(const unsigned char *in, unsigned char *out) +{ + int x, y; + for (x = 0; x < 4; x++) { + out[x] = 0; + for (y = 0; y < 8; y++) { + out[x] ^= gf_mult(in[y], RS[x][y], RS_POLY); + } + } +} + +#endif + +/* computes h(x) */ +static void h_func(const unsigned char *in, unsigned char *out, unsigned char *M, int k, int offset) +{ + int x; + unsigned char y[4]; + for (x = 0; x < 4; x++) { + y[x] = in[x]; + } + switch (k) { + case 4: + y[0] = (unsigned char)(sbox(1, (ulong32)y[0]) ^ M[4 * (6 + offset) + 0]); + y[1] = (unsigned char)(sbox(0, (ulong32)y[1]) ^ M[4 * (6 + offset) + 1]); + y[2] = (unsigned char)(sbox(0, (ulong32)y[2]) ^ M[4 * (6 + offset) + 2]); + y[3] = (unsigned char)(sbox(1, (ulong32)y[3]) ^ M[4 * (6 + offset) + 3]); + /* FALLTHROUGH */ + case 3: + y[0] = (unsigned char)(sbox(1, (ulong32)y[0]) ^ M[4 * (4 + offset) + 0]); + y[1] = (unsigned char)(sbox(1, (ulong32)y[1]) ^ M[4 * (4 + offset) + 1]); + y[2] = (unsigned char)(sbox(0, (ulong32)y[2]) ^ M[4 * (4 + offset) + 2]); + y[3] = (unsigned char)(sbox(0, (ulong32)y[3]) ^ M[4 * (4 + offset) + 3]); + /* FALLTHROUGH */ + case 2: + y[0] = (unsigned char)(sbox(1, sbox(0, sbox(0, (ulong32)y[0]) ^ M[4 * (2 + offset) + 0]) ^ M[4 * (0 + offset) + 0])); + y[1] = (unsigned char)(sbox(0, sbox(0, sbox(1, (ulong32)y[1]) ^ M[4 * (2 + offset) + 1]) ^ M[4 * (0 + offset) + 1])); + y[2] = (unsigned char)(sbox(1, sbox(1, sbox(0, (ulong32)y[2]) ^ M[4 * (2 + offset) + 2]) ^ M[4 * (0 + offset) + 2])); + y[3] = (unsigned char)(sbox(0, sbox(1, sbox(1, (ulong32)y[3]) ^ M[4 * (2 + offset) + 3]) ^ M[4 * (0 + offset) + 3])); + /* FALLTHROUGH */ + } + mds_mult(y, out); +} + +#ifndef LTC_TWOFISH_SMALL + +/* for GCC we don't use pointer aliases */ +#if defined(__GNUC__) + #define S1 skey->twofish.S[0] + #define S2 skey->twofish.S[1] + #define S3 skey->twofish.S[2] + #define S4 skey->twofish.S[3] +#endif + +/* the G function */ +#define g_func(x, dum) (S1[byte(x,0)] ^ S2[byte(x,1)] ^ S3[byte(x,2)] ^ S4[byte(x,3)]) +#define g1_func(x, dum) (S2[byte(x,0)] ^ S3[byte(x,1)] ^ S4[byte(x,2)] ^ S1[byte(x,3)]) + +#else + +#ifdef LTC_CLEAN_STACK +static ulong32 _g_func(ulong32 x, symmetric_key *key) +#else +static ulong32 g_func(ulong32 x, symmetric_key *key) +#endif +{ + unsigned char g, i, y, z; + ulong32 res; + + res = 0; + for (y = 0; y < 4; y++) { + z = key->twofish.start; + + /* do unkeyed substitution */ + g = sbox(qord[y][z++], (x >> (8*y)) & 255); + + /* first subkey */ + i = 0; + + /* do key mixing+sbox until z==5 */ + while (z != 5) { + g = g ^ key->twofish.S[4*i++ + y]; + g = sbox(qord[y][z++], g); + } + + /* multiply g by a column of the MDS */ + res ^= mds_column_mult(g, y); + } + return res; +} + +#define g1_func(x, key) g_func(ROLc(x, 8), key) + +#ifdef LTC_CLEAN_STACK +static ulong32 g_func(ulong32 x, symmetric_key *key) +{ + ulong32 y; + y = _g_func(x, key); + burn_stack(sizeof(unsigned char) * 4 + sizeof(ulong32)); + return y; +} +#endif /* LTC_CLEAN_STACK */ + +#endif /* LTC_TWOFISH_SMALL */ + + /** + Initialize the Twofish block cipher + @param key The symmetric key you wish to pass + @param keylen The key length in bytes + @param num_rounds The number of rounds desired (0 for default) + @param skey The key in as scheduled by this function. + @return CRYPT_OK if successful + */ +#ifdef LTC_CLEAN_STACK +static int _twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#else +int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#endif +{ +#ifndef LTC_TWOFISH_SMALL + unsigned char S[4*4], tmpx0, tmpx1; +#endif + int k, x, y; + unsigned char tmp[4], tmp2[4], M[8*4]; + ulong32 A, B; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + /* invalid arguments? */ + if (num_rounds != 16 && num_rounds != 0) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen != 16 && keylen != 24 && keylen != 32) { + return CRYPT_INVALID_KEYSIZE; + } + + /* k = keysize/64 [but since our keysize is in bytes...] */ + k = keylen / 8; + + /* copy the key into M */ + for (x = 0; x < keylen; x++) { + M[x] = key[x] & 255; + } + + /* create the S[..] words */ +#ifndef LTC_TWOFISH_SMALL + for (x = 0; x < k; x++) { + rs_mult(M+(x*8), S+(x*4)); + } +#else + for (x = 0; x < k; x++) { + rs_mult(M+(x*8), skey->twofish.S+(x*4)); + } +#endif + + /* make subkeys */ + for (x = 0; x < 20; x++) { + /* A = h(p * 2x, Me) */ + for (y = 0; y < 4; y++) { + tmp[y] = x+x; + } + h_func(tmp, tmp2, M, k, 0); + LOAD32L(A, tmp2); + + /* B = ROL(h(p * (2x + 1), Mo), 8) */ + for (y = 0; y < 4; y++) { + tmp[y] = (unsigned char)(x+x+1); + } + h_func(tmp, tmp2, M, k, 1); + LOAD32L(B, tmp2); + B = ROLc(B, 8); + + /* K[2i] = A + B */ + skey->twofish.K[x+x] = (A + B) & 0xFFFFFFFFUL; + + /* K[2i+1] = (A + 2B) <<< 9 */ + skey->twofish.K[x+x+1] = ROLc(B + B + A, 9); + } + +#ifndef LTC_TWOFISH_SMALL + /* make the sboxes (large ram variant) */ + if (k == 2) { + for (x = 0; x < 256; x++) { + tmpx0 = (unsigned char)sbox(0, x); + tmpx1 = (unsigned char)sbox(1, x); + skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, tmpx0 ^ S[0]) ^ S[4])),0); + skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, tmpx1 ^ S[1]) ^ S[5])),1); + skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, tmpx0 ^ S[2]) ^ S[6])),2); + skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, tmpx1 ^ S[3]) ^ S[7])),3); + } + } else if (k == 3) { + for (x = 0; x < 256; x++) { + tmpx0 = (unsigned char)sbox(0, x); + tmpx1 = (unsigned char)sbox(1, x); + skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, sbox(0, tmpx1 ^ S[0]) ^ S[4]) ^ S[8])),0); + skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, sbox(1, tmpx1 ^ S[1]) ^ S[5]) ^ S[9])),1); + skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, sbox(0, tmpx0 ^ S[2]) ^ S[6]) ^ S[10])),2); + skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, sbox(1, tmpx0 ^ S[3]) ^ S[7]) ^ S[11])),3); + } + } else { + for (x = 0; x < 256; x++) { + tmpx0 = (unsigned char)sbox(0, x); + tmpx1 = (unsigned char)sbox(1, x); + skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, sbox(0, sbox(1, tmpx1 ^ S[0]) ^ S[4]) ^ S[8]) ^ S[12])),0); + skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, sbox(1, sbox(1, tmpx0 ^ S[1]) ^ S[5]) ^ S[9]) ^ S[13])),1); + skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, sbox(0, sbox(0, tmpx0 ^ S[2]) ^ S[6]) ^ S[10]) ^ S[14])),2); + skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, sbox(1, sbox(0, tmpx1 ^ S[3]) ^ S[7]) ^ S[11]) ^ S[15])),3); + } + } +#else + /* where to start in the sbox layers */ + /* small ram variant */ + switch (k) { + case 4 : skey->twofish.start = 0; break; + case 3 : skey->twofish.start = 1; break; + default: skey->twofish.start = 2; break; + } +#endif + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int x; + x = _twofish_setup(key, keylen, num_rounds, skey); + burn_stack(sizeof(int) * 7 + sizeof(unsigned char) * 56 + sizeof(ulong32) * 2); + return x; +} +#endif + +/** + Encrypts a block of text with Twofish + @param pt The input plaintext (16 bytes) + @param ct The output ciphertext (16 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +#ifdef LTC_CLEAN_STACK +static int _twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#else +int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#endif +{ + ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k; + int r; +#if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__) + ulong32 *S1, *S2, *S3, *S4; +#endif + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + +#if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__) + S1 = skey->twofish.S[0]; + S2 = skey->twofish.S[1]; + S3 = skey->twofish.S[2]; + S4 = skey->twofish.S[3]; +#endif + + LOAD32L(a,&pt[0]); LOAD32L(b,&pt[4]); + LOAD32L(c,&pt[8]); LOAD32L(d,&pt[12]); + a ^= skey->twofish.K[0]; + b ^= skey->twofish.K[1]; + c ^= skey->twofish.K[2]; + d ^= skey->twofish.K[3]; + + k = skey->twofish.K + 8; + for (r = 8; r != 0; --r) { + t2 = g1_func(b, skey); + t1 = g_func(a, skey) + t2; + c = RORc(c ^ (t1 + k[0]), 1); + d = ROLc(d, 1) ^ (t2 + t1 + k[1]); + + t2 = g1_func(d, skey); + t1 = g_func(c, skey) + t2; + a = RORc(a ^ (t1 + k[2]), 1); + b = ROLc(b, 1) ^ (t2 + t1 + k[3]); + k += 4; + } + + /* output with "undo last swap" */ + ta = c ^ skey->twofish.K[4]; + tb = d ^ skey->twofish.K[5]; + tc = a ^ skey->twofish.K[6]; + td = b ^ skey->twofish.K[7]; + + /* store output */ + STORE32L(ta,&ct[0]); STORE32L(tb,&ct[4]); + STORE32L(tc,&ct[8]); STORE32L(td,&ct[12]); + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + int err = _twofish_ecb_encrypt(pt, ct, skey); + burn_stack(sizeof(ulong32) * 10 + sizeof(int)); + return err; +} +#endif + +/** + Decrypts a block of text with Twofish + @param ct The input ciphertext (16 bytes) + @param pt The output plaintext (16 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +#ifdef LTC_CLEAN_STACK +static int _twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#else +int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#endif +{ + ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k; + int r; +#if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__) + ulong32 *S1, *S2, *S3, *S4; +#endif + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + +#if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__) + S1 = skey->twofish.S[0]; + S2 = skey->twofish.S[1]; + S3 = skey->twofish.S[2]; + S4 = skey->twofish.S[3]; +#endif + + /* load input */ + LOAD32L(ta,&ct[0]); LOAD32L(tb,&ct[4]); + LOAD32L(tc,&ct[8]); LOAD32L(td,&ct[12]); + + /* undo undo final swap */ + a = tc ^ skey->twofish.K[6]; + b = td ^ skey->twofish.K[7]; + c = ta ^ skey->twofish.K[4]; + d = tb ^ skey->twofish.K[5]; + + k = skey->twofish.K + 36; + for (r = 8; r != 0; --r) { + t2 = g1_func(d, skey); + t1 = g_func(c, skey) + t2; + a = ROLc(a, 1) ^ (t1 + k[2]); + b = RORc(b ^ (t2 + t1 + k[3]), 1); + + t2 = g1_func(b, skey); + t1 = g_func(a, skey) + t2; + c = ROLc(c, 1) ^ (t1 + k[0]); + d = RORc(d ^ (t2 + t1 + k[1]), 1); + k -= 4; + } + + /* pre-white */ + a ^= skey->twofish.K[0]; + b ^= skey->twofish.K[1]; + c ^= skey->twofish.K[2]; + d ^= skey->twofish.K[3]; + + /* store */ + STORE32L(a, &pt[0]); STORE32L(b, &pt[4]); + STORE32L(c, &pt[8]); STORE32L(d, &pt[12]); + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + int err =_twofish_ecb_decrypt(ct, pt, skey); + burn_stack(sizeof(ulong32) * 10 + sizeof(int)); + return err; +} +#endif + +/** + Performs a self-test of the Twofish block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int twofish_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + int keylen; + unsigned char key[32], pt[16], ct[16]; + } tests[] = { + { 16, + { 0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32, + 0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A }, + { 0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E, + 0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19 }, + { 0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85, + 0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3 } + }, { + 24, + { 0x88, 0xB2, 0xB2, 0x70, 0x6B, 0x10, 0x5E, 0x36, + 0xB4, 0x46, 0xBB, 0x6D, 0x73, 0x1A, 0x1E, 0x88, + 0xEF, 0xA7, 0x1F, 0x78, 0x89, 0x65, 0xBD, 0x44 }, + { 0x39, 0xDA, 0x69, 0xD6, 0xBA, 0x49, 0x97, 0xD5, + 0x85, 0xB6, 0xDC, 0x07, 0x3C, 0xA3, 0x41, 0xB2 }, + { 0x18, 0x2B, 0x02, 0xD8, 0x14, 0x97, 0xEA, 0x45, + 0xF9, 0xDA, 0xAC, 0xDC, 0x29, 0x19, 0x3A, 0x65 } + }, { + 32, + { 0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46, + 0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D, + 0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B, + 0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F }, + { 0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F, + 0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6 }, + { 0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97, + 0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA } + } +}; + + + symmetric_key key; + unsigned char tmp[2][16]; + int err, i, y; + + for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { + if ((err = twofish_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { + return err; + } + twofish_ecb_encrypt(tests[i].pt, tmp[0], &key); + twofish_ecb_decrypt(tmp[0], tmp[1], &key); + if (XMEMCMP(tmp[0], tests[i].ct, 16) != 0 || XMEMCMP(tmp[1], tests[i].pt, 16) != 0) { +#if 0 + printf("Twofish failed test %d, %d, %d\n", i, XMEMCMP(tmp[0], tests[i].ct, 16), XMEMCMP(tmp[1], tests[i].pt, 16)); +#endif + return CRYPT_FAIL_TESTVECTOR; + } + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 16; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) twofish_ecb_encrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) twofish_ecb_decrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; +#endif +} + +/** Terminate the context + @param skey The scheduled key +*/ +void twofish_done(symmetric_key *skey) +{ + LTC_UNUSED_PARAM(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. + @return CRYPT_OK if the input key size is acceptable. +*/ +int twofish_keysize(int *keysize) +{ + LTC_ARGCHK(keysize); + if (*keysize < 16) + return CRYPT_INVALID_KEYSIZE; + if (*keysize < 24) { + *keysize = 16; + return CRYPT_OK; + } else if (*keysize < 32) { + *keysize = 24; + return CRYPT_OK; + } else { + *keysize = 32; + return CRYPT_OK; + } +} + +#endif + + + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/ciphers/twofish/twofish_tab.c b/src/ltc/ciphers/twofish/twofish_tab.c new file mode 100644 index 0000000..7ea8586 --- /dev/null +++ b/src/ltc/ciphers/twofish/twofish_tab.c @@ -0,0 +1,498 @@ +/* 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://libtom.org + */ + + /** + @file twofish_tab.c + Twofish tables, Tom St Denis + */ +#ifdef LTC_TWOFISH_TABLES +#ifdef __LTC_TWOFISH_TAB_C__ + +/* pre generated 8x8 tables from the four 4x4s */ +static const unsigned char SBOX[2][256] = { +{ + 0xa9, 0x67, 0xb3, 0xe8, 0x04, 0xfd, 0xa3, 0x76, 0x9a, 0x92, + 0x80, 0x78, 0xe4, 0xdd, 0xd1, 0x38, 0x0d, 0xc6, 0x35, 0x98, + 0x18, 0xf7, 0xec, 0x6c, 0x43, 0x75, 0x37, 0x26, 0xfa, 0x13, + 0x94, 0x48, 0xf2, 0xd0, 0x8b, 0x30, 0x84, 0x54, 0xdf, 0x23, + 0x19, 0x5b, 0x3d, 0x59, 0xf3, 0xae, 0xa2, 0x82, 0x63, 0x01, + 0x83, 0x2e, 0xd9, 0x51, 0x9b, 0x7c, 0xa6, 0xeb, 0xa5, 0xbe, + 0x16, 0x0c, 0xe3, 0x61, 0xc0, 0x8c, 0x3a, 0xf5, 0x73, 0x2c, + 0x25, 0x0b, 0xbb, 0x4e, 0x89, 0x6b, 0x53, 0x6a, 0xb4, 0xf1, + 0xe1, 0xe6, 0xbd, 0x45, 0xe2, 0xf4, 0xb6, 0x66, 0xcc, 0x95, + 0x03, 0x56, 0xd4, 0x1c, 0x1e, 0xd7, 0xfb, 0xc3, 0x8e, 0xb5, + 0xe9, 0xcf, 0xbf, 0xba, 0xea, 0x77, 0x39, 0xaf, 0x33, 0xc9, + 0x62, 0x71, 0x81, 0x79, 0x09, 0xad, 0x24, 0xcd, 0xf9, 0xd8, + 0xe5, 0xc5, 0xb9, 0x4d, 0x44, 0x08, 0x86, 0xe7, 0xa1, 0x1d, + 0xaa, 0xed, 0x06, 0x70, 0xb2, 0xd2, 0x41, 0x7b, 0xa0, 0x11, + 0x31, 0xc2, 0x27, 0x90, 0x20, 0xf6, 0x60, 0xff, 0x96, 0x5c, + 0xb1, 0xab, 0x9e, 0x9c, 0x52, 0x1b, 0x5f, 0x93, 0x0a, 0xef, + 0x91, 0x85, 0x49, 0xee, 0x2d, 0x4f, 0x8f, 0x3b, 0x47, 0x87, + 0x6d, 0x46, 0xd6, 0x3e, 0x69, 0x64, 0x2a, 0xce, 0xcb, 0x2f, + 0xfc, 0x97, 0x05, 0x7a, 0xac, 0x7f, 0xd5, 0x1a, 0x4b, 0x0e, + 0xa7, 0x5a, 0x28, 0x14, 0x3f, 0x29, 0x88, 0x3c, 0x4c, 0x02, + 0xb8, 0xda, 0xb0, 0x17, 0x55, 0x1f, 0x8a, 0x7d, 0x57, 0xc7, + 0x8d, 0x74, 0xb7, 0xc4, 0x9f, 0x72, 0x7e, 0x15, 0x22, 0x12, + 0x58, 0x07, 0x99, 0x34, 0x6e, 0x50, 0xde, 0x68, 0x65, 0xbc, + 0xdb, 0xf8, 0xc8, 0xa8, 0x2b, 0x40, 0xdc, 0xfe, 0x32, 0xa4, + 0xca, 0x10, 0x21, 0xf0, 0xd3, 0x5d, 0x0f, 0x00, 0x6f, 0x9d, + 0x36, 0x42, 0x4a, 0x5e, 0xc1, 0xe0}, +{ + 0x75, 0xf3, 0xc6, 0xf4, 0xdb, 0x7b, 0xfb, 0xc8, 0x4a, 0xd3, + 0xe6, 0x6b, 0x45, 0x7d, 0xe8, 0x4b, 0xd6, 0x32, 0xd8, 0xfd, + 0x37, 0x71, 0xf1, 0xe1, 0x30, 0x0f, 0xf8, 0x1b, 0x87, 0xfa, + 0x06, 0x3f, 0x5e, 0xba, 0xae, 0x5b, 0x8a, 0x00, 0xbc, 0x9d, + 0x6d, 0xc1, 0xb1, 0x0e, 0x80, 0x5d, 0xd2, 0xd5, 0xa0, 0x84, + 0x07, 0x14, 0xb5, 0x90, 0x2c, 0xa3, 0xb2, 0x73, 0x4c, 0x54, + 0x92, 0x74, 0x36, 0x51, 0x38, 0xb0, 0xbd, 0x5a, 0xfc, 0x60, + 0x62, 0x96, 0x6c, 0x42, 0xf7, 0x10, 0x7c, 0x28, 0x27, 0x8c, + 0x13, 0x95, 0x9c, 0xc7, 0x24, 0x46, 0x3b, 0x70, 0xca, 0xe3, + 0x85, 0xcb, 0x11, 0xd0, 0x93, 0xb8, 0xa6, 0x83, 0x20, 0xff, + 0x9f, 0x77, 0xc3, 0xcc, 0x03, 0x6f, 0x08, 0xbf, 0x40, 0xe7, + 0x2b, 0xe2, 0x79, 0x0c, 0xaa, 0x82, 0x41, 0x3a, 0xea, 0xb9, + 0xe4, 0x9a, 0xa4, 0x97, 0x7e, 0xda, 0x7a, 0x17, 0x66, 0x94, + 0xa1, 0x1d, 0x3d, 0xf0, 0xde, 0xb3, 0x0b, 0x72, 0xa7, 0x1c, + 0xef, 0xd1, 0x53, 0x3e, 0x8f, 0x33, 0x26, 0x5f, 0xec, 0x76, + 0x2a, 0x49, 0x81, 0x88, 0xee, 0x21, 0xc4, 0x1a, 0xeb, 0xd9, + 0xc5, 0x39, 0x99, 0xcd, 0xad, 0x31, 0x8b, 0x01, 0x18, 0x23, + 0xdd, 0x1f, 0x4e, 0x2d, 0xf9, 0x48, 0x4f, 0xf2, 0x65, 0x8e, + 0x78, 0x5c, 0x58, 0x19, 0x8d, 0xe5, 0x98, 0x57, 0x67, 0x7f, + 0x05, 0x64, 0xaf, 0x63, 0xb6, 0xfe, 0xf5, 0xb7, 0x3c, 0xa5, + 0xce, 0xe9, 0x68, 0x44, 0xe0, 0x4d, 0x43, 0x69, 0x29, 0x2e, + 0xac, 0x15, 0x59, 0xa8, 0x0a, 0x9e, 0x6e, 0x47, 0xdf, 0x34, + 0x35, 0x6a, 0xcf, 0xdc, 0x22, 0xc9, 0xc0, 0x9b, 0x89, 0xd4, + 0xed, 0xab, 0x12, 0xa2, 0x0d, 0x52, 0xbb, 0x02, 0x2f, 0xa9, + 0xd7, 0x61, 0x1e, 0xb4, 0x50, 0x04, 0xf6, 0xc2, 0x16, 0x25, + 0x86, 0x56, 0x55, 0x09, 0xbe, 0x91} +}; + +/* the 4x4 MDS in a nicer format */ +static const ulong32 mds_tab[4][256] = { +{ +0x00000000UL, 0xefef5b01UL, 0xb7b7b602UL, 0x5858ed03UL, 0x07070504UL, 0xe8e85e05UL, 0xb0b0b306UL, 0x5f5fe807UL, +0x0e0e0a08UL, 0xe1e15109UL, 0xb9b9bc0aUL, 0x5656e70bUL, 0x09090f0cUL, 0xe6e6540dUL, 0xbebeb90eUL, 0x5151e20fUL, +0x1c1c1410UL, 0xf3f34f11UL, 0xababa212UL, 0x4444f913UL, 0x1b1b1114UL, 0xf4f44a15UL, 0xacaca716UL, 0x4343fc17UL, +0x12121e18UL, 0xfdfd4519UL, 0xa5a5a81aUL, 0x4a4af31bUL, 0x15151b1cUL, 0xfafa401dUL, 0xa2a2ad1eUL, 0x4d4df61fUL, +0x38382820UL, 0xd7d77321UL, 0x8f8f9e22UL, 0x6060c523UL, 0x3f3f2d24UL, 0xd0d07625UL, 0x88889b26UL, 0x6767c027UL, +0x36362228UL, 0xd9d97929UL, 0x8181942aUL, 0x6e6ecf2bUL, 0x3131272cUL, 0xdede7c2dUL, 0x8686912eUL, 0x6969ca2fUL, +0x24243c30UL, 0xcbcb6731UL, 0x93938a32UL, 0x7c7cd133UL, 0x23233934UL, 0xcccc6235UL, 0x94948f36UL, 0x7b7bd437UL, +0x2a2a3638UL, 0xc5c56d39UL, 0x9d9d803aUL, 0x7272db3bUL, 0x2d2d333cUL, 0xc2c2683dUL, 0x9a9a853eUL, 0x7575de3fUL, +0x70705040UL, 0x9f9f0b41UL, 0xc7c7e642UL, 0x2828bd43UL, 0x77775544UL, 0x98980e45UL, 0xc0c0e346UL, 0x2f2fb847UL, +0x7e7e5a48UL, 0x91910149UL, 0xc9c9ec4aUL, 0x2626b74bUL, 0x79795f4cUL, 0x9696044dUL, 0xcecee94eUL, 0x2121b24fUL, +0x6c6c4450UL, 0x83831f51UL, 0xdbdbf252UL, 0x3434a953UL, 0x6b6b4154UL, 0x84841a55UL, 0xdcdcf756UL, 0x3333ac57UL, +0x62624e58UL, 0x8d8d1559UL, 0xd5d5f85aUL, 0x3a3aa35bUL, 0x65654b5cUL, 0x8a8a105dUL, 0xd2d2fd5eUL, 0x3d3da65fUL, +0x48487860UL, 0xa7a72361UL, 0xffffce62UL, 0x10109563UL, 0x4f4f7d64UL, 0xa0a02665UL, 0xf8f8cb66UL, 0x17179067UL, +0x46467268UL, 0xa9a92969UL, 0xf1f1c46aUL, 0x1e1e9f6bUL, 0x4141776cUL, 0xaeae2c6dUL, 0xf6f6c16eUL, 0x19199a6fUL, +0x54546c70UL, 0xbbbb3771UL, 0xe3e3da72UL, 0x0c0c8173UL, 0x53536974UL, 0xbcbc3275UL, 0xe4e4df76UL, 0x0b0b8477UL, +0x5a5a6678UL, 0xb5b53d79UL, 0xededd07aUL, 0x02028b7bUL, 0x5d5d637cUL, 0xb2b2387dUL, 0xeaead57eUL, 0x05058e7fUL, +0xe0e0a080UL, 0x0f0ffb81UL, 0x57571682UL, 0xb8b84d83UL, 0xe7e7a584UL, 0x0808fe85UL, 0x50501386UL, 0xbfbf4887UL, +0xeeeeaa88UL, 0x0101f189UL, 0x59591c8aUL, 0xb6b6478bUL, 0xe9e9af8cUL, 0x0606f48dUL, 0x5e5e198eUL, 0xb1b1428fUL, +0xfcfcb490UL, 0x1313ef91UL, 0x4b4b0292UL, 0xa4a45993UL, 0xfbfbb194UL, 0x1414ea95UL, 0x4c4c0796UL, 0xa3a35c97UL, +0xf2f2be98UL, 0x1d1de599UL, 0x4545089aUL, 0xaaaa539bUL, 0xf5f5bb9cUL, 0x1a1ae09dUL, 0x42420d9eUL, 0xadad569fUL, +0xd8d888a0UL, 0x3737d3a1UL, 0x6f6f3ea2UL, 0x808065a3UL, 0xdfdf8da4UL, 0x3030d6a5UL, 0x68683ba6UL, 0x878760a7UL, +0xd6d682a8UL, 0x3939d9a9UL, 0x616134aaUL, 0x8e8e6fabUL, 0xd1d187acUL, 0x3e3edcadUL, 0x666631aeUL, 0x89896aafUL, +0xc4c49cb0UL, 0x2b2bc7b1UL, 0x73732ab2UL, 0x9c9c71b3UL, 0xc3c399b4UL, 0x2c2cc2b5UL, 0x74742fb6UL, 0x9b9b74b7UL, +0xcaca96b8UL, 0x2525cdb9UL, 0x7d7d20baUL, 0x92927bbbUL, 0xcdcd93bcUL, 0x2222c8bdUL, 0x7a7a25beUL, 0x95957ebfUL, +0x9090f0c0UL, 0x7f7fabc1UL, 0x272746c2UL, 0xc8c81dc3UL, 0x9797f5c4UL, 0x7878aec5UL, 0x202043c6UL, 0xcfcf18c7UL, +0x9e9efac8UL, 0x7171a1c9UL, 0x29294ccaUL, 0xc6c617cbUL, 0x9999ffccUL, 0x7676a4cdUL, 0x2e2e49ceUL, 0xc1c112cfUL, +0x8c8ce4d0UL, 0x6363bfd1UL, 0x3b3b52d2UL, 0xd4d409d3UL, 0x8b8be1d4UL, 0x6464bad5UL, 0x3c3c57d6UL, 0xd3d30cd7UL, +0x8282eed8UL, 0x6d6db5d9UL, 0x353558daUL, 0xdada03dbUL, 0x8585ebdcUL, 0x6a6ab0ddUL, 0x32325ddeUL, 0xdddd06dfUL, +0xa8a8d8e0UL, 0x474783e1UL, 0x1f1f6ee2UL, 0xf0f035e3UL, 0xafafdde4UL, 0x404086e5UL, 0x18186be6UL, 0xf7f730e7UL, +0xa6a6d2e8UL, 0x494989e9UL, 0x111164eaUL, 0xfefe3febUL, 0xa1a1d7ecUL, 0x4e4e8cedUL, 0x161661eeUL, 0xf9f93aefUL, +0xb4b4ccf0UL, 0x5b5b97f1UL, 0x03037af2UL, 0xecec21f3UL, 0xb3b3c9f4UL, 0x5c5c92f5UL, 0x04047ff6UL, 0xebeb24f7UL, +0xbabac6f8UL, 0x55559df9UL, 0x0d0d70faUL, 0xe2e22bfbUL, 0xbdbdc3fcUL, 0x525298fdUL, 0x0a0a75feUL, 0xe5e52effUL +}, +{ +0x00000000UL, 0x015befefUL, 0x02b6b7b7UL, 0x03ed5858UL, 0x04050707UL, 0x055ee8e8UL, 0x06b3b0b0UL, 0x07e85f5fUL, +0x080a0e0eUL, 0x0951e1e1UL, 0x0abcb9b9UL, 0x0be75656UL, 0x0c0f0909UL, 0x0d54e6e6UL, 0x0eb9bebeUL, 0x0fe25151UL, +0x10141c1cUL, 0x114ff3f3UL, 0x12a2ababUL, 0x13f94444UL, 0x14111b1bUL, 0x154af4f4UL, 0x16a7acacUL, 0x17fc4343UL, +0x181e1212UL, 0x1945fdfdUL, 0x1aa8a5a5UL, 0x1bf34a4aUL, 0x1c1b1515UL, 0x1d40fafaUL, 0x1eada2a2UL, 0x1ff64d4dUL, +0x20283838UL, 0x2173d7d7UL, 0x229e8f8fUL, 0x23c56060UL, 0x242d3f3fUL, 0x2576d0d0UL, 0x269b8888UL, 0x27c06767UL, +0x28223636UL, 0x2979d9d9UL, 0x2a948181UL, 0x2bcf6e6eUL, 0x2c273131UL, 0x2d7cdedeUL, 0x2e918686UL, 0x2fca6969UL, +0x303c2424UL, 0x3167cbcbUL, 0x328a9393UL, 0x33d17c7cUL, 0x34392323UL, 0x3562ccccUL, 0x368f9494UL, 0x37d47b7bUL, +0x38362a2aUL, 0x396dc5c5UL, 0x3a809d9dUL, 0x3bdb7272UL, 0x3c332d2dUL, 0x3d68c2c2UL, 0x3e859a9aUL, 0x3fde7575UL, +0x40507070UL, 0x410b9f9fUL, 0x42e6c7c7UL, 0x43bd2828UL, 0x44557777UL, 0x450e9898UL, 0x46e3c0c0UL, 0x47b82f2fUL, +0x485a7e7eUL, 0x49019191UL, 0x4aecc9c9UL, 0x4bb72626UL, 0x4c5f7979UL, 0x4d049696UL, 0x4ee9ceceUL, 0x4fb22121UL, +0x50446c6cUL, 0x511f8383UL, 0x52f2dbdbUL, 0x53a93434UL, 0x54416b6bUL, 0x551a8484UL, 0x56f7dcdcUL, 0x57ac3333UL, +0x584e6262UL, 0x59158d8dUL, 0x5af8d5d5UL, 0x5ba33a3aUL, 0x5c4b6565UL, 0x5d108a8aUL, 0x5efdd2d2UL, 0x5fa63d3dUL, +0x60784848UL, 0x6123a7a7UL, 0x62ceffffUL, 0x63951010UL, 0x647d4f4fUL, 0x6526a0a0UL, 0x66cbf8f8UL, 0x67901717UL, +0x68724646UL, 0x6929a9a9UL, 0x6ac4f1f1UL, 0x6b9f1e1eUL, 0x6c774141UL, 0x6d2caeaeUL, 0x6ec1f6f6UL, 0x6f9a1919UL, +0x706c5454UL, 0x7137bbbbUL, 0x72dae3e3UL, 0x73810c0cUL, 0x74695353UL, 0x7532bcbcUL, 0x76dfe4e4UL, 0x77840b0bUL, +0x78665a5aUL, 0x793db5b5UL, 0x7ad0ededUL, 0x7b8b0202UL, 0x7c635d5dUL, 0x7d38b2b2UL, 0x7ed5eaeaUL, 0x7f8e0505UL, +0x80a0e0e0UL, 0x81fb0f0fUL, 0x82165757UL, 0x834db8b8UL, 0x84a5e7e7UL, 0x85fe0808UL, 0x86135050UL, 0x8748bfbfUL, +0x88aaeeeeUL, 0x89f10101UL, 0x8a1c5959UL, 0x8b47b6b6UL, 0x8cafe9e9UL, 0x8df40606UL, 0x8e195e5eUL, 0x8f42b1b1UL, +0x90b4fcfcUL, 0x91ef1313UL, 0x92024b4bUL, 0x9359a4a4UL, 0x94b1fbfbUL, 0x95ea1414UL, 0x96074c4cUL, 0x975ca3a3UL, +0x98bef2f2UL, 0x99e51d1dUL, 0x9a084545UL, 0x9b53aaaaUL, 0x9cbbf5f5UL, 0x9de01a1aUL, 0x9e0d4242UL, 0x9f56adadUL, +0xa088d8d8UL, 0xa1d33737UL, 0xa23e6f6fUL, 0xa3658080UL, 0xa48ddfdfUL, 0xa5d63030UL, 0xa63b6868UL, 0xa7608787UL, +0xa882d6d6UL, 0xa9d93939UL, 0xaa346161UL, 0xab6f8e8eUL, 0xac87d1d1UL, 0xaddc3e3eUL, 0xae316666UL, 0xaf6a8989UL, +0xb09cc4c4UL, 0xb1c72b2bUL, 0xb22a7373UL, 0xb3719c9cUL, 0xb499c3c3UL, 0xb5c22c2cUL, 0xb62f7474UL, 0xb7749b9bUL, +0xb896cacaUL, 0xb9cd2525UL, 0xba207d7dUL, 0xbb7b9292UL, 0xbc93cdcdUL, 0xbdc82222UL, 0xbe257a7aUL, 0xbf7e9595UL, +0xc0f09090UL, 0xc1ab7f7fUL, 0xc2462727UL, 0xc31dc8c8UL, 0xc4f59797UL, 0xc5ae7878UL, 0xc6432020UL, 0xc718cfcfUL, +0xc8fa9e9eUL, 0xc9a17171UL, 0xca4c2929UL, 0xcb17c6c6UL, 0xccff9999UL, 0xcda47676UL, 0xce492e2eUL, 0xcf12c1c1UL, +0xd0e48c8cUL, 0xd1bf6363UL, 0xd2523b3bUL, 0xd309d4d4UL, 0xd4e18b8bUL, 0xd5ba6464UL, 0xd6573c3cUL, 0xd70cd3d3UL, +0xd8ee8282UL, 0xd9b56d6dUL, 0xda583535UL, 0xdb03dadaUL, 0xdceb8585UL, 0xddb06a6aUL, 0xde5d3232UL, 0xdf06ddddUL, +0xe0d8a8a8UL, 0xe1834747UL, 0xe26e1f1fUL, 0xe335f0f0UL, 0xe4ddafafUL, 0xe5864040UL, 0xe66b1818UL, 0xe730f7f7UL, +0xe8d2a6a6UL, 0xe9894949UL, 0xea641111UL, 0xeb3ffefeUL, 0xecd7a1a1UL, 0xed8c4e4eUL, 0xee611616UL, 0xef3af9f9UL, +0xf0ccb4b4UL, 0xf1975b5bUL, 0xf27a0303UL, 0xf321ececUL, 0xf4c9b3b3UL, 0xf5925c5cUL, 0xf67f0404UL, 0xf724ebebUL, +0xf8c6babaUL, 0xf99d5555UL, 0xfa700d0dUL, 0xfb2be2e2UL, 0xfcc3bdbdUL, 0xfd985252UL, 0xfe750a0aUL, 0xff2ee5e5UL +}, +{ +0x00000000UL, 0xef01ef5bUL, 0xb702b7b6UL, 0x580358edUL, 0x07040705UL, 0xe805e85eUL, 0xb006b0b3UL, 0x5f075fe8UL, +0x0e080e0aUL, 0xe109e151UL, 0xb90ab9bcUL, 0x560b56e7UL, 0x090c090fUL, 0xe60de654UL, 0xbe0ebeb9UL, 0x510f51e2UL, +0x1c101c14UL, 0xf311f34fUL, 0xab12aba2UL, 0x441344f9UL, 0x1b141b11UL, 0xf415f44aUL, 0xac16aca7UL, 0x431743fcUL, +0x1218121eUL, 0xfd19fd45UL, 0xa51aa5a8UL, 0x4a1b4af3UL, 0x151c151bUL, 0xfa1dfa40UL, 0xa21ea2adUL, 0x4d1f4df6UL, +0x38203828UL, 0xd721d773UL, 0x8f228f9eUL, 0x602360c5UL, 0x3f243f2dUL, 0xd025d076UL, 0x8826889bUL, 0x672767c0UL, +0x36283622UL, 0xd929d979UL, 0x812a8194UL, 0x6e2b6ecfUL, 0x312c3127UL, 0xde2dde7cUL, 0x862e8691UL, 0x692f69caUL, +0x2430243cUL, 0xcb31cb67UL, 0x9332938aUL, 0x7c337cd1UL, 0x23342339UL, 0xcc35cc62UL, 0x9436948fUL, 0x7b377bd4UL, +0x2a382a36UL, 0xc539c56dUL, 0x9d3a9d80UL, 0x723b72dbUL, 0x2d3c2d33UL, 0xc23dc268UL, 0x9a3e9a85UL, 0x753f75deUL, +0x70407050UL, 0x9f419f0bUL, 0xc742c7e6UL, 0x284328bdUL, 0x77447755UL, 0x9845980eUL, 0xc046c0e3UL, 0x2f472fb8UL, +0x7e487e5aUL, 0x91499101UL, 0xc94ac9ecUL, 0x264b26b7UL, 0x794c795fUL, 0x964d9604UL, 0xce4ecee9UL, 0x214f21b2UL, +0x6c506c44UL, 0x8351831fUL, 0xdb52dbf2UL, 0x345334a9UL, 0x6b546b41UL, 0x8455841aUL, 0xdc56dcf7UL, 0x335733acUL, +0x6258624eUL, 0x8d598d15UL, 0xd55ad5f8UL, 0x3a5b3aa3UL, 0x655c654bUL, 0x8a5d8a10UL, 0xd25ed2fdUL, 0x3d5f3da6UL, +0x48604878UL, 0xa761a723UL, 0xff62ffceUL, 0x10631095UL, 0x4f644f7dUL, 0xa065a026UL, 0xf866f8cbUL, 0x17671790UL, +0x46684672UL, 0xa969a929UL, 0xf16af1c4UL, 0x1e6b1e9fUL, 0x416c4177UL, 0xae6dae2cUL, 0xf66ef6c1UL, 0x196f199aUL, +0x5470546cUL, 0xbb71bb37UL, 0xe372e3daUL, 0x0c730c81UL, 0x53745369UL, 0xbc75bc32UL, 0xe476e4dfUL, 0x0b770b84UL, +0x5a785a66UL, 0xb579b53dUL, 0xed7aedd0UL, 0x027b028bUL, 0x5d7c5d63UL, 0xb27db238UL, 0xea7eead5UL, 0x057f058eUL, +0xe080e0a0UL, 0x0f810ffbUL, 0x57825716UL, 0xb883b84dUL, 0xe784e7a5UL, 0x088508feUL, 0x50865013UL, 0xbf87bf48UL, +0xee88eeaaUL, 0x018901f1UL, 0x598a591cUL, 0xb68bb647UL, 0xe98ce9afUL, 0x068d06f4UL, 0x5e8e5e19UL, 0xb18fb142UL, +0xfc90fcb4UL, 0x139113efUL, 0x4b924b02UL, 0xa493a459UL, 0xfb94fbb1UL, 0x149514eaUL, 0x4c964c07UL, 0xa397a35cUL, +0xf298f2beUL, 0x1d991de5UL, 0x459a4508UL, 0xaa9baa53UL, 0xf59cf5bbUL, 0x1a9d1ae0UL, 0x429e420dUL, 0xad9fad56UL, +0xd8a0d888UL, 0x37a137d3UL, 0x6fa26f3eUL, 0x80a38065UL, 0xdfa4df8dUL, 0x30a530d6UL, 0x68a6683bUL, 0x87a78760UL, +0xd6a8d682UL, 0x39a939d9UL, 0x61aa6134UL, 0x8eab8e6fUL, 0xd1acd187UL, 0x3ead3edcUL, 0x66ae6631UL, 0x89af896aUL, +0xc4b0c49cUL, 0x2bb12bc7UL, 0x73b2732aUL, 0x9cb39c71UL, 0xc3b4c399UL, 0x2cb52cc2UL, 0x74b6742fUL, 0x9bb79b74UL, +0xcab8ca96UL, 0x25b925cdUL, 0x7dba7d20UL, 0x92bb927bUL, 0xcdbccd93UL, 0x22bd22c8UL, 0x7abe7a25UL, 0x95bf957eUL, +0x90c090f0UL, 0x7fc17fabUL, 0x27c22746UL, 0xc8c3c81dUL, 0x97c497f5UL, 0x78c578aeUL, 0x20c62043UL, 0xcfc7cf18UL, +0x9ec89efaUL, 0x71c971a1UL, 0x29ca294cUL, 0xc6cbc617UL, 0x99cc99ffUL, 0x76cd76a4UL, 0x2ece2e49UL, 0xc1cfc112UL, +0x8cd08ce4UL, 0x63d163bfUL, 0x3bd23b52UL, 0xd4d3d409UL, 0x8bd48be1UL, 0x64d564baUL, 0x3cd63c57UL, 0xd3d7d30cUL, +0x82d882eeUL, 0x6dd96db5UL, 0x35da3558UL, 0xdadbda03UL, 0x85dc85ebUL, 0x6add6ab0UL, 0x32de325dUL, 0xdddfdd06UL, +0xa8e0a8d8UL, 0x47e14783UL, 0x1fe21f6eUL, 0xf0e3f035UL, 0xafe4afddUL, 0x40e54086UL, 0x18e6186bUL, 0xf7e7f730UL, +0xa6e8a6d2UL, 0x49e94989UL, 0x11ea1164UL, 0xfeebfe3fUL, 0xa1eca1d7UL, 0x4eed4e8cUL, 0x16ee1661UL, 0xf9eff93aUL, +0xb4f0b4ccUL, 0x5bf15b97UL, 0x03f2037aUL, 0xecf3ec21UL, 0xb3f4b3c9UL, 0x5cf55c92UL, 0x04f6047fUL, 0xebf7eb24UL, +0xbaf8bac6UL, 0x55f9559dUL, 0x0dfa0d70UL, 0xe2fbe22bUL, 0xbdfcbdc3UL, 0x52fd5298UL, 0x0afe0a75UL, 0xe5ffe52eUL +}, +{ +0x00000000UL, 0x5bef015bUL, 0xb6b702b6UL, 0xed5803edUL, 0x05070405UL, 0x5ee8055eUL, 0xb3b006b3UL, 0xe85f07e8UL, +0x0a0e080aUL, 0x51e10951UL, 0xbcb90abcUL, 0xe7560be7UL, 0x0f090c0fUL, 0x54e60d54UL, 0xb9be0eb9UL, 0xe2510fe2UL, +0x141c1014UL, 0x4ff3114fUL, 0xa2ab12a2UL, 0xf94413f9UL, 0x111b1411UL, 0x4af4154aUL, 0xa7ac16a7UL, 0xfc4317fcUL, +0x1e12181eUL, 0x45fd1945UL, 0xa8a51aa8UL, 0xf34a1bf3UL, 0x1b151c1bUL, 0x40fa1d40UL, 0xada21eadUL, 0xf64d1ff6UL, +0x28382028UL, 0x73d72173UL, 0x9e8f229eUL, 0xc56023c5UL, 0x2d3f242dUL, 0x76d02576UL, 0x9b88269bUL, 0xc06727c0UL, +0x22362822UL, 0x79d92979UL, 0x94812a94UL, 0xcf6e2bcfUL, 0x27312c27UL, 0x7cde2d7cUL, 0x91862e91UL, 0xca692fcaUL, +0x3c24303cUL, 0x67cb3167UL, 0x8a93328aUL, 0xd17c33d1UL, 0x39233439UL, 0x62cc3562UL, 0x8f94368fUL, 0xd47b37d4UL, +0x362a3836UL, 0x6dc5396dUL, 0x809d3a80UL, 0xdb723bdbUL, 0x332d3c33UL, 0x68c23d68UL, 0x859a3e85UL, 0xde753fdeUL, +0x50704050UL, 0x0b9f410bUL, 0xe6c742e6UL, 0xbd2843bdUL, 0x55774455UL, 0x0e98450eUL, 0xe3c046e3UL, 0xb82f47b8UL, +0x5a7e485aUL, 0x01914901UL, 0xecc94aecUL, 0xb7264bb7UL, 0x5f794c5fUL, 0x04964d04UL, 0xe9ce4ee9UL, 0xb2214fb2UL, +0x446c5044UL, 0x1f83511fUL, 0xf2db52f2UL, 0xa93453a9UL, 0x416b5441UL, 0x1a84551aUL, 0xf7dc56f7UL, 0xac3357acUL, +0x4e62584eUL, 0x158d5915UL, 0xf8d55af8UL, 0xa33a5ba3UL, 0x4b655c4bUL, 0x108a5d10UL, 0xfdd25efdUL, 0xa63d5fa6UL, +0x78486078UL, 0x23a76123UL, 0xceff62ceUL, 0x95106395UL, 0x7d4f647dUL, 0x26a06526UL, 0xcbf866cbUL, 0x90176790UL, +0x72466872UL, 0x29a96929UL, 0xc4f16ac4UL, 0x9f1e6b9fUL, 0x77416c77UL, 0x2cae6d2cUL, 0xc1f66ec1UL, 0x9a196f9aUL, +0x6c54706cUL, 0x37bb7137UL, 0xdae372daUL, 0x810c7381UL, 0x69537469UL, 0x32bc7532UL, 0xdfe476dfUL, 0x840b7784UL, +0x665a7866UL, 0x3db5793dUL, 0xd0ed7ad0UL, 0x8b027b8bUL, 0x635d7c63UL, 0x38b27d38UL, 0xd5ea7ed5UL, 0x8e057f8eUL, +0xa0e080a0UL, 0xfb0f81fbUL, 0x16578216UL, 0x4db8834dUL, 0xa5e784a5UL, 0xfe0885feUL, 0x13508613UL, 0x48bf8748UL, +0xaaee88aaUL, 0xf10189f1UL, 0x1c598a1cUL, 0x47b68b47UL, 0xafe98cafUL, 0xf4068df4UL, 0x195e8e19UL, 0x42b18f42UL, +0xb4fc90b4UL, 0xef1391efUL, 0x024b9202UL, 0x59a49359UL, 0xb1fb94b1UL, 0xea1495eaUL, 0x074c9607UL, 0x5ca3975cUL, +0xbef298beUL, 0xe51d99e5UL, 0x08459a08UL, 0x53aa9b53UL, 0xbbf59cbbUL, 0xe01a9de0UL, 0x0d429e0dUL, 0x56ad9f56UL, +0x88d8a088UL, 0xd337a1d3UL, 0x3e6fa23eUL, 0x6580a365UL, 0x8ddfa48dUL, 0xd630a5d6UL, 0x3b68a63bUL, 0x6087a760UL, +0x82d6a882UL, 0xd939a9d9UL, 0x3461aa34UL, 0x6f8eab6fUL, 0x87d1ac87UL, 0xdc3eaddcUL, 0x3166ae31UL, 0x6a89af6aUL, +0x9cc4b09cUL, 0xc72bb1c7UL, 0x2a73b22aUL, 0x719cb371UL, 0x99c3b499UL, 0xc22cb5c2UL, 0x2f74b62fUL, 0x749bb774UL, +0x96cab896UL, 0xcd25b9cdUL, 0x207dba20UL, 0x7b92bb7bUL, 0x93cdbc93UL, 0xc822bdc8UL, 0x257abe25UL, 0x7e95bf7eUL, +0xf090c0f0UL, 0xab7fc1abUL, 0x4627c246UL, 0x1dc8c31dUL, 0xf597c4f5UL, 0xae78c5aeUL, 0x4320c643UL, 0x18cfc718UL, +0xfa9ec8faUL, 0xa171c9a1UL, 0x4c29ca4cUL, 0x17c6cb17UL, 0xff99ccffUL, 0xa476cda4UL, 0x492ece49UL, 0x12c1cf12UL, +0xe48cd0e4UL, 0xbf63d1bfUL, 0x523bd252UL, 0x09d4d309UL, 0xe18bd4e1UL, 0xba64d5baUL, 0x573cd657UL, 0x0cd3d70cUL, +0xee82d8eeUL, 0xb56dd9b5UL, 0x5835da58UL, 0x03dadb03UL, 0xeb85dcebUL, 0xb06addb0UL, 0x5d32de5dUL, 0x06dddf06UL, +0xd8a8e0d8UL, 0x8347e183UL, 0x6e1fe26eUL, 0x35f0e335UL, 0xddafe4ddUL, 0x8640e586UL, 0x6b18e66bUL, 0x30f7e730UL, +0xd2a6e8d2UL, 0x8949e989UL, 0x6411ea64UL, 0x3ffeeb3fUL, 0xd7a1ecd7UL, 0x8c4eed8cUL, 0x6116ee61UL, 0x3af9ef3aUL, +0xccb4f0ccUL, 0x975bf197UL, 0x7a03f27aUL, 0x21ecf321UL, 0xc9b3f4c9UL, 0x925cf592UL, 0x7f04f67fUL, 0x24ebf724UL, +0xc6baf8c6UL, 0x9d55f99dUL, 0x700dfa70UL, 0x2be2fb2bUL, 0xc3bdfcc3UL, 0x9852fd98UL, 0x750afe75UL, 0x2ee5ff2eUL +}}; + +#ifdef LTC_TWOFISH_ALL_TABLES + +/* the 4x8 RS transform */ +static const ulong32 rs_tab0[256] = { +0x00000000LU, 0xa402a401LU, 0x05040502LU, 0xa106a103LU, 0x0a080a04LU, 0xae0aae05LU, 0x0f0c0f06LU, 0xab0eab07LU, +0x14101408LU, 0xb012b009LU, 0x1114110aLU, 0xb516b50bLU, 0x1e181e0cLU, 0xba1aba0dLU, 0x1b1c1b0eLU, 0xbf1ebf0fLU, +0x28202810LU, 0x8c228c11LU, 0x2d242d12LU, 0x89268913LU, 0x22282214LU, 0x862a8615LU, 0x272c2716LU, 0x832e8317LU, +0x3c303c18LU, 0x98329819LU, 0x3934391aLU, 0x9d369d1bLU, 0x3638361cLU, 0x923a921dLU, 0x333c331eLU, 0x973e971fLU, +0x50405020LU, 0xf442f421LU, 0x55445522LU, 0xf146f123LU, 0x5a485a24LU, 0xfe4afe25LU, 0x5f4c5f26LU, 0xfb4efb27LU, +0x44504428LU, 0xe052e029LU, 0x4154412aLU, 0xe556e52bLU, 0x4e584e2cLU, 0xea5aea2dLU, 0x4b5c4b2eLU, 0xef5eef2fLU, +0x78607830LU, 0xdc62dc31LU, 0x7d647d32LU, 0xd966d933LU, 0x72687234LU, 0xd66ad635LU, 0x776c7736LU, 0xd36ed337LU, +0x6c706c38LU, 0xc872c839LU, 0x6974693aLU, 0xcd76cd3bLU, 0x6678663cLU, 0xc27ac23dLU, 0x637c633eLU, 0xc77ec73fLU, +0xa080a040LU, 0x04820441LU, 0xa584a542LU, 0x01860143LU, 0xaa88aa44LU, 0x0e8a0e45LU, 0xaf8caf46LU, 0x0b8e0b47LU, +0xb490b448LU, 0x10921049LU, 0xb194b14aLU, 0x1596154bLU, 0xbe98be4cLU, 0x1a9a1a4dLU, 0xbb9cbb4eLU, 0x1f9e1f4fLU, +0x88a08850LU, 0x2ca22c51LU, 0x8da48d52LU, 0x29a62953LU, 0x82a88254LU, 0x26aa2655LU, 0x87ac8756LU, 0x23ae2357LU, +0x9cb09c58LU, 0x38b23859LU, 0x99b4995aLU, 0x3db63d5bLU, 0x96b8965cLU, 0x32ba325dLU, 0x93bc935eLU, 0x37be375fLU, +0xf0c0f060LU, 0x54c25461LU, 0xf5c4f562LU, 0x51c65163LU, 0xfac8fa64LU, 0x5eca5e65LU, 0xffccff66LU, 0x5bce5b67LU, +0xe4d0e468LU, 0x40d24069LU, 0xe1d4e16aLU, 0x45d6456bLU, 0xeed8ee6cLU, 0x4ada4a6dLU, 0xebdceb6eLU, 0x4fde4f6fLU, +0xd8e0d870LU, 0x7ce27c71LU, 0xdde4dd72LU, 0x79e67973LU, 0xd2e8d274LU, 0x76ea7675LU, 0xd7ecd776LU, 0x73ee7377LU, +0xccf0cc78LU, 0x68f26879LU, 0xc9f4c97aLU, 0x6df66d7bLU, 0xc6f8c67cLU, 0x62fa627dLU, 0xc3fcc37eLU, 0x67fe677fLU, +0x0d4d0d80LU, 0xa94fa981LU, 0x08490882LU, 0xac4bac83LU, 0x07450784LU, 0xa347a385LU, 0x02410286LU, 0xa643a687LU, +0x195d1988LU, 0xbd5fbd89LU, 0x1c591c8aLU, 0xb85bb88bLU, 0x1355138cLU, 0xb757b78dLU, 0x1651168eLU, 0xb253b28fLU, +0x256d2590LU, 0x816f8191LU, 0x20692092LU, 0x846b8493LU, 0x2f652f94LU, 0x8b678b95LU, 0x2a612a96LU, 0x8e638e97LU, +0x317d3198LU, 0x957f9599LU, 0x3479349aLU, 0x907b909bLU, 0x3b753b9cLU, 0x9f779f9dLU, 0x3e713e9eLU, 0x9a739a9fLU, +0x5d0d5da0LU, 0xf90ff9a1LU, 0x580958a2LU, 0xfc0bfca3LU, 0x570557a4LU, 0xf307f3a5LU, 0x520152a6LU, 0xf603f6a7LU, +0x491d49a8LU, 0xed1feda9LU, 0x4c194caaLU, 0xe81be8abLU, 0x431543acLU, 0xe717e7adLU, 0x461146aeLU, 0xe213e2afLU, +0x752d75b0LU, 0xd12fd1b1LU, 0x702970b2LU, 0xd42bd4b3LU, 0x7f257fb4LU, 0xdb27dbb5LU, 0x7a217ab6LU, 0xde23deb7LU, +0x613d61b8LU, 0xc53fc5b9LU, 0x643964baLU, 0xc03bc0bbLU, 0x6b356bbcLU, 0xcf37cfbdLU, 0x6e316ebeLU, 0xca33cabfLU, +0xadcdadc0LU, 0x09cf09c1LU, 0xa8c9a8c2LU, 0x0ccb0cc3LU, 0xa7c5a7c4LU, 0x03c703c5LU, 0xa2c1a2c6LU, 0x06c306c7LU, +0xb9ddb9c8LU, 0x1ddf1dc9LU, 0xbcd9bccaLU, 0x18db18cbLU, 0xb3d5b3ccLU, 0x17d717cdLU, 0xb6d1b6ceLU, 0x12d312cfLU, +0x85ed85d0LU, 0x21ef21d1LU, 0x80e980d2LU, 0x24eb24d3LU, 0x8fe58fd4LU, 0x2be72bd5LU, 0x8ae18ad6LU, 0x2ee32ed7LU, +0x91fd91d8LU, 0x35ff35d9LU, 0x94f994daLU, 0x30fb30dbLU, 0x9bf59bdcLU, 0x3ff73fddLU, 0x9ef19edeLU, 0x3af33adfLU, +0xfd8dfde0LU, 0x598f59e1LU, 0xf889f8e2LU, 0x5c8b5ce3LU, 0xf785f7e4LU, 0x538753e5LU, 0xf281f2e6LU, 0x568356e7LU, +0xe99de9e8LU, 0x4d9f4de9LU, 0xec99eceaLU, 0x489b48ebLU, 0xe395e3ecLU, 0x479747edLU, 0xe691e6eeLU, 0x429342efLU, +0xd5add5f0LU, 0x71af71f1LU, 0xd0a9d0f2LU, 0x74ab74f3LU, 0xdfa5dff4LU, 0x7ba77bf5LU, 0xdaa1daf6LU, 0x7ea37ef7LU, +0xc1bdc1f8LU, 0x65bf65f9LU, 0xc4b9c4faLU, 0x60bb60fbLU, 0xcbb5cbfcLU, 0x6fb76ffdLU, 0xceb1cefeLU, 0x6ab36affLU }; + +static const ulong32 rs_tab1[256] = { +0x00000000LU, 0x55a156a4LU, 0xaa0fac05LU, 0xffaefaa1LU, 0x191e150aLU, 0x4cbf43aeLU, 0xb311b90fLU, 0xe6b0efabLU, +0x323c2a14LU, 0x679d7cb0LU, 0x98338611LU, 0xcd92d0b5LU, 0x2b223f1eLU, 0x7e8369baLU, 0x812d931bLU, 0xd48cc5bfLU, +0x64785428LU, 0x31d9028cLU, 0xce77f82dLU, 0x9bd6ae89LU, 0x7d664122LU, 0x28c71786LU, 0xd769ed27LU, 0x82c8bb83LU, +0x56447e3cLU, 0x03e52898LU, 0xfc4bd239LU, 0xa9ea849dLU, 0x4f5a6b36LU, 0x1afb3d92LU, 0xe555c733LU, 0xb0f49197LU, +0xc8f0a850LU, 0x9d51fef4LU, 0x62ff0455LU, 0x375e52f1LU, 0xd1eebd5aLU, 0x844febfeLU, 0x7be1115fLU, 0x2e4047fbLU, +0xfacc8244LU, 0xaf6dd4e0LU, 0x50c32e41LU, 0x056278e5LU, 0xe3d2974eLU, 0xb673c1eaLU, 0x49dd3b4bLU, 0x1c7c6defLU, +0xac88fc78LU, 0xf929aadcLU, 0x0687507dLU, 0x532606d9LU, 0xb596e972LU, 0xe037bfd6LU, 0x1f994577LU, 0x4a3813d3LU, +0x9eb4d66cLU, 0xcb1580c8LU, 0x34bb7a69LU, 0x611a2ccdLU, 0x87aac366LU, 0xd20b95c2LU, 0x2da56f63LU, 0x780439c7LU, +0xddad1da0LU, 0x880c4b04LU, 0x77a2b1a5LU, 0x2203e701LU, 0xc4b308aaLU, 0x91125e0eLU, 0x6ebca4afLU, 0x3b1df20bLU, +0xef9137b4LU, 0xba306110LU, 0x459e9bb1LU, 0x103fcd15LU, 0xf68f22beLU, 0xa32e741aLU, 0x5c808ebbLU, 0x0921d81fLU, +0xb9d54988LU, 0xec741f2cLU, 0x13dae58dLU, 0x467bb329LU, 0xa0cb5c82LU, 0xf56a0a26LU, 0x0ac4f087LU, 0x5f65a623LU, +0x8be9639cLU, 0xde483538LU, 0x21e6cf99LU, 0x7447993dLU, 0x92f77696LU, 0xc7562032LU, 0x38f8da93LU, 0x6d598c37LU, +0x155db5f0LU, 0x40fce354LU, 0xbf5219f5LU, 0xeaf34f51LU, 0x0c43a0faLU, 0x59e2f65eLU, 0xa64c0cffLU, 0xf3ed5a5bLU, +0x27619fe4LU, 0x72c0c940LU, 0x8d6e33e1LU, 0xd8cf6545LU, 0x3e7f8aeeLU, 0x6bdedc4aLU, 0x947026ebLU, 0xc1d1704fLU, +0x7125e1d8LU, 0x2484b77cLU, 0xdb2a4dddLU, 0x8e8b1b79LU, 0x683bf4d2LU, 0x3d9aa276LU, 0xc23458d7LU, 0x97950e73LU, +0x4319cbccLU, 0x16b89d68LU, 0xe91667c9LU, 0xbcb7316dLU, 0x5a07dec6LU, 0x0fa68862LU, 0xf00872c3LU, 0xa5a92467LU, +0xf7173a0dLU, 0xa2b66ca9LU, 0x5d189608LU, 0x08b9c0acLU, 0xee092f07LU, 0xbba879a3LU, 0x44068302LU, 0x11a7d5a6LU, +0xc52b1019LU, 0x908a46bdLU, 0x6f24bc1cLU, 0x3a85eab8LU, 0xdc350513LU, 0x899453b7LU, 0x763aa916LU, 0x239bffb2LU, +0x936f6e25LU, 0xc6ce3881LU, 0x3960c220LU, 0x6cc19484LU, 0x8a717b2fLU, 0xdfd02d8bLU, 0x207ed72aLU, 0x75df818eLU, +0xa1534431LU, 0xf4f21295LU, 0x0b5ce834LU, 0x5efdbe90LU, 0xb84d513bLU, 0xedec079fLU, 0x1242fd3eLU, 0x47e3ab9aLU, +0x3fe7925dLU, 0x6a46c4f9LU, 0x95e83e58LU, 0xc04968fcLU, 0x26f98757LU, 0x7358d1f3LU, 0x8cf62b52LU, 0xd9577df6LU, +0x0ddbb849LU, 0x587aeeedLU, 0xa7d4144cLU, 0xf27542e8LU, 0x14c5ad43LU, 0x4164fbe7LU, 0xbeca0146LU, 0xeb6b57e2LU, +0x5b9fc675LU, 0x0e3e90d1LU, 0xf1906a70LU, 0xa4313cd4LU, 0x4281d37fLU, 0x172085dbLU, 0xe88e7f7aLU, 0xbd2f29deLU, +0x69a3ec61LU, 0x3c02bac5LU, 0xc3ac4064LU, 0x960d16c0LU, 0x70bdf96bLU, 0x251cafcfLU, 0xdab2556eLU, 0x8f1303caLU, +0x2aba27adLU, 0x7f1b7109LU, 0x80b58ba8LU, 0xd514dd0cLU, 0x33a432a7LU, 0x66056403LU, 0x99ab9ea2LU, 0xcc0ac806LU, +0x18860db9LU, 0x4d275b1dLU, 0xb289a1bcLU, 0xe728f718LU, 0x019818b3LU, 0x54394e17LU, 0xab97b4b6LU, 0xfe36e212LU, +0x4ec27385LU, 0x1b632521LU, 0xe4cddf80LU, 0xb16c8924LU, 0x57dc668fLU, 0x027d302bLU, 0xfdd3ca8aLU, 0xa8729c2eLU, +0x7cfe5991LU, 0x295f0f35LU, 0xd6f1f594LU, 0x8350a330LU, 0x65e04c9bLU, 0x30411a3fLU, 0xcfefe09eLU, 0x9a4eb63aLU, +0xe24a8ffdLU, 0xb7ebd959LU, 0x484523f8LU, 0x1de4755cLU, 0xfb549af7LU, 0xaef5cc53LU, 0x515b36f2LU, 0x04fa6056LU, +0xd076a5e9LU, 0x85d7f34dLU, 0x7a7909ecLU, 0x2fd85f48LU, 0xc968b0e3LU, 0x9cc9e647LU, 0x63671ce6LU, 0x36c64a42LU, +0x8632dbd5LU, 0xd3938d71LU, 0x2c3d77d0LU, 0x799c2174LU, 0x9f2ccedfLU, 0xca8d987bLU, 0x352362daLU, 0x6082347eLU, +0xb40ef1c1LU, 0xe1afa765LU, 0x1e015dc4LU, 0x4ba00b60LU, 0xad10e4cbLU, 0xf8b1b26fLU, 0x071f48ceLU, 0x52be1e6aLU }; + +static const ulong32 rs_tab2[256] = { +0x00000000LU, 0x87fc8255LU, 0x43b549aaLU, 0xc449cbffLU, 0x86279219LU, 0x01db104cLU, 0xc592dbb3LU, 0x426e59e6LU, +0x414e6932LU, 0xc6b2eb67LU, 0x02fb2098LU, 0x8507a2cdLU, 0xc769fb2bLU, 0x4095797eLU, 0x84dcb281LU, 0x032030d4LU, +0x829cd264LU, 0x05605031LU, 0xc1299bceLU, 0x46d5199bLU, 0x04bb407dLU, 0x8347c228LU, 0x470e09d7LU, 0xc0f28b82LU, +0xc3d2bb56LU, 0x442e3903LU, 0x8067f2fcLU, 0x079b70a9LU, 0x45f5294fLU, 0xc209ab1aLU, 0x064060e5LU, 0x81bce2b0LU, +0x4975e9c8LU, 0xce896b9dLU, 0x0ac0a062LU, 0x8d3c2237LU, 0xcf527bd1LU, 0x48aef984LU, 0x8ce7327bLU, 0x0b1bb02eLU, +0x083b80faLU, 0x8fc702afLU, 0x4b8ec950LU, 0xcc724b05LU, 0x8e1c12e3LU, 0x09e090b6LU, 0xcda95b49LU, 0x4a55d91cLU, +0xcbe93bacLU, 0x4c15b9f9LU, 0x885c7206LU, 0x0fa0f053LU, 0x4dcea9b5LU, 0xca322be0LU, 0x0e7be01fLU, 0x8987624aLU, +0x8aa7529eLU, 0x0d5bd0cbLU, 0xc9121b34LU, 0x4eee9961LU, 0x0c80c087LU, 0x8b7c42d2LU, 0x4f35892dLU, 0xc8c90b78LU, +0x92ea9fddLU, 0x15161d88LU, 0xd15fd677LU, 0x56a35422LU, 0x14cd0dc4LU, 0x93318f91LU, 0x5778446eLU, 0xd084c63bLU, +0xd3a4f6efLU, 0x545874baLU, 0x9011bf45LU, 0x17ed3d10LU, 0x558364f6LU, 0xd27fe6a3LU, 0x16362d5cLU, 0x91caaf09LU, +0x10764db9LU, 0x978acfecLU, 0x53c30413LU, 0xd43f8646LU, 0x9651dfa0LU, 0x11ad5df5LU, 0xd5e4960aLU, 0x5218145fLU, +0x5138248bLU, 0xd6c4a6deLU, 0x128d6d21LU, 0x9571ef74LU, 0xd71fb692LU, 0x50e334c7LU, 0x94aaff38LU, 0x13567d6dLU, +0xdb9f7615LU, 0x5c63f440LU, 0x982a3fbfLU, 0x1fd6bdeaLU, 0x5db8e40cLU, 0xda446659LU, 0x1e0dada6LU, 0x99f12ff3LU, +0x9ad11f27LU, 0x1d2d9d72LU, 0xd964568dLU, 0x5e98d4d8LU, 0x1cf68d3eLU, 0x9b0a0f6bLU, 0x5f43c494LU, 0xd8bf46c1LU, +0x5903a471LU, 0xdeff2624LU, 0x1ab6eddbLU, 0x9d4a6f8eLU, 0xdf243668LU, 0x58d8b43dLU, 0x9c917fc2LU, 0x1b6dfd97LU, +0x184dcd43LU, 0x9fb14f16LU, 0x5bf884e9LU, 0xdc0406bcLU, 0x9e6a5f5aLU, 0x1996dd0fLU, 0xdddf16f0LU, 0x5a2394a5LU, +0x699973f7LU, 0xee65f1a2LU, 0x2a2c3a5dLU, 0xadd0b808LU, 0xefbee1eeLU, 0x684263bbLU, 0xac0ba844LU, 0x2bf72a11LU, +0x28d71ac5LU, 0xaf2b9890LU, 0x6b62536fLU, 0xec9ed13aLU, 0xaef088dcLU, 0x290c0a89LU, 0xed45c176LU, 0x6ab94323LU, +0xeb05a193LU, 0x6cf923c6LU, 0xa8b0e839LU, 0x2f4c6a6cLU, 0x6d22338aLU, 0xeadeb1dfLU, 0x2e977a20LU, 0xa96bf875LU, +0xaa4bc8a1LU, 0x2db74af4LU, 0xe9fe810bLU, 0x6e02035eLU, 0x2c6c5ab8LU, 0xab90d8edLU, 0x6fd91312LU, 0xe8259147LU, +0x20ec9a3fLU, 0xa710186aLU, 0x6359d395LU, 0xe4a551c0LU, 0xa6cb0826LU, 0x21378a73LU, 0xe57e418cLU, 0x6282c3d9LU, +0x61a2f30dLU, 0xe65e7158LU, 0x2217baa7LU, 0xa5eb38f2LU, 0xe7856114LU, 0x6079e341LU, 0xa43028beLU, 0x23ccaaebLU, +0xa270485bLU, 0x258cca0eLU, 0xe1c501f1LU, 0x663983a4LU, 0x2457da42LU, 0xa3ab5817LU, 0x67e293e8LU, 0xe01e11bdLU, +0xe33e2169LU, 0x64c2a33cLU, 0xa08b68c3LU, 0x2777ea96LU, 0x6519b370LU, 0xe2e53125LU, 0x26acfadaLU, 0xa150788fLU, +0xfb73ec2aLU, 0x7c8f6e7fLU, 0xb8c6a580LU, 0x3f3a27d5LU, 0x7d547e33LU, 0xfaa8fc66LU, 0x3ee13799LU, 0xb91db5ccLU, +0xba3d8518LU, 0x3dc1074dLU, 0xf988ccb2LU, 0x7e744ee7LU, 0x3c1a1701LU, 0xbbe69554LU, 0x7faf5eabLU, 0xf853dcfeLU, +0x79ef3e4eLU, 0xfe13bc1bLU, 0x3a5a77e4LU, 0xbda6f5b1LU, 0xffc8ac57LU, 0x78342e02LU, 0xbc7de5fdLU, 0x3b8167a8LU, +0x38a1577cLU, 0xbf5dd529LU, 0x7b141ed6LU, 0xfce89c83LU, 0xbe86c565LU, 0x397a4730LU, 0xfd338ccfLU, 0x7acf0e9aLU, +0xb20605e2LU, 0x35fa87b7LU, 0xf1b34c48LU, 0x764fce1dLU, 0x342197fbLU, 0xb3dd15aeLU, 0x7794de51LU, 0xf0685c04LU, +0xf3486cd0LU, 0x74b4ee85LU, 0xb0fd257aLU, 0x3701a72fLU, 0x756ffec9LU, 0xf2937c9cLU, 0x36dab763LU, 0xb1263536LU, +0x309ad786LU, 0xb76655d3LU, 0x732f9e2cLU, 0xf4d31c79LU, 0xb6bd459fLU, 0x3141c7caLU, 0xf5080c35LU, 0x72f48e60LU, +0x71d4beb4LU, 0xf6283ce1LU, 0x3261f71eLU, 0xb59d754bLU, 0xf7f32cadLU, 0x700faef8LU, 0xb4466507LU, 0x33bae752LU }; + +static const ulong32 rs_tab3[256] = { +0x00000000LU, 0x5ac1f387LU, 0xb4cfab43LU, 0xee0e58c4LU, 0x25d31b86LU, 0x7f12e801LU, 0x911cb0c5LU, 0xcbdd4342LU, +0x4aeb3641LU, 0x102ac5c6LU, 0xfe249d02LU, 0xa4e56e85LU, 0x6f382dc7LU, 0x35f9de40LU, 0xdbf78684LU, 0x81367503LU, +0x949b6c82LU, 0xce5a9f05LU, 0x2054c7c1LU, 0x7a953446LU, 0xb1487704LU, 0xeb898483LU, 0x0587dc47LU, 0x5f462fc0LU, +0xde705ac3LU, 0x84b1a944LU, 0x6abff180LU, 0x307e0207LU, 0xfba34145LU, 0xa162b2c2LU, 0x4f6cea06LU, 0x15ad1981LU, +0x657bd849LU, 0x3fba2bceLU, 0xd1b4730aLU, 0x8b75808dLU, 0x40a8c3cfLU, 0x1a693048LU, 0xf467688cLU, 0xaea69b0bLU, +0x2f90ee08LU, 0x75511d8fLU, 0x9b5f454bLU, 0xc19eb6ccLU, 0x0a43f58eLU, 0x50820609LU, 0xbe8c5ecdLU, 0xe44dad4aLU, +0xf1e0b4cbLU, 0xab21474cLU, 0x452f1f88LU, 0x1feeec0fLU, 0xd433af4dLU, 0x8ef25ccaLU, 0x60fc040eLU, 0x3a3df789LU, +0xbb0b828aLU, 0xe1ca710dLU, 0x0fc429c9LU, 0x5505da4eLU, 0x9ed8990cLU, 0xc4196a8bLU, 0x2a17324fLU, 0x70d6c1c8LU, +0xcaf6fd92LU, 0x90370e15LU, 0x7e3956d1LU, 0x24f8a556LU, 0xef25e614LU, 0xb5e41593LU, 0x5bea4d57LU, 0x012bbed0LU, +0x801dcbd3LU, 0xdadc3854LU, 0x34d26090LU, 0x6e139317LU, 0xa5ced055LU, 0xff0f23d2LU, 0x11017b16LU, 0x4bc08891LU, +0x5e6d9110LU, 0x04ac6297LU, 0xeaa23a53LU, 0xb063c9d4LU, 0x7bbe8a96LU, 0x217f7911LU, 0xcf7121d5LU, 0x95b0d252LU, +0x1486a751LU, 0x4e4754d6LU, 0xa0490c12LU, 0xfa88ff95LU, 0x3155bcd7LU, 0x6b944f50LU, 0x859a1794LU, 0xdf5be413LU, +0xaf8d25dbLU, 0xf54cd65cLU, 0x1b428e98LU, 0x41837d1fLU, 0x8a5e3e5dLU, 0xd09fcddaLU, 0x3e91951eLU, 0x64506699LU, +0xe566139aLU, 0xbfa7e01dLU, 0x51a9b8d9LU, 0x0b684b5eLU, 0xc0b5081cLU, 0x9a74fb9bLU, 0x747aa35fLU, 0x2ebb50d8LU, +0x3b164959LU, 0x61d7badeLU, 0x8fd9e21aLU, 0xd518119dLU, 0x1ec552dfLU, 0x4404a158LU, 0xaa0af99cLU, 0xf0cb0a1bLU, +0x71fd7f18LU, 0x2b3c8c9fLU, 0xc532d45bLU, 0x9ff327dcLU, 0x542e649eLU, 0x0eef9719LU, 0xe0e1cfddLU, 0xba203c5aLU, +0xd9a1b769LU, 0x836044eeLU, 0x6d6e1c2aLU, 0x37afefadLU, 0xfc72acefLU, 0xa6b35f68LU, 0x48bd07acLU, 0x127cf42bLU, +0x934a8128LU, 0xc98b72afLU, 0x27852a6bLU, 0x7d44d9ecLU, 0xb6999aaeLU, 0xec586929LU, 0x025631edLU, 0x5897c26aLU, +0x4d3adbebLU, 0x17fb286cLU, 0xf9f570a8LU, 0xa334832fLU, 0x68e9c06dLU, 0x322833eaLU, 0xdc266b2eLU, 0x86e798a9LU, +0x07d1edaaLU, 0x5d101e2dLU, 0xb31e46e9LU, 0xe9dfb56eLU, 0x2202f62cLU, 0x78c305abLU, 0x96cd5d6fLU, 0xcc0caee8LU, +0xbcda6f20LU, 0xe61b9ca7LU, 0x0815c463LU, 0x52d437e4LU, 0x990974a6LU, 0xc3c88721LU, 0x2dc6dfe5LU, 0x77072c62LU, +0xf6315961LU, 0xacf0aae6LU, 0x42fef222LU, 0x183f01a5LU, 0xd3e242e7LU, 0x8923b160LU, 0x672de9a4LU, 0x3dec1a23LU, +0x284103a2LU, 0x7280f025LU, 0x9c8ea8e1LU, 0xc64f5b66LU, 0x0d921824LU, 0x5753eba3LU, 0xb95db367LU, 0xe39c40e0LU, +0x62aa35e3LU, 0x386bc664LU, 0xd6659ea0LU, 0x8ca46d27LU, 0x47792e65LU, 0x1db8dde2LU, 0xf3b68526LU, 0xa97776a1LU, +0x13574afbLU, 0x4996b97cLU, 0xa798e1b8LU, 0xfd59123fLU, 0x3684517dLU, 0x6c45a2faLU, 0x824bfa3eLU, 0xd88a09b9LU, +0x59bc7cbaLU, 0x037d8f3dLU, 0xed73d7f9LU, 0xb7b2247eLU, 0x7c6f673cLU, 0x26ae94bbLU, 0xc8a0cc7fLU, 0x92613ff8LU, +0x87cc2679LU, 0xdd0dd5feLU, 0x33038d3aLU, 0x69c27ebdLU, 0xa21f3dffLU, 0xf8dece78LU, 0x16d096bcLU, 0x4c11653bLU, +0xcd271038LU, 0x97e6e3bfLU, 0x79e8bb7bLU, 0x232948fcLU, 0xe8f40bbeLU, 0xb235f839LU, 0x5c3ba0fdLU, 0x06fa537aLU, +0x762c92b2LU, 0x2ced6135LU, 0xc2e339f1LU, 0x9822ca76LU, 0x53ff8934LU, 0x093e7ab3LU, 0xe7302277LU, 0xbdf1d1f0LU, +0x3cc7a4f3LU, 0x66065774LU, 0x88080fb0LU, 0xd2c9fc37LU, 0x1914bf75LU, 0x43d54cf2LU, 0xaddb1436LU, 0xf71ae7b1LU, +0xe2b7fe30LU, 0xb8760db7LU, 0x56785573LU, 0x0cb9a6f4LU, 0xc764e5b6LU, 0x9da51631LU, 0x73ab4ef5LU, 0x296abd72LU, +0xa85cc871LU, 0xf29d3bf6LU, 0x1c936332LU, 0x465290b5LU, 0x8d8fd3f7LU, 0xd74e2070LU, 0x394078b4LU, 0x63818b33LU }; + +static const ulong32 rs_tab4[256] = { +0x00000000LU, 0x58471e5aLU, 0xb08e3cb4LU, 0xe8c922eeLU, 0x2d517825LU, 0x7516667fLU, 0x9ddf4491LU, 0xc5985acbLU, +0x5aa2f04aLU, 0x02e5ee10LU, 0xea2cccfeLU, 0xb26bd2a4LU, 0x77f3886fLU, 0x2fb49635LU, 0xc77db4dbLU, 0x9f3aaa81LU, +0xb409ad94LU, 0xec4eb3ceLU, 0x04879120LU, 0x5cc08f7aLU, 0x9958d5b1LU, 0xc11fcbebLU, 0x29d6e905LU, 0x7191f75fLU, +0xeeab5ddeLU, 0xb6ec4384LU, 0x5e25616aLU, 0x06627f30LU, 0xc3fa25fbLU, 0x9bbd3ba1LU, 0x7374194fLU, 0x2b330715LU, +0x25121765LU, 0x7d55093fLU, 0x959c2bd1LU, 0xcddb358bLU, 0x08436f40LU, 0x5004711aLU, 0xb8cd53f4LU, 0xe08a4daeLU, +0x7fb0e72fLU, 0x27f7f975LU, 0xcf3edb9bLU, 0x9779c5c1LU, 0x52e19f0aLU, 0x0aa68150LU, 0xe26fa3beLU, 0xba28bde4LU, +0x911bbaf1LU, 0xc95ca4abLU, 0x21958645LU, 0x79d2981fLU, 0xbc4ac2d4LU, 0xe40ddc8eLU, 0x0cc4fe60LU, 0x5483e03aLU, +0xcbb94abbLU, 0x93fe54e1LU, 0x7b37760fLU, 0x23706855LU, 0xe6e8329eLU, 0xbeaf2cc4LU, 0x56660e2aLU, 0x0e211070LU, +0x4a242ecaLU, 0x12633090LU, 0xfaaa127eLU, 0xa2ed0c24LU, 0x677556efLU, 0x3f3248b5LU, 0xd7fb6a5bLU, 0x8fbc7401LU, +0x1086de80LU, 0x48c1c0daLU, 0xa008e234LU, 0xf84ffc6eLU, 0x3dd7a6a5LU, 0x6590b8ffLU, 0x8d599a11LU, 0xd51e844bLU, +0xfe2d835eLU, 0xa66a9d04LU, 0x4ea3bfeaLU, 0x16e4a1b0LU, 0xd37cfb7bLU, 0x8b3be521LU, 0x63f2c7cfLU, 0x3bb5d995LU, +0xa48f7314LU, 0xfcc86d4eLU, 0x14014fa0LU, 0x4c4651faLU, 0x89de0b31LU, 0xd199156bLU, 0x39503785LU, 0x611729dfLU, +0x6f3639afLU, 0x377127f5LU, 0xdfb8051bLU, 0x87ff1b41LU, 0x4267418aLU, 0x1a205fd0LU, 0xf2e97d3eLU, 0xaaae6364LU, +0x3594c9e5LU, 0x6dd3d7bfLU, 0x851af551LU, 0xdd5deb0bLU, 0x18c5b1c0LU, 0x4082af9aLU, 0xa84b8d74LU, 0xf00c932eLU, +0xdb3f943bLU, 0x83788a61LU, 0x6bb1a88fLU, 0x33f6b6d5LU, 0xf66eec1eLU, 0xae29f244LU, 0x46e0d0aaLU, 0x1ea7cef0LU, +0x819d6471LU, 0xd9da7a2bLU, 0x311358c5LU, 0x6954469fLU, 0xaccc1c54LU, 0xf48b020eLU, 0x1c4220e0LU, 0x44053ebaLU, +0x94485cd9LU, 0xcc0f4283LU, 0x24c6606dLU, 0x7c817e37LU, 0xb91924fcLU, 0xe15e3aa6LU, 0x09971848LU, 0x51d00612LU, +0xceeaac93LU, 0x96adb2c9LU, 0x7e649027LU, 0x26238e7dLU, 0xe3bbd4b6LU, 0xbbfccaecLU, 0x5335e802LU, 0x0b72f658LU, +0x2041f14dLU, 0x7806ef17LU, 0x90cfcdf9LU, 0xc888d3a3LU, 0x0d108968LU, 0x55579732LU, 0xbd9eb5dcLU, 0xe5d9ab86LU, +0x7ae30107LU, 0x22a41f5dLU, 0xca6d3db3LU, 0x922a23e9LU, 0x57b27922LU, 0x0ff56778LU, 0xe73c4596LU, 0xbf7b5bccLU, +0xb15a4bbcLU, 0xe91d55e6LU, 0x01d47708LU, 0x59936952LU, 0x9c0b3399LU, 0xc44c2dc3LU, 0x2c850f2dLU, 0x74c21177LU, +0xebf8bbf6LU, 0xb3bfa5acLU, 0x5b768742LU, 0x03319918LU, 0xc6a9c3d3LU, 0x9eeedd89LU, 0x7627ff67LU, 0x2e60e13dLU, +0x0553e628LU, 0x5d14f872LU, 0xb5ddda9cLU, 0xed9ac4c6LU, 0x28029e0dLU, 0x70458057LU, 0x988ca2b9LU, 0xc0cbbce3LU, +0x5ff11662LU, 0x07b60838LU, 0xef7f2ad6LU, 0xb738348cLU, 0x72a06e47LU, 0x2ae7701dLU, 0xc22e52f3LU, 0x9a694ca9LU, +0xde6c7213LU, 0x862b6c49LU, 0x6ee24ea7LU, 0x36a550fdLU, 0xf33d0a36LU, 0xab7a146cLU, 0x43b33682LU, 0x1bf428d8LU, +0x84ce8259LU, 0xdc899c03LU, 0x3440beedLU, 0x6c07a0b7LU, 0xa99ffa7cLU, 0xf1d8e426LU, 0x1911c6c8LU, 0x4156d892LU, +0x6a65df87LU, 0x3222c1ddLU, 0xdaebe333LU, 0x82acfd69LU, 0x4734a7a2LU, 0x1f73b9f8LU, 0xf7ba9b16LU, 0xaffd854cLU, +0x30c72fcdLU, 0x68803197LU, 0x80491379LU, 0xd80e0d23LU, 0x1d9657e8LU, 0x45d149b2LU, 0xad186b5cLU, 0xf55f7506LU, +0xfb7e6576LU, 0xa3397b2cLU, 0x4bf059c2LU, 0x13b74798LU, 0xd62f1d53LU, 0x8e680309LU, 0x66a121e7LU, 0x3ee63fbdLU, +0xa1dc953cLU, 0xf99b8b66LU, 0x1152a988LU, 0x4915b7d2LU, 0x8c8ded19LU, 0xd4caf343LU, 0x3c03d1adLU, 0x6444cff7LU, +0x4f77c8e2LU, 0x1730d6b8LU, 0xfff9f456LU, 0xa7beea0cLU, 0x6226b0c7LU, 0x3a61ae9dLU, 0xd2a88c73LU, 0x8aef9229LU, +0x15d538a8LU, 0x4d9226f2LU, 0xa55b041cLU, 0xfd1c1a46LU, 0x3884408dLU, 0x60c35ed7LU, 0x880a7c39LU, 0xd04d6263LU }; + +static const ulong32 rs_tab5[256] = { +0x00000000LU, 0xdbaec658LU, 0xfb11c1b0LU, 0x20bf07e8LU, 0xbb22cf2dLU, 0x608c0975LU, 0x40330e9dLU, 0x9b9dc8c5LU, +0x3b44d35aLU, 0xe0ea1502LU, 0xc05512eaLU, 0x1bfbd4b2LU, 0x80661c77LU, 0x5bc8da2fLU, 0x7b77ddc7LU, 0xa0d91b9fLU, +0x7688ebb4LU, 0xad262decLU, 0x8d992a04LU, 0x5637ec5cLU, 0xcdaa2499LU, 0x1604e2c1LU, 0x36bbe529LU, 0xed152371LU, +0x4dcc38eeLU, 0x9662feb6LU, 0xb6ddf95eLU, 0x6d733f06LU, 0xf6eef7c3LU, 0x2d40319bLU, 0x0dff3673LU, 0xd651f02bLU, +0xec5d9b25LU, 0x37f35d7dLU, 0x174c5a95LU, 0xcce29ccdLU, 0x577f5408LU, 0x8cd19250LU, 0xac6e95b8LU, 0x77c053e0LU, +0xd719487fLU, 0x0cb78e27LU, 0x2c0889cfLU, 0xf7a64f97LU, 0x6c3b8752LU, 0xb795410aLU, 0x972a46e2LU, 0x4c8480baLU, +0x9ad57091LU, 0x417bb6c9LU, 0x61c4b121LU, 0xba6a7779LU, 0x21f7bfbcLU, 0xfa5979e4LU, 0xdae67e0cLU, 0x0148b854LU, +0xa191a3cbLU, 0x7a3f6593LU, 0x5a80627bLU, 0x812ea423LU, 0x1ab36ce6LU, 0xc11daabeLU, 0xe1a2ad56LU, 0x3a0c6b0eLU, +0x95ba7b4aLU, 0x4e14bd12LU, 0x6eabbafaLU, 0xb5057ca2LU, 0x2e98b467LU, 0xf536723fLU, 0xd58975d7LU, 0x0e27b38fLU, +0xaefea810LU, 0x75506e48LU, 0x55ef69a0LU, 0x8e41aff8LU, 0x15dc673dLU, 0xce72a165LU, 0xeecda68dLU, 0x356360d5LU, +0xe33290feLU, 0x389c56a6LU, 0x1823514eLU, 0xc38d9716LU, 0x58105fd3LU, 0x83be998bLU, 0xa3019e63LU, 0x78af583bLU, +0xd87643a4LU, 0x03d885fcLU, 0x23678214LU, 0xf8c9444cLU, 0x63548c89LU, 0xb8fa4ad1LU, 0x98454d39LU, 0x43eb8b61LU, +0x79e7e06fLU, 0xa2492637LU, 0x82f621dfLU, 0x5958e787LU, 0xc2c52f42LU, 0x196be91aLU, 0x39d4eef2LU, 0xe27a28aaLU, +0x42a33335LU, 0x990df56dLU, 0xb9b2f285LU, 0x621c34ddLU, 0xf981fc18LU, 0x222f3a40LU, 0x02903da8LU, 0xd93efbf0LU, +0x0f6f0bdbLU, 0xd4c1cd83LU, 0xf47eca6bLU, 0x2fd00c33LU, 0xb44dc4f6LU, 0x6fe302aeLU, 0x4f5c0546LU, 0x94f2c31eLU, +0x342bd881LU, 0xef851ed9LU, 0xcf3a1931LU, 0x1494df69LU, 0x8f0917acLU, 0x54a7d1f4LU, 0x7418d61cLU, 0xafb61044LU, +0x6739f694LU, 0xbc9730ccLU, 0x9c283724LU, 0x4786f17cLU, 0xdc1b39b9LU, 0x07b5ffe1LU, 0x270af809LU, 0xfca43e51LU, +0x5c7d25ceLU, 0x87d3e396LU, 0xa76ce47eLU, 0x7cc22226LU, 0xe75feae3LU, 0x3cf12cbbLU, 0x1c4e2b53LU, 0xc7e0ed0bLU, +0x11b11d20LU, 0xca1fdb78LU, 0xeaa0dc90LU, 0x310e1ac8LU, 0xaa93d20dLU, 0x713d1455LU, 0x518213bdLU, 0x8a2cd5e5LU, +0x2af5ce7aLU, 0xf15b0822LU, 0xd1e40fcaLU, 0x0a4ac992LU, 0x91d70157LU, 0x4a79c70fLU, 0x6ac6c0e7LU, 0xb16806bfLU, +0x8b646db1LU, 0x50caabe9LU, 0x7075ac01LU, 0xabdb6a59LU, 0x3046a29cLU, 0xebe864c4LU, 0xcb57632cLU, 0x10f9a574LU, +0xb020beebLU, 0x6b8e78b3LU, 0x4b317f5bLU, 0x909fb903LU, 0x0b0271c6LU, 0xd0acb79eLU, 0xf013b076LU, 0x2bbd762eLU, +0xfdec8605LU, 0x2642405dLU, 0x06fd47b5LU, 0xdd5381edLU, 0x46ce4928LU, 0x9d608f70LU, 0xbddf8898LU, 0x66714ec0LU, +0xc6a8555fLU, 0x1d069307LU, 0x3db994efLU, 0xe61752b7LU, 0x7d8a9a72LU, 0xa6245c2aLU, 0x869b5bc2LU, 0x5d359d9aLU, +0xf2838ddeLU, 0x292d4b86LU, 0x09924c6eLU, 0xd23c8a36LU, 0x49a142f3LU, 0x920f84abLU, 0xb2b08343LU, 0x691e451bLU, +0xc9c75e84LU, 0x126998dcLU, 0x32d69f34LU, 0xe978596cLU, 0x72e591a9LU, 0xa94b57f1LU, 0x89f45019LU, 0x525a9641LU, +0x840b666aLU, 0x5fa5a032LU, 0x7f1aa7daLU, 0xa4b46182LU, 0x3f29a947LU, 0xe4876f1fLU, 0xc43868f7LU, 0x1f96aeafLU, +0xbf4fb530LU, 0x64e17368LU, 0x445e7480LU, 0x9ff0b2d8LU, 0x046d7a1dLU, 0xdfc3bc45LU, 0xff7cbbadLU, 0x24d27df5LU, +0x1ede16fbLU, 0xc570d0a3LU, 0xe5cfd74bLU, 0x3e611113LU, 0xa5fcd9d6LU, 0x7e521f8eLU, 0x5eed1866LU, 0x8543de3eLU, +0x259ac5a1LU, 0xfe3403f9LU, 0xde8b0411LU, 0x0525c249LU, 0x9eb80a8cLU, 0x4516ccd4LU, 0x65a9cb3cLU, 0xbe070d64LU, +0x6856fd4fLU, 0xb3f83b17LU, 0x93473cffLU, 0x48e9faa7LU, 0xd3743262LU, 0x08daf43aLU, 0x2865f3d2LU, 0xf3cb358aLU, +0x53122e15LU, 0x88bce84dLU, 0xa803efa5LU, 0x73ad29fdLU, 0xe830e138LU, 0x339e2760LU, 0x13212088LU, 0xc88fe6d0LU }; + +static const ulong32 rs_tab6[256] = { +0x00000000LU, 0x9e3d68dbLU, 0x717ad0fbLU, 0xef47b820LU, 0xe2f4edbbLU, 0x7cc98560LU, 0x938e3d40LU, 0x0db3559bLU, +0x89a5973bLU, 0x1798ffe0LU, 0xf8df47c0LU, 0x66e22f1bLU, 0x6b517a80LU, 0xf56c125bLU, 0x1a2baa7bLU, 0x8416c2a0LU, +0x5f076376LU, 0xc13a0badLU, 0x2e7db38dLU, 0xb040db56LU, 0xbdf38ecdLU, 0x23cee616LU, 0xcc895e36LU, 0x52b436edLU, +0xd6a2f44dLU, 0x489f9c96LU, 0xa7d824b6LU, 0x39e54c6dLU, 0x345619f6LU, 0xaa6b712dLU, 0x452cc90dLU, 0xdb11a1d6LU, +0xbe0ec6ecLU, 0x2033ae37LU, 0xcf741617LU, 0x51497eccLU, 0x5cfa2b57LU, 0xc2c7438cLU, 0x2d80fbacLU, 0xb3bd9377LU, +0x37ab51d7LU, 0xa996390cLU, 0x46d1812cLU, 0xd8ece9f7LU, 0xd55fbc6cLU, 0x4b62d4b7LU, 0xa4256c97LU, 0x3a18044cLU, +0xe109a59aLU, 0x7f34cd41LU, 0x90737561LU, 0x0e4e1dbaLU, 0x03fd4821LU, 0x9dc020faLU, 0x728798daLU, 0xecbaf001LU, +0x68ac32a1LU, 0xf6915a7aLU, 0x19d6e25aLU, 0x87eb8a81LU, 0x8a58df1aLU, 0x1465b7c1LU, 0xfb220fe1LU, 0x651f673aLU, +0x311cc195LU, 0xaf21a94eLU, 0x4066116eLU, 0xde5b79b5LU, 0xd3e82c2eLU, 0x4dd544f5LU, 0xa292fcd5LU, 0x3caf940eLU, +0xb8b956aeLU, 0x26843e75LU, 0xc9c38655LU, 0x57feee8eLU, 0x5a4dbb15LU, 0xc470d3ceLU, 0x2b376beeLU, 0xb50a0335LU, +0x6e1ba2e3LU, 0xf026ca38LU, 0x1f617218LU, 0x815c1ac3LU, 0x8cef4f58LU, 0x12d22783LU, 0xfd959fa3LU, 0x63a8f778LU, +0xe7be35d8LU, 0x79835d03LU, 0x96c4e523LU, 0x08f98df8LU, 0x054ad863LU, 0x9b77b0b8LU, 0x74300898LU, 0xea0d6043LU, +0x8f120779LU, 0x112f6fa2LU, 0xfe68d782LU, 0x6055bf59LU, 0x6de6eac2LU, 0xf3db8219LU, 0x1c9c3a39LU, 0x82a152e2LU, +0x06b79042LU, 0x988af899LU, 0x77cd40b9LU, 0xe9f02862LU, 0xe4437df9LU, 0x7a7e1522LU, 0x9539ad02LU, 0x0b04c5d9LU, +0xd015640fLU, 0x4e280cd4LU, 0xa16fb4f4LU, 0x3f52dc2fLU, 0x32e189b4LU, 0xacdce16fLU, 0x439b594fLU, 0xdda63194LU, +0x59b0f334LU, 0xc78d9befLU, 0x28ca23cfLU, 0xb6f74b14LU, 0xbb441e8fLU, 0x25797654LU, 0xca3ece74LU, 0x5403a6afLU, +0x6238cf67LU, 0xfc05a7bcLU, 0x13421f9cLU, 0x8d7f7747LU, 0x80cc22dcLU, 0x1ef14a07LU, 0xf1b6f227LU, 0x6f8b9afcLU, +0xeb9d585cLU, 0x75a03087LU, 0x9ae788a7LU, 0x04dae07cLU, 0x0969b5e7LU, 0x9754dd3cLU, 0x7813651cLU, 0xe62e0dc7LU, +0x3d3fac11LU, 0xa302c4caLU, 0x4c457ceaLU, 0xd2781431LU, 0xdfcb41aaLU, 0x41f62971LU, 0xaeb19151LU, 0x308cf98aLU, +0xb49a3b2aLU, 0x2aa753f1LU, 0xc5e0ebd1LU, 0x5bdd830aLU, 0x566ed691LU, 0xc853be4aLU, 0x2714066aLU, 0xb9296eb1LU, +0xdc36098bLU, 0x420b6150LU, 0xad4cd970LU, 0x3371b1abLU, 0x3ec2e430LU, 0xa0ff8cebLU, 0x4fb834cbLU, 0xd1855c10LU, +0x55939eb0LU, 0xcbaef66bLU, 0x24e94e4bLU, 0xbad42690LU, 0xb767730bLU, 0x295a1bd0LU, 0xc61da3f0LU, 0x5820cb2bLU, +0x83316afdLU, 0x1d0c0226LU, 0xf24bba06LU, 0x6c76d2ddLU, 0x61c58746LU, 0xfff8ef9dLU, 0x10bf57bdLU, 0x8e823f66LU, +0x0a94fdc6LU, 0x94a9951dLU, 0x7bee2d3dLU, 0xe5d345e6LU, 0xe860107dLU, 0x765d78a6LU, 0x991ac086LU, 0x0727a85dLU, +0x53240ef2LU, 0xcd196629LU, 0x225ede09LU, 0xbc63b6d2LU, 0xb1d0e349LU, 0x2fed8b92LU, 0xc0aa33b2LU, 0x5e975b69LU, +0xda8199c9LU, 0x44bcf112LU, 0xabfb4932LU, 0x35c621e9LU, 0x38757472LU, 0xa6481ca9LU, 0x490fa489LU, 0xd732cc52LU, +0x0c236d84LU, 0x921e055fLU, 0x7d59bd7fLU, 0xe364d5a4LU, 0xeed7803fLU, 0x70eae8e4LU, 0x9fad50c4LU, 0x0190381fLU, +0x8586fabfLU, 0x1bbb9264LU, 0xf4fc2a44LU, 0x6ac1429fLU, 0x67721704LU, 0xf94f7fdfLU, 0x1608c7ffLU, 0x8835af24LU, +0xed2ac81eLU, 0x7317a0c5LU, 0x9c5018e5LU, 0x026d703eLU, 0x0fde25a5LU, 0x91e34d7eLU, 0x7ea4f55eLU, 0xe0999d85LU, +0x648f5f25LU, 0xfab237feLU, 0x15f58fdeLU, 0x8bc8e705LU, 0x867bb29eLU, 0x1846da45LU, 0xf7016265LU, 0x693c0abeLU, +0xb22dab68LU, 0x2c10c3b3LU, 0xc3577b93LU, 0x5d6a1348LU, 0x50d946d3LU, 0xcee42e08LU, 0x21a39628LU, 0xbf9efef3LU, +0x3b883c53LU, 0xa5b55488LU, 0x4af2eca8LU, 0xd4cf8473LU, 0xd97cd1e8LU, 0x4741b933LU, 0xa8060113LU, 0x363b69c8LU }; + +static const ulong32 rs_tab7[256] = { +0x00000000LU, 0x0319e59eLU, 0x06328771LU, 0x052b62efLU, 0x0c6443e2LU, 0x0f7da67cLU, 0x0a56c493LU, 0x094f210dLU, +0x18c88689LU, 0x1bd16317LU, 0x1efa01f8LU, 0x1de3e466LU, 0x14acc56bLU, 0x17b520f5LU, 0x129e421aLU, 0x1187a784LU, +0x30dd415fLU, 0x33c4a4c1LU, 0x36efc62eLU, 0x35f623b0LU, 0x3cb902bdLU, 0x3fa0e723LU, 0x3a8b85ccLU, 0x39926052LU, +0x2815c7d6LU, 0x2b0c2248LU, 0x2e2740a7LU, 0x2d3ea539LU, 0x24718434LU, 0x276861aaLU, 0x22430345LU, 0x215ae6dbLU, +0x60f782beLU, 0x63ee6720LU, 0x66c505cfLU, 0x65dce051LU, 0x6c93c15cLU, 0x6f8a24c2LU, 0x6aa1462dLU, 0x69b8a3b3LU, +0x783f0437LU, 0x7b26e1a9LU, 0x7e0d8346LU, 0x7d1466d8LU, 0x745b47d5LU, 0x7742a24bLU, 0x7269c0a4LU, 0x7170253aLU, +0x502ac3e1LU, 0x5333267fLU, 0x56184490LU, 0x5501a10eLU, 0x5c4e8003LU, 0x5f57659dLU, 0x5a7c0772LU, 0x5965e2ecLU, +0x48e24568LU, 0x4bfba0f6LU, 0x4ed0c219LU, 0x4dc92787LU, 0x4486068aLU, 0x479fe314LU, 0x42b481fbLU, 0x41ad6465LU, +0xc0a34931LU, 0xc3baacafLU, 0xc691ce40LU, 0xc5882bdeLU, 0xccc70ad3LU, 0xcfdeef4dLU, 0xcaf58da2LU, 0xc9ec683cLU, +0xd86bcfb8LU, 0xdb722a26LU, 0xde5948c9LU, 0xdd40ad57LU, 0xd40f8c5aLU, 0xd71669c4LU, 0xd23d0b2bLU, 0xd124eeb5LU, +0xf07e086eLU, 0xf367edf0LU, 0xf64c8f1fLU, 0xf5556a81LU, 0xfc1a4b8cLU, 0xff03ae12LU, 0xfa28ccfdLU, 0xf9312963LU, +0xe8b68ee7LU, 0xebaf6b79LU, 0xee840996LU, 0xed9dec08LU, 0xe4d2cd05LU, 0xe7cb289bLU, 0xe2e04a74LU, 0xe1f9afeaLU, +0xa054cb8fLU, 0xa34d2e11LU, 0xa6664cfeLU, 0xa57fa960LU, 0xac30886dLU, 0xaf296df3LU, 0xaa020f1cLU, 0xa91bea82LU, +0xb89c4d06LU, 0xbb85a898LU, 0xbeaeca77LU, 0xbdb72fe9LU, 0xb4f80ee4LU, 0xb7e1eb7aLU, 0xb2ca8995LU, 0xb1d36c0bLU, +0x90898ad0LU, 0x93906f4eLU, 0x96bb0da1LU, 0x95a2e83fLU, 0x9cedc932LU, 0x9ff42cacLU, 0x9adf4e43LU, 0x99c6abddLU, +0x88410c59LU, 0x8b58e9c7LU, 0x8e738b28LU, 0x8d6a6eb6LU, 0x84254fbbLU, 0x873caa25LU, 0x8217c8caLU, 0x810e2d54LU, +0xcd0b9262LU, 0xce1277fcLU, 0xcb391513LU, 0xc820f08dLU, 0xc16fd180LU, 0xc276341eLU, 0xc75d56f1LU, 0xc444b36fLU, +0xd5c314ebLU, 0xd6daf175LU, 0xd3f1939aLU, 0xd0e87604LU, 0xd9a75709LU, 0xdabeb297LU, 0xdf95d078LU, 0xdc8c35e6LU, +0xfdd6d33dLU, 0xfecf36a3LU, 0xfbe4544cLU, 0xf8fdb1d2LU, 0xf1b290dfLU, 0xf2ab7541LU, 0xf78017aeLU, 0xf499f230LU, +0xe51e55b4LU, 0xe607b02aLU, 0xe32cd2c5LU, 0xe035375bLU, 0xe97a1656LU, 0xea63f3c8LU, 0xef489127LU, 0xec5174b9LU, +0xadfc10dcLU, 0xaee5f542LU, 0xabce97adLU, 0xa8d77233LU, 0xa198533eLU, 0xa281b6a0LU, 0xa7aad44fLU, 0xa4b331d1LU, +0xb5349655LU, 0xb62d73cbLU, 0xb3061124LU, 0xb01ff4baLU, 0xb950d5b7LU, 0xba493029LU, 0xbf6252c6LU, 0xbc7bb758LU, +0x9d215183LU, 0x9e38b41dLU, 0x9b13d6f2LU, 0x980a336cLU, 0x91451261LU, 0x925cf7ffLU, 0x97779510LU, 0x946e708eLU, +0x85e9d70aLU, 0x86f03294LU, 0x83db507bLU, 0x80c2b5e5LU, 0x898d94e8LU, 0x8a947176LU, 0x8fbf1399LU, 0x8ca6f607LU, +0x0da8db53LU, 0x0eb13ecdLU, 0x0b9a5c22LU, 0x0883b9bcLU, 0x01cc98b1LU, 0x02d57d2fLU, 0x07fe1fc0LU, 0x04e7fa5eLU, +0x15605ddaLU, 0x1679b844LU, 0x1352daabLU, 0x104b3f35LU, 0x19041e38LU, 0x1a1dfba6LU, 0x1f369949LU, 0x1c2f7cd7LU, +0x3d759a0cLU, 0x3e6c7f92LU, 0x3b471d7dLU, 0x385ef8e3LU, 0x3111d9eeLU, 0x32083c70LU, 0x37235e9fLU, 0x343abb01LU, +0x25bd1c85LU, 0x26a4f91bLU, 0x238f9bf4LU, 0x20967e6aLU, 0x29d95f67LU, 0x2ac0baf9LU, 0x2febd816LU, 0x2cf23d88LU, +0x6d5f59edLU, 0x6e46bc73LU, 0x6b6dde9cLU, 0x68743b02LU, 0x613b1a0fLU, 0x6222ff91LU, 0x67099d7eLU, 0x641078e0LU, +0x7597df64LU, 0x768e3afaLU, 0x73a55815LU, 0x70bcbd8bLU, 0x79f39c86LU, 0x7aea7918LU, 0x7fc11bf7LU, 0x7cd8fe69LU, +0x5d8218b2LU, 0x5e9bfd2cLU, 0x5bb09fc3LU, 0x58a97a5dLU, 0x51e65b50LU, 0x52ffbeceLU, 0x57d4dc21LU, 0x54cd39bfLU, +0x454a9e3bLU, 0x46537ba5LU, 0x4378194aLU, 0x4061fcd4LU, 0x492eddd9LU, 0x4a373847LU, 0x4f1c5aa8LU, 0x4c05bf36LU }; + +#endif /* LTC_TWOFISH_ALL_TABLES */ + +#endif /* __LTC_TWOFISH_TAB_C__ */ +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/ciphers/xtea.c b/src/ltc/ciphers/xtea.c new file mode 100644 index 0000000..4b3b52b --- /dev/null +++ b/src/ltc/ciphers/xtea.c @@ -0,0 +1,278 @@ +/* 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://libtom.org + */ + +/** + @file xtea.c + Implementation of LTC_XTEA, Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_XTEA + +const struct ltc_cipher_descriptor xtea_desc = +{ + "xtea", + 1, + 16, 16, 8, 32, + &xtea_setup, + &xtea_ecb_encrypt, + &xtea_ecb_decrypt, + &xtea_test, + &xtea_done, + &xtea_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + ulong32 x, sum, K[4]; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(skey != NULL); + + /* check arguments */ + if (keylen != 16) { + return CRYPT_INVALID_KEYSIZE; + } + + if (num_rounds != 0 && num_rounds != 32) { + return CRYPT_INVALID_ROUNDS; + } + + /* load key */ + LOAD32H(K[0], key+0); + LOAD32H(K[1], key+4); + LOAD32H(K[2], key+8); + LOAD32H(K[3], key+12); + + for (x = sum = 0; x < 32; x++) { + skey->xtea.A[x] = (sum + K[sum&3]) & 0xFFFFFFFFUL; + sum = (sum + 0x9E3779B9UL) & 0xFFFFFFFFUL; + skey->xtea.B[x] = (sum + K[(sum>>11)&3]) & 0xFFFFFFFFUL; + } + +#ifdef LTC_CLEAN_STACK + zeromem(&K, sizeof(K)); +#endif + + return CRYPT_OK; +} + +/** + Encrypts a block of text with LTC_XTEA + @param pt The input plaintext (8 bytes) + @param ct The output ciphertext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + ulong32 y, z; + int r; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + + LOAD32H(y, &pt[0]); + LOAD32H(z, &pt[4]); + for (r = 0; r < 32; r += 4) { + y = (y + ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r])) & 0xFFFFFFFFUL; + z = (z + ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r])) & 0xFFFFFFFFUL; + + y = (y + ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r+1])) & 0xFFFFFFFFUL; + z = (z + ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r+1])) & 0xFFFFFFFFUL; + + y = (y + ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r+2])) & 0xFFFFFFFFUL; + z = (z + ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r+2])) & 0xFFFFFFFFUL; + + y = (y + ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r+3])) & 0xFFFFFFFFUL; + z = (z + ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r+3])) & 0xFFFFFFFFUL; + } + STORE32H(y, &ct[0]); + STORE32H(z, &ct[4]); + return CRYPT_OK; +} + +/** + Decrypts a block of text with LTC_XTEA + @param ct The input ciphertext (8 bytes) + @param pt The output plaintext (8 bytes) + @param skey The key as scheduled + @return CRYPT_OK if successful +*/ +int xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + ulong32 y, z; + int r; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(skey != NULL); + + LOAD32H(y, &ct[0]); + LOAD32H(z, &ct[4]); + for (r = 31; r >= 0; r -= 4) { + z = (z - ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r])) & 0xFFFFFFFFUL; + y = (y - ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r])) & 0xFFFFFFFFUL; + + z = (z - ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r-1])) & 0xFFFFFFFFUL; + y = (y - ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r-1])) & 0xFFFFFFFFUL; + + z = (z - ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r-2])) & 0xFFFFFFFFUL; + y = (y - ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r-2])) & 0xFFFFFFFFUL; + + z = (z - ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r-3])) & 0xFFFFFFFFUL; + y = (y - ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r-3])) & 0xFFFFFFFFUL; + } + STORE32H(y, &pt[0]); + STORE32H(z, &pt[4]); + return CRYPT_OK; +} + +/** + Performs a self-test of the LTC_XTEA block cipher + @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled +*/ +int xtea_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + unsigned char key[16], pt[8], ct[8]; + } tests[] = { + { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xde, 0xe9, 0xd4, 0xd8, 0xf7, 0x13, 0x1e, 0xd9 } + }, { + { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xa5, 0x97, 0xab, 0x41, 0x76, 0x01, 0x4d, 0x72 } + }, { + { 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06 }, + { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02 }, + { 0xb1, 0xfd, 0x5d, 0xa9, 0xcc, 0x6d, 0xc9, 0xdc } + }, { + { 0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f, + 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 }, + { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 }, + { 0x70, 0x4b, 0x31, 0x34, 0x47, 0x44, 0xdf, 0xab } + }, { + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 }, + { 0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5 } + }, { + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, + { 0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8 } + }, { + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + { 0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f }, + { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 } + }, { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 }, + { 0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5 } + }, { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, + { 0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d } + }, { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55 }, + { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 } + } + }; + unsigned char tmp[2][8]; + symmetric_key skey; + int i, err, y; + for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { + zeromem(&skey, sizeof(skey)); + if ((err = xtea_setup(tests[i].key, 16, 0, &skey)) != CRYPT_OK) { + return err; + } + xtea_ecb_encrypt(tests[i].pt, tmp[0], &skey); + xtea_ecb_decrypt(tmp[0], tmp[1], &skey); + + if (XMEMCMP(tmp[0], tests[i].ct, 8) != 0 || XMEMCMP(tmp[1], tests[i].pt, 8) != 0) { +#if 0 + printf("\n\nTest %d failed\n", i); + if (XMEMCMP(tmp[0], tests[i].ct, 8)) { + printf("CT: "); + for (i = 0; i < 8; i++) { + printf("%02x ", tmp[0][i]); + } + printf("\n"); + } else { + printf("PT: "); + for (i = 0; i < 8; i++) { + printf("%02x ", tmp[1][i]); + } + printf("\n"); + } +#endif + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) xtea_ecb_encrypt(tmp[0], tmp[0], &skey); + for (y = 0; y < 1000; y++) xtea_ecb_decrypt(tmp[0], tmp[0], &skey); + for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } /* for */ + + return CRYPT_OK; + #endif +} + +/** Terminate the context + @param skey The scheduled key +*/ +void xtea_done(symmetric_key *skey) +{ + LTC_UNUSED_PARAM(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. + @return CRYPT_OK if the input key size is acceptable. +*/ +int xtea_keysize(int *keysize) +{ + LTC_ARGCHK(keysize != NULL); + if (*keysize < 16) { + return CRYPT_INVALID_KEYSIZE; + } + *keysize = 16; + return CRYPT_OK; +} + + +#endif + + + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/encauth/ccm/ccm_add_aad.c b/src/ltc/encauth/ccm/ccm_add_aad.c new file mode 100644 index 0000000..43a3d53 --- /dev/null +++ b/src/ltc/encauth/ccm/ccm_add_aad.c @@ -0,0 +1,61 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +#ifdef LTC_CCM_MODE + +/** + Add AAD to the CCM state + @param ccm The CCM state + @param adata The additional authentication data to add to the CCM state + @param adatalen The length of the AAD data. + @return CRYPT_OK on success + */ +int ccm_add_aad(ccm_state *ccm, + const unsigned char *adata, unsigned long adatalen) +{ + unsigned long y; + int err; + + LTC_ARGCHK(ccm != NULL); + LTC_ARGCHK(adata != NULL); + + if (ccm->aadlen < ccm->current_aadlen + adatalen) { + return CRYPT_INVALID_ARG; + } + ccm->current_aadlen += adatalen; + + /* now add the data */ + for (y = 0; y < adatalen; y++) { + if (ccm->x == 16) { + /* full block so let's encrypt it */ + if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->PAD, ccm->PAD, &ccm->K)) != CRYPT_OK) { + return err; + } + ccm->x = 0; + } + ccm->PAD[ccm->x++] ^= adata[y]; + } + + /* remainder? */ + if (ccm->aadlen == ccm->current_aadlen) { + if (ccm->x != 0) { + if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->PAD, ccm->PAD, &ccm->K)) != CRYPT_OK) { + return err; + } + } + ccm->x = 0; + } + + return CRYPT_OK; +} + +#endif diff --git a/src/ltc/encauth/ccm/ccm_add_nonce.c b/src/ltc/encauth/ccm/ccm_add_nonce.c new file mode 100644 index 0000000..0f67fc2 --- /dev/null +++ b/src/ltc/encauth/ccm/ccm_add_nonce.c @@ -0,0 +1,111 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +#ifdef LTC_CCM_MODE + +/** + Add nonce data to the CCM state + @param ccm The CCM state + @param nonce The nonce data to add + @param noncelen The length of the nonce + @return CRYPT_OK on success + */ +int ccm_add_nonce(ccm_state *ccm, + const unsigned char *nonce, unsigned long noncelen) +{ + unsigned long x, y, len; + int err; + + LTC_ARGCHK(ccm != NULL); + LTC_ARGCHK(nonce != NULL); + + /* increase L to match the nonce len */ + ccm->noncelen = (noncelen > 13) ? 13 : noncelen; + if ((15 - ccm->noncelen) > ccm->L) { + ccm->L = 15 - ccm->noncelen; + } + + /* decrease noncelen to match L */ + if ((ccm->noncelen + ccm->L) > 15) { + ccm->noncelen = 15 - ccm->L; + } + + /* form B_0 == flags | Nonce N | l(m) */ + x = 0; + ccm->PAD[x++] = (unsigned char)(((ccm->aadlen > 0) ? (1<<6) : 0) | + (((ccm->taglen - 2)>>1)<<3) | + (ccm->L-1)); + + /* nonce */ + for (y = 0; y < (16 - (ccm->L + 1)); y++) { + ccm->PAD[x++] = nonce[y]; + } + + /* store len */ + len = ccm->ptlen; + + /* shift len so the upper bytes of len are the contents of the length */ + for (y = ccm->L; y < 4; y++) { + len <<= 8; + } + + /* store l(m) (only store 32-bits) */ + for (y = 0; ccm->L > 4 && (ccm->L-y)>4; y++) { + ccm->PAD[x++] = 0; + } + for (; y < ccm->L; y++) { + ccm->PAD[x++] = (unsigned char)((len >> 24) & 255); + len <<= 8; + } + + /* encrypt PAD */ + if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->PAD, ccm->PAD, &ccm->K)) != CRYPT_OK) { + return err; + } + + /* handle header */ + ccm->x = 0; + if (ccm->aadlen > 0) { + /* store length */ + if (ccm->aadlen < ((1UL<<16) - (1UL<<8))) { + ccm->PAD[ccm->x++] ^= (ccm->aadlen>>8) & 255; + ccm->PAD[ccm->x++] ^= ccm->aadlen & 255; + } else { + ccm->PAD[ccm->x++] ^= 0xFF; + ccm->PAD[ccm->x++] ^= 0xFE; + ccm->PAD[ccm->x++] ^= (ccm->aadlen>>24) & 255; + ccm->PAD[ccm->x++] ^= (ccm->aadlen>>16) & 255; + ccm->PAD[ccm->x++] ^= (ccm->aadlen>>8) & 255; + ccm->PAD[ccm->x++] ^= ccm->aadlen & 255; + } + } + + /* setup the ctr counter */ + x = 0; + + /* flags */ + ccm->ctr[x++] = (unsigned char)ccm->L-1; + + /* nonce */ + for (y = 0; y < (16 - (ccm->L+1)); ++y) { + ccm->ctr[x++] = nonce[y]; + } + /* offset */ + while (x < 16) { + ccm->ctr[x++] = 0; + } + + ccm->CTRlen = 16; + return CRYPT_OK; +} + +#endif diff --git a/src/ltc/encauth/ccm/ccm_done.c b/src/ltc/encauth/ccm/ccm_done.c new file mode 100644 index 0000000..64c9f9f --- /dev/null +++ b/src/ltc/encauth/ccm/ccm_done.c @@ -0,0 +1,63 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +#ifdef LTC_CCM_MODE + +/** + Terminate a CCM stream + @param ccm The CCM 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 ccm_done(ccm_state *ccm, + unsigned char *tag, unsigned long *taglen) +{ + unsigned long x, y; + int err; + + LTC_ARGCHK(ccm != NULL); + + /* Check all data have been processed */ + if (ccm->ptlen != ccm->current_ptlen) { + return CRYPT_ERROR; + } + + LTC_ARGCHK(tag != NULL); + LTC_ARGCHK(taglen != NULL); + + if (ccm->x != 0) { + if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->PAD, ccm->PAD, &ccm->K)) != CRYPT_OK) { + return err; + } + } + + /* setup CTR for the TAG (zero the count) */ + for (y = 15; y > 15 - ccm->L; y--) { + ccm->ctr[y] = 0x00; + } + if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->ctr, ccm->CTRPAD, &ccm->K)) != CRYPT_OK) { + return err; + } + + cipher_descriptor[ccm->cipher].done(&ccm->K); + + /* store the TAG */ + for (x = 0; x < 16 && x < *taglen; x++) { + tag[x] = ccm->PAD[x] ^ ccm->CTRPAD[x]; + } + *taglen = x; + + return CRYPT_OK; +} + +#endif diff --git a/src/ltc/encauth/ccm/ccm_init.c b/src/ltc/encauth/ccm/ccm_init.c new file mode 100644 index 0000000..7e3bdf8 --- /dev/null +++ b/src/ltc/encauth/ccm/ccm_init.c @@ -0,0 +1,79 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +#ifdef LTC_CCM_MODE + +/** + Initialize a CCM state + @param ccm The CCM 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 + @param ptlen The length of the plain/cipher text that will be processed + @param taglen The max length of the MAC tag + @param aadlen The length of the AAD + + @return CRYPT_OK on success + */ +int ccm_init(ccm_state *ccm, int cipher, + const unsigned char *key, int keylen, int ptlen, int taglen, int aadlen) +{ + int err; + + LTC_ARGCHK(ccm != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(taglen != 0); + + XMEMSET(ccm, 0, sizeof(ccm_state)); + + /* 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 */ + ccm->taglen = taglen; + ccm->taglen &= ~1; + if (ccm->taglen > 16) { + ccm->taglen = 16; + } + + /* can't use < 4 */ + if (ccm->taglen < 4) { + return CRYPT_INVALID_ARG; + } + + /* schedule key */ + if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &ccm->K)) != CRYPT_OK) { + return err; + } + ccm->cipher = cipher; + + /* let's get the L value */ + ccm->ptlen = ptlen; + ccm->L = 0; + while (ptlen) { + ++ccm->L; + ptlen >>= 8; + } + if (ccm->L <= 1) { + ccm->L = 2; + } + + ccm->aadlen = aadlen; + return CRYPT_OK; +} + +#endif diff --git a/src/ltc/encauth/ccm/ccm_memory.c b/src/ltc/encauth/ccm/ccm_memory.c new file mode 100644 index 0000000..eb41f99 --- /dev/null +++ b/src/ltc/encauth/ccm/ccm_memory.c @@ -0,0 +1,405 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ccm_memory.c + CCM support, process a block of memory, Tom St Denis +*/ + +#ifdef LTC_CCM_MODE + +/** + CCM encrypt/decrypt and produce an authentication tag + + *1 'pt', 'ct' and 'tag' can both be 'in' or 'out', depending on 'direction' + + @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 uskey A previously scheduled key [optional can be NULL] + @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 [*1] The plaintext + @param ptlen The length of the plaintext (octets) + @param ct [*1] The ciphertext + @param tag [*1] The destination tag + @param taglen 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, + symmetric_key *uskey, + 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], ptTag[16], b, *pt_real; + unsigned char *pt_work = NULL; + symmetric_key *skey; + int err; + unsigned long len, L, x, y, z, CTRlen; +#ifdef LTC_FAST + LTC_FAST_TYPE fastMask = -1; /* initialize fastMask at all zeroes */ +#endif + unsigned char mask = 0xff; /* initialize mask at all zeroes */ + + if (uskey == NULL) { + 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); + + pt_real = pt; + +#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) { + return cipher_descriptor[cipher].accel_ccm_memory( + key, keylen, + uskey, + nonce, noncelen, + header, headerlen, + pt, ptlen, + ct, + tag, taglen, + direction); + } + + /* 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 */ + if (uskey == NULL) { + 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; + } + } else { + skey = uskey; + } + + /* initialize buffer for pt */ + if (direction == CCM_DECRYPT) { + pt_work = XMALLOC(ptlen); + if (pt_work == NULL) { + goto error; + } + pt = pt_work; + } + + /* form B_0 == flags | Nonce N | l(m) */ + x = 0; + PAD[x++] = (unsigned char)(((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++] = (unsigned char)((len >> 24) & 255); + len <<= 8; + } + + /* encrypt PAD */ + if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { + goto error; + } + + /* 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 */ + if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { + goto error; + } + x = 0; + } + PAD[x++] ^= header[y]; + } + + /* remainder */ + if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { + goto error; + } + } + + /* setup the ctr counter */ + x = 0; + + /* flags */ + ctr[x++] = (unsigned char)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; + } + if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) { + goto error; + } + + /* xor the PT against the pad first */ + for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) { + *(LTC_FAST_TYPE_PTR_CAST(&PAD[z])) ^= *(LTC_FAST_TYPE_PTR_CAST(&pt[y+z])); + *(LTC_FAST_TYPE_PTR_CAST(&ct[y+z])) = *(LTC_FAST_TYPE_PTR_CAST(&pt[y+z])) ^ *(LTC_FAST_TYPE_PTR_CAST(&CTRPAD[z])); + } + if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { + goto error; + } + } + } else { /* direction == CCM_DECRYPT */ + 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; + } + if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) { + goto error; + } + + /* xor the PT against the pad last */ + for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) { + *(LTC_FAST_TYPE_PTR_CAST(&pt[y+z])) = *(LTC_FAST_TYPE_PTR_CAST(&ct[y+z])) ^ *(LTC_FAST_TYPE_PTR_CAST(&CTRPAD[z])); + *(LTC_FAST_TYPE_PTR_CAST(&PAD[z])) ^= *(LTC_FAST_TYPE_PTR_CAST(&pt[y+z])); + } + if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { + goto error; + } + } + } + } +#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; + } + if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) { + goto error; + } + 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) { + if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { + goto error; + } + x = 0; + } + PAD[x++] ^= b; + } + + if (x != 0) { + if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { + goto error; + } + } + } + + /* setup CTR for the TAG (zero the count) */ + for (y = 15; y > 15 - L; y--) { + ctr[y] = 0x00; + } + if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) { + goto error; + } + + if (skey != uskey) { + cipher_descriptor[cipher].done(skey); + } + + if (direction == CCM_ENCRYPT) { + /* store the TAG */ + for (x = 0; x < 16 && x < *taglen; x++) { + tag[x] = PAD[x] ^ CTRPAD[x]; + } + *taglen = x; + } else { /* direction == CCM_DECRYPT */ + /* decrypt the tag */ + for (x = 0; x < 16 && x < *taglen; x++) { + ptTag[x] = tag[x] ^ CTRPAD[x]; + } + *taglen = x; + + /* check validity of the decrypted tag against the computed PAD (in constant time) */ + /* HACK: the boolean value of XMEM_NEQ becomes either 0 (CRYPT_OK) or 1 (CRYPT_ERR). + * there should be a better way of setting the correct error code in constant + * time. + */ + err = XMEM_NEQ(ptTag, PAD, *taglen); + + /* Zero the plaintext if the tag was invalid (in constant time) */ + if (ptlen > 0) { + y = 0; + mask *= 1 - err; /* mask = ( err ? 0 : 0xff ) */ +#ifdef LTC_FAST + fastMask *= 1 - err; + if (ptlen & ~15) { + for (; y < (ptlen & ~15); y += 16) { + for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) { + *(LTC_FAST_TYPE_PTR_CAST(&pt_real[y+z])) = *(LTC_FAST_TYPE_PTR_CAST(&pt[y+z])) & fastMask; + } + } + } +#endif + for (; y < ptlen; y++) { + pt_real[y] = pt[y] & mask; + } + } + } + +#ifdef LTC_CLEAN_STACK + fastMask = 0; + mask = 0; + zeromem(skey, sizeof(*skey)); + zeromem(PAD, sizeof(PAD)); + zeromem(CTRPAD, sizeof(CTRPAD)); + if (pt_work != NULL) { + zeromem(pt_work, ptlen); + } +#endif +error: + if (pt_work) { + XFREE(pt_work); + } + if (skey != uskey) { + XFREE(skey); + } + + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/encauth/ccm/ccm_process.c b/src/ltc/encauth/ccm/ccm_process.c new file mode 100644 index 0000000..1f650ca --- /dev/null +++ b/src/ltc/encauth/ccm/ccm_process.c @@ -0,0 +1,86 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +#ifdef LTC_CCM_MODE + +/** + Process plaintext/ciphertext through CCM + @param ccm The CCM 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 (CCM_ENCRYPT or CCM_DECRYPT) + @return CRYPT_OK on success + */ +int ccm_process(ccm_state *ccm, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + int direction) +{ + unsigned char y, z, b; + int err; + + LTC_ARGCHK(ccm != NULL); + + /* Check aad has been correctly added */ + if (ccm->aadlen != ccm->current_aadlen) { + return CRYPT_ERROR; + } + + /* Check we do not process too much data */ + if (ccm->ptlen < ccm->current_ptlen + ptlen) { + return CRYPT_ERROR; + } + ccm->current_ptlen += ptlen; + + /* now handle the PT */ + if (ptlen > 0) { + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + y = 0; + + for (; y < ptlen; y++) { + /* increment the ctr? */ + if (ccm->CTRlen == 16) { + for (z = 15; z > 15-ccm->L; z--) { + ccm->ctr[z] = (ccm->ctr[z] + 1) & 255; + if (ccm->ctr[z]) break; + } + if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->ctr, ccm->CTRPAD, &ccm->K)) != CRYPT_OK) { + return err; + } + ccm->CTRlen = 0; + } + + /* if we encrypt we add the bytes to the MAC first */ + if (direction == CCM_ENCRYPT) { + b = pt[y]; + ct[y] = b ^ ccm->CTRPAD[ccm->CTRlen++]; + } else { + b = ct[y] ^ ccm->CTRPAD[ccm->CTRlen++]; + pt[y] = b; + } + + if (ccm->x == 16) { + if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->PAD, ccm->PAD, &ccm->K)) != CRYPT_OK) { + return err; + } + ccm->x = 0; + } + ccm->PAD[ccm->x++] ^= b; + } + } + + return CRYPT_OK; +} + +#endif diff --git a/src/ltc/encauth/ccm/ccm_reset.c b/src/ltc/encauth/ccm/ccm_reset.c new file mode 100644 index 0000000..855789d --- /dev/null +++ b/src/ltc/encauth/ccm/ccm_reset.c @@ -0,0 +1,33 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +#ifdef LTC_CCM_MODE + +/** + Reset a CCM state to as if you just called ccm_init(). This saves the initialization time. + @param ccm The CCM state to reset + @return CRYPT_OK on success +*/ +int ccm_reset(ccm_state *ccm) +{ + LTC_ARGCHK(ccm != NULL); + zeromem(ccm->PAD, sizeof(ccm->PAD)); + zeromem(ccm->ctr, sizeof(ccm->ctr)); + zeromem(ccm->CTRPAD, sizeof(ccm->CTRPAD)); + ccm->CTRlen = 0; + ccm->current_ptlen = 0; + ccm->current_aadlen = 0; + + return CRYPT_OK; +} + +#endif diff --git a/src/ltc/encauth/chachapoly/chacha20poly1305_add_aad.c b/src/ltc/encauth/chachapoly/chacha20poly1305_add_aad.c new file mode 100644 index 0000000..8d530a1 --- /dev/null +++ b/src/ltc/encauth/chachapoly/chacha20poly1305_add_aad.c @@ -0,0 +1,34 @@ +/* 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. + */ + +#include "tomcrypt.h" + +#ifdef LTC_CHACHA20POLY1305_MODE + +/** + Add AAD to the ChaCha20Poly1305 state + @param st The ChaCha20Poly1305 state + @param in The additional authentication data to add to the ChaCha20Poly1305 state + @param inlen The length of the ChaCha20Poly1305 data. + @return CRYPT_OK on success + */ +int chacha20poly1305_add_aad(chacha20poly1305_state *st, const unsigned char *in, unsigned long inlen) +{ + int err; + + if (inlen == 0) return CRYPT_OK; /* nothing to do */ + LTC_ARGCHK(st != NULL); + + if (st->aadflg == 0) return CRYPT_ERROR; + if ((err = poly1305_process(&st->poly, in, inlen)) != CRYPT_OK) return err; + st->aadlen += (ulong64)inlen; + return CRYPT_OK; +} + +#endif diff --git a/src/ltc/encauth/chachapoly/chacha20poly1305_decrypt.c b/src/ltc/encauth/chachapoly/chacha20poly1305_decrypt.c new file mode 100644 index 0000000..2677aff --- /dev/null +++ b/src/ltc/encauth/chachapoly/chacha20poly1305_decrypt.c @@ -0,0 +1,45 @@ +/* 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. + */ + +#include "tomcrypt.h" + +#ifdef LTC_CHACHA20POLY1305_MODE + +/** + Decrypt bytes of ciphertext with ChaCha20Poly1305 + @param st The ChaCha20Poly1305 state + @param in The ciphertext + @param inlen The length of the input (octets) + @param out [out] The plaintext (length inlen) + @return CRYPT_OK if successful +*/ +int chacha20poly1305_decrypt(chacha20poly1305_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out) +{ + unsigned char padzero[16] = { 0 }; + unsigned long padlen; + int err; + + if (inlen == 0) return CRYPT_OK; /* nothing to do */ + LTC_ARGCHK(st != NULL); + + if (st->aadflg) { + padlen = 16 - (st->aadlen % 16); + if (padlen < 16) { + if ((err = poly1305_process(&st->poly, padzero, padlen)) != CRYPT_OK) return err; + } + st->aadflg = 0; /* no more AAD */ + } + if (st->aadflg) st->aadflg = 0; /* no more AAD */ + if ((err = poly1305_process(&st->poly, in, inlen)) != CRYPT_OK) return err; + if ((err = chacha_crypt(&st->chacha, in, inlen, out)) != CRYPT_OK) return err; + st->ctlen += (ulong64)inlen; + return CRYPT_OK; +} + +#endif diff --git a/src/ltc/encauth/chachapoly/chacha20poly1305_done.c b/src/ltc/encauth/chachapoly/chacha20poly1305_done.c new file mode 100644 index 0000000..1b41589 --- /dev/null +++ b/src/ltc/encauth/chachapoly/chacha20poly1305_done.c @@ -0,0 +1,42 @@ +/* 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. + */ + +#include "tomcrypt.h" + +#ifdef LTC_CHACHA20POLY1305_MODE + +/** + Terminate a ChaCha20Poly1305 stream + @param st The ChaCha20Poly1305 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 chacha20poly1305_done(chacha20poly1305_state *st, unsigned char *tag, unsigned long *taglen) +{ + unsigned char padzero[16] = { 0 }; + unsigned long padlen; + unsigned char buf[16]; + int err; + + LTC_ARGCHK(st != NULL); + + padlen = 16 - (st->ctlen % 16); + if (padlen < 16) { + if ((err = poly1305_process(&st->poly, padzero, padlen)) != CRYPT_OK) return err; + } + STORE64L(st->aadlen, buf); + STORE64L(st->ctlen, buf + 8); + if ((err = poly1305_process(&st->poly, buf, 16)) != CRYPT_OK) return err; + if ((err = poly1305_done(&st->poly, tag, taglen)) != CRYPT_OK) return err; + if ((err = chacha_done(&st->chacha)) != CRYPT_OK) return err; + return CRYPT_OK; +} + +#endif diff --git a/src/ltc/encauth/chachapoly/chacha20poly1305_encrypt.c b/src/ltc/encauth/chachapoly/chacha20poly1305_encrypt.c new file mode 100644 index 0000000..511f24b --- /dev/null +++ b/src/ltc/encauth/chachapoly/chacha20poly1305_encrypt.c @@ -0,0 +1,44 @@ +/* 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. + */ + +#include "tomcrypt.h" + +#ifdef LTC_CHACHA20POLY1305_MODE + +/** + Encrypt bytes of ciphertext with ChaCha20Poly1305 + @param st The ChaCha20Poly1305 state + @param in The plaintext + @param inlen The length of the input (octets) + @param out [out] The ciphertext (length inlen) + @return CRYPT_OK if successful +*/ +int chacha20poly1305_encrypt(chacha20poly1305_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out) +{ + unsigned char padzero[16] = { 0 }; + unsigned long padlen; + int err; + + if (inlen == 0) return CRYPT_OK; /* nothing to do */ + LTC_ARGCHK(st != NULL); + + if ((err = chacha_crypt(&st->chacha, in, inlen, out)) != CRYPT_OK) return err; + if (st->aadflg) { + padlen = 16 - (st->aadlen % 16); + if (padlen < 16) { + if ((err = poly1305_process(&st->poly, padzero, padlen)) != CRYPT_OK) return err; + } + st->aadflg = 0; /* no more AAD */ + } + if ((err = poly1305_process(&st->poly, out, inlen)) != CRYPT_OK) return err; + st->ctlen += (ulong64)inlen; + return CRYPT_OK; +} + +#endif diff --git a/src/ltc/encauth/chachapoly/chacha20poly1305_init.c b/src/ltc/encauth/chachapoly/chacha20poly1305_init.c new file mode 100644 index 0000000..5195d12 --- /dev/null +++ b/src/ltc/encauth/chachapoly/chacha20poly1305_init.c @@ -0,0 +1,26 @@ +/* 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. + */ + +#include "tomcrypt.h" + +#ifdef LTC_CHACHA20POLY1305_MODE + +/** + Initialize an ChaCha20Poly1305 context (only the key) + @param st [out] The destination of the ChaCha20Poly1305 state + @param key The secret key + @param keylen The length of the secret key (octets) + @return CRYPT_OK if successful +*/ +int chacha20poly1305_init(chacha20poly1305_state *st, const unsigned char *key, unsigned long keylen) +{ + return chacha_setup(&st->chacha, key, keylen, 20); +} + +#endif diff --git a/src/ltc/encauth/chachapoly/chacha20poly1305_memory.c b/src/ltc/encauth/chachapoly/chacha20poly1305_memory.c new file mode 100644 index 0000000..759e704 --- /dev/null +++ b/src/ltc/encauth/chachapoly/chacha20poly1305_memory.c @@ -0,0 +1,70 @@ +/* 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. + */ + +#include "tomcrypt.h" + +#ifdef LTC_CHACHA20POLY1305_MODE + +/** + Process an entire GCM packet in one call. + @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 aad The additional authentication data (header) + @param aadlen The length of the aad + @param in The plaintext + @param inlen The length of the plaintext (ciphertext length is the same) + @param out The ciphertext + @param tag [out] The MAC tag + @param taglen [in/out] The MAC tag length + @param direction Encrypt or Decrypt mode (CHCHA20POLY1305_ENCRYPT or CHCHA20POLY1305_DECRYPT) + @return CRYPT_OK on success + */ +int chacha20poly1305_memory(const unsigned char *key, unsigned long keylen, + const unsigned char *iv, unsigned long ivlen, + const unsigned char *aad, unsigned long aadlen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, + unsigned char *tag, unsigned long *taglen, + int direction) +{ + chacha20poly1305_state st; + int err; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(iv != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(tag != NULL); + + if ((err = chacha20poly1305_init(&st, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = chacha20poly1305_setiv(&st, iv, ivlen)) != CRYPT_OK) { goto LBL_ERR; } + if (aad && aadlen > 0) { + if ((err = chacha20poly1305_add_aad(&st, aad, aadlen)) != CRYPT_OK) { goto LBL_ERR; } + } + if (direction == CHCHA20POLY1305_ENCRYPT) { + if ((err = chacha20poly1305_encrypt(&st, in, inlen, out)) != CRYPT_OK) { goto LBL_ERR; } + } + else if (direction == CHCHA20POLY1305_DECRYPT) { + if ((err = chacha20poly1305_decrypt(&st, in, inlen, out)) != CRYPT_OK) { goto LBL_ERR; } + } + else { + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + err = chacha20poly1305_done(&st, tag, taglen); +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(&st, sizeof(chacha20poly1305_state)); +#endif + return err; +} + +#endif diff --git a/src/ltc/encauth/chachapoly/chacha20poly1305_setiv.c b/src/ltc/encauth/chachapoly/chacha20poly1305_setiv.c new file mode 100644 index 0000000..e5d41c9 --- /dev/null +++ b/src/ltc/encauth/chachapoly/chacha20poly1305_setiv.c @@ -0,0 +1,64 @@ +/* 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. + */ + +#include "tomcrypt.h" + +#ifdef LTC_CHACHA20POLY1305_MODE + +/** + Set IV + counter data to the ChaCha20Poly1305 state and reset the context + @param st The ChaCha20Poly1305 state + @param iv The IV data to add + @param inlen The length of the IV (must be 12 or 8) + @return CRYPT_OK on success + */ +int chacha20poly1305_setiv(chacha20poly1305_state *st, const unsigned char *iv, unsigned long ivlen) +{ + chacha_state tmp_st; + int i, err; + unsigned char polykey[32]; + + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(iv != NULL); + LTC_ARGCHK(ivlen == 12 || ivlen == 8); + + /* set IV for chacha20 */ + if (ivlen == 12) { + /* IV 96bit */ + if ((err = chacha_ivctr32(&st->chacha, iv, ivlen, 1)) != CRYPT_OK) return err; + } + else { + /* IV 64bit */ + if ((err = chacha_ivctr64(&st->chacha, iv, ivlen, 1)) != CRYPT_OK) return err; + } + + /* copy chacha20 key to temporary state */ + for(i = 0; i < 12; i++) tmp_st.input[i] = st->chacha.input[i]; + tmp_st.rounds = 20; + /* set IV */ + if (ivlen == 12) { + /* IV 32bit */ + if ((err = chacha_ivctr32(&tmp_st, iv, ivlen, 0)) != CRYPT_OK) return err; + } + else { + /* IV 64bit */ + if ((err = chacha_ivctr64(&tmp_st, iv, ivlen, 0)) != CRYPT_OK) return err; + } + /* (re)generate new poly1305 key */ + if ((err = chacha_keystream(&tmp_st, polykey, 32)) != CRYPT_OK) return err; + /* (re)initialise poly1305 */ + if ((err = poly1305_init(&st->poly, polykey, 32)) != CRYPT_OK) return err; + st->ctlen = 0; + st->aadlen = 0; + st->aadflg = 1; + + return CRYPT_OK; +} + +#endif diff --git a/src/ltc/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.c b/src/ltc/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.c new file mode 100644 index 0000000..6bb4e58 --- /dev/null +++ b/src/ltc/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.c @@ -0,0 +1,36 @@ +/* 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. + */ + +#include "tomcrypt.h" + +#ifdef LTC_CHACHA20POLY1305_MODE + +/** + Set IV + counter data (with RFC7905-magic) to the ChaCha20Poly1305 state and reset the context + @param st The ChaCha20Poly1305 state + @param iv The IV data to add + @param inlen The length of the IV (must be 12 or 8) + @param sequence_number 64bit sequence number which is incorporated into IV as described in RFC7905 + @return CRYPT_OK on success + */ +int chacha20poly1305_setiv_rfc7905(chacha20poly1305_state *st, const unsigned char *iv, unsigned long ivlen, ulong64 sequence_number) +{ + int i; + unsigned char combined_iv[12] = { 0 }; + + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(iv != NULL); + LTC_ARGCHK(ivlen == 12); + + STORE64L(sequence_number, combined_iv + 4); + for (i = 0; i < 12; i++) combined_iv[i] = iv[i] ^ combined_iv[i]; + return chacha20poly1305_setiv(st, combined_iv, 12); +} + +#endif diff --git a/src/ltc/encauth/eax/eax_addheader.c b/src/ltc/encauth/eax/eax_addheader.c new file mode 100644 index 0000000..3c1d79b --- /dev/null +++ b/src/ltc/encauth/eax/eax_addheader.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://libtom.org + */ +/** + @file eax_addheader.c + EAX implementation, add meta-data, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_EAX_MODE + +/** + add header (metadata) to the stream + @param eax The current EAX state + @param header The header (meta-data) data you wish to add to the state + @param length The length of the header data + @return CRYPT_OK if successful +*/ +int eax_addheader(eax_state *eax, const unsigned char *header, + unsigned long length) +{ + LTC_ARGCHK(eax != NULL); + LTC_ARGCHK(header != NULL); + return omac_process(&eax->headeromac, header, length); +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/encauth/eax/eax_decrypt.c b/src/ltc/encauth/eax/eax_decrypt.c new file mode 100644 index 0000000..512b5b7 --- /dev/null +++ b/src/ltc/encauth/eax/eax_decrypt.c @@ -0,0 +1,50 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file eax_decrypt.c + EAX implementation, decrypt block, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_EAX_MODE + +/** + Decrypt data with the EAX protocol + @param eax The EAX state + @param ct The ciphertext + @param pt [out] The plaintext + @param length The length (octets) of the ciphertext + @return CRYPT_OK if successful +*/ +int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt, + unsigned long length) +{ + int err; + + LTC_ARGCHK(eax != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + + /* omac ciphertext */ + if ((err = omac_process(&eax->ctomac, ct, length)) != CRYPT_OK) { + return err; + } + + /* decrypt */ + return ctr_decrypt(ct, pt, length, &eax->ctr); +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/encauth/eax/eax_decrypt_verify_memory.c b/src/ltc/encauth/eax/eax_decrypt_verify_memory.c new file mode 100644 index 0000000..be07cf5 --- /dev/null +++ b/src/ltc/encauth/eax/eax_decrypt_verify_memory.c @@ -0,0 +1,108 @@ +/* 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://libtom.org + */ + +/** + @file eax_decrypt_verify_memory.c + EAX implementation, decrypt block of memory, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_EAX_MODE + +/** + Decrypt a block of memory and verify the provided MAC tag with EAX + @param cipher The index of the cipher desired + @param key The secret key + @param keylen The length of the key (octets) + @param nonce The nonce data (use once) for the session + @param noncelen The length of the nonce data. + @param header The session header data + @param headerlen The length of the header (octets) + @param ct The ciphertext + @param ctlen The length of the ciphertext (octets) + @param pt [out] The plaintext + @param tag The authentication tag provided by the encoder + @param taglen [in/out] The length of the tag (octets) + @param stat [out] The result of the decryption (1==valid tag, 0==invalid) + @return CRYPT_OK if successful regardless of the resulting tag comparison +*/ +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 err; + eax_state *eax; + unsigned char *buf; + unsigned long buflen; + + LTC_ARGCHK(stat != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(tag != NULL); + + /* default to zero */ + *stat = 0; + + /* allocate ram */ + buf = XMALLOC(taglen); + eax = XMALLOC(sizeof(*eax)); + if (eax == NULL || buf == NULL) { + if (eax != NULL) { + XFREE(eax); + } + if (buf != NULL) { + XFREE(buf); + } + return CRYPT_MEM; + } + + if ((err = eax_init(eax, cipher, key, keylen, nonce, noncelen, header, headerlen)) != CRYPT_OK) { + goto LBL_ERR; + } + + if ((err = eax_decrypt(eax, ct, pt, ctlen)) != CRYPT_OK) { + goto LBL_ERR; + } + + buflen = taglen; + if ((err = eax_done(eax, buf, &buflen)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* compare tags */ + if (buflen >= taglen && XMEMCMP(buf, tag, taglen) == 0) { + *stat = 1; + } + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(buf, taglen); + zeromem(eax, sizeof(*eax)); +#endif + + XFREE(eax); + XFREE(buf); + + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/encauth/eax/eax_done.c b/src/ltc/encauth/eax/eax_done.c new file mode 100644 index 0000000..cac6093 --- /dev/null +++ b/src/ltc/encauth/eax/eax_done.c @@ -0,0 +1,94 @@ +/* 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://libtom.org + */ + +/** + @file eax_done.c + EAX implementation, terminate session, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_EAX_MODE + +/** + Terminate an EAX session and get the tag. + @param eax The EAX state + @param tag [out] The destination of the authentication tag + @param taglen [in/out] The max length and resulting length of the authentication tag + @return CRYPT_OK if successful +*/ +int eax_done(eax_state *eax, unsigned char *tag, unsigned long *taglen) +{ + int err; + unsigned char *headermac, *ctmac; + unsigned long x, len; + + LTC_ARGCHK(eax != NULL); + LTC_ARGCHK(tag != NULL); + LTC_ARGCHK(taglen != NULL); + + /* allocate ram */ + headermac = XMALLOC(MAXBLOCKSIZE); + ctmac = XMALLOC(MAXBLOCKSIZE); + + if (headermac == NULL || ctmac == NULL) { + if (headermac != NULL) { + XFREE(headermac); + } + if (ctmac != NULL) { + XFREE(ctmac); + } + return CRYPT_MEM; + } + + /* finish ctomac */ + len = MAXBLOCKSIZE; + if ((err = omac_done(&eax->ctomac, ctmac, &len)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* finish headeromac */ + + /* note we specifically don't reset len so the two lens are minimal */ + + if ((err = omac_done(&eax->headeromac, headermac, &len)) != CRYPT_OK) { + 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]; + } + *taglen = x; + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(ctmac, MAXBLOCKSIZE); + zeromem(headermac, MAXBLOCKSIZE); + zeromem(eax, sizeof(*eax)); +#endif + + XFREE(ctmac); + XFREE(headermac); + + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/encauth/eax/eax_encrypt.c b/src/ltc/encauth/eax/eax_encrypt.c new file mode 100644 index 0000000..29eb6ee --- /dev/null +++ b/src/ltc/encauth/eax/eax_encrypt.c @@ -0,0 +1,51 @@ +/* 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://libtom.org + */ + +/** + @file eax_encrypt.c + EAX implementation, encrypt block by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_EAX_MODE + +/** + Encrypt with EAX a block of data. + @param eax The EAX state + @param pt The plaintext to encrypt + @param ct [out] The ciphertext as encrypted + @param length The length of the plaintext (octets) + @return CRYPT_OK if successful +*/ +int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct, + unsigned long length) +{ + int err; + + LTC_ARGCHK(eax != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + + /* encrypt */ + if ((err = ctr_encrypt(pt, ct, length, &eax->ctr)) != CRYPT_OK) { + return err; + } + + /* omac ciphertext */ + return omac_process(&eax->ctomac, ct, length); +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/encauth/eax/eax_encrypt_authenticate_memory.c b/src/ltc/encauth/eax/eax_encrypt_authenticate_memory.c new file mode 100644 index 0000000..4b4815f --- /dev/null +++ b/src/ltc/encauth/eax/eax_encrypt_authenticate_memory.c @@ -0,0 +1,82 @@ +/* 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://libtom.org + */ + +/** + @file eax_encrypt_authenticate_memory.c + EAX implementation, encrypt a block of memory, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_EAX_MODE + +/** + EAX encrypt 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 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 + @return CRYPT_OK if successful +*/ +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 err; + eax_state *eax; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(tag != NULL); + LTC_ARGCHK(taglen != NULL); + + eax = XMALLOC(sizeof(*eax)); + + if ((err = eax_init(eax, cipher, key, keylen, nonce, noncelen, header, headerlen)) != CRYPT_OK) { + goto LBL_ERR; + } + + if ((err = eax_encrypt(eax, pt, ct, ptlen)) != CRYPT_OK) { + goto LBL_ERR; + } + + if ((err = eax_done(eax, tag, taglen)) != CRYPT_OK) { + goto LBL_ERR; + } + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(eax, sizeof(*eax)); +#endif + + XFREE(eax); + + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/encauth/eax/eax_init.c b/src/ltc/encauth/eax/eax_init.c new file mode 100644 index 0000000..55d8df1 --- /dev/null +++ b/src/ltc/encauth/eax/eax_init.c @@ -0,0 +1,144 @@ +/* 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://libtom.org + */ + +/** + @file eax_init.c + EAX implementation, initialized EAX state, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_EAX_MODE + +/** + Initialized an EAX state + @param eax [out] The EAX state to initialize + @param cipher The index of the desired cipher + @param key The secret key + @param keylen The length of the secret key (octets) + @param nonce The use-once nonce for the session + @param noncelen The length of the nonce (octets) + @param header The header for the EAX state + @param headerlen The header length (octets) + @return CRYPT_OK if successful +*/ +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) +{ + unsigned char *buf; + int err, blklen; + omac_state *omac; + unsigned long len; + + + LTC_ARGCHK(eax != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(nonce != NULL); + if (headerlen > 0) { + LTC_ARGCHK(header != NULL); + } + + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + blklen = cipher_descriptor[cipher].block_length; + + /* allocate ram */ + buf = XMALLOC(MAXBLOCKSIZE); + omac = XMALLOC(sizeof(*omac)); + + if (buf == NULL || omac == NULL) { + if (buf != NULL) { + XFREE(buf); + } + if (omac != NULL) { + XFREE(omac); + } + return CRYPT_MEM; + } + + /* N = LTC_OMAC_0K(nonce) */ + zeromem(buf, MAXBLOCKSIZE); + if ((err = omac_init(omac, cipher, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* omac the [0]_n */ + if ((err = omac_process(omac, buf, blklen)) != CRYPT_OK) { + goto LBL_ERR; + } + /* omac the nonce */ + if ((err = omac_process(omac, nonce, noncelen)) != CRYPT_OK) { + goto LBL_ERR; + } + /* store result */ + len = sizeof(eax->N); + if ((err = omac_done(omac, eax->N, &len)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* H = LTC_OMAC_1K(header) */ + zeromem(buf, MAXBLOCKSIZE); + buf[blklen - 1] = 1; + + if ((err = omac_init(&eax->headeromac, cipher, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* omac the [1]_n */ + if ((err = omac_process(&eax->headeromac, buf, blklen)) != CRYPT_OK) { + goto LBL_ERR; + } + /* omac the header */ + if (headerlen != 0) { + if ((err = omac_process(&eax->headeromac, header, headerlen)) != CRYPT_OK) { + goto LBL_ERR; + } + } + + /* note we don't finish the headeromac, this allows us to add more header later */ + + /* setup the CTR mode */ + if ((err = ctr_start(cipher, eax->N, key, keylen, 0, CTR_COUNTER_BIG_ENDIAN, &eax->ctr)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* setup the LTC_OMAC for the ciphertext */ + if ((err = omac_init(&eax->ctomac, cipher, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* omac [2]_n */ + zeromem(buf, MAXBLOCKSIZE); + buf[blklen-1] = 2; + if ((err = omac_process(&eax->ctomac, buf, blklen)) != CRYPT_OK) { + goto LBL_ERR; + } + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(buf, MAXBLOCKSIZE); + zeromem(omac, sizeof(*omac)); +#endif + + XFREE(omac); + XFREE(buf); + + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/encauth/gcm/gcm_add_aad.c b/src/ltc/encauth/gcm/gcm_add_aad.c new file mode 100644 index 0000000..b9eb2df --- /dev/null +++ b/src/ltc/encauth/gcm/gcm_add_aad.c @@ -0,0 +1,124 @@ +/* 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://libtom.org + */ + +/** + @file gcm_add_aad.c + GCM implementation, Add AAD data to the stream, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_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; + int err; +#ifdef LTC_FAST + unsigned long y; +#endif + + 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 == LTC_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 = LTC_GCM_MODE_AAD; + } + + if (gcm->mode != LTC_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_PTR_CAST(&gcm->X[y])) ^= *(LTC_FAST_TYPE_PTR_CAST(&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->X[gcm->buflen++] ^= *adata++; + + if (gcm->buflen == 16) { + /* GF mult it */ + gcm_mult_h(gcm, gcm->X); + gcm->buflen = 0; + gcm->totlen += 128; + } + } + + return CRYPT_OK; +} +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/encauth/gcm/gcm_add_iv.c b/src/ltc/encauth/gcm/gcm_add_iv.c new file mode 100644 index 0000000..bf0871a --- /dev/null +++ b/src/ltc/encauth/gcm/gcm_add_iv.c @@ -0,0 +1,94 @@ +/* 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://libtom.org + */ + +/** + @file gcm_add_iv.c + GCM implementation, add IV data to the state, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_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 != LTC_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_PTR_CAST(&gcm->X[y])) ^= *(LTC_FAST_TYPE_PTR_CAST(&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 + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/encauth/gcm/gcm_done.c b/src/ltc/encauth/gcm/gcm_done.c new file mode 100644 index 0000000..db950a5 --- /dev/null +++ b/src/ltc/encauth/gcm/gcm_done.c @@ -0,0 +1,83 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/** + @file gcm_done.c + GCM implementation, Terminate the stream, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_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 != LTC_GCM_MODE_TEXT) { + return CRYPT_INVALID_ARG; + } + + /* handle remaining ciphertext */ + if (gcm->buflen) { + 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 */ + if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y_0, gcm->buf, &gcm->K)) != CRYPT_OK) { + return err; + } + 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 + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/encauth/gcm/gcm_gf_mult.c b/src/ltc/encauth/gcm/gcm_gf_mult.c new file mode 100644 index 0000000..1b3387f --- /dev/null +++ b/src/ltc/encauth/gcm/gcm_gf_mult.c @@ -0,0 +1,221 @@ +/* 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://libtom.org + */ + +/** + @file gcm_gf_mult.c + GCM implementation, do the GF mult, by Tom St Denis +*/ +#include "tomcrypt.h" + +#if defined(LTC_GCM_TABLES) || defined(LTC_LRW_TABLES) || ((defined(LTC_GCM_MODE) || defined(LTC_GCM_MODE)) && defined(LTC_FAST)) + +/* this is x*2^128 mod p(x) ... the results are 16 bytes each stored in a packed format. Since only the + * lower 16 bits are not zero'ed I removed the upper 14 bytes */ +const unsigned char gcm_shift_table[256*2] = { +0x00, 0x00, 0x01, 0xc2, 0x03, 0x84, 0x02, 0x46, 0x07, 0x08, 0x06, 0xca, 0x04, 0x8c, 0x05, 0x4e, +0x0e, 0x10, 0x0f, 0xd2, 0x0d, 0x94, 0x0c, 0x56, 0x09, 0x18, 0x08, 0xda, 0x0a, 0x9c, 0x0b, 0x5e, +0x1c, 0x20, 0x1d, 0xe2, 0x1f, 0xa4, 0x1e, 0x66, 0x1b, 0x28, 0x1a, 0xea, 0x18, 0xac, 0x19, 0x6e, +0x12, 0x30, 0x13, 0xf2, 0x11, 0xb4, 0x10, 0x76, 0x15, 0x38, 0x14, 0xfa, 0x16, 0xbc, 0x17, 0x7e, +0x38, 0x40, 0x39, 0x82, 0x3b, 0xc4, 0x3a, 0x06, 0x3f, 0x48, 0x3e, 0x8a, 0x3c, 0xcc, 0x3d, 0x0e, +0x36, 0x50, 0x37, 0x92, 0x35, 0xd4, 0x34, 0x16, 0x31, 0x58, 0x30, 0x9a, 0x32, 0xdc, 0x33, 0x1e, +0x24, 0x60, 0x25, 0xa2, 0x27, 0xe4, 0x26, 0x26, 0x23, 0x68, 0x22, 0xaa, 0x20, 0xec, 0x21, 0x2e, +0x2a, 0x70, 0x2b, 0xb2, 0x29, 0xf4, 0x28, 0x36, 0x2d, 0x78, 0x2c, 0xba, 0x2e, 0xfc, 0x2f, 0x3e, +0x70, 0x80, 0x71, 0x42, 0x73, 0x04, 0x72, 0xc6, 0x77, 0x88, 0x76, 0x4a, 0x74, 0x0c, 0x75, 0xce, +0x7e, 0x90, 0x7f, 0x52, 0x7d, 0x14, 0x7c, 0xd6, 0x79, 0x98, 0x78, 0x5a, 0x7a, 0x1c, 0x7b, 0xde, +0x6c, 0xa0, 0x6d, 0x62, 0x6f, 0x24, 0x6e, 0xe6, 0x6b, 0xa8, 0x6a, 0x6a, 0x68, 0x2c, 0x69, 0xee, +0x62, 0xb0, 0x63, 0x72, 0x61, 0x34, 0x60, 0xf6, 0x65, 0xb8, 0x64, 0x7a, 0x66, 0x3c, 0x67, 0xfe, +0x48, 0xc0, 0x49, 0x02, 0x4b, 0x44, 0x4a, 0x86, 0x4f, 0xc8, 0x4e, 0x0a, 0x4c, 0x4c, 0x4d, 0x8e, +0x46, 0xd0, 0x47, 0x12, 0x45, 0x54, 0x44, 0x96, 0x41, 0xd8, 0x40, 0x1a, 0x42, 0x5c, 0x43, 0x9e, +0x54, 0xe0, 0x55, 0x22, 0x57, 0x64, 0x56, 0xa6, 0x53, 0xe8, 0x52, 0x2a, 0x50, 0x6c, 0x51, 0xae, +0x5a, 0xf0, 0x5b, 0x32, 0x59, 0x74, 0x58, 0xb6, 0x5d, 0xf8, 0x5c, 0x3a, 0x5e, 0x7c, 0x5f, 0xbe, +0xe1, 0x00, 0xe0, 0xc2, 0xe2, 0x84, 0xe3, 0x46, 0xe6, 0x08, 0xe7, 0xca, 0xe5, 0x8c, 0xe4, 0x4e, +0xef, 0x10, 0xee, 0xd2, 0xec, 0x94, 0xed, 0x56, 0xe8, 0x18, 0xe9, 0xda, 0xeb, 0x9c, 0xea, 0x5e, +0xfd, 0x20, 0xfc, 0xe2, 0xfe, 0xa4, 0xff, 0x66, 0xfa, 0x28, 0xfb, 0xea, 0xf9, 0xac, 0xf8, 0x6e, +0xf3, 0x30, 0xf2, 0xf2, 0xf0, 0xb4, 0xf1, 0x76, 0xf4, 0x38, 0xf5, 0xfa, 0xf7, 0xbc, 0xf6, 0x7e, +0xd9, 0x40, 0xd8, 0x82, 0xda, 0xc4, 0xdb, 0x06, 0xde, 0x48, 0xdf, 0x8a, 0xdd, 0xcc, 0xdc, 0x0e, +0xd7, 0x50, 0xd6, 0x92, 0xd4, 0xd4, 0xd5, 0x16, 0xd0, 0x58, 0xd1, 0x9a, 0xd3, 0xdc, 0xd2, 0x1e, +0xc5, 0x60, 0xc4, 0xa2, 0xc6, 0xe4, 0xc7, 0x26, 0xc2, 0x68, 0xc3, 0xaa, 0xc1, 0xec, 0xc0, 0x2e, +0xcb, 0x70, 0xca, 0xb2, 0xc8, 0xf4, 0xc9, 0x36, 0xcc, 0x78, 0xcd, 0xba, 0xcf, 0xfc, 0xce, 0x3e, +0x91, 0x80, 0x90, 0x42, 0x92, 0x04, 0x93, 0xc6, 0x96, 0x88, 0x97, 0x4a, 0x95, 0x0c, 0x94, 0xce, +0x9f, 0x90, 0x9e, 0x52, 0x9c, 0x14, 0x9d, 0xd6, 0x98, 0x98, 0x99, 0x5a, 0x9b, 0x1c, 0x9a, 0xde, +0x8d, 0xa0, 0x8c, 0x62, 0x8e, 0x24, 0x8f, 0xe6, 0x8a, 0xa8, 0x8b, 0x6a, 0x89, 0x2c, 0x88, 0xee, +0x83, 0xb0, 0x82, 0x72, 0x80, 0x34, 0x81, 0xf6, 0x84, 0xb8, 0x85, 0x7a, 0x87, 0x3c, 0x86, 0xfe, +0xa9, 0xc0, 0xa8, 0x02, 0xaa, 0x44, 0xab, 0x86, 0xae, 0xc8, 0xaf, 0x0a, 0xad, 0x4c, 0xac, 0x8e, +0xa7, 0xd0, 0xa6, 0x12, 0xa4, 0x54, 0xa5, 0x96, 0xa0, 0xd8, 0xa1, 0x1a, 0xa3, 0x5c, 0xa2, 0x9e, +0xb5, 0xe0, 0xb4, 0x22, 0xb6, 0x64, 0xb7, 0xa6, 0xb2, 0xe8, 0xb3, 0x2a, 0xb1, 0x6c, 0xb0, 0xae, +0xbb, 0xf0, 0xba, 0x32, 0xb8, 0x74, 0xb9, 0xb6, 0xbc, 0xf8, 0xbd, 0x3a, 0xbf, 0x7c, 0xbe, 0xbe }; + +#endif + + +#if defined(LTC_GCM_MODE) || defined(LRW_MODE) + +#ifndef LTC_FAST +/* 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) bitserial + @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 char 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); +} + +#else + +/* map normal numbers to "ieee" way ... e.g. bit reversed */ +#define M(x) ( ((x&8)>>3) | ((x&4)>>1) | ((x&2)<<1) | ((x&1)<<3) ) + +#define BPD (sizeof(LTC_FAST_TYPE) * 8) +#define WPV (1 + (16 / sizeof(LTC_FAST_TYPE))) + +/** + GCM GF multiplier (internal use only) word oriented + @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) +{ + int i, j, k, u; + LTC_FAST_TYPE B[16][WPV], tmp[32 / sizeof(LTC_FAST_TYPE)], pB[16 / sizeof(LTC_FAST_TYPE)], zz, z; + unsigned char pTmp[32]; + + /* create simple tables */ + zeromem(B[0], sizeof(B[0])); + zeromem(B[M(1)], sizeof(B[M(1)])); + +#ifdef ENDIAN_32BITWORD + for (i = 0; i < 4; i++) { + LOAD32H(B[M(1)][i], a + (i<<2)); + LOAD32L(pB[i], b + (i<<2)); + } +#else + for (i = 0; i < 2; i++) { + LOAD64H(B[M(1)][i], a + (i<<3)); + LOAD64L(pB[i], b + (i<<3)); + } +#endif + + /* now create 2, 4 and 8 */ + B[M(2)][0] = B[M(1)][0] >> 1; + B[M(4)][0] = B[M(1)][0] >> 2; + B[M(8)][0] = B[M(1)][0] >> 3; + for (i = 1; i < (int)WPV; i++) { + B[M(2)][i] = (B[M(1)][i-1] << (BPD-1)) | (B[M(1)][i] >> 1); + B[M(4)][i] = (B[M(1)][i-1] << (BPD-2)) | (B[M(1)][i] >> 2); + B[M(8)][i] = (B[M(1)][i-1] << (BPD-3)) | (B[M(1)][i] >> 3); + } + + /* now all values with two bits which are 3, 5, 6, 9, 10, 12 */ + for (i = 0; i < (int)WPV; i++) { + B[M(3)][i] = B[M(1)][i] ^ B[M(2)][i]; + B[M(5)][i] = B[M(1)][i] ^ B[M(4)][i]; + B[M(6)][i] = B[M(2)][i] ^ B[M(4)][i]; + B[M(9)][i] = B[M(1)][i] ^ B[M(8)][i]; + B[M(10)][i] = B[M(2)][i] ^ B[M(8)][i]; + B[M(12)][i] = B[M(8)][i] ^ B[M(4)][i]; + + /* now all 3 bit values and the only 4 bit value: 7, 11, 13, 14, 15 */ + B[M(7)][i] = B[M(3)][i] ^ B[M(4)][i]; + B[M(11)][i] = B[M(3)][i] ^ B[M(8)][i]; + B[M(13)][i] = B[M(1)][i] ^ B[M(12)][i]; + B[M(14)][i] = B[M(6)][i] ^ B[M(8)][i]; + B[M(15)][i] = B[M(7)][i] ^ B[M(8)][i]; + } + + zeromem(tmp, sizeof(tmp)); + + /* compute product four bits of each word at a time */ + /* for each nibble */ + for (i = (BPD/4)-1; i >= 0; i--) { + /* for each word */ + for (j = 0; j < (int)(WPV-1); j++) { + /* grab the 4 bits recall the nibbles are backwards so it's a shift by (i^1)*4 */ + u = (pB[j] >> ((i^1)<<2)) & 15; + + /* add offset by the word count the table looked up value to the result */ + for (k = 0; k < (int)WPV; k++) { + tmp[k+j] ^= B[u][k]; + } + } + /* shift result up by 4 bits */ + if (i != 0) { + for (z = j = 0; j < (int)(32 / sizeof(LTC_FAST_TYPE)); j++) { + zz = tmp[j] << (BPD-4); + tmp[j] = (tmp[j] >> 4) | z; + z = zz; + } + } + } + + /* store product */ +#ifdef ENDIAN_32BITWORD + for (i = 0; i < 8; i++) { + STORE32H(tmp[i], pTmp + (i<<2)); + } +#else + for (i = 0; i < 4; i++) { + STORE64H(tmp[i], pTmp + (i<<3)); + } +#endif + + /* reduce by taking most significant byte and adding the appropriate two byte sequence 16 bytes down */ + for (i = 31; i >= 16; i--) { + pTmp[i-16] ^= gcm_shift_table[((unsigned)pTmp[i]<<1)]; + pTmp[i-15] ^= gcm_shift_table[((unsigned)pTmp[i]<<1)+1]; + } + + for (i = 0; i < 16; i++) { + c[i] = pTmp[i]; + } + +} + +#endif + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ + diff --git a/src/ltc/encauth/gcm/gcm_init.c b/src/ltc/encauth/gcm/gcm_init.c new file mode 100644 index 0000000..65282c1 --- /dev/null +++ b/src/ltc/encauth/gcm/gcm_init.c @@ -0,0 +1,107 @@ +/* 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://libtom.org + */ + +/** + @file gcm_init.c + GCM implementation, initialize state, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_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 LTC_GCM_TABLES + int x, y, z, t; +#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); + if ((err = cipher_descriptor[cipher].ecb_encrypt(B, gcm->H, &gcm->K)) != CRYPT_OK) { + return err; + } + + /* setup state */ + zeromem(gcm->buf, sizeof(gcm->buf)); + zeromem(gcm->X, sizeof(gcm->X)); + gcm->cipher = cipher; + gcm->mode = LTC_GCM_MODE_IV; + gcm->ivmode = 0; + gcm->buflen = 0; + gcm->totlen = 0; + gcm->pttotlen = 0; + +#ifdef LTC_GCM_TABLES + /* setup tables */ + + /* generate the first table as it has no shifting (from which we make the other tables) */ + zeromem(B, 16); + for (y = 0; y < 256; y++) { + B[0] = y; + gcm_gf_mult(gcm->H, B, &gcm->PC[0][y][0]); + } + + /* now generate the rest of the tables based the previous table */ + for (x = 1; x < 16; x++) { + for (y = 0; y < 256; y++) { + /* now shift it right by 8 bits */ + t = gcm->PC[x-1][y][15]; + for (z = 15; z > 0; z--) { + gcm->PC[x][y][z] = gcm->PC[x-1][y][z-1]; + } + gcm->PC[x][y][0] = gcm_shift_table[t<<1]; + gcm->PC[x][y][1] ^= gcm_shift_table[(t<<1)+1]; + } + } + +#endif + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/encauth/gcm/gcm_memory.c b/src/ltc/encauth/gcm/gcm_memory.c new file mode 100644 index 0000000..05d471b --- /dev/null +++ b/src/ltc/encauth/gcm/gcm_memory.c @@ -0,0 +1,108 @@ +/* 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://libtom.org + */ + +/** + @file gcm_memory.c + GCM implementation, process a packet, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_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) +{ + void *orig; + gcm_state *gcm; + int err; + + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + if (cipher_descriptor[cipher].accel_gcm_memory != NULL) { + return cipher_descriptor[cipher].accel_gcm_memory + (key, keylen, + IV, IVlen, + adata, adatalen, + pt, ptlen, + ct, + tag, taglen, + direction); + } + + + +#ifndef LTC_GCM_TABLES_SSE2 + orig = gcm = XMALLOC(sizeof(*gcm)); +#else + orig = gcm = XMALLOC(sizeof(*gcm) + 16); +#endif + if (gcm == NULL) { + return CRYPT_MEM; + } + + /* Force GCM to be on a multiple of 16 so we can use 128-bit aligned operations + * note that we only modify gcm and keep orig intact. This code is not portable + * but again it's only for SSE2 anyways, so who cares? + */ +#ifdef LTC_GCM_TABLES_SSE2 + if ((unsigned long)gcm & 15) { + gcm = (gcm_state *)((unsigned long)gcm + (16 - ((unsigned long)gcm & 15))); + } +#endif + + 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(orig); + return err; +} +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/encauth/gcm/gcm_mult_h.c b/src/ltc/encauth/gcm/gcm_mult_h.c new file mode 100644 index 0000000..8eee280 --- /dev/null +++ b/src/ltc/encauth/gcm/gcm_mult_h.c @@ -0,0 +1,59 @@ +/* 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://libtom.org + */ + +/** + @file gcm_mult_h.c + GCM implementation, do the GF mult, by Tom St Denis +*/ +#include "tomcrypt.h" + +#if defined(LTC_GCM_MODE) +/** + 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 LTC_GCM_TABLES + int x; +#ifdef LTC_GCM_TABLES_SSE2 + asm("movdqa (%0),%%xmm0"::"r"(&gcm->PC[0][I[0]][0])); + for (x = 1; x < 16; x++) { + asm("pxor (%0),%%xmm0"::"r"(&gcm->PC[x][I[x]][0])); + } + asm("movdqa %%xmm0,(%0)"::"r"(&T)); +#else + int 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_PTR_CAST(T + y)) ^= *(LTC_FAST_TYPE_PTR_CAST(&gcm->PC[x][I[x]][y])); + } +#else + for (y = 0; y < 16; y++) { + T[y] ^= gcm->PC[x][I[x]][y]; + } +#endif /* LTC_FAST */ + } +#endif /* LTC_GCM_TABLES_SSE2 */ +#else + gcm_gf_mult(gcm->H, I, T); +#endif + XMEMCPY(I, T, 16); +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/encauth/gcm/gcm_process.c b/src/ltc/encauth/gcm/gcm_process.c new file mode 100644 index 0000000..4116db8 --- /dev/null +++ b/src/ltc/encauth/gcm/gcm_process.c @@ -0,0 +1,157 @@ +/* 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://libtom.org + */ + +/** + @file gcm_process.c + GCM implementation, process message data, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_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; + int y, err; + unsigned char b; + + LTC_ARGCHK(gcm != NULL); + if (ptlen > 0) { + 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; + } + + /* 0xFFFFFFFE0 = ((2^39)-256)/8 */ + if (gcm->pttotlen / 8 + (ulong64)gcm->buflen + (ulong64)ptlen >= CONST64(0xFFFFFFFE0)) { + return CRYPT_INVALID_ARG; + } + + /* in AAD mode? */ + if (gcm->mode == LTC_GCM_MODE_AAD) { + /* let's process the AAD */ + if (gcm->buflen) { + gcm->totlen += gcm->buflen * CONST64(8); + gcm_mult_h(gcm, gcm->X); + } + + /* increment counter */ + for (y = 15; y >= 12; y--) { + if (++gcm->Y[y] & 255) { break; } + } + /* encrypt the counter */ + if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) { + return err; + } + + gcm->buflen = 0; + gcm->mode = LTC_GCM_MODE_TEXT; + } + + if (gcm->mode != LTC_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_PTR_CAST(&ct[x + y])) = *(LTC_FAST_TYPE_PTR_CAST(&pt[x+y])) ^ *(LTC_FAST_TYPE_PTR_CAST(&gcm->buf[y])); + *(LTC_FAST_TYPE_PTR_CAST(&gcm->X[y])) ^= *(LTC_FAST_TYPE_PTR_CAST(&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] & 255) { break; } + } + if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) { + return err; + } + } + } else { + for (x = 0; x < (ptlen & ~15); x += 16) { + /* ctr encrypt */ + for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { + *(LTC_FAST_TYPE_PTR_CAST(&gcm->X[y])) ^= *(LTC_FAST_TYPE_PTR_CAST(&ct[x+y])); + *(LTC_FAST_TYPE_PTR_CAST(&pt[x + y])) = *(LTC_FAST_TYPE_PTR_CAST(&ct[x+y])) ^ *(LTC_FAST_TYPE_PTR_CAST(&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] & 255) { break; } + } + if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) { + return err; + } + } + } + } +#endif + + /* process text */ + for (; x < ptlen; x++) { + if (gcm->buflen == 16) { + gcm->pttotlen += 128; + gcm_mult_h(gcm, gcm->X); + + /* increment counter */ + for (y = 15; y >= 12; y--) { + if (++gcm->Y[y] & 255) { break; } + } + if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) { + return err; + } + 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->X[gcm->buflen++] ^= b; + } + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/encauth/gcm/gcm_reset.c b/src/ltc/encauth/gcm/gcm_reset.c new file mode 100644 index 0000000..f9596b4 --- /dev/null +++ b/src/ltc/encauth/gcm/gcm_reset.c @@ -0,0 +1,44 @@ +/* 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://libtom.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 LTC_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 = LTC_GCM_MODE_IV; + gcm->ivmode = 0; + gcm->buflen = 0; + gcm->totlen = 0; + gcm->pttotlen = 0; + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/encauth/ocb3/ocb3_add_aad.c b/src/ltc/encauth/ocb3/ocb3_add_aad.c new file mode 100644 index 0000000..88f4d08 --- /dev/null +++ b/src/ltc/encauth/ocb3/ocb3_add_aad.c @@ -0,0 +1,81 @@ +/* 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. + */ + +/** + @file ocb3_add_aad.c + OCB implementation, add AAD data, by Karel Miko +*/ +#include "tomcrypt.h" + +#ifdef LTC_OCB3_MODE + +/** + Add AAD - additional associated data + @param ocb The OCB state + @param aad The AAD data + @param aadlen The size of AAD data (octets) + @return CRYPT_OK if successful +*/ +int ocb3_add_aad(ocb3_state *ocb, const unsigned char *aad, unsigned long aadlen) +{ + int err, x, full_blocks, full_blocks_len, last_block_len; + unsigned char *data; + unsigned long datalen, l; + + LTC_ARGCHK(ocb != NULL); + LTC_ARGCHK(aad != NULL); + + if (aadlen == 0) return CRYPT_OK; + + if (ocb->adata_buffer_bytes > 0) { + l = ocb->block_len - ocb->adata_buffer_bytes; + if (l > aadlen) l = aadlen; + XMEMCPY(ocb->adata_buffer+ocb->adata_buffer_bytes, aad, l); + ocb->adata_buffer_bytes += l; + + if (ocb->adata_buffer_bytes == ocb->block_len) { + if ((err = ocb3_int_aad_add_block(ocb, ocb->adata_buffer)) != CRYPT_OK) { + return err; + } + ocb->adata_buffer_bytes = 0; + } + + data = (unsigned char *)aad + l; + datalen = aadlen - l; + } + else { + data = (unsigned char *)aad; + datalen = aadlen; + } + + if (datalen == 0) return CRYPT_OK; + + full_blocks = datalen/ocb->block_len; + full_blocks_len = full_blocks * ocb->block_len; + last_block_len = datalen - full_blocks_len; + + for (x=0; xblock_len)) != CRYPT_OK) { + return err; + } + } + + if (last_block_len>0) { + XMEMCPY(ocb->adata_buffer, data+full_blocks_len, last_block_len); + ocb->adata_buffer_bytes = last_block_len; + } + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/encauth/ocb3/ocb3_decrypt.c b/src/ltc/encauth/ocb3/ocb3_decrypt.c new file mode 100644 index 0000000..24d6ad1 --- /dev/null +++ b/src/ltc/encauth/ocb3/ocb3_decrypt.c @@ -0,0 +1,86 @@ +/* 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://libtom.org + */ + +/** + @file ocb3_decrypt.c + OCB implementation, decrypt data, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_OCB3_MODE + +/** + Decrypt blocks of ciphertext with OCB + @param ocb The OCB state + @param ct The ciphertext (length multiple of the block size of the block cipher) + @param ctlen The length of the input (octets) + @param pt [out] The plaintext (length of ct) + @return CRYPT_OK if successful +*/ +int ocb3_decrypt(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt) +{ + unsigned char tmp[MAXBLOCKSIZE]; + int err, i, full_blocks; + unsigned char *pt_b, *ct_b; + + LTC_ARGCHK(ocb != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) { + return err; + } + if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) { + return CRYPT_INVALID_ARG; + } + + if (ctlen % ocb->block_len) { /* ctlen has to bu multiple of block_len */ + return CRYPT_INVALID_ARG; + } + + full_blocks = ctlen/ocb->block_len; + for(i=0; iblock_len; + ct_b = (unsigned char *)ct+i*ocb->block_len; + + /* ocb->Offset_current[] = ocb->Offset_current[] ^ Offset_{ntz(block_index)} */ + ocb3_int_xor_blocks(ocb->Offset_current, ocb->Offset_current, ocb->L_[ocb3_int_ntz(ocb->block_index)], ocb->block_len); + + /* tmp[] = ct[] XOR ocb->Offset_current[] */ + ocb3_int_xor_blocks(tmp, ct_b, ocb->Offset_current, ocb->block_len); + + /* decrypt */ + if ((err = cipher_descriptor[ocb->cipher].ecb_decrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* pt[] = tmp[] XOR ocb->Offset_current[] */ + ocb3_int_xor_blocks(pt_b, tmp, ocb->Offset_current, ocb->block_len); + + /* ocb->checksum[] = ocb->checksum[] XOR pt[] */ + ocb3_int_xor_blocks(ocb->checksum, ocb->checksum, pt_b, ocb->block_len); + + ocb->block_index++; + } + + err = CRYPT_OK; + +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(tmp, sizeof(tmp)); +#endif + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/encauth/ocb3/ocb3_decrypt_last.c b/src/ltc/encauth/ocb3/ocb3_decrypt_last.c new file mode 100644 index 0000000..a932d53 --- /dev/null +++ b/src/ltc/encauth/ocb3/ocb3_decrypt_last.c @@ -0,0 +1,105 @@ +/* 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. + */ + +/** + @file ocb3_decrypt_last.c + OCB implementation, internal helper, by Karel Miko +*/ +#include "tomcrypt.h" + +#ifdef LTC_OCB3_MODE + +/** + Finish an OCB (decryption) stream + @param ocb The OCB state + @param ct The remaining ciphertext + @param ctlen The length of the ciphertext (octets) + @param pt [out] The output buffer + @return CRYPT_OK if successful +*/ +int ocb3_decrypt_last(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt) +{ + unsigned char iOffset_star[MAXBLOCKSIZE]; + unsigned char iPad[MAXBLOCKSIZE]; + int err, x, full_blocks, full_blocks_len, last_block_len; + + LTC_ARGCHK(ocb != NULL); + LTC_ARGCHK(ct != NULL); + if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) { + goto LBL_ERR; + } + + full_blocks = ctlen/ocb->block_len; + full_blocks_len = full_blocks * ocb->block_len; + last_block_len = ctlen - full_blocks_len; + + /* process full blocks first */ + if (full_blocks>0) { + if ((err = ocb3_decrypt(ocb, ct, full_blocks_len, pt)) != CRYPT_OK) { + goto LBL_ERR; + } + } + + if (last_block_len>0) { + /* Offset_* = Offset_m xor L_* */ + ocb3_int_xor_blocks(iOffset_star, ocb->Offset_current, ocb->L_star, ocb->block_len); + + /* Pad = ENCIPHER(K, Offset_*) */ + if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(iOffset_star, iPad, &ocb->key)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* P_* = C_* xor Pad[1..bitlen(C_*)] */ + ocb3_int_xor_blocks(pt+full_blocks_len, (unsigned char *)ct+full_blocks_len, iPad, last_block_len); + + /* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */ + ocb3_int_xor_blocks(ocb->checksum, ocb->checksum, pt+full_blocks_len, last_block_len); + for(x=last_block_len; xblock_len; x++) { + if (x == last_block_len) + ocb->checksum[x] ^= 0x80; + else + ocb->checksum[x] ^= 0x00; + } + + /* Tag = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) xor HASH(K,A) */ + /* at this point we calculate only: Tag_part = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) */ + for(x=0; xblock_len; x++) { + ocb->tag_part[x] = (ocb->checksum[x] ^ iOffset_star[x]) ^ ocb->L_dollar[x]; + } + if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) { + goto LBL_ERR; + } + } + else { + /* Tag = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) xor HASH(K,A) */ + /* at this point we calculate only: Tag_part = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) */ + for(x=0; xblock_len; x++) { + ocb->tag_part[x] = (ocb->checksum[x] ^ ocb->Offset_current[x]) ^ ocb->L_dollar[x]; + } + if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) { + goto LBL_ERR; + } + } + + err = CRYPT_OK; + +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(iOffset_star, MAXBLOCKSIZE); + zeromem(iPad, MAXBLOCKSIZE); +#endif + + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/encauth/ocb3/ocb3_decrypt_verify_memory.c b/src/ltc/encauth/ocb3/ocb3_decrypt_verify_memory.c new file mode 100644 index 0000000..ce8fe9c --- /dev/null +++ b/src/ltc/encauth/ocb3/ocb3_decrypt_verify_memory.c @@ -0,0 +1,112 @@ +/* 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://libtom.org + */ + +/** + @file ocb3_decrypt_verify_memory.c + OCB implementation, helper to decrypt block of memory, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_OCB3_MODE + +/** + Decrypt and compare the tag with OCB + @param cipher The index of the cipher desired + @param key The secret key + @param keylen The length of the secret key (octets) + @param nonce The session nonce (length of the block size of the block cipher) + @param noncelen The length of the nonce (octets) + @param adata The AAD - additional associated data + @param adatalen The length of AAD (octets) + @param ct The ciphertext + @param ctlen The length of the ciphertext (octets) + @param pt [out] The plaintext + @param tag The tag to compare against + @param taglen The length of the tag (octets) + @param stat [out] The result of the tag comparison (1==valid, 0==invalid) + @return CRYPT_OK if successful regardless of the tag comparison +*/ +int ocb3_decrypt_verify_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *adata, unsigned long adatalen, + const unsigned char *ct, unsigned long ctlen, + unsigned char *pt, + const unsigned char *tag, unsigned long taglen, + int *stat) +{ + int err; + ocb3_state *ocb; + unsigned char *buf; + unsigned long buflen; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(nonce != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(tag != NULL); + LTC_ARGCHK(stat != NULL); + + /* default to zero */ + *stat = 0; + + /* allocate memory */ + buf = XMALLOC(taglen); + ocb = XMALLOC(sizeof(ocb3_state)); + if (ocb == NULL || buf == NULL) { + if (ocb != NULL) { + XFREE(ocb); + } + if (buf != NULL) { + XFREE(buf); + } + return CRYPT_MEM; + } + + if ((err = ocb3_init(ocb, cipher, key, keylen, nonce, noncelen)) != CRYPT_OK) { + goto LBL_ERR; + } + + if ((err = ocb3_add_aad(ocb, adata, adatalen)) != CRYPT_OK) { + goto LBL_ERR; + } + + if ((err = ocb3_decrypt_last(ocb, ct, ctlen, pt)) != CRYPT_OK) { + goto LBL_ERR; + } + + buflen = taglen; + if ((err = ocb3_done(ocb, buf, &buflen)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* compare tags */ + if (buflen >= taglen && XMEMCMP(buf, tag, taglen) == 0) { + *stat = 1; + } + + err = CRYPT_OK; + +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(ocb, sizeof(ocb3_state)); +#endif + + XFREE(ocb); + XFREE(buf); + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/encauth/ocb3/ocb3_done.c b/src/ltc/encauth/ocb3/ocb3_done.c new file mode 100644 index 0000000..4102d9c --- /dev/null +++ b/src/ltc/encauth/ocb3/ocb3_done.c @@ -0,0 +1,92 @@ +/* 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://libtom.org + */ + +/** + @file ocb3_done.c + OCB implementation, INTERNAL ONLY helper, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_OCB3_MODE + +/** + Finish OCB processing and compute the tag + @param ocb The OCB state + @param tag [out] The destination for the authentication tag + @param taglen [in/out] The max size and resulting size of the authentication tag + @return CRYPT_OK if successful +*/ +int ocb3_done(ocb3_state *ocb, unsigned char *tag, unsigned long *taglen) +{ + unsigned char tmp[MAXBLOCKSIZE]; + int err, x; + + LTC_ARGCHK(ocb != NULL); + LTC_ARGCHK(tag != NULL); + LTC_ARGCHK(taglen != NULL); + if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* finalize AAD processing */ + + if (ocb->adata_buffer_bytes>0) { + /* Offset_* = Offset_m xor L_* */ + ocb3_int_xor_blocks(ocb->aOffset_current, ocb->aOffset_current, ocb->L_star, ocb->block_len); + + /* CipherInput = (A_* || 1 || zeros(127-bitlen(A_*))) xor Offset_* */ + ocb3_int_xor_blocks(tmp, ocb->adata_buffer, ocb->aOffset_current, ocb->adata_buffer_bytes); + for(x=ocb->adata_buffer_bytes; xblock_len; x++) { + if (x == ocb->adata_buffer_bytes) { + tmp[x] = 0x80 ^ ocb->aOffset_current[x]; + } + else { + tmp[x] = 0x00 ^ ocb->aOffset_current[x]; + } + } + + /* Sum = Sum_m xor ENCIPHER(K, CipherInput) */ + if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) { + goto LBL_ERR; + } + ocb3_int_xor_blocks(ocb->aSum_current, ocb->aSum_current, tmp, ocb->block_len); + } + + /* finalize TAG computing */ + + /* at this point ocb->aSum_current = HASH(K, A) */ + /* tag = tag ^ HASH(K, A) */ + ocb3_int_xor_blocks(tmp, ocb->tag_part, ocb->aSum_current, ocb->block_len); + + /* fix taglen if needed */ + if ((int)*taglen > ocb->block_len) { + *taglen = (unsigned long)ocb->block_len; + } + + /* copy tag bytes */ + for(x=0; x<(int)*taglen; x++) tag[x] = tmp[x]; + + err = CRYPT_OK; + +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(tmp, MAXBLOCKSIZE); + zeromem(ocb, sizeof(*ocb)); +#endif + + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/encauth/ocb3/ocb3_encrypt.c b/src/ltc/encauth/ocb3/ocb3_encrypt.c new file mode 100644 index 0000000..1450478 --- /dev/null +++ b/src/ltc/encauth/ocb3/ocb3_encrypt.c @@ -0,0 +1,86 @@ +/* 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://libtom.org + */ + +/** + @file ocb3_encrypt.c + OCB implementation, encrypt data, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_OCB3_MODE + +/** + Encrypt blocks of data with OCB + @param ocb The OCB state + @param pt The plaintext (length multiple of the block size of the block cipher) + @param ptlen The length of the input (octets) + @param ct [out] The ciphertext (same size as the pt) + @return CRYPT_OK if successful +*/ +int ocb3_encrypt(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct) +{ + unsigned char tmp[MAXBLOCKSIZE]; + int err, i, full_blocks; + unsigned char *pt_b, *ct_b; + + LTC_ARGCHK(ocb != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) { + return err; + } + if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) { + return CRYPT_INVALID_ARG; + } + + if (ptlen % ocb->block_len) { /* ptlen has to bu multiple of block_len */ + return CRYPT_INVALID_ARG; + } + + full_blocks = ptlen/ocb->block_len; + for(i=0; iblock_len; + ct_b = (unsigned char *)ct+i*ocb->block_len; + + /* ocb->Offset_current[] = ocb->Offset_current[] ^ Offset_{ntz(block_index)} */ + ocb3_int_xor_blocks(ocb->Offset_current, ocb->Offset_current, ocb->L_[ocb3_int_ntz(ocb->block_index)], ocb->block_len); + + /* tmp[] = pt[] XOR ocb->Offset_current[] */ + ocb3_int_xor_blocks(tmp, pt_b, ocb->Offset_current, ocb->block_len); + + /* encrypt */ + if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* ct[] = tmp[] XOR ocb->Offset_current[] */ + ocb3_int_xor_blocks(ct_b, tmp, ocb->Offset_current, ocb->block_len); + + /* ocb->checksum[] = ocb->checksum[] XOR pt[] */ + ocb3_int_xor_blocks(ocb->checksum, ocb->checksum, pt_b, ocb->block_len); + + ocb->block_index++; + } + + err = CRYPT_OK; + +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(tmp, sizeof(tmp)); +#endif + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/encauth/ocb3/ocb3_encrypt_authenticate_memory.c b/src/ltc/encauth/ocb3/ocb3_encrypt_authenticate_memory.c new file mode 100644 index 0000000..60264a2 --- /dev/null +++ b/src/ltc/encauth/ocb3/ocb3_encrypt_authenticate_memory.c @@ -0,0 +1,87 @@ +/* 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://libtom.org + */ + +/** + @file ocb3_encrypt_authenticate_memory.c + OCB implementation, encrypt block of memory, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_OCB3_MODE + +/** + Encrypt and generate an authentication code for a buffer of memory + @param cipher The index of the cipher desired + @param key The secret key + @param keylen The length of the secret key (octets) + @param nonce The session nonce (length of the block ciphers block size) + @param noncelen The length of the nonce (octets) + @param adata The AAD - additional associated data + @param adatalen The length of AAD (octets) + @param pt The plaintext + @param ptlen The length of the plaintext (octets) + @param ct [out] The ciphertext + @param tag [out] The authentication tag + @param taglen [in/out] The max size and resulting size of the authentication tag + @return CRYPT_OK if successful +*/ +int ocb3_encrypt_authenticate_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *adata, unsigned long adatalen, + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen) +{ + int err; + ocb3_state *ocb; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(nonce != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(tag != NULL); + LTC_ARGCHK(taglen != NULL); + + /* allocate memory */ + ocb = XMALLOC(sizeof(ocb3_state)); + if (ocb == NULL) { + return CRYPT_MEM; + } + + if ((err = ocb3_init(ocb, cipher, key, keylen, nonce, noncelen)) != CRYPT_OK) { + goto LBL_ERR; + } + + if ((err = ocb3_add_aad(ocb, adata, adatalen)) != CRYPT_OK) { + goto LBL_ERR; + } + + if ((err = ocb3_encrypt_last(ocb, pt, ptlen, ct)) != CRYPT_OK) { + goto LBL_ERR; + } + + err = ocb3_done(ocb, tag, taglen); + +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(ocb, sizeof(ocb3_state)); +#endif + + XFREE(ocb); + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/encauth/ocb3/ocb3_encrypt_last.c b/src/ltc/encauth/ocb3/ocb3_encrypt_last.c new file mode 100644 index 0000000..b21cfae --- /dev/null +++ b/src/ltc/encauth/ocb3/ocb3_encrypt_last.c @@ -0,0 +1,107 @@ +/* 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. + */ + +/** + @file ocb3_encrypt_last.c + OCB implementation, internal helper, by Karel Miko +*/ +#include "tomcrypt.h" + +#ifdef LTC_OCB3_MODE + +/** + Finish an OCB (encryption) stream + @param ocb The OCB state + @param pt The remaining plaintext + @param ptlen The length of the plaintext (octets) + @param ct [out] The output buffer + @return CRYPT_OK if successful +*/ +int ocb3_encrypt_last(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct) +{ + unsigned char iOffset_star[MAXBLOCKSIZE]; + unsigned char iPad[MAXBLOCKSIZE]; + int err, x, full_blocks, full_blocks_len, last_block_len; + + LTC_ARGCHK(ocb != NULL); + LTC_ARGCHK(pt != NULL); + if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) { + goto LBL_ERR; + } + + full_blocks = ptlen/ocb->block_len; + full_blocks_len = full_blocks * ocb->block_len; + last_block_len = ptlen - full_blocks_len; + + /* process full blocks first */ + if (full_blocks>0) { + if ((err = ocb3_encrypt(ocb, pt, full_blocks_len, ct)) != CRYPT_OK) { + goto LBL_ERR; + } + } + + /* at this point: m = ocb->block_index (last block index), Offset_m = ocb->Offset_current */ + + if (last_block_len>0) { + /* Offset_* = Offset_m xor L_* */ + ocb3_int_xor_blocks(iOffset_star, ocb->Offset_current, ocb->L_star, ocb->block_len); + + /* Pad = ENCIPHER(K, Offset_*) */ + if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(iOffset_star, iPad, &ocb->key)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* C_* = P_* xor Pad[1..bitlen(P_*)] */ + ocb3_int_xor_blocks(ct+full_blocks_len, pt+full_blocks_len, iPad, last_block_len); + + /* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */ + ocb3_int_xor_blocks(ocb->checksum, ocb->checksum, pt+full_blocks_len, last_block_len); + for(x=last_block_len; xblock_len; x++) { + if (x == last_block_len) + ocb->checksum[x] ^= 0x80; + else + ocb->checksum[x] ^= 0x00; + } + + /* Tag = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) xor HASH(K,A) */ + /* at this point we calculate only: Tag_part = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) */ + for(x=0; xblock_len; x++) { + ocb->tag_part[x] = (ocb->checksum[x] ^ iOffset_star[x]) ^ ocb->L_dollar[x]; + } + if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) { + goto LBL_ERR; + } + } + else { + /* Tag = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) xor HASH(K,A) */ + /* at this point we calculate only: Tag_part = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) */ + for(x=0; xblock_len; x++) { + ocb->tag_part[x] = (ocb->checksum[x] ^ ocb->Offset_current[x]) ^ ocb->L_dollar[x]; + } + if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) { + goto LBL_ERR; + } + } + + err = CRYPT_OK; + +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(iOffset_star, MAXBLOCKSIZE); + zeromem(iPad, MAXBLOCKSIZE); +#endif + + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/encauth/ocb3/ocb3_init.c b/src/ltc/encauth/ocb3/ocb3_init.c new file mode 100644 index 0000000..c73cb96 --- /dev/null +++ b/src/ltc/encauth/ocb3/ocb3_init.c @@ -0,0 +1,138 @@ +/* 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://libtom.org + */ + +/** + @file ocb3_init.c + OCB implementation, initialize state, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_OCB3_MODE + +static const struct { + int len; + unsigned char poly_div[MAXBLOCKSIZE], + poly_mul[MAXBLOCKSIZE]; +} polys[] = { +{ + 8, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B } +}, { + 16, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 } +} +}; + +/** + Initialize an OCB context + @param ocb [out] The destination of the OCB state + @param cipher The index of the desired cipher + @param key The secret key + @param keylen The length of the secret key (octets) + @param nonce The session nonce + @param noncelen The length of the session nonce (octets) + @return CRYPT_OK if successful +*/ +int ocb3_init(ocb3_state *ocb, int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen) +{ + int poly, x, y, m, err; + unsigned char *previous, *current; + + LTC_ARGCHK(ocb != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(nonce != NULL); + + /* valid cipher? */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + ocb->cipher = cipher; + + /* determine which polys to use */ + ocb->block_len = cipher_descriptor[cipher].block_length; + x = (int)(sizeof(polys)/sizeof(polys[0])); + for (poly = 0; poly < x; poly++) { + if (polys[poly].len == ocb->block_len) { + break; + } + } + if (poly == x) { + return CRYPT_INVALID_ARG; /* block_len not found in polys */ + } + if (polys[poly].len != ocb->block_len) { + return CRYPT_INVALID_ARG; + } + + /* schedule the key */ + if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &ocb->key)) != CRYPT_OK) { + return err; + } + + /* L_* = ENCIPHER(K, zeros(128)) */ + zeromem(ocb->L_star, ocb->block_len); + if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->L_star, ocb->L_star, &ocb->key)) != CRYPT_OK) { + return err; + } + + /* compute L_$, L_0, L_1, ... */ + for (x = -1; x < 32; x++) { + if (x == -1) { /* gonna compute: L_$ = double(L_*) */ + current = ocb->L_dollar; + previous = ocb->L_star; + } + else if (x == 0) { /* gonna compute: L_0 = double(L_$) */ + current = ocb->L_[0]; + previous = ocb->L_dollar; + } + else { /* gonna compute: L_i = double(L_{i-1}) for every integer i > 0 */ + current = ocb->L_[x]; + previous = ocb->L_[x-1]; + } + m = previous[0] >> 7; + for (y = 0; y < ocb->block_len-1; y++) { + current[y] = ((previous[y] << 1) | (previous[y+1] >> 7)) & 255; + } + current[ocb->block_len-1] = (previous[ocb->block_len-1] << 1) & 255; + if (m == 1) { + /* current[] = current[] XOR polys[poly].poly_mul[]*/ + ocb3_int_xor_blocks(current, current, polys[poly].poly_mul, ocb->block_len); + } + } + + /* initialize ocb->Offset_current = Offset_0 */ + ocb3_int_calc_offset_zero(ocb, nonce, noncelen); + + /* initialize checksum to all zeros */ + zeromem(ocb->checksum, ocb->block_len); + + /* set block index */ + ocb->block_index = 1; + + /* initialize AAD related stuff */ + ocb->ablock_index = 1; + ocb->adata_buffer_bytes = 0; + zeromem(ocb->aOffset_current, ocb->block_len); + zeromem(ocb->aSum_current, ocb->block_len); + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/encauth/ocb3/ocb3_int_aad_add_block.c b/src/ltc/encauth/ocb3/ocb3_int_aad_add_block.c new file mode 100644 index 0000000..0b7d8f7 --- /dev/null +++ b/src/ltc/encauth/ocb3/ocb3_int_aad_add_block.c @@ -0,0 +1,49 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ + +/** + @file ocb3_int_aad_add_block.c + OCB implementation, INTERNALL ONLY helper, by Karel Miko +*/ +#include "tomcrypt.h" + +#ifdef LTC_OCB3_MODE + +/** + Add one block of AAD data (internal function) + @param ocb The OCB state + @param aad_block [in] AAD data (block_len size) + @return CRYPT_OK if successful +*/ +int ocb3_int_aad_add_block(ocb3_state *ocb, const unsigned char *aad_block) +{ + unsigned char tmp[MAXBLOCKSIZE]; + int err; + + /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ + ocb3_int_xor_blocks(ocb->aOffset_current, ocb->aOffset_current, ocb->L_[ocb3_int_ntz(ocb->ablock_index)], ocb->block_len); + + /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ + ocb3_int_xor_blocks(tmp, aad_block, ocb->aOffset_current, ocb->block_len); + if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) { + return err; + } + ocb3_int_xor_blocks(ocb->aSum_current, ocb->aSum_current, tmp, ocb->block_len); + + ocb->ablock_index++; + + return CRYPT_OK; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/encauth/ocb3/ocb3_int_calc_offset_zero.c b/src/ltc/encauth/ocb3/ocb3_int_calc_offset_zero.c new file mode 100644 index 0000000..93b171f --- /dev/null +++ b/src/ltc/encauth/ocb3/ocb3_int_calc_offset_zero.c @@ -0,0 +1,72 @@ +/* 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. + */ + +/** + @file ocb3_int_calc_offset_zero.c + OCB implementation, INTERNAL ONLY helper, by Karel Miko +*/ +#include "tomcrypt.h" + +#ifdef LTC_OCB3_MODE + +/** + Sets 'ocb->Offset_current' to 'Offset_0' value (internal function) + @param ocb The OCB state + @param nonce The session nonce + @param noncelen The length of the session nonce (octets) +*/ +void ocb3_int_calc_offset_zero(ocb3_state *ocb, const unsigned char *nonce, unsigned long noncelen) +{ + int x, y, bottom; + int idx, shift; + unsigned char iNonce[MAXBLOCKSIZE]; + unsigned char iKtop[MAXBLOCKSIZE]; + unsigned char iStretch[MAXBLOCKSIZE+8]; + + /* Nonce = zeros(127-bitlen(N)) || 1 || N */ + zeromem(iNonce, sizeof(iNonce)); + for (x = ocb->block_len-1, y=0; y<(int)noncelen; x--, y++) { + iNonce[x] = nonce[noncelen-y-1]; + } + iNonce[x] = 0x01; + + /* bottom = str2num(Nonce[123..128]) */ + bottom = iNonce[ocb->block_len-1] & 0x3F; + + /* Ktop = ENCIPHER(K, Nonce[1..122] || zeros(6)) */ + iNonce[ocb->block_len-1] = iNonce[ocb->block_len-1] & 0xC0; + if ((cipher_descriptor[ocb->cipher].ecb_encrypt(iNonce, iKtop, &ocb->key)) != CRYPT_OK) { + zeromem(ocb->Offset_current, ocb->block_len); + return; + } + + /* Stretch = Ktop || (Ktop[1..64] xor Ktop[9..72]) */ + for (x = 0; x < ocb->block_len; x++) { + iStretch[x] = iKtop[x]; + } + for (y = 0; y < 8; y++) { + iStretch[x+y] = iKtop[y] ^ iKtop[y+1]; + } + + /* Offset_0 = Stretch[1+bottom..128+bottom] */ + idx = bottom / 8; + shift = (bottom % 8); + for (x = 0; x < ocb->block_len; x++) { + ocb->Offset_current[x] = iStretch[idx+x] << shift; + if (shift > 0) { + ocb->Offset_current[x] |= iStretch[idx+x+1] >> (8-shift); + } + } +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/encauth/ocb3/ocb3_int_ntz.c b/src/ltc/encauth/ocb3/ocb3_int_ntz.c new file mode 100644 index 0000000..48239fe --- /dev/null +++ b/src/ltc/encauth/ocb3/ocb3_int_ntz.c @@ -0,0 +1,41 @@ +/* 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://libtom.org + */ + +/** + @file ocb3_int_ntz.c + OCB implementation, INTERNAL ONLY helper, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef LTC_OCB3_MODE + +/** + Returns the number of leading zero bits [from lsb up] (internal function) + @param x The 32-bit value to observe + @return The number of bits [from the lsb up] that are zero +*/ +int ocb3_int_ntz(unsigned long x) +{ + int c; + x &= 0xFFFFFFFFUL; + c = 0; + while ((x & 1) == 0) { + ++c; + x >>= 1; + } + return c; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/encauth/ocb3/ocb3_int_xor_blocks.c b/src/ltc/encauth/ocb3/ocb3_int_xor_blocks.c new file mode 100644 index 0000000..92eb293 --- /dev/null +++ b/src/ltc/encauth/ocb3/ocb3_int_xor_blocks.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. + */ + +/** + @file ocb3_int_xor_blocks.c + OCB implementation, INTERNAL ONLY helper, by Karel Miko +*/ +#include "tomcrypt.h" + +#ifdef LTC_OCB3_MODE + +/** + Compute xor for two blocks of bytes 'out = block_a XOR block_b' (internal function) + @param out The block of bytes (output) + @param block_a The block of bytes (input) + @param block_b The block of bytes (input) + @param block_len The size of block_a, block_b, out +*/ +void ocb3_int_xor_blocks(unsigned char *out, const unsigned char *block_a, const unsigned char *block_b, unsigned long block_len) +{ + int x; + if (out == block_a) { + for (x = 0; x < (int)block_len; x++) out[x] ^= block_b[x]; + } + else { + for (x = 0; x < (int)block_len; x++) out[x] = block_a[x] ^ block_b[x]; + } +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/hashes/blake2b.c b/src/ltc/hashes/blake2b.c new file mode 100644 index 0000000..b01f63e --- /dev/null +++ b/src/ltc/hashes/blake2b.c @@ -0,0 +1,580 @@ +/* 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. + */ + +/* + BLAKE2 reference source code package - reference C implementations + + Copyright 2012, Samuel Neves . You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ +/* see also https://www.ietf.org/rfc/rfc7693.txt */ + +#include "tomcrypt.h" + +#ifdef LTC_BLAKE2B + +enum blake2b_constant { + BLAKE2B_BLOCKBYTES = 128, + BLAKE2B_OUTBYTES = 64, + BLAKE2B_KEYBYTES = 64, + BLAKE2B_SALTBYTES = 16, + BLAKE2B_PERSONALBYTES = 16, + BLAKE2B_PARAM_SIZE = 64 +}; + +/* param offsets */ +enum { + O_DIGEST_LENGTH = 0, + O_KEY_LENGTH = 1, + O_FANOUT = 2, + O_DEPTH = 3, + O_LEAF_LENGTH = 4, + O_NODE_OFFSET = 8, + O_XOF_LENGTH = 12, + O_NODE_DEPTH = 16, + O_INNER_LENGTH = 17, + O_RESERVED = 18, + O_SALT = 32, + O_PERSONAL = 48 +}; + +/* +struct blake2b_param { + unsigned char digest_length; + unsigned char key_length; + unsigned char fanout; + unsigned char depth; + ulong32 leaf_length; + ulong32 node_offset; + ulong32 xof_length; + unsigned char node_depth; + unsigned char inner_length; + unsigned char reserved[14]; + unsigned char salt[BLAKE2B_SALTBYTES]; + unsigned char personal[BLAKE2B_PERSONALBYTES]; +}; +*/ + +const struct ltc_hash_descriptor blake2b_160_desc = +{ + "blake2b-160", + 25, + 20, + 128, + { 1, 3, 6, 1, 4, 1, 1722, 12, 2, 1, 5 }, + 11, + &blake2b_160_init, + &blake2b_process, + &blake2b_done, + &blake2b_160_test, + NULL +}; + +const struct ltc_hash_descriptor blake2b_256_desc = +{ + "blake2b-256", + 26, + 32, + 128, + { 1, 3, 6, 1, 4, 1, 1722, 12, 2, 1, 8 }, + 11, + &blake2b_256_init, + &blake2b_process, + &blake2b_done, + &blake2b_256_test, + NULL +}; + +const struct ltc_hash_descriptor blake2b_384_desc = +{ + "blake2b-384", + 27, + 48, + 128, + { 1, 3, 6, 1, 4, 1, 1722, 12, 2, 1, 12 }, + 11, + &blake2b_384_init, + &blake2b_process, + &blake2b_done, + &blake2b_384_test, + NULL +}; + +const struct ltc_hash_descriptor blake2b_512_desc = +{ + "blake2b-512", + 28, + 64, + 128, + { 1, 3, 6, 1, 4, 1, 1722, 12, 2, 1, 16 }, + 11, + &blake2b_512_init, + &blake2b_process, + &blake2b_done, + &blake2b_512_test, + NULL +}; + +static const ulong64 blake2b_IV[8] = +{ + CONST64(0x6a09e667f3bcc908), CONST64(0xbb67ae8584caa73b), + CONST64(0x3c6ef372fe94f82b), CONST64(0xa54ff53a5f1d36f1), + CONST64(0x510e527fade682d1), CONST64(0x9b05688c2b3e6c1f), + CONST64(0x1f83d9abfb41bd6b), CONST64(0x5be0cd19137e2179) +}; + +static const unsigned char blake2b_sigma[12][16] = +{ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } +}; + +static void blake2b_set_lastnode(hash_state *md) { md->blake2b.f[1] = CONST64(0xffffffffffffffff); } + +/* Some helper functions, not necessarily useful */ +static int blake2b_is_lastblock(const hash_state *md) { return md->blake2b.f[0] != 0; } + +static void blake2b_set_lastblock(hash_state *md) +{ + if (md->blake2b.last_node) + blake2b_set_lastnode(md); + + md->blake2b.f[0] = CONST64(0xffffffffffffffff); +} + +static void blake2b_increment_counter(hash_state *md, ulong64 inc) +{ + md->blake2b.t[0] += inc; + if (md->blake2b.t[0] < inc) md->blake2b.t[1]++; +} + +static void blake2b_init0(hash_state *md) +{ + unsigned long i; + XMEMSET(&md->blake2b, 0, sizeof(md->blake2b)); + + for (i = 0; i < 8; ++i) + md->blake2b.h[i] = blake2b_IV[i]; +} + +/* init xors IV with input parameter block */ +static int blake2b_init_param(hash_state *md, const unsigned char *P) +{ + unsigned long i; + + blake2b_init0(md); + + /* IV XOR ParamBlock */ + for (i = 0; i < 8; ++i) { + ulong64 tmp; + LOAD64L(tmp, P + i * 8); + md->blake2b.h[i] ^= tmp; + } + + md->blake2b.outlen = P[O_DIGEST_LENGTH]; + return CRYPT_OK; +} + +int blake2b_init(hash_state *md, unsigned long outlen, const unsigned char *key, unsigned long keylen) +{ + unsigned char P[BLAKE2B_PARAM_SIZE]; + int err; + + LTC_ARGCHK(md != NULL); + + if ((!outlen) || (outlen > BLAKE2B_OUTBYTES)) + return CRYPT_INVALID_ARG; + + if ((key && !keylen) || (keylen && !key) || (keylen > BLAKE2B_KEYBYTES)) + return CRYPT_INVALID_ARG; + + XMEMSET(P, 0, sizeof(P)); + + P[O_DIGEST_LENGTH] = (unsigned char)outlen; + P[O_KEY_LENGTH] = (unsigned char)keylen; + P[O_FANOUT] = 1; + P[O_DEPTH] = 1; + + err = blake2b_init_param(md, P); + if (err != CRYPT_OK) return err; + + if (key) { + unsigned char block[BLAKE2B_BLOCKBYTES]; + + XMEMSET(block, 0, BLAKE2B_BLOCKBYTES); + XMEMCPY(block, key, keylen); + blake2b_process(md, block, BLAKE2B_BLOCKBYTES); + +#ifdef LTC_CLEAN_STACK + zeromem(block, sizeof(block)); +#endif + } + + return CRYPT_OK; +} + +int blake2b_160_init(hash_state *md) { return blake2b_init(md, 20, NULL, 0); } + +int blake2b_256_init(hash_state *md) { return blake2b_init(md, 32, NULL, 0); } + +int blake2b_384_init(hash_state *md) { return blake2b_init(md, 48, NULL, 0); } + +int blake2b_512_init(hash_state *md) { return blake2b_init(md, 64, NULL, 0); } + +#define G(r, i, a, b, c, d) \ + do { \ + a = a + b + m[blake2b_sigma[r][2 * i + 0]]; \ + d = ROR64(d ^ a, 32); \ + c = c + d; \ + b = ROR64(b ^ c, 24); \ + a = a + b + m[blake2b_sigma[r][2 * i + 1]]; \ + d = ROR64(d ^ a, 16); \ + c = c + d; \ + b = ROR64(b ^ c, 63); \ + } while (0) + +#define ROUND(r) \ + do { \ + G(r, 0, v[0], v[4], v[8], v[12]); \ + G(r, 1, v[1], v[5], v[9], v[13]); \ + G(r, 2, v[2], v[6], v[10], v[14]); \ + G(r, 3, v[3], v[7], v[11], v[15]); \ + G(r, 4, v[0], v[5], v[10], v[15]); \ + G(r, 5, v[1], v[6], v[11], v[12]); \ + G(r, 6, v[2], v[7], v[8], v[13]); \ + G(r, 7, v[3], v[4], v[9], v[14]); \ + } while (0) + +#ifdef LTC_CLEAN_STACK +static int _blake2b_compress(hash_state *md, const unsigned char *buf) +#else +static int blake2b_compress(hash_state *md, const unsigned char *buf) +#endif +{ + ulong64 m[16]; + ulong64 v[16]; + unsigned long i; + + for (i = 0; i < 16; ++i) { + LOAD64L(m[i], buf + i * sizeof(m[i])); + } + + for (i = 0; i < 8; ++i) { + v[i] = md->blake2b.h[i]; + } + + v[8] = blake2b_IV[0]; + v[9] = blake2b_IV[1]; + v[10] = blake2b_IV[2]; + v[11] = blake2b_IV[3]; + v[12] = blake2b_IV[4] ^ md->blake2b.t[0]; + v[13] = blake2b_IV[5] ^ md->blake2b.t[1]; + v[14] = blake2b_IV[6] ^ md->blake2b.f[0]; + v[15] = blake2b_IV[7] ^ md->blake2b.f[1]; + + ROUND(0); + ROUND(1); + ROUND(2); + ROUND(3); + ROUND(4); + ROUND(5); + ROUND(6); + ROUND(7); + ROUND(8); + ROUND(9); + ROUND(10); + ROUND(11); + + for (i = 0; i < 8; ++i) { + md->blake2b.h[i] = md->blake2b.h[i] ^ v[i] ^ v[i + 8]; + } + return CRYPT_OK; +} + +#undef G +#undef ROUND + +#ifdef LTC_CLEAN_STACK +static int blake2b_compress(hash_state *md, const unsigned char *buf) +{ + int err; + err = _blake2b_compress(md, buf); + burn_stack(sizeof(ulong64) * 32 + sizeof(unsigned long)); + return err; +} +#endif + +int blake2b_process(hash_state *md, const unsigned char *in, unsigned long inlen) +{ + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(in != NULL); + + if (md->blake2b.curlen > sizeof(md->blake2b.buf)) { + return CRYPT_INVALID_ARG; + } + + if (inlen > 0) { + unsigned long left = md->blake2b.curlen; + unsigned long fill = BLAKE2B_BLOCKBYTES - left; + if (inlen > fill) { + md->blake2b.curlen = 0; + XMEMCPY(md->blake2b.buf + left, in, fill); /* Fill buffer */ + blake2b_increment_counter(md, BLAKE2B_BLOCKBYTES); + blake2b_compress(md, md->blake2b.buf); /* Compress */ + in += fill; + inlen -= fill; + while (inlen > BLAKE2B_BLOCKBYTES) { + blake2b_increment_counter(md, BLAKE2B_BLOCKBYTES); + blake2b_compress(md, in); + in += BLAKE2B_BLOCKBYTES; + inlen -= BLAKE2B_BLOCKBYTES; + } + } + XMEMCPY(md->blake2b.buf + md->blake2b.curlen, in, inlen); + md->blake2b.curlen += inlen; + } + return CRYPT_OK; +} + +int blake2b_done(hash_state *md, unsigned char *out) +{ + unsigned char buffer[BLAKE2B_OUTBYTES] = { 0 }; + unsigned long i; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + /* if(md->blakebs.outlen != outlen) return CRYPT_INVALID_ARG; */ + + if (blake2b_is_lastblock(md)) + return CRYPT_ERROR; + + blake2b_increment_counter(md, md->blake2b.curlen); + blake2b_set_lastblock(md); + XMEMSET(md->blake2b.buf + md->blake2b.curlen, 0, BLAKE2B_BLOCKBYTES - md->blake2b.curlen); /* Padding */ + blake2b_compress(md, md->blake2b.buf); + + for (i = 0; i < 8; ++i) /* Output full hash to temp buffer */ + STORE64L(md->blake2b.h[i], buffer + i * 8); + + XMEMCPY(out, buffer, md->blake2b.outlen); + zeromem(md, sizeof(hash_state)); +#ifdef LTC_CLEAN_STACK + zeromem(buffer, sizeof(buffer)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int blake2b_512_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + char *msg; + unsigned char hash[64]; + } tests[] = { + { "", + { 0x78, 0x6a, 0x02, 0xf7, 0x42, 0x01, 0x59, 0x03, + 0xc6, 0xc6, 0xfd, 0x85, 0x25, 0x52, 0xd2, 0x72, + 0x91, 0x2f, 0x47, 0x40, 0xe1, 0x58, 0x47, 0x61, + 0x8a, 0x86, 0xe2, 0x17, 0xf7, 0x1f, 0x54, 0x19, + 0xd2, 0x5e, 0x10, 0x31, 0xaf, 0xee, 0x58, 0x53, + 0x13, 0x89, 0x64, 0x44, 0x93, 0x4e, 0xb0, 0x4b, + 0x90, 0x3a, 0x68, 0x5b, 0x14, 0x48, 0xb7, 0x55, + 0xd5, 0x6f, 0x70, 0x1a, 0xfe, 0x9b, 0xe2, 0xce } }, + { "abc", + { 0xba, 0x80, 0xa5, 0x3f, 0x98, 0x1c, 0x4d, 0x0d, + 0x6a, 0x27, 0x97, 0xb6, 0x9f, 0x12, 0xf6, 0xe9, + 0x4c, 0x21, 0x2f, 0x14, 0x68, 0x5a, 0xc4, 0xb7, + 0x4b, 0x12, 0xbb, 0x6f, 0xdb, 0xff, 0xa2, 0xd1, + 0x7d, 0x87, 0xc5, 0x39, 0x2a, 0xab, 0x79, 0x2d, + 0xc2, 0x52, 0xd5, 0xde, 0x45, 0x33, 0xcc, 0x95, + 0x18, 0xd3, 0x8a, 0xa8, 0xdb, 0xf1, 0x92, 0x5a, + 0xb9, 0x23, 0x86, 0xed, 0xd4, 0x00, 0x99, 0x23 } }, + + { NULL, { 0 } } + }; + + int i; + unsigned char tmp[64]; + hash_state md; + + for (i = 0; tests[i].msg != NULL; i++) { + blake2b_512_init(&md); + blake2b_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + blake2b_done(&md, tmp); + if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2B_512", i)) + return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; +#endif +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int blake2b_384_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + char *msg; + unsigned char hash[48]; + } tests[] = { + { "", + { 0xb3, 0x28, 0x11, 0x42, 0x33, 0x77, 0xf5, 0x2d, + 0x78, 0x62, 0x28, 0x6e, 0xe1, 0xa7, 0x2e, 0xe5, + 0x40, 0x52, 0x43, 0x80, 0xfd, 0xa1, 0x72, 0x4a, + 0x6f, 0x25, 0xd7, 0x97, 0x8c, 0x6f, 0xd3, 0x24, + 0x4a, 0x6c, 0xaf, 0x04, 0x98, 0x81, 0x26, 0x73, + 0xc5, 0xe0, 0x5e, 0xf5, 0x83, 0x82, 0x51, 0x00 } }, + { "abc", + { 0x6f, 0x56, 0xa8, 0x2c, 0x8e, 0x7e, 0xf5, 0x26, + 0xdf, 0xe1, 0x82, 0xeb, 0x52, 0x12, 0xf7, 0xdb, + 0x9d, 0xf1, 0x31, 0x7e, 0x57, 0x81, 0x5d, 0xbd, + 0xa4, 0x60, 0x83, 0xfc, 0x30, 0xf5, 0x4e, 0xe6, + 0xc6, 0x6b, 0xa8, 0x3b, 0xe6, 0x4b, 0x30, 0x2d, + 0x7c, 0xba, 0x6c, 0xe1, 0x5b, 0xb5, 0x56, 0xf4 } }, + + { NULL, { 0 } } + }; + + int i; + unsigned char tmp[48]; + hash_state md; + + for (i = 0; tests[i].msg != NULL; i++) { + blake2b_384_init(&md); + blake2b_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + blake2b_done(&md, tmp); + if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2B_384", i)) + return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; +#endif +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int blake2b_256_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + char *msg; + unsigned char hash[32]; + } tests[] = { + { "", + { 0x0e, 0x57, 0x51, 0xc0, 0x26, 0xe5, 0x43, 0xb2, + 0xe8, 0xab, 0x2e, 0xb0, 0x60, 0x99, 0xda, 0xa1, + 0xd1, 0xe5, 0xdf, 0x47, 0x77, 0x8f, 0x77, 0x87, + 0xfa, 0xab, 0x45, 0xcd, 0xf1, 0x2f, 0xe3, 0xa8 } }, + { "abc", + { 0xbd, 0xdd, 0x81, 0x3c, 0x63, 0x42, 0x39, 0x72, + 0x31, 0x71, 0xef, 0x3f, 0xee, 0x98, 0x57, 0x9b, + 0x94, 0x96, 0x4e, 0x3b, 0xb1, 0xcb, 0x3e, 0x42, + 0x72, 0x62, 0xc8, 0xc0, 0x68, 0xd5, 0x23, 0x19 } }, + { "12345678901234567890123456789012345678901234567890" + "12345678901234567890123456789012345678901234567890" + "12345678901234567890123456789012345678901234567890" + "12345678901234567890123456789012345678901234567890" + "12345678901234567890123456789012345678901234567890" + "12345678901234567890123456789012345678901234567890", + { 0x0f, 0x6e, 0x01, 0x8d, 0x38, 0xd6, 0x3f, 0x08, + 0x4d, 0x58, 0xe3, 0x0c, 0x90, 0xfb, 0xa2, 0x41, + 0x5f, 0xca, 0x17, 0xfa, 0x66, 0x26, 0x49, 0xf3, + 0x8a, 0x30, 0x41, 0x7c, 0x57, 0xcd, 0xa8, 0x14 } }, + + { NULL, { 0 } } + }; + + int i; + unsigned char tmp[32]; + hash_state md; + + for (i = 0; tests[i].msg != NULL; i++) { + blake2b_256_init(&md); + blake2b_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + blake2b_done(&md, tmp); + if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2B_256", i)) + return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; +#endif +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int blake2b_160_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + char *msg; + unsigned char hash[20]; + } tests[] = { + { "", + { 0x33, 0x45, 0x52, 0x4a, 0xbf, 0x6b, 0xbe, 0x18, + 0x09, 0x44, 0x92, 0x24, 0xb5, 0x97, 0x2c, 0x41, + 0x79, 0x0b, 0x6c, 0xf2 } }, + { "abc", + { 0x38, 0x42, 0x64, 0xf6, 0x76, 0xf3, 0x95, 0x36, + 0x84, 0x05, 0x23, 0xf2, 0x84, 0x92, 0x1c, 0xdc, + 0x68, 0xb6, 0x84, 0x6b } }, + + { NULL, { 0 } } + }; + + int i; + unsigned char tmp[20]; + hash_state md; + + for (i = 0; tests[i].msg != NULL; i++) { + blake2b_160_init(&md); + blake2b_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + blake2b_done(&md, tmp); + if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2B_160", i)) + return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; +#endif +} + +#endif diff --git a/src/ltc/hashes/blake2s.c b/src/ltc/hashes/blake2s.c new file mode 100644 index 0000000..daa45a5 --- /dev/null +++ b/src/ltc/hashes/blake2s.c @@ -0,0 +1,555 @@ +/* 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. + */ + +/* + BLAKE2 reference source code package - reference C implementations + + Copyright 2012, Samuel Neves . You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ +/* see also https://www.ietf.org/rfc/rfc7693.txt */ + +#include "tomcrypt.h" + +#ifdef LTC_BLAKE2S + +enum blake2s_constant { + BLAKE2S_BLOCKBYTES = 64, + BLAKE2S_OUTBYTES = 32, + BLAKE2S_KEYBYTES = 32, + BLAKE2S_SALTBYTES = 8, + BLAKE2S_PERSONALBYTES = 8, + BLAKE2S_PARAM_SIZE = 32 +}; + +/* param offsets */ +enum { + O_DIGEST_LENGTH = 0, + O_KEY_LENGTH = 1, + O_FANOUT = 2, + O_DEPTH = 3, + O_LEAF_LENGTH = 4, + O_NODE_OFFSET = 8, + O_XOF_LENGTH = 12, + O_NODE_DEPTH = 14, + O_INNER_LENGTH = 15, + O_SALT = 16, + O_PERSONAL = 24 +}; + +/* +struct blake2s_param { + unsigned char digest_length; + unsigned char key_length; + unsigned char fanout; + unsigned char depth; + ulong32 leaf_length; + ulong32 node_offset; + ushort16 xof_length; + unsigned char node_depth; + unsigned char inner_length; + unsigned char salt[BLAKE2S_SALTBYTES]; + unsigned char personal[BLAKE2S_PERSONALBYTES]; +}; +*/ + +const struct ltc_hash_descriptor blake2s_128_desc = +{ + "blake2s-128", + 21, + 16, + 64, + { 1, 3, 6, 1, 4, 1, 1722, 12, 2, 2, 4 }, + 11, + &blake2s_128_init, + &blake2s_process, + &blake2s_done, + &blake2s_128_test, + NULL +}; + +const struct ltc_hash_descriptor blake2s_160_desc = +{ + "blake2s-160", + 22, + 20, + 64, + { 1, 3, 6, 1, 4, 1, 1722, 12, 2, 2, 5 }, + 11, + &blake2s_160_init, + &blake2s_process, + &blake2s_done, + &blake2s_160_test, + NULL +}; + +const struct ltc_hash_descriptor blake2s_224_desc = +{ + "blake2s-224", + 23, + 28, + 64, + { 1, 3, 6, 1, 4, 1, 1722, 12, 2, 2, 7 }, + 11, + &blake2s_224_init, + &blake2s_process, + &blake2s_done, + &blake2s_224_test, + NULL +}; + +const struct ltc_hash_descriptor blake2s_256_desc = +{ + "blake2s-256", + 24, + 32, + 64, + { 1, 3, 6, 1, 4, 1, 1722, 12, 2, 2, 8 }, + 11, + &blake2s_256_init, + &blake2s_process, + &blake2s_done, + &blake2s_256_test, + NULL +}; + +static const ulong32 blake2s_IV[8] = { + 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, + 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL +}; + +static const unsigned char blake2s_sigma[10][16] = { + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }, + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 }, + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 }, + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 }, + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 }, + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 }, + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 }, + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 }, + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 }, +}; + +static void blake2s_set_lastnode(hash_state *md) { md->blake2s.f[1] = 0xffffffffUL; } + +/* Some helper functions, not necessarily useful */ +static int blake2s_is_lastblock(const hash_state *md) { return md->blake2s.f[0] != 0; } + +static void blake2s_set_lastblock(hash_state *md) +{ + if (md->blake2s.last_node) + blake2s_set_lastnode(md); + + md->blake2s.f[0] = 0xffffffffUL; +} + +static void blake2s_increment_counter(hash_state *md, const ulong32 inc) +{ + md->blake2s.t[0] += inc; + if (md->blake2s.t[0] < inc) md->blake2s.t[1]++; +} + +static int blake2s_init0(hash_state *md) +{ + int i; + XMEMSET(&md->blake2s, 0, sizeof(struct blake2s_state)); + + for (i = 0; i < 8; ++i) + md->blake2s.h[i] = blake2s_IV[i]; + + return CRYPT_OK; +} + +/* init2 xors IV with input parameter block */ +static int blake2s_init_param(hash_state *md, const unsigned char *P) +{ + unsigned long i; + + blake2s_init0(md); + + /* IV XOR ParamBlock */ + for (i = 0; i < 8; ++i) { + ulong32 tmp; + LOAD32L(tmp, P + i * 4); + md->blake2s.h[i] ^= tmp; + } + + md->blake2s.outlen = P[O_DIGEST_LENGTH]; + return CRYPT_OK; +} + +int blake2s_init(hash_state *md, unsigned long outlen, const unsigned char *key, unsigned long keylen) +{ + unsigned char P[BLAKE2S_PARAM_SIZE]; + int err; + + LTC_ARGCHK(md != NULL); + + if ((!outlen) || (outlen > BLAKE2S_OUTBYTES)) + return CRYPT_INVALID_ARG; + + if ((key && !keylen) || (keylen && !key) || (keylen > BLAKE2S_KEYBYTES)) + return CRYPT_INVALID_ARG; + + XMEMSET(P, 0, sizeof(P)); + + P[O_DIGEST_LENGTH] = (unsigned char)outlen; + P[O_KEY_LENGTH] = (unsigned char)keylen; + P[O_FANOUT] = 1; + P[O_DEPTH] = 1; + + err = blake2s_init_param(md, P); + if (err != CRYPT_OK) return err; + + if (key) { + unsigned char block[BLAKE2S_BLOCKBYTES]; + + XMEMSET(block, 0, BLAKE2S_BLOCKBYTES); + XMEMCPY(block, key, keylen); + blake2s_process(md, block, BLAKE2S_BLOCKBYTES); + +#ifdef LTC_CLEAN_STACK + zeromem(block, sizeof(block)); +#endif + } + return CRYPT_OK; +} + +int blake2s_128_init(hash_state *md) { return blake2s_init(md, 16, NULL, 0); } + +int blake2s_160_init(hash_state *md) { return blake2s_init(md, 20, NULL, 0); } + +int blake2s_224_init(hash_state *md) { return blake2s_init(md, 28, NULL, 0); } + +int blake2s_256_init(hash_state *md) { return blake2s_init(md, 32, NULL, 0); } + +#define G(r, i, a, b, c, d) \ + do { \ + a = a + b + m[blake2s_sigma[r][2 * i + 0]]; \ + d = ROR(d ^ a, 16); \ + c = c + d; \ + b = ROR(b ^ c, 12); \ + a = a + b + m[blake2s_sigma[r][2 * i + 1]]; \ + d = ROR(d ^ a, 8); \ + c = c + d; \ + b = ROR(b ^ c, 7); \ + } while (0) +#define ROUND(r) \ + do { \ + G(r, 0, v[0], v[4], v[8], v[12]); \ + G(r, 1, v[1], v[5], v[9], v[13]); \ + G(r, 2, v[2], v[6], v[10], v[14]); \ + G(r, 3, v[3], v[7], v[11], v[15]); \ + G(r, 4, v[0], v[5], v[10], v[15]); \ + G(r, 5, v[1], v[6], v[11], v[12]); \ + G(r, 6, v[2], v[7], v[8], v[13]); \ + G(r, 7, v[3], v[4], v[9], v[14]); \ + } while (0) + +#ifdef LTC_CLEAN_STACK +static int _blake2s_compress(hash_state *md, const unsigned char *buf) +#else +static int blake2s_compress(hash_state *md, const unsigned char *buf) +#endif +{ + unsigned long i; + ulong32 m[16]; + ulong32 v[16]; + + for (i = 0; i < 16; ++i) { + LOAD32L(m[i], buf + i * sizeof(m[i])); + } + + for (i = 0; i < 8; ++i) + v[i] = md->blake2s.h[i]; + + v[8] = blake2s_IV[0]; + v[9] = blake2s_IV[1]; + v[10] = blake2s_IV[2]; + v[11] = blake2s_IV[3]; + v[12] = md->blake2s.t[0] ^ blake2s_IV[4]; + v[13] = md->blake2s.t[1] ^ blake2s_IV[5]; + v[14] = md->blake2s.f[0] ^ blake2s_IV[6]; + v[15] = md->blake2s.f[1] ^ blake2s_IV[7]; + + ROUND(0); + ROUND(1); + ROUND(2); + ROUND(3); + ROUND(4); + ROUND(5); + ROUND(6); + ROUND(7); + ROUND(8); + ROUND(9); + + for (i = 0; i < 8; ++i) + md->blake2s.h[i] = md->blake2s.h[i] ^ v[i] ^ v[i + 8]; + + return CRYPT_OK; +} +#undef G +#undef ROUND + +#ifdef LTC_CLEAN_STACK +static int blake2s_compress(hash_state *md, const unsigned char *buf) +{ + int err; + err = _blake2s_compress(md, buf); + burn_stack(sizeof(ulong32) * (32) + sizeof(unsigned long)); + return err; +} +#endif + +int blake2s_process(hash_state *md, const unsigned char *in, unsigned long inlen) +{ + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(in != NULL); + + if (md->blake2s.curlen > sizeof(md->blake2s.buf)) { + return CRYPT_INVALID_ARG; + } + + if (inlen > 0) { + unsigned long left = md->blake2s.curlen; + unsigned long fill = BLAKE2S_BLOCKBYTES - left; + if (inlen > fill) { + md->blake2s.curlen = 0; + XMEMCPY(md->blake2s.buf + left, in, fill); /* Fill buffer */ + blake2s_increment_counter(md, BLAKE2S_BLOCKBYTES); + blake2s_compress(md, md->blake2s.buf); /* Compress */ + in += fill; + inlen -= fill; + while (inlen > BLAKE2S_BLOCKBYTES) { + blake2s_increment_counter(md, BLAKE2S_BLOCKBYTES); + blake2s_compress(md, in); + in += BLAKE2S_BLOCKBYTES; + inlen -= BLAKE2S_BLOCKBYTES; + } + } + XMEMCPY(md->blake2s.buf + md->blake2s.curlen, in, inlen); + md->blake2s.curlen += inlen; + } + return CRYPT_OK; +} + +int blake2s_done(hash_state *md, unsigned char *out) +{ + unsigned char buffer[BLAKE2S_OUTBYTES] = { 0 }; + unsigned long i; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + /* if(md->blake2s.outlen != outlen) return CRYPT_INVALID_ARG; */ + + if (blake2s_is_lastblock(md)) + return CRYPT_ERROR; + + blake2s_increment_counter(md, md->blake2s.curlen); + blake2s_set_lastblock(md); + XMEMSET(md->blake2s.buf + md->blake2s.curlen, 0, BLAKE2S_BLOCKBYTES - md->blake2s.curlen); /* Padding */ + blake2s_compress(md, md->blake2s.buf); + + for (i = 0; i < 8; ++i) /* Output full hash to temp buffer */ + STORE32L(md->blake2s.h[i], buffer + i * 4); + + XMEMCPY(out, buffer, md->blake2s.outlen); + zeromem(md, sizeof(hash_state)); +#ifdef LTC_CLEAN_STACK + zeromem(buffer, sizeof(buffer)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int blake2s_256_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + char *msg; + unsigned char hash[32]; + } tests[] = { + { "", + { 0x69, 0x21, 0x7a, 0x30, 0x79, 0x90, 0x80, 0x94, + 0xe1, 0x11, 0x21, 0xd0, 0x42, 0x35, 0x4a, 0x7c, + 0x1f, 0x55, 0xb6, 0x48, 0x2c, 0xa1, 0xa5, 0x1e, + 0x1b, 0x25, 0x0d, 0xfd, 0x1e, 0xd0, 0xee, 0xf9 } }, + { "abc", + { 0x50, 0x8c, 0x5e, 0x8c, 0x32, 0x7c, 0x14, 0xe2, + 0xe1, 0xa7, 0x2b, 0xa3, 0x4e, 0xeb, 0x45, 0x2f, + 0x37, 0x45, 0x8b, 0x20, 0x9e, 0xd6, 0x3a, 0x29, + 0x4d, 0x99, 0x9b, 0x4c, 0x86, 0x67, 0x59, 0x82 } }, + { "12345678901234567890123456789012345678901234567890" + "12345678901234567890123456789012345678901234567890" + "12345678901234567890123456789012345678901234567890" + "12345678901234567890123456789012345678901234567890" + "12345678901234567890123456789012345678901234567890" + "12345678901234567890123456789012345678901234567890", + { 0xa3, 0x78, 0x8b, 0x5b, 0x59, 0xee, 0xe4, 0x41, + 0x95, 0x23, 0x58, 0x00, 0xa4, 0xf9, 0xfa, 0x41, + 0x86, 0x0c, 0x7b, 0x1c, 0x35, 0xa2, 0x42, 0x70, + 0x50, 0x80, 0x79, 0x56, 0xe3, 0xbe, 0x31, 0x74 } }, + + { NULL, { 0 } } + }; + + int i; + unsigned char tmp[32]; + hash_state md; + + for (i = 0; tests[i].msg != NULL; i++) { + blake2s_256_init(&md); + blake2s_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + blake2s_done(&md, tmp); + if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2S_256", i)) + return CRYPT_FAIL_TESTVECTOR; + + } + return CRYPT_OK; +#endif +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int blake2s_224_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + char *msg; + unsigned char hash[28]; + } tests[] = { + { "", + { 0x1f, 0xa1, 0x29, 0x1e, 0x65, 0x24, 0x8b, 0x37, + 0xb3, 0x43, 0x34, 0x75, 0xb2, 0xa0, 0xdd, 0x63, + 0xd5, 0x4a, 0x11, 0xec, 0xc4, 0xe3, 0xe0, 0x34, + 0xe7, 0xbc, 0x1e, 0xf4 } }, + { "abc", + { 0x0b, 0x03, 0x3f, 0xc2, 0x26, 0xdf, 0x7a, 0xbd, + 0xe2, 0x9f, 0x67, 0xa0, 0x5d, 0x3d, 0xc6, 0x2c, + 0xf2, 0x71, 0xef, 0x3d, 0xfe, 0xa4, 0xd3, 0x87, + 0x40, 0x7f, 0xbd, 0x55 } }, + + { NULL, { 0 } } + }; + + int i; + unsigned char tmp[28]; + hash_state md; + + for (i = 0; tests[i].msg != NULL; i++) { + blake2s_224_init(&md); + blake2s_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + blake2s_done(&md, tmp); + if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2S_224", i)) + return CRYPT_FAIL_TESTVECTOR; + + } + return CRYPT_OK; +#endif +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int blake2s_160_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + char *msg; + unsigned char hash[20]; + } tests[] = { + { "", + { 0x35, 0x4c, 0x9c, 0x33, 0xf7, 0x35, 0x96, 0x24, + 0x18, 0xbd, 0xac, 0xb9, 0x47, 0x98, 0x73, 0x42, + 0x9c, 0x34, 0x91, 0x6f} }, + { "abc", + { 0x5a, 0xe3, 0xb9, 0x9b, 0xe2, 0x9b, 0x01, 0x83, + 0x4c, 0x3b, 0x50, 0x85, 0x21, 0xed, 0xe6, 0x04, + 0x38, 0xf8, 0xde, 0x17 } }, + + { NULL, { 0 } } + }; + + int i; + unsigned char tmp[20]; + hash_state md; + + for (i = 0; tests[i].msg != NULL; i++) { + blake2s_160_init(&md); + blake2s_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + blake2s_done(&md, tmp); + if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2S_160", i)) + return CRYPT_FAIL_TESTVECTOR; + + } + return CRYPT_OK; +#endif +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int blake2s_128_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + char *msg; + unsigned char hash[16]; + } tests[] = { + { "", + { 0x64, 0x55, 0x0d, 0x6f, 0xfe, 0x2c, 0x0a, 0x01, + 0xa1, 0x4a, 0xba, 0x1e, 0xad, 0xe0, 0x20, 0x0c } }, + { "abc", + { 0xaa, 0x49, 0x38, 0x11, 0x9b, 0x1d, 0xc7, 0xb8, + 0x7c, 0xba, 0xd0, 0xff, 0xd2, 0x00, 0xd0, 0xae } }, + + { NULL, { 0 } } + }; + + int i; + unsigned char tmp[16]; + hash_state md; + + for (i = 0; tests[i].msg != NULL; i++) { + blake2s_128_init(&md); + blake2s_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + blake2s_done(&md, tmp); + if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2S_128", i)) + return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; +#endif +} + +#endif diff --git a/src/ltc/hashes/chc/chc.c b/src/ltc/hashes/chc/chc.c new file mode 100644 index 0000000..bff4d80 --- /dev/null +++ b/src/ltc/hashes/chc/chc.c @@ -0,0 +1,302 @@ +/* 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://libtom.org + */ + +#include "tomcrypt.h" + +/** + @file chc.c + CHC support. (Tom St Denis) +*/ + +#ifdef LTC_CHC_HASH + +#define UNDEFED_HASH -17 + +/* chc settings */ +static int cipher_idx=UNDEFED_HASH, /* which cipher */ + cipher_blocksize; /* blocksize of cipher */ + + +const struct ltc_hash_descriptor chc_desc = { + "chc_hash", 12, 0, 0, { 0 }, 0, + &chc_init, + &chc_process, + &chc_done, + &chc_test, + NULL +}; + +/** + Initialize the CHC state with a given cipher + @param cipher The index of the cipher you wish to bind + @return CRYPT_OK if successful +*/ +int chc_register(int cipher) +{ + int err, kl, idx; + + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + /* will it be valid? */ + kl = cipher_descriptor[cipher].block_length; + + /* must be >64 bit block */ + if (kl <= 8) { + return CRYPT_INVALID_CIPHER; + } + + /* can we use the ideal keysize? */ + if ((err = cipher_descriptor[cipher].keysize(&kl)) != CRYPT_OK) { + return err; + } + /* we require that key size == block size be a valid choice */ + if (kl != cipher_descriptor[cipher].block_length) { + return CRYPT_INVALID_CIPHER; + } + + /* determine if chc_hash has been register_hash'ed already */ + if ((err = hash_is_valid(idx = find_hash("chc_hash"))) != CRYPT_OK) { + return err; + } + + /* store into descriptor */ + hash_descriptor[idx].hashsize = + hash_descriptor[idx].blocksize = cipher_descriptor[cipher].block_length; + + /* store the idx and block size */ + cipher_idx = cipher; + cipher_blocksize = cipher_descriptor[cipher].block_length; + return CRYPT_OK; +} + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int chc_init(hash_state *md) +{ + symmetric_key *key; + unsigned char buf[MAXBLOCKSIZE]; + int err; + + LTC_ARGCHK(md != NULL); + + /* is the cipher valid? */ + if ((err = cipher_is_valid(cipher_idx)) != CRYPT_OK) { + return err; + } + + if (cipher_blocksize != cipher_descriptor[cipher_idx].block_length) { + return CRYPT_INVALID_CIPHER; + } + + if ((key = XMALLOC(sizeof(*key))) == NULL) { + return CRYPT_MEM; + } + + /* zero key and what not */ + zeromem(buf, cipher_blocksize); + if ((err = cipher_descriptor[cipher_idx].setup(buf, cipher_blocksize, 0, key)) != CRYPT_OK) { + XFREE(key); + return err; + } + + /* encrypt zero block */ + cipher_descriptor[cipher_idx].ecb_encrypt(buf, md->chc.state, key); + + /* zero other members */ + md->chc.length = 0; + md->chc.curlen = 0; + zeromem(md->chc.buf, sizeof(md->chc.buf)); + XFREE(key); + return CRYPT_OK; +} + +/* + key <= state + T0,T1 <= block + T0 <= encrypt T0 + state <= state xor T0 xor T1 +*/ +static int chc_compress(hash_state *md, unsigned char *buf) +{ + unsigned char T[2][MAXBLOCKSIZE]; + symmetric_key *key; + int err, x; + + if ((key = XMALLOC(sizeof(*key))) == NULL) { + return CRYPT_MEM; + } + if ((err = cipher_descriptor[cipher_idx].setup(md->chc.state, cipher_blocksize, 0, key)) != CRYPT_OK) { + XFREE(key); + return err; + } + XMEMCPY(T[1], buf, cipher_blocksize); + cipher_descriptor[cipher_idx].ecb_encrypt(buf, T[0], key); + for (x = 0; x < cipher_blocksize; x++) { + md->chc.state[x] ^= T[0][x] ^ T[1][x]; + } +#ifdef LTC_CLEAN_STACK + zeromem(T, sizeof(T)); + zeromem(key, sizeof(*key)); +#endif + XFREE(key); + return CRYPT_OK; +} + +/* function for processing blocks */ +static int _chc_process(hash_state * md, const unsigned char *buf, unsigned long len); +static HASH_PROCESS(_chc_process, chc_compress, chc, (unsigned long)cipher_blocksize) + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +int chc_process(hash_state * md, const unsigned char *in, unsigned long inlen) +{ + int err; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(in != NULL); + + /* is the cipher valid? */ + if ((err = cipher_is_valid(cipher_idx)) != CRYPT_OK) { + return err; + } + if (cipher_blocksize != cipher_descriptor[cipher_idx].block_length) { + return CRYPT_INVALID_CIPHER; + } + + return _chc_process(md, in, inlen); +} + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (length of the block size of the block cipher) + @return CRYPT_OK if successful +*/ +int chc_done(hash_state *md, unsigned char *out) +{ + int err; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + /* is the cipher valid? */ + if ((err = cipher_is_valid(cipher_idx)) != CRYPT_OK) { + return err; + } + if (cipher_blocksize != cipher_descriptor[cipher_idx].block_length) { + return CRYPT_INVALID_CIPHER; + } + + if (md->chc.curlen >= sizeof(md->chc.buf)) { + return CRYPT_INVALID_ARG; + } + + /* increase the length of the message */ + md->chc.length += md->chc.curlen * 8; + + /* append the '1' bit */ + md->chc.buf[md->chc.curlen++] = (unsigned char)0x80; + + /* if the length is currently above l-8 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->chc.curlen > (unsigned long)(cipher_blocksize - 8)) { + while (md->chc.curlen < (unsigned long)cipher_blocksize) { + md->chc.buf[md->chc.curlen++] = (unsigned char)0; + } + chc_compress(md, md->chc.buf); + md->chc.curlen = 0; + } + + /* pad upto l-8 bytes of zeroes */ + while (md->chc.curlen < (unsigned long)(cipher_blocksize - 8)) { + md->chc.buf[md->chc.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->chc.length, md->chc.buf+(cipher_blocksize-8)); + chc_compress(md, md->chc.buf); + + /* copy output */ + XMEMCPY(out, md->chc.state, cipher_blocksize); + +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int chc_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + unsigned char *msg, + md[MAXBLOCKSIZE]; + int len; + } tests[] = { +{ + (unsigned char *)"hello world", + { 0xcf, 0x57, 0x9d, 0xc3, 0x0a, 0x0e, 0xea, 0x61, + 0x0d, 0x54, 0x47, 0xc4, 0x3c, 0x06, 0xf5, 0x4e }, + 16 +} +}; + int x, oldhashidx, idx; + unsigned char out[MAXBLOCKSIZE]; + hash_state md; + + /* AES can be under rijndael or aes... try to find it */ + if ((idx = find_cipher("aes")) == -1) { + if ((idx = find_cipher("rijndael")) == -1) { + return CRYPT_NOP; + } + } + oldhashidx = cipher_idx; + chc_register(idx); + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + chc_init(&md); + chc_process(&md, tests[x].msg, strlen((char *)tests[x].msg)); + chc_done(&md, out); + if (XMEMCMP(out, tests[x].md, tests[x].len)) { + return CRYPT_FAIL_TESTVECTOR; + } + } + if (oldhashidx != UNDEFED_HASH) { + chc_register(oldhashidx); + } + + return CRYPT_OK; +#endif +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/hashes/helper/hash_file.c b/src/ltc/hashes/helper/hash_file.c new file mode 100644 index 0000000..bb899a1 --- /dev/null +++ b/src/ltc/hashes/helper/hash_file.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://libtom.org + */ +#include "tomcrypt.h" + +#ifndef LTC_NO_FILE +/** + @file hash_file.c + Hash a file, Tom St Denis +*/ + +/** + @param hash The index of the hash desired + @param fname The name of the file you wish to hash + @param out [out] The destination of the digest + @param outlen [in/out] The max size and resulting size of the message digest + @result CRYPT_OK if successful +*/ +int hash_file(int hash, const char *fname, unsigned char *out, unsigned long *outlen) +{ + FILE *in; + int err; + LTC_ARGCHK(fname != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + in = fopen(fname, "rb"); + if (in == NULL) { + return CRYPT_FILE_NOTFOUND; + } + + err = hash_filehandle(hash, in, out, outlen); + if (fclose(in) != 0) { + return CRYPT_ERROR; + } + + return err; +} +#endif /* #ifndef LTC_NO_FILE */ + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/hashes/helper/hash_filehandle.c b/src/ltc/hashes/helper/hash_filehandle.c new file mode 100644 index 0000000..e1d037e --- /dev/null +++ b/src/ltc/hashes/helper/hash_filehandle.c @@ -0,0 +1,75 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +#ifndef LTC_NO_FILE +/** + @file hash_filehandle.c + Hash open files, Tom St Denis +*/ + +/** + Hash data from an open file handle. + @param hash The index of the hash you want to use + @param in The FILE* handle of the file you want to hash + @param out [out] The destination of the digest + @param outlen [in/out] The max size and resulting size of the digest + @result CRYPT_OK if successful +*/ +int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned long *outlen) +{ + hash_state md; + unsigned char *buf; + size_t x; + int err; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(in != NULL); + + if ((buf = XMALLOC(LTC_FILE_READ_BUFSIZE)) == NULL) { + return CRYPT_MEM; + } + + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + goto LBL_ERR; + } + + if (*outlen < hash_descriptor[hash].hashsize) { + *outlen = hash_descriptor[hash].hashsize; + err = CRYPT_BUFFER_OVERFLOW; + goto LBL_ERR; + } + if ((err = hash_descriptor[hash].init(&md)) != CRYPT_OK) { + goto LBL_ERR; + } + + *outlen = hash_descriptor[hash].hashsize; + do { + x = fread(buf, 1, LTC_FILE_READ_BUFSIZE, in); + if ((err = hash_descriptor[hash].process(&md, buf, (unsigned long)x)) != CRYPT_OK) { + goto LBL_CLEANBUF; + } + } while (x == LTC_FILE_READ_BUFSIZE); + err = hash_descriptor[hash].done(&md, out); + +LBL_CLEANBUF: + zeromem(buf, LTC_FILE_READ_BUFSIZE); +LBL_ERR: + XFREE(buf); + return err; +} +#endif /* #ifndef LTC_NO_FILE */ + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/hashes/helper/hash_memory.c b/src/ltc/hashes/helper/hash_memory.c new file mode 100644 index 0000000..53caa5d --- /dev/null +++ b/src/ltc/hashes/helper/hash_memory.c @@ -0,0 +1,71 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +#ifdef LTC_HASH_HELPERS +/** + @file hash_memory.c + Hash memory helper, Tom St Denis +*/ + +/** + Hash a block of memory and store the digest. + @param hash The index of the hash you wish to use + @param in The data you wish to hash + @param inlen The length of the data to hash (octets) + @param out [out] Where to store the digest + @param outlen [in/out] Max size and resulting size of the digest + @return CRYPT_OK if successful +*/ +int hash_memory(int hash, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) +{ + hash_state *md; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + if (*outlen < hash_descriptor[hash].hashsize) { + *outlen = hash_descriptor[hash].hashsize; + return CRYPT_BUFFER_OVERFLOW; + } + + md = XMALLOC(sizeof(hash_state)); + if (md == NULL) { + return CRYPT_MEM; + } + + if ((err = hash_descriptor[hash].init(md)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash].process(md, in, inlen)) != CRYPT_OK) { + goto LBL_ERR; + } + err = hash_descriptor[hash].done(md, out); + *outlen = hash_descriptor[hash].hashsize; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + XFREE(md); + + return err; +} +#endif /* #ifdef LTC_HASH_HELPERS */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/hashes/helper/hash_memory_multi.c b/src/ltc/hashes/helper/hash_memory_multi.c new file mode 100644 index 0000000..560d6f6 --- /dev/null +++ b/src/ltc/hashes/helper/hash_memory_multi.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://libtom.org + */ +#include "tomcrypt.h" +#include + +#ifdef LTC_HASH_HELPERS +/** + @file hash_memory_multi.c + Hash (multiple buffers) memory helper, Tom St Denis +*/ + +/** + Hash multiple (non-adjacent) blocks of memory at once. + @param hash The index of the hash you wish to use + @param out [out] Where to store the digest + @param outlen [in/out] Max size and resulting size of the digest + @param in The data you wish to hash + @param inlen The length of the data to hash (octets) + @param ... tuples of (data,len) pairs to hash, terminated with a (NULL,x) (x=don't care) + @return CRYPT_OK if successful +*/ +int hash_memory_multi(int hash, unsigned char *out, unsigned long *outlen, + const unsigned char *in, unsigned long inlen, ...) +{ + hash_state *md; + int err; + va_list args; + const unsigned char *curptr; + unsigned long curlen; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + if (*outlen < hash_descriptor[hash].hashsize) { + *outlen = hash_descriptor[hash].hashsize; + return CRYPT_BUFFER_OVERFLOW; + } + + md = XMALLOC(sizeof(hash_state)); + if (md == NULL) { + return CRYPT_MEM; + } + + if ((err = hash_descriptor[hash].init(md)) != CRYPT_OK) { + goto LBL_ERR; + } + + va_start(args, inlen); + curptr = in; + curlen = inlen; + for (;;) { + /* process buf */ + if ((err = hash_descriptor[hash].process(md, curptr, curlen)) != CRYPT_OK) { + goto LBL_ERR; + } + /* step to next */ + curptr = va_arg(args, const unsigned char*); + if (curptr == NULL) { + break; + } + curlen = va_arg(args, unsigned long); + } + err = hash_descriptor[hash].done(md, out); + *outlen = hash_descriptor[hash].hashsize; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + XFREE(md); + va_end(args); + return err; +} +#endif /* #ifdef LTC_HASH_HELPERS */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/hashes/md2.c b/src/ltc/hashes/md2.c new file mode 100644 index 0000000..0410923 --- /dev/null +++ b/src/ltc/hashes/md2.c @@ -0,0 +1,251 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @param md2.c + LTC_MD2 (RFC 1319) hash function implementation by Tom St Denis +*/ + +#ifdef LTC_MD2 + +const struct ltc_hash_descriptor md2_desc = +{ + "md2", + 7, + 16, + 16, + + /* OID */ + { 1, 2, 840, 113549, 2, 2, }, + 6, + + &md2_init, + &md2_process, + &md2_done, + &md2_test, + NULL +}; + +static const unsigned char PI_SUBST[256] = { + 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6, + 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, + 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, + 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251, + 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63, + 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50, + 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165, + 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210, + 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157, + 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27, + 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15, + 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197, + 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65, + 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123, + 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233, + 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228, + 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237, + 31, 26, 219, 153, 141, 51, 159, 17, 131, 20 +}; + +/* adds 16 bytes to the checksum */ +static void md2_update_chksum(hash_state *md) +{ + int j; + unsigned char L; + L = md->md2.chksum[15]; + for (j = 0; j < 16; j++) { + +/* caution, the RFC says its "C[j] = S[M[i*16+j] xor L]" but the reference source code [and test vectors] say + otherwise. +*/ + L = (md->md2.chksum[j] ^= PI_SUBST[(int)(md->md2.buf[j] ^ L)] & 255); + } +} + +static void md2_compress(hash_state *md) +{ + int j, k; + unsigned char t; + + /* copy block */ + for (j = 0; j < 16; j++) { + md->md2.X[16+j] = md->md2.buf[j]; + md->md2.X[32+j] = md->md2.X[j] ^ md->md2.X[16+j]; + } + + t = (unsigned char)0; + + /* do 18 rounds */ + for (j = 0; j < 18; j++) { + for (k = 0; k < 48; k++) { + t = (md->md2.X[k] ^= PI_SUBST[(int)(t & 255)]); + } + t = (t + (unsigned char)j) & 255; + } +} + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int md2_init(hash_state *md) +{ + LTC_ARGCHK(md != NULL); + + /* LTC_MD2 uses a zero'ed state... */ + zeromem(md->md2.X, sizeof(md->md2.X)); + zeromem(md->md2.chksum, sizeof(md->md2.chksum)); + zeromem(md->md2.buf, sizeof(md->md2.buf)); + md->md2.curlen = 0; + return CRYPT_OK; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +int md2_process(hash_state *md, const unsigned char *in, unsigned long inlen) +{ + unsigned long n; + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(in != NULL); + if (md-> md2 .curlen > sizeof(md-> md2 .buf)) { + return CRYPT_INVALID_ARG; + } + while (inlen > 0) { + n = MIN(inlen, (16 - md->md2.curlen)); + XMEMCPY(md->md2.buf + md->md2.curlen, in, (size_t)n); + md->md2.curlen += n; + in += n; + inlen -= n; + + /* is 16 bytes full? */ + if (md->md2.curlen == 16) { + md2_compress(md); + md2_update_chksum(md); + md->md2.curlen = 0; + } + } + return CRYPT_OK; +} + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (16 bytes) + @return CRYPT_OK if successful +*/ +int md2_done(hash_state * md, unsigned char *out) +{ + unsigned long i, k; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->md2.curlen >= sizeof(md->md2.buf)) { + return CRYPT_INVALID_ARG; + } + + + /* pad the message */ + k = 16 - md->md2.curlen; + for (i = md->md2.curlen; i < 16; i++) { + md->md2.buf[i] = (unsigned char)k; + } + + /* hash and update */ + md2_compress(md); + md2_update_chksum(md); + + /* hash checksum */ + XMEMCPY(md->md2.buf, md->md2.chksum, 16); + md2_compress(md); + + /* output is lower 16 bytes of X */ + XMEMCPY(out, md->md2.X, 16); + +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int md2_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char md[16]; + } tests[] = { + { "", + {0x83,0x50,0xe5,0xa3,0xe2,0x4c,0x15,0x3d, + 0xf2,0x27,0x5c,0x9f,0x80,0x69,0x27,0x73 + } + }, + { "a", + {0x32,0xec,0x01,0xec,0x4a,0x6d,0xac,0x72, + 0xc0,0xab,0x96,0xfb,0x34,0xc0,0xb5,0xd1 + } + }, + { "message digest", + {0xab,0x4f,0x49,0x6b,0xfb,0x2a,0x53,0x0b, + 0x21,0x9f,0xf3,0x30,0x31,0xfe,0x06,0xb0 + } + }, + { "abcdefghijklmnopqrstuvwxyz", + {0x4e,0x8d,0xdf,0xf3,0x65,0x02,0x92,0xab, + 0x5a,0x41,0x08,0xc3,0xaa,0x47,0x94,0x0b + } + }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + {0xda,0x33,0xde,0xf2,0xa4,0x2d,0xf1,0x39, + 0x75,0x35,0x28,0x46,0xc3,0x03,0x38,0xcd + } + }, + { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", + {0xd5,0x97,0x6f,0x79,0xd8,0x3d,0x3a,0x0d, + 0xc9,0x80,0x6c,0x3c,0x66,0xf3,0xef,0xd8 + } + } + }; + int i; + hash_state md; + unsigned char buf[16]; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + md2_init(&md); + md2_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + md2_done(&md, buf); + if (XMEMCMP(buf, tests[i].md, 16) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/hashes/md4.c b/src/ltc/hashes/md4.c new file mode 100644 index 0000000..b2527b5 --- /dev/null +++ b/src/ltc/hashes/md4.c @@ -0,0 +1,307 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @param md4.c + Submitted by Dobes Vandermeer (dobes@smartt.com) +*/ + +#ifdef LTC_MD4 + +const struct ltc_hash_descriptor md4_desc = +{ + "md4", + 6, + 16, + 64, + + /* OID */ + { 1, 2, 840, 113549, 2, 4, }, + 6, + + &md4_init, + &md4_process, + &md4_done, + &md4_test, + NULL +}; + +#define S11 3 +#define S12 7 +#define S13 11 +#define S14 19 +#define S21 3 +#define S22 5 +#define S23 9 +#define S24 13 +#define S31 3 +#define S32 9 +#define S33 11 +#define S34 15 + +/* F, G and H are basic LTC_MD4 functions. */ +#define F(x, y, z) (z ^ (x & (y ^ z))) +#define G(x, y, z) ((x & y) | (z & (x | y))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) + +/* ROTATE_LEFT rotates x left n bits. */ +#define ROTATE_LEFT(x, n) ROLc(x, n) + +/* FF, GG and HH are transformations for rounds 1, 2 and 3 */ +/* Rotation is separate from addition to prevent recomputation */ + +#define FF(a, b, c, d, x, s) { \ + (a) += F ((b), (c), (d)) + (x); \ + (a) = ROTATE_LEFT ((a), (s)); \ + } +#define GG(a, b, c, d, x, s) { \ + (a) += G ((b), (c), (d)) + (x) + 0x5a827999UL; \ + (a) = ROTATE_LEFT ((a), (s)); \ + } +#define HH(a, b, c, d, x, s) { \ + (a) += H ((b), (c), (d)) + (x) + 0x6ed9eba1UL; \ + (a) = ROTATE_LEFT ((a), (s)); \ + } + +#ifdef LTC_CLEAN_STACK +static int _md4_compress(hash_state *md, unsigned char *buf) +#else +static int md4_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong32 x[16], a, b, c, d; + int i; + + /* copy state */ + a = md->md4.state[0]; + b = md->md4.state[1]; + c = md->md4.state[2]; + d = md->md4.state[3]; + + /* copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) { + LOAD32L(x[i], buf + (4*i)); + } + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11); /* 1 */ + FF (d, a, b, c, x[ 1], S12); /* 2 */ + FF (c, d, a, b, x[ 2], S13); /* 3 */ + FF (b, c, d, a, x[ 3], S14); /* 4 */ + FF (a, b, c, d, x[ 4], S11); /* 5 */ + FF (d, a, b, c, x[ 5], S12); /* 6 */ + FF (c, d, a, b, x[ 6], S13); /* 7 */ + FF (b, c, d, a, x[ 7], S14); /* 8 */ + FF (a, b, c, d, x[ 8], S11); /* 9 */ + FF (d, a, b, c, x[ 9], S12); /* 10 */ + FF (c, d, a, b, x[10], S13); /* 11 */ + FF (b, c, d, a, x[11], S14); /* 12 */ + FF (a, b, c, d, x[12], S11); /* 13 */ + FF (d, a, b, c, x[13], S12); /* 14 */ + FF (c, d, a, b, x[14], S13); /* 15 */ + FF (b, c, d, a, x[15], S14); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 0], S21); /* 17 */ + GG (d, a, b, c, x[ 4], S22); /* 18 */ + GG (c, d, a, b, x[ 8], S23); /* 19 */ + GG (b, c, d, a, x[12], S24); /* 20 */ + GG (a, b, c, d, x[ 1], S21); /* 21 */ + GG (d, a, b, c, x[ 5], S22); /* 22 */ + GG (c, d, a, b, x[ 9], S23); /* 23 */ + GG (b, c, d, a, x[13], S24); /* 24 */ + GG (a, b, c, d, x[ 2], S21); /* 25 */ + GG (d, a, b, c, x[ 6], S22); /* 26 */ + GG (c, d, a, b, x[10], S23); /* 27 */ + GG (b, c, d, a, x[14], S24); /* 28 */ + GG (a, b, c, d, x[ 3], S21); /* 29 */ + GG (d, a, b, c, x[ 7], S22); /* 30 */ + GG (c, d, a, b, x[11], S23); /* 31 */ + GG (b, c, d, a, x[15], S24); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 0], S31); /* 33 */ + HH (d, a, b, c, x[ 8], S32); /* 34 */ + HH (c, d, a, b, x[ 4], S33); /* 35 */ + HH (b, c, d, a, x[12], S34); /* 36 */ + HH (a, b, c, d, x[ 2], S31); /* 37 */ + HH (d, a, b, c, x[10], S32); /* 38 */ + HH (c, d, a, b, x[ 6], S33); /* 39 */ + HH (b, c, d, a, x[14], S34); /* 40 */ + HH (a, b, c, d, x[ 1], S31); /* 41 */ + HH (d, a, b, c, x[ 9], S32); /* 42 */ + HH (c, d, a, b, x[ 5], S33); /* 43 */ + HH (b, c, d, a, x[13], S34); /* 44 */ + HH (a, b, c, d, x[ 3], S31); /* 45 */ + HH (d, a, b, c, x[11], S32); /* 46 */ + HH (c, d, a, b, x[ 7], S33); /* 47 */ + HH (b, c, d, a, x[15], S34); /* 48 */ + + + /* Update our state */ + md->md4.state[0] = md->md4.state[0] + a; + md->md4.state[1] = md->md4.state[1] + b; + md->md4.state[2] = md->md4.state[2] + c; + md->md4.state[3] = md->md4.state[3] + d; + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +static int md4_compress(hash_state *md, unsigned char *buf) +{ + int err; + err = _md4_compress(md, buf); + burn_stack(sizeof(ulong32) * 20 + sizeof(int)); + return err; +} +#endif + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int md4_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + md->md4.state[0] = 0x67452301UL; + md->md4.state[1] = 0xefcdab89UL; + md->md4.state[2] = 0x98badcfeUL; + md->md4.state[3] = 0x10325476UL; + md->md4.length = 0; + md->md4.curlen = 0; + return CRYPT_OK; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +HASH_PROCESS(md4_process, md4_compress, md4, 64) + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (16 bytes) + @return CRYPT_OK if successful +*/ +int md4_done(hash_state * md, unsigned char *out) +{ + int i; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->md4.curlen >= sizeof(md->md4.buf)) { + return CRYPT_INVALID_ARG; + } + + /* increase the length of the message */ + md->md4.length += md->md4.curlen * 8; + + /* append the '1' bit */ + md->md4.buf[md->md4.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->md4.curlen > 56) { + while (md->md4.curlen < 64) { + md->md4.buf[md->md4.curlen++] = (unsigned char)0; + } + md4_compress(md, md->md4.buf); + md->md4.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->md4.curlen < 56) { + md->md4.buf[md->md4.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->md4.length, md->md4.buf+56); + md4_compress(md, md->md4.buf); + + /* copy output */ + for (i = 0; i < 4; i++) { + STORE32L(md->md4.state[i], out+(4*i)); + } +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int md4_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct md4_test_case { + char *input; + unsigned char digest[16]; + } cases[] = { + { "", + {0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31, + 0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0} }, + { "a", + {0xbd, 0xe5, 0x2c, 0xb3, 0x1d, 0xe3, 0x3e, 0x46, + 0x24, 0x5e, 0x05, 0xfb, 0xdb, 0xd6, 0xfb, 0x24} }, + { "abc", + {0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52, + 0x5f, 0xc1, 0x0a, 0xe8, 0x7a, 0xa6, 0x72, 0x9d} }, + { "message digest", + {0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8, + 0x18, 0x87, 0x48, 0x06, 0xe1, 0xc7, 0x01, 0x4b} }, + { "abcdefghijklmnopqrstuvwxyz", + {0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd, + 0xee, 0xa8, 0xed, 0x63, 0xdf, 0x41, 0x2d, 0xa9} }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + {0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35, + 0x1c, 0xe6, 0x27, 0xe1, 0x53, 0xe7, 0xf0, 0xe4} }, + { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", + {0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19, + 0x9c, 0x3e, 0x7b, 0x16, 0x4f, 0xcc, 0x05, 0x36} }, + }; + int i; + hash_state md; + unsigned char digest[16]; + + for(i = 0; i < (int)(sizeof(cases) / sizeof(cases[0])); i++) { + md4_init(&md); + md4_process(&md, (unsigned char *)cases[i].input, (unsigned long)strlen(cases[i].input)); + md4_done(&md, digest); + if (XMEMCMP(digest, cases[i].digest, 16) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + } + return CRYPT_OK; + #endif +} + +#endif + + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/hashes/md5.c b/src/ltc/hashes/md5.c new file mode 100644 index 0000000..1d0ec92 --- /dev/null +++ b/src/ltc/hashes/md5.c @@ -0,0 +1,368 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + + +/** + @file md5.c + LTC_MD5 hash function by Tom St Denis +*/ + +#ifdef LTC_MD5 + +const struct ltc_hash_descriptor md5_desc = +{ + "md5", + 3, + 16, + 64, + + /* OID */ + { 1, 2, 840, 113549, 2, 5, }, + 6, + + &md5_init, + &md5_process, + &md5_done, + &md5_test, + NULL +}; + +#define F(x,y,z) (z ^ (x & (y ^ z))) +#define G(x,y,z) (y ^ (z & (y ^ x))) +#define H(x,y,z) (x^y^z) +#define I(x,y,z) (y^(x|(~z))) + +#ifdef LTC_SMALL_CODE + +#define FF(a,b,c,d,M,s,t) \ + a = (a + F(b,c,d) + M + t); a = ROL(a, s) + b; + +#define GG(a,b,c,d,M,s,t) \ + a = (a + G(b,c,d) + M + t); a = ROL(a, s) + b; + +#define HH(a,b,c,d,M,s,t) \ + a = (a + H(b,c,d) + M + t); a = ROL(a, s) + b; + +#define II(a,b,c,d,M,s,t) \ + a = (a + I(b,c,d) + M + t); a = ROL(a, s) + b; + +static const unsigned char Worder[64] = { + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12, + 5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2, + 0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9 +}; + +static const unsigned char Rorder[64] = { + 7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22, + 5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20, + 4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23, + 6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21 +}; + +static const ulong32 Korder[64] = { +0xd76aa478UL, 0xe8c7b756UL, 0x242070dbUL, 0xc1bdceeeUL, 0xf57c0fafUL, 0x4787c62aUL, 0xa8304613UL, 0xfd469501UL, +0x698098d8UL, 0x8b44f7afUL, 0xffff5bb1UL, 0x895cd7beUL, 0x6b901122UL, 0xfd987193UL, 0xa679438eUL, 0x49b40821UL, +0xf61e2562UL, 0xc040b340UL, 0x265e5a51UL, 0xe9b6c7aaUL, 0xd62f105dUL, 0x02441453UL, 0xd8a1e681UL, 0xe7d3fbc8UL, +0x21e1cde6UL, 0xc33707d6UL, 0xf4d50d87UL, 0x455a14edUL, 0xa9e3e905UL, 0xfcefa3f8UL, 0x676f02d9UL, 0x8d2a4c8aUL, +0xfffa3942UL, 0x8771f681UL, 0x6d9d6122UL, 0xfde5380cUL, 0xa4beea44UL, 0x4bdecfa9UL, 0xf6bb4b60UL, 0xbebfbc70UL, +0x289b7ec6UL, 0xeaa127faUL, 0xd4ef3085UL, 0x04881d05UL, 0xd9d4d039UL, 0xe6db99e5UL, 0x1fa27cf8UL, 0xc4ac5665UL, +0xf4292244UL, 0x432aff97UL, 0xab9423a7UL, 0xfc93a039UL, 0x655b59c3UL, 0x8f0ccc92UL, 0xffeff47dUL, 0x85845dd1UL, +0x6fa87e4fUL, 0xfe2ce6e0UL, 0xa3014314UL, 0x4e0811a1UL, 0xf7537e82UL, 0xbd3af235UL, 0x2ad7d2bbUL, 0xeb86d391UL +}; + +#else + +#define FF(a,b,c,d,M,s,t) \ + a = (a + F(b,c,d) + M + t); a = ROLc(a, s) + b; + +#define GG(a,b,c,d,M,s,t) \ + a = (a + G(b,c,d) + M + t); a = ROLc(a, s) + b; + +#define HH(a,b,c,d,M,s,t) \ + a = (a + H(b,c,d) + M + t); a = ROLc(a, s) + b; + +#define II(a,b,c,d,M,s,t) \ + a = (a + I(b,c,d) + M + t); a = ROLc(a, s) + b; + + +#endif + +#ifdef LTC_CLEAN_STACK +static int _md5_compress(hash_state *md, unsigned char *buf) +#else +static int md5_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong32 i, W[16], a, b, c, d; +#ifdef LTC_SMALL_CODE + ulong32 t; +#endif + + /* copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) { + LOAD32L(W[i], buf + (4*i)); + } + + /* copy state */ + a = md->md5.state[0]; + b = md->md5.state[1]; + c = md->md5.state[2]; + d = md->md5.state[3]; + +#ifdef LTC_SMALL_CODE + for (i = 0; i < 16; ++i) { + FF(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]); + t = d; d = c; c = b; b = a; a = t; + } + + for (; i < 32; ++i) { + GG(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]); + t = d; d = c; c = b; b = a; a = t; + } + + for (; i < 48; ++i) { + HH(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]); + t = d; d = c; c = b; b = a; a = t; + } + + for (; i < 64; ++i) { + II(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]); + t = d; d = c; c = b; b = a; a = t; + } + +#else + FF(a,b,c,d,W[0],7,0xd76aa478UL) + FF(d,a,b,c,W[1],12,0xe8c7b756UL) + FF(c,d,a,b,W[2],17,0x242070dbUL) + FF(b,c,d,a,W[3],22,0xc1bdceeeUL) + FF(a,b,c,d,W[4],7,0xf57c0fafUL) + FF(d,a,b,c,W[5],12,0x4787c62aUL) + FF(c,d,a,b,W[6],17,0xa8304613UL) + FF(b,c,d,a,W[7],22,0xfd469501UL) + FF(a,b,c,d,W[8],7,0x698098d8UL) + FF(d,a,b,c,W[9],12,0x8b44f7afUL) + FF(c,d,a,b,W[10],17,0xffff5bb1UL) + FF(b,c,d,a,W[11],22,0x895cd7beUL) + FF(a,b,c,d,W[12],7,0x6b901122UL) + FF(d,a,b,c,W[13],12,0xfd987193UL) + FF(c,d,a,b,W[14],17,0xa679438eUL) + FF(b,c,d,a,W[15],22,0x49b40821UL) + GG(a,b,c,d,W[1],5,0xf61e2562UL) + GG(d,a,b,c,W[6],9,0xc040b340UL) + GG(c,d,a,b,W[11],14,0x265e5a51UL) + GG(b,c,d,a,W[0],20,0xe9b6c7aaUL) + GG(a,b,c,d,W[5],5,0xd62f105dUL) + GG(d,a,b,c,W[10],9,0x02441453UL) + GG(c,d,a,b,W[15],14,0xd8a1e681UL) + GG(b,c,d,a,W[4],20,0xe7d3fbc8UL) + GG(a,b,c,d,W[9],5,0x21e1cde6UL) + GG(d,a,b,c,W[14],9,0xc33707d6UL) + GG(c,d,a,b,W[3],14,0xf4d50d87UL) + GG(b,c,d,a,W[8],20,0x455a14edUL) + GG(a,b,c,d,W[13],5,0xa9e3e905UL) + GG(d,a,b,c,W[2],9,0xfcefa3f8UL) + GG(c,d,a,b,W[7],14,0x676f02d9UL) + GG(b,c,d,a,W[12],20,0x8d2a4c8aUL) + HH(a,b,c,d,W[5],4,0xfffa3942UL) + HH(d,a,b,c,W[8],11,0x8771f681UL) + HH(c,d,a,b,W[11],16,0x6d9d6122UL) + HH(b,c,d,a,W[14],23,0xfde5380cUL) + HH(a,b,c,d,W[1],4,0xa4beea44UL) + HH(d,a,b,c,W[4],11,0x4bdecfa9UL) + HH(c,d,a,b,W[7],16,0xf6bb4b60UL) + HH(b,c,d,a,W[10],23,0xbebfbc70UL) + HH(a,b,c,d,W[13],4,0x289b7ec6UL) + HH(d,a,b,c,W[0],11,0xeaa127faUL) + HH(c,d,a,b,W[3],16,0xd4ef3085UL) + HH(b,c,d,a,W[6],23,0x04881d05UL) + HH(a,b,c,d,W[9],4,0xd9d4d039UL) + HH(d,a,b,c,W[12],11,0xe6db99e5UL) + HH(c,d,a,b,W[15],16,0x1fa27cf8UL) + HH(b,c,d,a,W[2],23,0xc4ac5665UL) + II(a,b,c,d,W[0],6,0xf4292244UL) + II(d,a,b,c,W[7],10,0x432aff97UL) + II(c,d,a,b,W[14],15,0xab9423a7UL) + II(b,c,d,a,W[5],21,0xfc93a039UL) + II(a,b,c,d,W[12],6,0x655b59c3UL) + II(d,a,b,c,W[3],10,0x8f0ccc92UL) + II(c,d,a,b,W[10],15,0xffeff47dUL) + II(b,c,d,a,W[1],21,0x85845dd1UL) + II(a,b,c,d,W[8],6,0x6fa87e4fUL) + II(d,a,b,c,W[15],10,0xfe2ce6e0UL) + II(c,d,a,b,W[6],15,0xa3014314UL) + II(b,c,d,a,W[13],21,0x4e0811a1UL) + II(a,b,c,d,W[4],6,0xf7537e82UL) + II(d,a,b,c,W[11],10,0xbd3af235UL) + II(c,d,a,b,W[2],15,0x2ad7d2bbUL) + II(b,c,d,a,W[9],21,0xeb86d391UL) +#endif + + md->md5.state[0] = md->md5.state[0] + a; + md->md5.state[1] = md->md5.state[1] + b; + md->md5.state[2] = md->md5.state[2] + c; + md->md5.state[3] = md->md5.state[3] + d; + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +static int md5_compress(hash_state *md, unsigned char *buf) +{ + int err; + err = _md5_compress(md, buf); + burn_stack(sizeof(ulong32) * 21); + return err; +} +#endif + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int md5_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + md->md5.state[0] = 0x67452301UL; + md->md5.state[1] = 0xefcdab89UL; + md->md5.state[2] = 0x98badcfeUL; + md->md5.state[3] = 0x10325476UL; + md->md5.curlen = 0; + md->md5.length = 0; + return CRYPT_OK; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +HASH_PROCESS(md5_process, md5_compress, md5, 64) + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (16 bytes) + @return CRYPT_OK if successful +*/ +int md5_done(hash_state * md, unsigned char *out) +{ + int i; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->md5.curlen >= sizeof(md->md5.buf)) { + return CRYPT_INVALID_ARG; + } + + + /* increase the length of the message */ + md->md5.length += md->md5.curlen * 8; + + /* append the '1' bit */ + md->md5.buf[md->md5.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->md5.curlen > 56) { + while (md->md5.curlen < 64) { + md->md5.buf[md->md5.curlen++] = (unsigned char)0; + } + md5_compress(md, md->md5.buf); + md->md5.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->md5.curlen < 56) { + md->md5.buf[md->md5.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->md5.length, md->md5.buf+56); + md5_compress(md, md->md5.buf); + + /* copy output */ + for (i = 0; i < 4; i++) { + STORE32L(md->md5.state[i], out+(4*i)); + } +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int md5_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[16]; + } tests[] = { + { "", + { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, + 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } }, + { "a", + {0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8, + 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } }, + { "abc", + { 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, + 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } }, + { "message digest", + { 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d, + 0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } }, + { "abcdefghijklmnopqrstuvwxyz", + { 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00, + 0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b } }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + { 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5, + 0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f } }, + { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", + { 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55, + 0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } }, + { NULL, { 0 } } + }; + + int i; + unsigned char tmp[16]; + hash_state md; + + for (i = 0; tests[i].msg != NULL; i++) { + md5_init(&md); + md5_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + md5_done(&md, tmp); + if (XMEMCMP(tmp, tests[i].hash, 16) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#endif + + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/hashes/rmd128.c b/src/ltc/hashes/rmd128.c new file mode 100644 index 0000000..af16f1f --- /dev/null +++ b/src/ltc/hashes/rmd128.c @@ -0,0 +1,410 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @param rmd128.c + RMD128 Hash function +*/ + +/* Implementation of LTC_RIPEMD-128 based on the source by Antoon Bosselaers, ESAT-COSIC + * + * This source has been radically overhauled to be portable and work within + * the LibTomCrypt API by Tom St Denis + */ + +#ifdef LTC_RIPEMD128 + +const struct ltc_hash_descriptor rmd128_desc = +{ + "rmd128", + 8, + 16, + 64, + + /* OID */ + { 1, 0, 10118, 3, 0, 50 }, + 6, + + &rmd128_init, + &rmd128_process, + &rmd128_done, + &rmd128_test, + NULL +}; + +/* the four basic functions F(), G() and H() */ +#define F(x, y, z) ((x) ^ (y) ^ (z)) +#define G(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define H(x, y, z) (((x) | ~(y)) ^ (z)) +#define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) + +/* the eight basic operations FF() through III() */ +#define FF(a, b, c, d, x, s) \ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROLc((a), (s)); + +#define GG(a, b, c, d, x, s) \ + (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ + (a) = ROLc((a), (s)); + +#define HH(a, b, c, d, x, s) \ + (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ + (a) = ROLc((a), (s)); + +#define II(a, b, c, d, x, s) \ + (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ + (a) = ROLc((a), (s)); + +#define FFF(a, b, c, d, x, s) \ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROLc((a), (s)); + +#define GGG(a, b, c, d, x, s) \ + (a) += G((b), (c), (d)) + (x) + 0x6d703ef3UL;\ + (a) = ROLc((a), (s)); + +#define HHH(a, b, c, d, x, s) \ + (a) += H((b), (c), (d)) + (x) + 0x5c4dd124UL;\ + (a) = ROLc((a), (s)); + +#define III(a, b, c, d, x, s) \ + (a) += I((b), (c), (d)) + (x) + 0x50a28be6UL;\ + (a) = ROLc((a), (s)); + +#ifdef LTC_CLEAN_STACK +static int _rmd128_compress(hash_state *md, unsigned char *buf) +#else +static int rmd128_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong32 aa,bb,cc,dd,aaa,bbb,ccc,ddd,X[16]; + int i; + + /* load words X */ + for (i = 0; i < 16; i++){ + LOAD32L(X[i], buf + (4 * i)); + } + + /* load state */ + aa = aaa = md->rmd128.state[0]; + bb = bbb = md->rmd128.state[1]; + cc = ccc = md->rmd128.state[2]; + dd = ddd = md->rmd128.state[3]; + + /* round 1 */ + FF(aa, bb, cc, dd, X[ 0], 11); + FF(dd, aa, bb, cc, X[ 1], 14); + FF(cc, dd, aa, bb, X[ 2], 15); + FF(bb, cc, dd, aa, X[ 3], 12); + FF(aa, bb, cc, dd, X[ 4], 5); + FF(dd, aa, bb, cc, X[ 5], 8); + FF(cc, dd, aa, bb, X[ 6], 7); + FF(bb, cc, dd, aa, X[ 7], 9); + FF(aa, bb, cc, dd, X[ 8], 11); + FF(dd, aa, bb, cc, X[ 9], 13); + FF(cc, dd, aa, bb, X[10], 14); + FF(bb, cc, dd, aa, X[11], 15); + FF(aa, bb, cc, dd, X[12], 6); + FF(dd, aa, bb, cc, X[13], 7); + FF(cc, dd, aa, bb, X[14], 9); + FF(bb, cc, dd, aa, X[15], 8); + + /* round 2 */ + GG(aa, bb, cc, dd, X[ 7], 7); + GG(dd, aa, bb, cc, X[ 4], 6); + GG(cc, dd, aa, bb, X[13], 8); + GG(bb, cc, dd, aa, X[ 1], 13); + GG(aa, bb, cc, dd, X[10], 11); + GG(dd, aa, bb, cc, X[ 6], 9); + GG(cc, dd, aa, bb, X[15], 7); + GG(bb, cc, dd, aa, X[ 3], 15); + GG(aa, bb, cc, dd, X[12], 7); + GG(dd, aa, bb, cc, X[ 0], 12); + GG(cc, dd, aa, bb, X[ 9], 15); + GG(bb, cc, dd, aa, X[ 5], 9); + GG(aa, bb, cc, dd, X[ 2], 11); + GG(dd, aa, bb, cc, X[14], 7); + GG(cc, dd, aa, bb, X[11], 13); + GG(bb, cc, dd, aa, X[ 8], 12); + + /* round 3 */ + HH(aa, bb, cc, dd, X[ 3], 11); + HH(dd, aa, bb, cc, X[10], 13); + HH(cc, dd, aa, bb, X[14], 6); + HH(bb, cc, dd, aa, X[ 4], 7); + HH(aa, bb, cc, dd, X[ 9], 14); + HH(dd, aa, bb, cc, X[15], 9); + HH(cc, dd, aa, bb, X[ 8], 13); + HH(bb, cc, dd, aa, X[ 1], 15); + HH(aa, bb, cc, dd, X[ 2], 14); + HH(dd, aa, bb, cc, X[ 7], 8); + HH(cc, dd, aa, bb, X[ 0], 13); + HH(bb, cc, dd, aa, X[ 6], 6); + HH(aa, bb, cc, dd, X[13], 5); + HH(dd, aa, bb, cc, X[11], 12); + HH(cc, dd, aa, bb, X[ 5], 7); + HH(bb, cc, dd, aa, X[12], 5); + + /* round 4 */ + II(aa, bb, cc, dd, X[ 1], 11); + II(dd, aa, bb, cc, X[ 9], 12); + II(cc, dd, aa, bb, X[11], 14); + II(bb, cc, dd, aa, X[10], 15); + II(aa, bb, cc, dd, X[ 0], 14); + II(dd, aa, bb, cc, X[ 8], 15); + II(cc, dd, aa, bb, X[12], 9); + II(bb, cc, dd, aa, X[ 4], 8); + II(aa, bb, cc, dd, X[13], 9); + II(dd, aa, bb, cc, X[ 3], 14); + II(cc, dd, aa, bb, X[ 7], 5); + II(bb, cc, dd, aa, X[15], 6); + II(aa, bb, cc, dd, X[14], 8); + II(dd, aa, bb, cc, X[ 5], 6); + II(cc, dd, aa, bb, X[ 6], 5); + II(bb, cc, dd, aa, X[ 2], 12); + + /* parallel round 1 */ + III(aaa, bbb, ccc, ddd, X[ 5], 8); + III(ddd, aaa, bbb, ccc, X[14], 9); + III(ccc, ddd, aaa, bbb, X[ 7], 9); + III(bbb, ccc, ddd, aaa, X[ 0], 11); + III(aaa, bbb, ccc, ddd, X[ 9], 13); + III(ddd, aaa, bbb, ccc, X[ 2], 15); + III(ccc, ddd, aaa, bbb, X[11], 15); + III(bbb, ccc, ddd, aaa, X[ 4], 5); + III(aaa, bbb, ccc, ddd, X[13], 7); + III(ddd, aaa, bbb, ccc, X[ 6], 7); + III(ccc, ddd, aaa, bbb, X[15], 8); + III(bbb, ccc, ddd, aaa, X[ 8], 11); + III(aaa, bbb, ccc, ddd, X[ 1], 14); + III(ddd, aaa, bbb, ccc, X[10], 14); + III(ccc, ddd, aaa, bbb, X[ 3], 12); + III(bbb, ccc, ddd, aaa, X[12], 6); + + /* parallel round 2 */ + HHH(aaa, bbb, ccc, ddd, X[ 6], 9); + HHH(ddd, aaa, bbb, ccc, X[11], 13); + HHH(ccc, ddd, aaa, bbb, X[ 3], 15); + HHH(bbb, ccc, ddd, aaa, X[ 7], 7); + HHH(aaa, bbb, ccc, ddd, X[ 0], 12); + HHH(ddd, aaa, bbb, ccc, X[13], 8); + HHH(ccc, ddd, aaa, bbb, X[ 5], 9); + HHH(bbb, ccc, ddd, aaa, X[10], 11); + HHH(aaa, bbb, ccc, ddd, X[14], 7); + HHH(ddd, aaa, bbb, ccc, X[15], 7); + HHH(ccc, ddd, aaa, bbb, X[ 8], 12); + HHH(bbb, ccc, ddd, aaa, X[12], 7); + HHH(aaa, bbb, ccc, ddd, X[ 4], 6); + HHH(ddd, aaa, bbb, ccc, X[ 9], 15); + HHH(ccc, ddd, aaa, bbb, X[ 1], 13); + HHH(bbb, ccc, ddd, aaa, X[ 2], 11); + + /* parallel round 3 */ + GGG(aaa, bbb, ccc, ddd, X[15], 9); + GGG(ddd, aaa, bbb, ccc, X[ 5], 7); + GGG(ccc, ddd, aaa, bbb, X[ 1], 15); + GGG(bbb, ccc, ddd, aaa, X[ 3], 11); + GGG(aaa, bbb, ccc, ddd, X[ 7], 8); + GGG(ddd, aaa, bbb, ccc, X[14], 6); + GGG(ccc, ddd, aaa, bbb, X[ 6], 6); + GGG(bbb, ccc, ddd, aaa, X[ 9], 14); + GGG(aaa, bbb, ccc, ddd, X[11], 12); + GGG(ddd, aaa, bbb, ccc, X[ 8], 13); + GGG(ccc, ddd, aaa, bbb, X[12], 5); + GGG(bbb, ccc, ddd, aaa, X[ 2], 14); + GGG(aaa, bbb, ccc, ddd, X[10], 13); + GGG(ddd, aaa, bbb, ccc, X[ 0], 13); + GGG(ccc, ddd, aaa, bbb, X[ 4], 7); + GGG(bbb, ccc, ddd, aaa, X[13], 5); + + /* parallel round 4 */ + FFF(aaa, bbb, ccc, ddd, X[ 8], 15); + FFF(ddd, aaa, bbb, ccc, X[ 6], 5); + FFF(ccc, ddd, aaa, bbb, X[ 4], 8); + FFF(bbb, ccc, ddd, aaa, X[ 1], 11); + FFF(aaa, bbb, ccc, ddd, X[ 3], 14); + FFF(ddd, aaa, bbb, ccc, X[11], 14); + FFF(ccc, ddd, aaa, bbb, X[15], 6); + FFF(bbb, ccc, ddd, aaa, X[ 0], 14); + FFF(aaa, bbb, ccc, ddd, X[ 5], 6); + FFF(ddd, aaa, bbb, ccc, X[12], 9); + FFF(ccc, ddd, aaa, bbb, X[ 2], 12); + FFF(bbb, ccc, ddd, aaa, X[13], 9); + FFF(aaa, bbb, ccc, ddd, X[ 9], 12); + FFF(ddd, aaa, bbb, ccc, X[ 7], 5); + FFF(ccc, ddd, aaa, bbb, X[10], 15); + FFF(bbb, ccc, ddd, aaa, X[14], 8); + + /* combine results */ + ddd += cc + md->rmd128.state[1]; /* final result for MDbuf[0] */ + md->rmd128.state[1] = md->rmd128.state[2] + dd + aaa; + md->rmd128.state[2] = md->rmd128.state[3] + aa + bbb; + md->rmd128.state[3] = md->rmd128.state[0] + bb + ccc; + md->rmd128.state[0] = ddd; + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +static int rmd128_compress(hash_state *md, unsigned char *buf) +{ + int err; + err = _rmd128_compress(md, buf); + burn_stack(sizeof(ulong32) * 24 + sizeof(int)); + return err; +} +#endif + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int rmd128_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + md->rmd128.state[0] = 0x67452301UL; + md->rmd128.state[1] = 0xefcdab89UL; + md->rmd128.state[2] = 0x98badcfeUL; + md->rmd128.state[3] = 0x10325476UL; + md->rmd128.curlen = 0; + md->rmd128.length = 0; + return CRYPT_OK; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +HASH_PROCESS(rmd128_process, rmd128_compress, rmd128, 64) + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (16 bytes) + @return CRYPT_OK if successful +*/ +int rmd128_done(hash_state * md, unsigned char *out) +{ + int i; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->rmd128.curlen >= sizeof(md->rmd128.buf)) { + return CRYPT_INVALID_ARG; + } + + + /* increase the length of the message */ + md->rmd128.length += md->rmd128.curlen * 8; + + /* append the '1' bit */ + md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->rmd128.curlen > 56) { + while (md->rmd128.curlen < 64) { + md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0; + } + rmd128_compress(md, md->rmd128.buf); + md->rmd128.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->rmd128.curlen < 56) { + md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->rmd128.length, md->rmd128.buf+56); + rmd128_compress(md, md->rmd128.buf); + + /* copy output */ + for (i = 0; i < 4; i++) { + STORE32L(md->rmd128.state[i], out+(4*i)); + } +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int rmd128_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + char *msg; + unsigned char md[16]; + } tests[] = { + { "", + { 0xcd, 0xf2, 0x62, 0x13, 0xa1, 0x50, 0xdc, 0x3e, + 0xcb, 0x61, 0x0f, 0x18, 0xf6, 0xb3, 0x8b, 0x46 } + }, + { "a", + { 0x86, 0xbe, 0x7a, 0xfa, 0x33, 0x9d, 0x0f, 0xc7, + 0xcf, 0xc7, 0x85, 0xe7, 0x2f, 0x57, 0x8d, 0x33 } + }, + { "abc", + { 0xc1, 0x4a, 0x12, 0x19, 0x9c, 0x66, 0xe4, 0xba, + 0x84, 0x63, 0x6b, 0x0f, 0x69, 0x14, 0x4c, 0x77 } + }, + { "message digest", + { 0x9e, 0x32, 0x7b, 0x3d, 0x6e, 0x52, 0x30, 0x62, + 0xaf, 0xc1, 0x13, 0x2d, 0x7d, 0xf9, 0xd1, 0xb8 } + }, + { "abcdefghijklmnopqrstuvwxyz", + { 0xfd, 0x2a, 0xa6, 0x07, 0xf7, 0x1d, 0xc8, 0xf5, + 0x10, 0x71, 0x49, 0x22, 0xb3, 0x71, 0x83, 0x4e } + }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + { 0xd1, 0xe9, 0x59, 0xeb, 0x17, 0x9c, 0x91, 0x1f, + 0xae, 0xa4, 0x62, 0x4c, 0x60, 0xc5, 0xc7, 0x02 } + } + }; + int x; + unsigned char buf[16]; + hash_state md; + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + rmd128_init(&md); + rmd128_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg)); + rmd128_done(&md, buf); + if (XMEMCMP(buf, tests[x].md, 16) != 0) { + #if 0 + printf("Failed test %d\n", x); + #endif + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +#endif +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/hashes/rmd160.c b/src/ltc/hashes/rmd160.c new file mode 100644 index 0000000..ac41e5b --- /dev/null +++ b/src/ltc/hashes/rmd160.c @@ -0,0 +1,469 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file rmd160.c + RMD160 hash function +*/ + +/* Implementation of LTC_RIPEMD-160 based on the source by Antoon Bosselaers, ESAT-COSIC + * + * This source has been radically overhauled to be portable and work within + * the LibTomCrypt API by Tom St Denis + */ + +#ifdef LTC_RIPEMD160 + +const struct ltc_hash_descriptor rmd160_desc = +{ + "rmd160", + 9, + 20, + 64, + + /* OID */ + { 1, 3, 36, 3, 2, 1, }, + 6, + + &rmd160_init, + &rmd160_process, + &rmd160_done, + &rmd160_test, + NULL +}; + +/* the five basic functions F(), G() and H() */ +#define F(x, y, z) ((x) ^ (y) ^ (z)) +#define G(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define H(x, y, z) (((x) | ~(y)) ^ (z)) +#define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) +#define J(x, y, z) ((x) ^ ((y) | ~(z))) + +/* the ten basic operations FF() through III() */ +#define FF(a, b, c, d, e, x, s) \ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define GG(a, b, c, d, e, x, s) \ + (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define HH(a, b, c, d, e, x, s) \ + (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define II(a, b, c, d, e, x, s) \ + (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define JJ(a, b, c, d, e, x, s) \ + (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define FFF(a, b, c, d, e, x, s) \ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define GGG(a, b, c, d, e, x, s) \ + (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define HHH(a, b, c, d, e, x, s) \ + (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define III(a, b, c, d, e, x, s) \ + (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define JJJ(a, b, c, d, e, x, s) \ + (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + + +#ifdef LTC_CLEAN_STACK +static int _rmd160_compress(hash_state *md, unsigned char *buf) +#else +static int rmd160_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong32 aa,bb,cc,dd,ee,aaa,bbb,ccc,ddd,eee,X[16]; + int i; + + /* load words X */ + for (i = 0; i < 16; i++){ + LOAD32L(X[i], buf + (4 * i)); + } + + /* load state */ + aa = aaa = md->rmd160.state[0]; + bb = bbb = md->rmd160.state[1]; + cc = ccc = md->rmd160.state[2]; + dd = ddd = md->rmd160.state[3]; + ee = eee = md->rmd160.state[4]; + + /* round 1 */ + FF(aa, bb, cc, dd, ee, X[ 0], 11); + FF(ee, aa, bb, cc, dd, X[ 1], 14); + FF(dd, ee, aa, bb, cc, X[ 2], 15); + FF(cc, dd, ee, aa, bb, X[ 3], 12); + FF(bb, cc, dd, ee, aa, X[ 4], 5); + FF(aa, bb, cc, dd, ee, X[ 5], 8); + FF(ee, aa, bb, cc, dd, X[ 6], 7); + FF(dd, ee, aa, bb, cc, X[ 7], 9); + FF(cc, dd, ee, aa, bb, X[ 8], 11); + FF(bb, cc, dd, ee, aa, X[ 9], 13); + FF(aa, bb, cc, dd, ee, X[10], 14); + FF(ee, aa, bb, cc, dd, X[11], 15); + FF(dd, ee, aa, bb, cc, X[12], 6); + FF(cc, dd, ee, aa, bb, X[13], 7); + FF(bb, cc, dd, ee, aa, X[14], 9); + FF(aa, bb, cc, dd, ee, X[15], 8); + + /* round 2 */ + GG(ee, aa, bb, cc, dd, X[ 7], 7); + GG(dd, ee, aa, bb, cc, X[ 4], 6); + GG(cc, dd, ee, aa, bb, X[13], 8); + GG(bb, cc, dd, ee, aa, X[ 1], 13); + GG(aa, bb, cc, dd, ee, X[10], 11); + GG(ee, aa, bb, cc, dd, X[ 6], 9); + GG(dd, ee, aa, bb, cc, X[15], 7); + GG(cc, dd, ee, aa, bb, X[ 3], 15); + GG(bb, cc, dd, ee, aa, X[12], 7); + GG(aa, bb, cc, dd, ee, X[ 0], 12); + GG(ee, aa, bb, cc, dd, X[ 9], 15); + GG(dd, ee, aa, bb, cc, X[ 5], 9); + GG(cc, dd, ee, aa, bb, X[ 2], 11); + GG(bb, cc, dd, ee, aa, X[14], 7); + GG(aa, bb, cc, dd, ee, X[11], 13); + GG(ee, aa, bb, cc, dd, X[ 8], 12); + + /* round 3 */ + HH(dd, ee, aa, bb, cc, X[ 3], 11); + HH(cc, dd, ee, aa, bb, X[10], 13); + HH(bb, cc, dd, ee, aa, X[14], 6); + HH(aa, bb, cc, dd, ee, X[ 4], 7); + HH(ee, aa, bb, cc, dd, X[ 9], 14); + HH(dd, ee, aa, bb, cc, X[15], 9); + HH(cc, dd, ee, aa, bb, X[ 8], 13); + HH(bb, cc, dd, ee, aa, X[ 1], 15); + HH(aa, bb, cc, dd, ee, X[ 2], 14); + HH(ee, aa, bb, cc, dd, X[ 7], 8); + HH(dd, ee, aa, bb, cc, X[ 0], 13); + HH(cc, dd, ee, aa, bb, X[ 6], 6); + HH(bb, cc, dd, ee, aa, X[13], 5); + HH(aa, bb, cc, dd, ee, X[11], 12); + HH(ee, aa, bb, cc, dd, X[ 5], 7); + HH(dd, ee, aa, bb, cc, X[12], 5); + + /* round 4 */ + II(cc, dd, ee, aa, bb, X[ 1], 11); + II(bb, cc, dd, ee, aa, X[ 9], 12); + II(aa, bb, cc, dd, ee, X[11], 14); + II(ee, aa, bb, cc, dd, X[10], 15); + II(dd, ee, aa, bb, cc, X[ 0], 14); + II(cc, dd, ee, aa, bb, X[ 8], 15); + II(bb, cc, dd, ee, aa, X[12], 9); + II(aa, bb, cc, dd, ee, X[ 4], 8); + II(ee, aa, bb, cc, dd, X[13], 9); + II(dd, ee, aa, bb, cc, X[ 3], 14); + II(cc, dd, ee, aa, bb, X[ 7], 5); + II(bb, cc, dd, ee, aa, X[15], 6); + II(aa, bb, cc, dd, ee, X[14], 8); + II(ee, aa, bb, cc, dd, X[ 5], 6); + II(dd, ee, aa, bb, cc, X[ 6], 5); + II(cc, dd, ee, aa, bb, X[ 2], 12); + + /* round 5 */ + JJ(bb, cc, dd, ee, aa, X[ 4], 9); + JJ(aa, bb, cc, dd, ee, X[ 0], 15); + JJ(ee, aa, bb, cc, dd, X[ 5], 5); + JJ(dd, ee, aa, bb, cc, X[ 9], 11); + JJ(cc, dd, ee, aa, bb, X[ 7], 6); + JJ(bb, cc, dd, ee, aa, X[12], 8); + JJ(aa, bb, cc, dd, ee, X[ 2], 13); + JJ(ee, aa, bb, cc, dd, X[10], 12); + JJ(dd, ee, aa, bb, cc, X[14], 5); + JJ(cc, dd, ee, aa, bb, X[ 1], 12); + JJ(bb, cc, dd, ee, aa, X[ 3], 13); + JJ(aa, bb, cc, dd, ee, X[ 8], 14); + JJ(ee, aa, bb, cc, dd, X[11], 11); + JJ(dd, ee, aa, bb, cc, X[ 6], 8); + JJ(cc, dd, ee, aa, bb, X[15], 5); + JJ(bb, cc, dd, ee, aa, X[13], 6); + + /* parallel round 1 */ + JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8); + JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9); + JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13); + JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15); + JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5); + JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7); + JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8); + JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14); + JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12); + JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6); + + /* parallel round 2 */ + III(eee, aaa, bbb, ccc, ddd, X[ 6], 9); + III(ddd, eee, aaa, bbb, ccc, X[11], 13); + III(ccc, ddd, eee, aaa, bbb, X[ 3], 15); + III(bbb, ccc, ddd, eee, aaa, X[ 7], 7); + III(aaa, bbb, ccc, ddd, eee, X[ 0], 12); + III(eee, aaa, bbb, ccc, ddd, X[13], 8); + III(ddd, eee, aaa, bbb, ccc, X[ 5], 9); + III(ccc, ddd, eee, aaa, bbb, X[10], 11); + III(bbb, ccc, ddd, eee, aaa, X[14], 7); + III(aaa, bbb, ccc, ddd, eee, X[15], 7); + III(eee, aaa, bbb, ccc, ddd, X[ 8], 12); + III(ddd, eee, aaa, bbb, ccc, X[12], 7); + III(ccc, ddd, eee, aaa, bbb, X[ 4], 6); + III(bbb, ccc, ddd, eee, aaa, X[ 9], 15); + III(aaa, bbb, ccc, ddd, eee, X[ 1], 13); + III(eee, aaa, bbb, ccc, ddd, X[ 2], 11); + + /* parallel round 3 */ + HHH(ddd, eee, aaa, bbb, ccc, X[15], 9); + HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7); + HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15); + HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11); + HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8); + HHH(ddd, eee, aaa, bbb, ccc, X[14], 6); + HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6); + HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14); + HHH(aaa, bbb, ccc, ddd, eee, X[11], 12); + HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13); + HHH(ddd, eee, aaa, bbb, ccc, X[12], 5); + HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14); + HHH(bbb, ccc, ddd, eee, aaa, X[10], 13); + HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13); + HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7); + HHH(ddd, eee, aaa, bbb, ccc, X[13], 5); + + /* parallel round 4 */ + GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15); + GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5); + GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8); + GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11); + GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14); + GGG(ccc, ddd, eee, aaa, bbb, X[11], 14); + GGG(bbb, ccc, ddd, eee, aaa, X[15], 6); + GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14); + GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6); + GGG(ddd, eee, aaa, bbb, ccc, X[12], 9); + GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12); + GGG(bbb, ccc, ddd, eee, aaa, X[13], 9); + GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12); + GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5); + GGG(ddd, eee, aaa, bbb, ccc, X[10], 15); + GGG(ccc, ddd, eee, aaa, bbb, X[14], 8); + + /* parallel round 5 */ + FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8); + FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5); + FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12); + FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9); + FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12); + FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5); + FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14); + FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6); + FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8); + FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13); + FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6); + FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5); + FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15); + FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13); + FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11); + FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11); + + /* combine results */ + ddd += cc + md->rmd160.state[1]; /* final result for md->rmd160.state[0] */ + md->rmd160.state[1] = md->rmd160.state[2] + dd + eee; + md->rmd160.state[2] = md->rmd160.state[3] + ee + aaa; + md->rmd160.state[3] = md->rmd160.state[4] + aa + bbb; + md->rmd160.state[4] = md->rmd160.state[0] + bb + ccc; + md->rmd160.state[0] = ddd; + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +static int rmd160_compress(hash_state *md, unsigned char *buf) +{ + int err; + err = _rmd160_compress(md, buf); + burn_stack(sizeof(ulong32) * 26 + sizeof(int)); + return err; +} +#endif + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int rmd160_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + md->rmd160.state[0] = 0x67452301UL; + md->rmd160.state[1] = 0xefcdab89UL; + md->rmd160.state[2] = 0x98badcfeUL; + md->rmd160.state[3] = 0x10325476UL; + md->rmd160.state[4] = 0xc3d2e1f0UL; + md->rmd160.curlen = 0; + md->rmd160.length = 0; + return CRYPT_OK; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +HASH_PROCESS(rmd160_process, rmd160_compress, rmd160, 64) + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (20 bytes) + @return CRYPT_OK if successful +*/ +int rmd160_done(hash_state * md, unsigned char *out) +{ + int i; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->rmd160.curlen >= sizeof(md->rmd160.buf)) { + return CRYPT_INVALID_ARG; + } + + + /* increase the length of the message */ + md->rmd160.length += md->rmd160.curlen * 8; + + /* append the '1' bit */ + md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->rmd160.curlen > 56) { + while (md->rmd160.curlen < 64) { + md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0; + } + rmd160_compress(md, md->rmd160.buf); + md->rmd160.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->rmd160.curlen < 56) { + md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->rmd160.length, md->rmd160.buf+56); + rmd160_compress(md, md->rmd160.buf); + + /* copy output */ + for (i = 0; i < 5; i++) { + STORE32L(md->rmd160.state[i], out+(4*i)); + } +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int rmd160_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + char *msg; + unsigned char md[20]; + } tests[] = { + { "", + { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28, + 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 } + }, + { "a", + { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae, + 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe } + }, + { "abc", + { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04, + 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc } + }, + { "message digest", + { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8, + 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 } + }, + { "abcdefghijklmnopqrstuvwxyz", + { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb, + 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc } + }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05, + 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b } + } + }; + int x; + unsigned char buf[20]; + hash_state md; + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + rmd160_init(&md); + rmd160_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg)); + rmd160_done(&md, buf); + if (XMEMCMP(buf, tests[x].md, 20) != 0) { +#if 0 + printf("Failed test %d\n", x); +#endif + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +#endif +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/hashes/rmd256.c b/src/ltc/hashes/rmd256.c new file mode 100644 index 0000000..cbfadcc --- /dev/null +++ b/src/ltc/hashes/rmd256.c @@ -0,0 +1,431 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @param rmd256.c + RLTC_MD256 Hash function +*/ + +#ifdef LTC_RIPEMD256 + +const struct ltc_hash_descriptor rmd256_desc = +{ + "rmd256", + 13, + 32, + 64, + + /* OID */ + { 1, 3, 36, 3, 2, 3 }, + 6, + + &rmd256_init, + &rmd256_process, + &rmd256_done, + &rmd256_test, + NULL +}; + +/* the four basic functions F(), G() and H() */ +#define F(x, y, z) ((x) ^ (y) ^ (z)) +#define G(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define H(x, y, z) (((x) | ~(y)) ^ (z)) +#define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) + +/* the eight basic operations FF() through III() */ +#define FF(a, b, c, d, x, s) \ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROLc((a), (s)); + +#define GG(a, b, c, d, x, s) \ + (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ + (a) = ROLc((a), (s)); + +#define HH(a, b, c, d, x, s) \ + (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ + (a) = ROLc((a), (s)); + +#define II(a, b, c, d, x, s) \ + (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ + (a) = ROLc((a), (s)); + +#define FFF(a, b, c, d, x, s) \ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROLc((a), (s)); + +#define GGG(a, b, c, d, x, s) \ + (a) += G((b), (c), (d)) + (x) + 0x6d703ef3UL;\ + (a) = ROLc((a), (s)); + +#define HHH(a, b, c, d, x, s) \ + (a) += H((b), (c), (d)) + (x) + 0x5c4dd124UL;\ + (a) = ROLc((a), (s)); + +#define III(a, b, c, d, x, s) \ + (a) += I((b), (c), (d)) + (x) + 0x50a28be6UL;\ + (a) = ROLc((a), (s)); + +#ifdef LTC_CLEAN_STACK +static int _rmd256_compress(hash_state *md, unsigned char *buf) +#else +static int rmd256_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong32 aa,bb,cc,dd,aaa,bbb,ccc,ddd,tmp,X[16]; + int i; + + /* load words X */ + for (i = 0; i < 16; i++){ + LOAD32L(X[i], buf + (4 * i)); + } + + /* load state */ + aa = md->rmd256.state[0]; + bb = md->rmd256.state[1]; + cc = md->rmd256.state[2]; + dd = md->rmd256.state[3]; + aaa = md->rmd256.state[4]; + bbb = md->rmd256.state[5]; + ccc = md->rmd256.state[6]; + ddd = md->rmd256.state[7]; + + /* round 1 */ + FF(aa, bb, cc, dd, X[ 0], 11); + FF(dd, aa, bb, cc, X[ 1], 14); + FF(cc, dd, aa, bb, X[ 2], 15); + FF(bb, cc, dd, aa, X[ 3], 12); + FF(aa, bb, cc, dd, X[ 4], 5); + FF(dd, aa, bb, cc, X[ 5], 8); + FF(cc, dd, aa, bb, X[ 6], 7); + FF(bb, cc, dd, aa, X[ 7], 9); + FF(aa, bb, cc, dd, X[ 8], 11); + FF(dd, aa, bb, cc, X[ 9], 13); + FF(cc, dd, aa, bb, X[10], 14); + FF(bb, cc, dd, aa, X[11], 15); + FF(aa, bb, cc, dd, X[12], 6); + FF(dd, aa, bb, cc, X[13], 7); + FF(cc, dd, aa, bb, X[14], 9); + FF(bb, cc, dd, aa, X[15], 8); + + /* parallel round 1 */ + III(aaa, bbb, ccc, ddd, X[ 5], 8); + III(ddd, aaa, bbb, ccc, X[14], 9); + III(ccc, ddd, aaa, bbb, X[ 7], 9); + III(bbb, ccc, ddd, aaa, X[ 0], 11); + III(aaa, bbb, ccc, ddd, X[ 9], 13); + III(ddd, aaa, bbb, ccc, X[ 2], 15); + III(ccc, ddd, aaa, bbb, X[11], 15); + III(bbb, ccc, ddd, aaa, X[ 4], 5); + III(aaa, bbb, ccc, ddd, X[13], 7); + III(ddd, aaa, bbb, ccc, X[ 6], 7); + III(ccc, ddd, aaa, bbb, X[15], 8); + III(bbb, ccc, ddd, aaa, X[ 8], 11); + III(aaa, bbb, ccc, ddd, X[ 1], 14); + III(ddd, aaa, bbb, ccc, X[10], 14); + III(ccc, ddd, aaa, bbb, X[ 3], 12); + III(bbb, ccc, ddd, aaa, X[12], 6); + + tmp = aa; aa = aaa; aaa = tmp; + + /* round 2 */ + GG(aa, bb, cc, dd, X[ 7], 7); + GG(dd, aa, bb, cc, X[ 4], 6); + GG(cc, dd, aa, bb, X[13], 8); + GG(bb, cc, dd, aa, X[ 1], 13); + GG(aa, bb, cc, dd, X[10], 11); + GG(dd, aa, bb, cc, X[ 6], 9); + GG(cc, dd, aa, bb, X[15], 7); + GG(bb, cc, dd, aa, X[ 3], 15); + GG(aa, bb, cc, dd, X[12], 7); + GG(dd, aa, bb, cc, X[ 0], 12); + GG(cc, dd, aa, bb, X[ 9], 15); + GG(bb, cc, dd, aa, X[ 5], 9); + GG(aa, bb, cc, dd, X[ 2], 11); + GG(dd, aa, bb, cc, X[14], 7); + GG(cc, dd, aa, bb, X[11], 13); + GG(bb, cc, dd, aa, X[ 8], 12); + + /* parallel round 2 */ + HHH(aaa, bbb, ccc, ddd, X[ 6], 9); + HHH(ddd, aaa, bbb, ccc, X[11], 13); + HHH(ccc, ddd, aaa, bbb, X[ 3], 15); + HHH(bbb, ccc, ddd, aaa, X[ 7], 7); + HHH(aaa, bbb, ccc, ddd, X[ 0], 12); + HHH(ddd, aaa, bbb, ccc, X[13], 8); + HHH(ccc, ddd, aaa, bbb, X[ 5], 9); + HHH(bbb, ccc, ddd, aaa, X[10], 11); + HHH(aaa, bbb, ccc, ddd, X[14], 7); + HHH(ddd, aaa, bbb, ccc, X[15], 7); + HHH(ccc, ddd, aaa, bbb, X[ 8], 12); + HHH(bbb, ccc, ddd, aaa, X[12], 7); + HHH(aaa, bbb, ccc, ddd, X[ 4], 6); + HHH(ddd, aaa, bbb, ccc, X[ 9], 15); + HHH(ccc, ddd, aaa, bbb, X[ 1], 13); + HHH(bbb, ccc, ddd, aaa, X[ 2], 11); + + tmp = bb; bb = bbb; bbb = tmp; + + /* round 3 */ + HH(aa, bb, cc, dd, X[ 3], 11); + HH(dd, aa, bb, cc, X[10], 13); + HH(cc, dd, aa, bb, X[14], 6); + HH(bb, cc, dd, aa, X[ 4], 7); + HH(aa, bb, cc, dd, X[ 9], 14); + HH(dd, aa, bb, cc, X[15], 9); + HH(cc, dd, aa, bb, X[ 8], 13); + HH(bb, cc, dd, aa, X[ 1], 15); + HH(aa, bb, cc, dd, X[ 2], 14); + HH(dd, aa, bb, cc, X[ 7], 8); + HH(cc, dd, aa, bb, X[ 0], 13); + HH(bb, cc, dd, aa, X[ 6], 6); + HH(aa, bb, cc, dd, X[13], 5); + HH(dd, aa, bb, cc, X[11], 12); + HH(cc, dd, aa, bb, X[ 5], 7); + HH(bb, cc, dd, aa, X[12], 5); + + /* parallel round 3 */ + GGG(aaa, bbb, ccc, ddd, X[15], 9); + GGG(ddd, aaa, bbb, ccc, X[ 5], 7); + GGG(ccc, ddd, aaa, bbb, X[ 1], 15); + GGG(bbb, ccc, ddd, aaa, X[ 3], 11); + GGG(aaa, bbb, ccc, ddd, X[ 7], 8); + GGG(ddd, aaa, bbb, ccc, X[14], 6); + GGG(ccc, ddd, aaa, bbb, X[ 6], 6); + GGG(bbb, ccc, ddd, aaa, X[ 9], 14); + GGG(aaa, bbb, ccc, ddd, X[11], 12); + GGG(ddd, aaa, bbb, ccc, X[ 8], 13); + GGG(ccc, ddd, aaa, bbb, X[12], 5); + GGG(bbb, ccc, ddd, aaa, X[ 2], 14); + GGG(aaa, bbb, ccc, ddd, X[10], 13); + GGG(ddd, aaa, bbb, ccc, X[ 0], 13); + GGG(ccc, ddd, aaa, bbb, X[ 4], 7); + GGG(bbb, ccc, ddd, aaa, X[13], 5); + + tmp = cc; cc = ccc; ccc = tmp; + + /* round 4 */ + II(aa, bb, cc, dd, X[ 1], 11); + II(dd, aa, bb, cc, X[ 9], 12); + II(cc, dd, aa, bb, X[11], 14); + II(bb, cc, dd, aa, X[10], 15); + II(aa, bb, cc, dd, X[ 0], 14); + II(dd, aa, bb, cc, X[ 8], 15); + II(cc, dd, aa, bb, X[12], 9); + II(bb, cc, dd, aa, X[ 4], 8); + II(aa, bb, cc, dd, X[13], 9); + II(dd, aa, bb, cc, X[ 3], 14); + II(cc, dd, aa, bb, X[ 7], 5); + II(bb, cc, dd, aa, X[15], 6); + II(aa, bb, cc, dd, X[14], 8); + II(dd, aa, bb, cc, X[ 5], 6); + II(cc, dd, aa, bb, X[ 6], 5); + II(bb, cc, dd, aa, X[ 2], 12); + + /* parallel round 4 */ + FFF(aaa, bbb, ccc, ddd, X[ 8], 15); + FFF(ddd, aaa, bbb, ccc, X[ 6], 5); + FFF(ccc, ddd, aaa, bbb, X[ 4], 8); + FFF(bbb, ccc, ddd, aaa, X[ 1], 11); + FFF(aaa, bbb, ccc, ddd, X[ 3], 14); + FFF(ddd, aaa, bbb, ccc, X[11], 14); + FFF(ccc, ddd, aaa, bbb, X[15], 6); + FFF(bbb, ccc, ddd, aaa, X[ 0], 14); + FFF(aaa, bbb, ccc, ddd, X[ 5], 6); + FFF(ddd, aaa, bbb, ccc, X[12], 9); + FFF(ccc, ddd, aaa, bbb, X[ 2], 12); + FFF(bbb, ccc, ddd, aaa, X[13], 9); + FFF(aaa, bbb, ccc, ddd, X[ 9], 12); + FFF(ddd, aaa, bbb, ccc, X[ 7], 5); + FFF(ccc, ddd, aaa, bbb, X[10], 15); + FFF(bbb, ccc, ddd, aaa, X[14], 8); + + tmp = dd; dd = ddd; ddd = tmp; + + /* combine results */ + md->rmd256.state[0] += aa; + md->rmd256.state[1] += bb; + md->rmd256.state[2] += cc; + md->rmd256.state[3] += dd; + md->rmd256.state[4] += aaa; + md->rmd256.state[5] += bbb; + md->rmd256.state[6] += ccc; + md->rmd256.state[7] += ddd; + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +static int rmd256_compress(hash_state *md, unsigned char *buf) +{ + int err; + err = _rmd256_compress(md, buf); + burn_stack(sizeof(ulong32) * 25 + sizeof(int)); + return err; +} +#endif + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int rmd256_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + md->rmd256.state[0] = 0x67452301UL; + md->rmd256.state[1] = 0xefcdab89UL; + md->rmd256.state[2] = 0x98badcfeUL; + md->rmd256.state[3] = 0x10325476UL; + md->rmd256.state[4] = 0x76543210UL; + md->rmd256.state[5] = 0xfedcba98UL; + md->rmd256.state[6] = 0x89abcdefUL; + md->rmd256.state[7] = 0x01234567UL; + md->rmd256.curlen = 0; + md->rmd256.length = 0; + return CRYPT_OK; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +HASH_PROCESS(rmd256_process, rmd256_compress, rmd256, 64) + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (16 bytes) + @return CRYPT_OK if successful +*/ +int rmd256_done(hash_state * md, unsigned char *out) +{ + int i; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->rmd256.curlen >= sizeof(md->rmd256.buf)) { + return CRYPT_INVALID_ARG; + } + + + /* increase the length of the message */ + md->rmd256.length += md->rmd256.curlen * 8; + + /* append the '1' bit */ + md->rmd256.buf[md->rmd256.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->rmd256.curlen > 56) { + while (md->rmd256.curlen < 64) { + md->rmd256.buf[md->rmd256.curlen++] = (unsigned char)0; + } + rmd256_compress(md, md->rmd256.buf); + md->rmd256.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->rmd256.curlen < 56) { + md->rmd256.buf[md->rmd256.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->rmd256.length, md->rmd256.buf+56); + rmd256_compress(md, md->rmd256.buf); + + /* copy output */ + for (i = 0; i < 8; i++) { + STORE32L(md->rmd256.state[i], out+(4*i)); + } +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int rmd256_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + char *msg; + unsigned char md[32]; + } tests[] = { + { "", + { 0x02, 0xba, 0x4c, 0x4e, 0x5f, 0x8e, 0xcd, 0x18, + 0x77, 0xfc, 0x52, 0xd6, 0x4d, 0x30, 0xe3, 0x7a, + 0x2d, 0x97, 0x74, 0xfb, 0x1e, 0x5d, 0x02, 0x63, + 0x80, 0xae, 0x01, 0x68, 0xe3, 0xc5, 0x52, 0x2d } + }, + { "a", + { 0xf9, 0x33, 0x3e, 0x45, 0xd8, 0x57, 0xf5, 0xd9, + 0x0a, 0x91, 0xba, 0xb7, 0x0a, 0x1e, 0xba, 0x0c, + 0xfb, 0x1b, 0xe4, 0xb0, 0x78, 0x3c, 0x9a, 0xcf, + 0xcd, 0x88, 0x3a, 0x91, 0x34, 0x69, 0x29, 0x25 } + }, + { "abc", + { 0xaf, 0xbd, 0x6e, 0x22, 0x8b, 0x9d, 0x8c, 0xbb, + 0xce, 0xf5, 0xca, 0x2d, 0x03, 0xe6, 0xdb, 0xa1, + 0x0a, 0xc0, 0xbc, 0x7d, 0xcb, 0xe4, 0x68, 0x0e, + 0x1e, 0x42, 0xd2, 0xe9, 0x75, 0x45, 0x9b, 0x65 } + }, + { "message digest", + { 0x87, 0xe9, 0x71, 0x75, 0x9a, 0x1c, 0xe4, 0x7a, + 0x51, 0x4d, 0x5c, 0x91, 0x4c, 0x39, 0x2c, 0x90, + 0x18, 0xc7, 0xc4, 0x6b, 0xc1, 0x44, 0x65, 0x55, + 0x4a, 0xfc, 0xdf, 0x54, 0xa5, 0x07, 0x0c, 0x0e } + }, + { "abcdefghijklmnopqrstuvwxyz", + { 0x64, 0x9d, 0x30, 0x34, 0x75, 0x1e, 0xa2, 0x16, + 0x77, 0x6b, 0xf9, 0xa1, 0x8a, 0xcc, 0x81, 0xbc, + 0x78, 0x96, 0x11, 0x8a, 0x51, 0x97, 0x96, 0x87, + 0x82, 0xdd, 0x1f, 0xd9, 0x7d, 0x8d, 0x51, 0x33 } + }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + { 0x57, 0x40, 0xa4, 0x08, 0xac, 0x16, 0xb7, 0x20, + 0xb8, 0x44, 0x24, 0xae, 0x93, 0x1c, 0xbb, 0x1f, + 0xe3, 0x63, 0xd1, 0xd0, 0xbf, 0x40, 0x17, 0xf1, + 0xa8, 0x9f, 0x7e, 0xa6, 0xde, 0x77, 0xa0, 0xb8 } + } + }; + int x; + unsigned char buf[32]; + hash_state md; + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + rmd256_init(&md); + rmd256_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg)); + rmd256_done(&md, buf); + if (XMEMCMP(buf, tests[x].md, 32) != 0) { + #if 0 + printf("Failed test %d\n", x); + #endif + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +#endif +} + +#endif + diff --git a/src/ltc/hashes/rmd320.c b/src/ltc/hashes/rmd320.c new file mode 100644 index 0000000..26119f9 --- /dev/null +++ b/src/ltc/hashes/rmd320.c @@ -0,0 +1,496 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file rmd320.c + RMD320 hash function +*/ + +#ifdef LTC_RIPEMD320 + +const struct ltc_hash_descriptor rmd320_desc = +{ + "rmd320", + 14, + 40, + 64, + + /* OID ... does not exist + * http://oid-info.com/get/1.3.36.3.2 */ + { 0 }, + 0, + + &rmd320_init, + &rmd320_process, + &rmd320_done, + &rmd320_test, + NULL +}; + +/* the five basic functions F(), G() and H() */ +#define F(x, y, z) ((x) ^ (y) ^ (z)) +#define G(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define H(x, y, z) (((x) | ~(y)) ^ (z)) +#define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) +#define J(x, y, z) ((x) ^ ((y) | ~(z))) + +/* the ten basic operations FF() through III() */ +#define FF(a, b, c, d, e, x, s) \ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define GG(a, b, c, d, e, x, s) \ + (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define HH(a, b, c, d, e, x, s) \ + (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define II(a, b, c, d, e, x, s) \ + (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define JJ(a, b, c, d, e, x, s) \ + (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define FFF(a, b, c, d, e, x, s) \ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define GGG(a, b, c, d, e, x, s) \ + (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define HHH(a, b, c, d, e, x, s) \ + (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define III(a, b, c, d, e, x, s) \ + (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + +#define JJJ(a, b, c, d, e, x, s) \ + (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\ + (a) = ROLc((a), (s)) + (e);\ + (c) = ROLc((c), 10); + + +#ifdef LTC_CLEAN_STACK +static int _rmd320_compress(hash_state *md, unsigned char *buf) +#else +static int rmd320_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong32 aa,bb,cc,dd,ee,aaa,bbb,ccc,ddd,eee,tmp,X[16]; + int i; + + /* load words X */ + for (i = 0; i < 16; i++){ + LOAD32L(X[i], buf + (4 * i)); + } + + /* load state */ + aa = md->rmd320.state[0]; + bb = md->rmd320.state[1]; + cc = md->rmd320.state[2]; + dd = md->rmd320.state[3]; + ee = md->rmd320.state[4]; + aaa = md->rmd320.state[5]; + bbb = md->rmd320.state[6]; + ccc = md->rmd320.state[7]; + ddd = md->rmd320.state[8]; + eee = md->rmd320.state[9]; + + /* round 1 */ + FF(aa, bb, cc, dd, ee, X[ 0], 11); + FF(ee, aa, bb, cc, dd, X[ 1], 14); + FF(dd, ee, aa, bb, cc, X[ 2], 15); + FF(cc, dd, ee, aa, bb, X[ 3], 12); + FF(bb, cc, dd, ee, aa, X[ 4], 5); + FF(aa, bb, cc, dd, ee, X[ 5], 8); + FF(ee, aa, bb, cc, dd, X[ 6], 7); + FF(dd, ee, aa, bb, cc, X[ 7], 9); + FF(cc, dd, ee, aa, bb, X[ 8], 11); + FF(bb, cc, dd, ee, aa, X[ 9], 13); + FF(aa, bb, cc, dd, ee, X[10], 14); + FF(ee, aa, bb, cc, dd, X[11], 15); + FF(dd, ee, aa, bb, cc, X[12], 6); + FF(cc, dd, ee, aa, bb, X[13], 7); + FF(bb, cc, dd, ee, aa, X[14], 9); + FF(aa, bb, cc, dd, ee, X[15], 8); + + /* parallel round 1 */ + JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8); + JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9); + JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13); + JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15); + JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5); + JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7); + JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8); + JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14); + JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12); + JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6); + + tmp = aa; aa = aaa; aaa = tmp; + + /* round 2 */ + GG(ee, aa, bb, cc, dd, X[ 7], 7); + GG(dd, ee, aa, bb, cc, X[ 4], 6); + GG(cc, dd, ee, aa, bb, X[13], 8); + GG(bb, cc, dd, ee, aa, X[ 1], 13); + GG(aa, bb, cc, dd, ee, X[10], 11); + GG(ee, aa, bb, cc, dd, X[ 6], 9); + GG(dd, ee, aa, bb, cc, X[15], 7); + GG(cc, dd, ee, aa, bb, X[ 3], 15); + GG(bb, cc, dd, ee, aa, X[12], 7); + GG(aa, bb, cc, dd, ee, X[ 0], 12); + GG(ee, aa, bb, cc, dd, X[ 9], 15); + GG(dd, ee, aa, bb, cc, X[ 5], 9); + GG(cc, dd, ee, aa, bb, X[ 2], 11); + GG(bb, cc, dd, ee, aa, X[14], 7); + GG(aa, bb, cc, dd, ee, X[11], 13); + GG(ee, aa, bb, cc, dd, X[ 8], 12); + + /* parallel round 2 */ + III(eee, aaa, bbb, ccc, ddd, X[ 6], 9); + III(ddd, eee, aaa, bbb, ccc, X[11], 13); + III(ccc, ddd, eee, aaa, bbb, X[ 3], 15); + III(bbb, ccc, ddd, eee, aaa, X[ 7], 7); + III(aaa, bbb, ccc, ddd, eee, X[ 0], 12); + III(eee, aaa, bbb, ccc, ddd, X[13], 8); + III(ddd, eee, aaa, bbb, ccc, X[ 5], 9); + III(ccc, ddd, eee, aaa, bbb, X[10], 11); + III(bbb, ccc, ddd, eee, aaa, X[14], 7); + III(aaa, bbb, ccc, ddd, eee, X[15], 7); + III(eee, aaa, bbb, ccc, ddd, X[ 8], 12); + III(ddd, eee, aaa, bbb, ccc, X[12], 7); + III(ccc, ddd, eee, aaa, bbb, X[ 4], 6); + III(bbb, ccc, ddd, eee, aaa, X[ 9], 15); + III(aaa, bbb, ccc, ddd, eee, X[ 1], 13); + III(eee, aaa, bbb, ccc, ddd, X[ 2], 11); + + tmp = bb; bb = bbb; bbb = tmp; + + /* round 3 */ + HH(dd, ee, aa, bb, cc, X[ 3], 11); + HH(cc, dd, ee, aa, bb, X[10], 13); + HH(bb, cc, dd, ee, aa, X[14], 6); + HH(aa, bb, cc, dd, ee, X[ 4], 7); + HH(ee, aa, bb, cc, dd, X[ 9], 14); + HH(dd, ee, aa, bb, cc, X[15], 9); + HH(cc, dd, ee, aa, bb, X[ 8], 13); + HH(bb, cc, dd, ee, aa, X[ 1], 15); + HH(aa, bb, cc, dd, ee, X[ 2], 14); + HH(ee, aa, bb, cc, dd, X[ 7], 8); + HH(dd, ee, aa, bb, cc, X[ 0], 13); + HH(cc, dd, ee, aa, bb, X[ 6], 6); + HH(bb, cc, dd, ee, aa, X[13], 5); + HH(aa, bb, cc, dd, ee, X[11], 12); + HH(ee, aa, bb, cc, dd, X[ 5], 7); + HH(dd, ee, aa, bb, cc, X[12], 5); + + /* parallel round 3 */ + HHH(ddd, eee, aaa, bbb, ccc, X[15], 9); + HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7); + HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15); + HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11); + HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8); + HHH(ddd, eee, aaa, bbb, ccc, X[14], 6); + HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6); + HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14); + HHH(aaa, bbb, ccc, ddd, eee, X[11], 12); + HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13); + HHH(ddd, eee, aaa, bbb, ccc, X[12], 5); + HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14); + HHH(bbb, ccc, ddd, eee, aaa, X[10], 13); + HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13); + HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7); + HHH(ddd, eee, aaa, bbb, ccc, X[13], 5); + + tmp = cc; cc = ccc; ccc = tmp; + + /* round 4 */ + II(cc, dd, ee, aa, bb, X[ 1], 11); + II(bb, cc, dd, ee, aa, X[ 9], 12); + II(aa, bb, cc, dd, ee, X[11], 14); + II(ee, aa, bb, cc, dd, X[10], 15); + II(dd, ee, aa, bb, cc, X[ 0], 14); + II(cc, dd, ee, aa, bb, X[ 8], 15); + II(bb, cc, dd, ee, aa, X[12], 9); + II(aa, bb, cc, dd, ee, X[ 4], 8); + II(ee, aa, bb, cc, dd, X[13], 9); + II(dd, ee, aa, bb, cc, X[ 3], 14); + II(cc, dd, ee, aa, bb, X[ 7], 5); + II(bb, cc, dd, ee, aa, X[15], 6); + II(aa, bb, cc, dd, ee, X[14], 8); + II(ee, aa, bb, cc, dd, X[ 5], 6); + II(dd, ee, aa, bb, cc, X[ 6], 5); + II(cc, dd, ee, aa, bb, X[ 2], 12); + + /* parallel round 4 */ + GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15); + GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5); + GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8); + GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11); + GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14); + GGG(ccc, ddd, eee, aaa, bbb, X[11], 14); + GGG(bbb, ccc, ddd, eee, aaa, X[15], 6); + GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14); + GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6); + GGG(ddd, eee, aaa, bbb, ccc, X[12], 9); + GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12); + GGG(bbb, ccc, ddd, eee, aaa, X[13], 9); + GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12); + GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5); + GGG(ddd, eee, aaa, bbb, ccc, X[10], 15); + GGG(ccc, ddd, eee, aaa, bbb, X[14], 8); + + tmp = dd; dd = ddd; ddd = tmp; + + /* round 5 */ + JJ(bb, cc, dd, ee, aa, X[ 4], 9); + JJ(aa, bb, cc, dd, ee, X[ 0], 15); + JJ(ee, aa, bb, cc, dd, X[ 5], 5); + JJ(dd, ee, aa, bb, cc, X[ 9], 11); + JJ(cc, dd, ee, aa, bb, X[ 7], 6); + JJ(bb, cc, dd, ee, aa, X[12], 8); + JJ(aa, bb, cc, dd, ee, X[ 2], 13); + JJ(ee, aa, bb, cc, dd, X[10], 12); + JJ(dd, ee, aa, bb, cc, X[14], 5); + JJ(cc, dd, ee, aa, bb, X[ 1], 12); + JJ(bb, cc, dd, ee, aa, X[ 3], 13); + JJ(aa, bb, cc, dd, ee, X[ 8], 14); + JJ(ee, aa, bb, cc, dd, X[11], 11); + JJ(dd, ee, aa, bb, cc, X[ 6], 8); + JJ(cc, dd, ee, aa, bb, X[15], 5); + JJ(bb, cc, dd, ee, aa, X[13], 6); + + /* parallel round 5 */ + FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8); + FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5); + FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12); + FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9); + FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12); + FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5); + FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14); + FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6); + FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8); + FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13); + FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6); + FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5); + FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15); + FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13); + FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11); + FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11); + + tmp = ee; ee = eee; eee = tmp; + + /* combine results */ + md->rmd320.state[0] += aa; + md->rmd320.state[1] += bb; + md->rmd320.state[2] += cc; + md->rmd320.state[3] += dd; + md->rmd320.state[4] += ee; + md->rmd320.state[5] += aaa; + md->rmd320.state[6] += bbb; + md->rmd320.state[7] += ccc; + md->rmd320.state[8] += ddd; + md->rmd320.state[9] += eee; + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +static int rmd320_compress(hash_state *md, unsigned char *buf) +{ + int err; + err = _rmd320_compress(md, buf); + burn_stack(sizeof(ulong32) * 27 + sizeof(int)); + return err; +} +#endif + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int rmd320_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + md->rmd320.state[0] = 0x67452301UL; + md->rmd320.state[1] = 0xefcdab89UL; + md->rmd320.state[2] = 0x98badcfeUL; + md->rmd320.state[3] = 0x10325476UL; + md->rmd320.state[4] = 0xc3d2e1f0UL; + md->rmd320.state[5] = 0x76543210UL; + md->rmd320.state[6] = 0xfedcba98UL; + md->rmd320.state[7] = 0x89abcdefUL; + md->rmd320.state[8] = 0x01234567UL; + md->rmd320.state[9] = 0x3c2d1e0fUL; + md->rmd320.curlen = 0; + md->rmd320.length = 0; + return CRYPT_OK; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +HASH_PROCESS(rmd320_process, rmd320_compress, rmd320, 64) + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (20 bytes) + @return CRYPT_OK if successful +*/ +int rmd320_done(hash_state * md, unsigned char *out) +{ + int i; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->rmd320.curlen >= sizeof(md->rmd320.buf)) { + return CRYPT_INVALID_ARG; + } + + + /* increase the length of the message */ + md->rmd320.length += md->rmd320.curlen * 8; + + /* append the '1' bit */ + md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->rmd320.curlen > 56) { + while (md->rmd320.curlen < 64) { + md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0; + } + rmd320_compress(md, md->rmd320.buf); + md->rmd320.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->rmd320.curlen < 56) { + md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->rmd320.length, md->rmd320.buf+56); + rmd320_compress(md, md->rmd320.buf); + + /* copy output */ + for (i = 0; i < 10; i++) { + STORE32L(md->rmd320.state[i], out+(4*i)); + } +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int rmd320_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + char *msg; + unsigned char md[40]; + } tests[] = { + { "", + { 0x22, 0xd6, 0x5d, 0x56, 0x61, 0x53, 0x6c, 0xdc, 0x75, 0xc1, + 0xfd, 0xf5, 0xc6, 0xde, 0x7b, 0x41, 0xb9, 0xf2, 0x73, 0x25, + 0xeb, 0xc6, 0x1e, 0x85, 0x57, 0x17, 0x7d, 0x70, 0x5a, 0x0e, + 0xc8, 0x80, 0x15, 0x1c, 0x3a, 0x32, 0xa0, 0x08, 0x99, 0xb8 } + }, + { "a", + { 0xce, 0x78, 0x85, 0x06, 0x38, 0xf9, 0x26, 0x58, 0xa5, 0xa5, + 0x85, 0x09, 0x75, 0x79, 0x92, 0x6d, 0xda, 0x66, 0x7a, 0x57, + 0x16, 0x56, 0x2c, 0xfc, 0xf6, 0xfb, 0xe7, 0x7f, 0x63, 0x54, + 0x2f, 0x99, 0xb0, 0x47, 0x05, 0xd6, 0x97, 0x0d, 0xff, 0x5d } + }, + { "abc", + { 0xde, 0x4c, 0x01, 0xb3, 0x05, 0x4f, 0x89, 0x30, 0xa7, 0x9d, + 0x09, 0xae, 0x73, 0x8e, 0x92, 0x30, 0x1e, 0x5a, 0x17, 0x08, + 0x5b, 0xef, 0xfd, 0xc1, 0xb8, 0xd1, 0x16, 0x71, 0x3e, 0x74, + 0xf8, 0x2f, 0xa9, 0x42, 0xd6, 0x4c, 0xdb, 0xc4, 0x68, 0x2d } + }, + { "message digest", + { 0x3a, 0x8e, 0x28, 0x50, 0x2e, 0xd4, 0x5d, 0x42, 0x2f, 0x68, + 0x84, 0x4f, 0x9d, 0xd3, 0x16, 0xe7, 0xb9, 0x85, 0x33, 0xfa, + 0x3f, 0x2a, 0x91, 0xd2, 0x9f, 0x84, 0xd4, 0x25, 0xc8, 0x8d, + 0x6b, 0x4e, 0xff, 0x72, 0x7d, 0xf6, 0x6a, 0x7c, 0x01, 0x97 } + }, + { "abcdefghijklmnopqrstuvwxyz", + { 0xca, 0xbd, 0xb1, 0x81, 0x0b, 0x92, 0x47, 0x0a, 0x20, 0x93, + 0xaa, 0x6b, 0xce, 0x05, 0x95, 0x2c, 0x28, 0x34, 0x8c, 0xf4, + 0x3f, 0xf6, 0x08, 0x41, 0x97, 0x51, 0x66, 0xbb, 0x40, 0xed, + 0x23, 0x40, 0x04, 0xb8, 0x82, 0x44, 0x63, 0xe6, 0xb0, 0x09 } + }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + { 0xd0, 0x34, 0xa7, 0x95, 0x0c, 0xf7, 0x22, 0x02, 0x1b, 0xa4, + 0xb8, 0x4d, 0xf7, 0x69, 0xa5, 0xde, 0x20, 0x60, 0xe2, 0x59, + 0xdf, 0x4c, 0x9b, 0xb4, 0xa4, 0x26, 0x8c, 0x0e, 0x93, 0x5b, + 0xbc, 0x74, 0x70, 0xa9, 0x69, 0xc9, 0xd0, 0x72, 0xa1, 0xac } + } + }; + int x; + unsigned char buf[40]; + hash_state md; + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + rmd320_init(&md); + rmd320_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg)); + rmd320_done(&md, buf); + if (XMEMCMP(buf, tests[x].md, 40) != 0) { +#if 0 + printf("Failed test %d\n", x); +#endif + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +#endif +} + +#endif + diff --git a/src/ltc/hashes/sha1.c b/src/ltc/hashes/sha1.c new file mode 100644 index 0000000..96c3b93 --- /dev/null +++ b/src/ltc/hashes/sha1.c @@ -0,0 +1,288 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file sha1.c + LTC_SHA1 code by Tom St Denis +*/ + + +#ifdef LTC_SHA1 + +const struct ltc_hash_descriptor sha1_desc = +{ + "sha1", + 2, + 20, + 64, + + /* OID */ + { 1, 3, 14, 3, 2, 26, }, + 6, + + &sha1_init, + &sha1_process, + &sha1_done, + &sha1_test, + NULL +}; + +#define F0(x,y,z) (z ^ (x & (y ^ z))) +#define F1(x,y,z) (x ^ y ^ z) +#define F2(x,y,z) ((x & y) | (z & (x | y))) +#define F3(x,y,z) (x ^ y ^ z) + +#ifdef LTC_CLEAN_STACK +static int _sha1_compress(hash_state *md, unsigned char *buf) +#else +static int sha1_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong32 a,b,c,d,e,W[80],i; +#ifdef LTC_SMALL_CODE + ulong32 t; +#endif + + /* copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) { + LOAD32H(W[i], buf + (4*i)); + } + + /* copy state */ + a = md->sha1.state[0]; + b = md->sha1.state[1]; + c = md->sha1.state[2]; + d = md->sha1.state[3]; + e = md->sha1.state[4]; + + /* expand it */ + for (i = 16; i < 80; i++) { + W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1); + } + + /* compress */ + /* round one */ + #define FF0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROLc(b, 30); + #define FF1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30); + #define FF2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30); + #define FF3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30); + +#ifdef LTC_SMALL_CODE + + for (i = 0; i < 20; ) { + FF0(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; + } + + for (; i < 40; ) { + FF1(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; + } + + for (; i < 60; ) { + FF2(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; + } + + for (; i < 80; ) { + FF3(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; + } + +#else + + for (i = 0; i < 20; ) { + FF0(a,b,c,d,e,i++); + FF0(e,a,b,c,d,i++); + FF0(d,e,a,b,c,i++); + FF0(c,d,e,a,b,i++); + FF0(b,c,d,e,a,i++); + } + + /* round two */ + for (; i < 40; ) { + FF1(a,b,c,d,e,i++); + FF1(e,a,b,c,d,i++); + FF1(d,e,a,b,c,i++); + FF1(c,d,e,a,b,i++); + FF1(b,c,d,e,a,i++); + } + + /* round three */ + for (; i < 60; ) { + FF2(a,b,c,d,e,i++); + FF2(e,a,b,c,d,i++); + FF2(d,e,a,b,c,i++); + FF2(c,d,e,a,b,i++); + FF2(b,c,d,e,a,i++); + } + + /* round four */ + for (; i < 80; ) { + FF3(a,b,c,d,e,i++); + FF3(e,a,b,c,d,i++); + FF3(d,e,a,b,c,i++); + FF3(c,d,e,a,b,i++); + FF3(b,c,d,e,a,i++); + } +#endif + + #undef FF0 + #undef FF1 + #undef FF2 + #undef FF3 + + /* store */ + md->sha1.state[0] = md->sha1.state[0] + a; + md->sha1.state[1] = md->sha1.state[1] + b; + md->sha1.state[2] = md->sha1.state[2] + c; + md->sha1.state[3] = md->sha1.state[3] + d; + md->sha1.state[4] = md->sha1.state[4] + e; + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +static int sha1_compress(hash_state *md, unsigned char *buf) +{ + int err; + err = _sha1_compress(md, buf); + burn_stack(sizeof(ulong32) * 87); + return err; +} +#endif + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int sha1_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + md->sha1.state[0] = 0x67452301UL; + md->sha1.state[1] = 0xefcdab89UL; + md->sha1.state[2] = 0x98badcfeUL; + md->sha1.state[3] = 0x10325476UL; + md->sha1.state[4] = 0xc3d2e1f0UL; + md->sha1.curlen = 0; + md->sha1.length = 0; + return CRYPT_OK; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +HASH_PROCESS(sha1_process, sha1_compress, sha1, 64) + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (20 bytes) + @return CRYPT_OK if successful +*/ +int sha1_done(hash_state * md, unsigned char *out) +{ + int i; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->sha1.curlen >= sizeof(md->sha1.buf)) { + return CRYPT_INVALID_ARG; + } + + /* increase the length of the message */ + md->sha1.length += md->sha1.curlen * 8; + + /* append the '1' bit */ + md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->sha1.curlen > 56) { + while (md->sha1.curlen < 64) { + md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; + } + sha1_compress(md, md->sha1.buf); + md->sha1.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->sha1.curlen < 56) { + md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64H(md->sha1.length, md->sha1.buf+56); + sha1_compress(md, md->sha1.buf); + + /* copy output */ + for (i = 0; i < 5; i++) { + STORE32H(md->sha1.state[i], out+(4*i)); + } +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int sha1_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[20]; + } tests[] = { + { "abc", + { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, + 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, + 0x9c, 0xd0, 0xd8, 0x9d } + }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, + 0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, + 0xE5, 0x46, 0x70, 0xF1 } + } + }; + + int i; + unsigned char tmp[20]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + sha1_init(&md); + sha1_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + sha1_done(&md, tmp); + if (XMEMCMP(tmp, tests[i].hash, 20) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#endif + + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/hashes/sha2/sha224.c b/src/ltc/hashes/sha2/sha224.c new file mode 100644 index 0000000..2240aaf --- /dev/null +++ b/src/ltc/hashes/sha2/sha224.c @@ -0,0 +1,131 @@ +/* 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://libtom.org + */ +/** + @param sha224.c + LTC_SHA-224 new NIST standard based off of LTC_SHA-256 truncated to 224 bits (Tom St Denis) +*/ + +#include "tomcrypt.h" + +#if defined(LTC_SHA224) && defined(LTC_SHA256) + +const struct ltc_hash_descriptor sha224_desc = +{ + "sha224", + 10, + 28, + 64, + + /* OID */ + { 2, 16, 840, 1, 101, 3, 4, 2, 4, }, + 9, + + &sha224_init, + &sha256_process, + &sha224_done, + &sha224_test, + NULL +}; + +/* init the sha256 er... sha224 state ;-) */ +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int sha224_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + + md->sha256.curlen = 0; + md->sha256.length = 0; + md->sha256.state[0] = 0xc1059ed8UL; + md->sha256.state[1] = 0x367cd507UL; + md->sha256.state[2] = 0x3070dd17UL; + md->sha256.state[3] = 0xf70e5939UL; + md->sha256.state[4] = 0xffc00b31UL; + md->sha256.state[5] = 0x68581511UL; + md->sha256.state[6] = 0x64f98fa7UL; + md->sha256.state[7] = 0xbefa4fa4UL; + return CRYPT_OK; +} + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (28 bytes) + @return CRYPT_OK if successful +*/ +int sha224_done(hash_state * md, unsigned char *out) +{ + unsigned char buf[32]; + int err; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + err = sha256_done(md, buf); + XMEMCPY(out, buf, 28); +#ifdef LTC_CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + return err; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int sha224_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[28]; + } tests[] = { + { "abc", + { 0x23, 0x09, 0x7d, 0x22, 0x34, 0x05, 0xd8, + 0x22, 0x86, 0x42, 0xa4, 0x77, 0xbd, 0xa2, + 0x55, 0xb3, 0x2a, 0xad, 0xbc, 0xe4, 0xbd, + 0xa0, 0xb3, 0xf7, 0xe3, 0x6c, 0x9d, 0xa7 } + }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + { 0x75, 0x38, 0x8b, 0x16, 0x51, 0x27, 0x76, + 0xcc, 0x5d, 0xba, 0x5d, 0xa1, 0xfd, 0x89, + 0x01, 0x50, 0xb0, 0xc6, 0x45, 0x5c, 0xb4, + 0xf5, 0x8b, 0x19, 0x52, 0x52, 0x25, 0x25 } + }, + }; + + int i; + unsigned char tmp[28]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + sha224_init(&md); + sha224_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + sha224_done(&md, tmp); + if (XMEMCMP(tmp, tests[i].hash, 28) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#endif /* defined(LTC_SHA224) && defined(LTC_SHA256) */ + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/hashes/sha2/sha256.c b/src/ltc/hashes/sha2/sha256.c new file mode 100644 index 0000000..13ec9e6 --- /dev/null +++ b/src/ltc/hashes/sha2/sha256.c @@ -0,0 +1,336 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file sha256.c + LTC_SHA256 by Tom St Denis +*/ + +#ifdef LTC_SHA256 + +const struct ltc_hash_descriptor sha256_desc = +{ + "sha256", + 0, + 32, + 64, + + /* OID */ + { 2, 16, 840, 1, 101, 3, 4, 2, 1, }, + 9, + + &sha256_init, + &sha256_process, + &sha256_done, + &sha256_test, + NULL +}; + +#ifdef LTC_SMALL_CODE +/* the K array */ +static const ulong32 K[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, + 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, + 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, + 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, + 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, + 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, + 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, + 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, + 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, + 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; +#endif + +/* Various logical functions */ +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) (((x | y) & z) | (x & y)) +#define S(x, n) RORc((x),(n)) +#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) +#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) +#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) +#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) +#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) + +/* compress 512-bits */ +#ifdef LTC_CLEAN_STACK +static int _sha256_compress(hash_state * md, unsigned char *buf) +#else +static int sha256_compress(hash_state * md, unsigned char *buf) +#endif +{ + ulong32 S[8], W[64], t0, t1; +#ifdef LTC_SMALL_CODE + ulong32 t; +#endif + int i; + + /* copy state into S */ + for (i = 0; i < 8; i++) { + S[i] = md->sha256.state[i]; + } + + /* copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) { + LOAD32H(W[i], buf + (4*i)); + } + + /* fill W[16..63] */ + for (i = 16; i < 64; i++) { + W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; + } + + /* Compress */ +#ifdef LTC_SMALL_CODE +#define RND(a,b,c,d,e,f,g,h,i) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + + for (i = 0; i < 64; ++i) { + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i); + t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4]; + S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t; + } +#else +#define RND(a,b,c,d,e,f,g,h,i,ki) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2); + +#undef RND + +#endif + + /* feedback */ + for (i = 0; i < 8; i++) { + md->sha256.state[i] = md->sha256.state[i] + S[i]; + } + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +static int sha256_compress(hash_state * md, unsigned char *buf) +{ + int err; + err = _sha256_compress(md, buf); + burn_stack(sizeof(ulong32) * 74); + return err; +} +#endif + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int sha256_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + + md->sha256.curlen = 0; + md->sha256.length = 0; + md->sha256.state[0] = 0x6A09E667UL; + md->sha256.state[1] = 0xBB67AE85UL; + md->sha256.state[2] = 0x3C6EF372UL; + md->sha256.state[3] = 0xA54FF53AUL; + md->sha256.state[4] = 0x510E527FUL; + md->sha256.state[5] = 0x9B05688CUL; + md->sha256.state[6] = 0x1F83D9ABUL; + md->sha256.state[7] = 0x5BE0CD19UL; + return CRYPT_OK; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +HASH_PROCESS(sha256_process, sha256_compress, sha256, 64) + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (32 bytes) + @return CRYPT_OK if successful +*/ +int sha256_done(hash_state * md, unsigned char *out) +{ + int i; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->sha256.curlen >= sizeof(md->sha256.buf)) { + return CRYPT_INVALID_ARG; + } + + + /* increase the length of the message */ + md->sha256.length += md->sha256.curlen * 8; + + /* append the '1' bit */ + md->sha256.buf[md->sha256.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->sha256.curlen > 56) { + while (md->sha256.curlen < 64) { + md->sha256.buf[md->sha256.curlen++] = (unsigned char)0; + } + sha256_compress(md, md->sha256.buf); + md->sha256.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->sha256.curlen < 56) { + md->sha256.buf[md->sha256.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64H(md->sha256.length, md->sha256.buf+56); + sha256_compress(md, md->sha256.buf); + + /* copy output */ + for (i = 0; i < 8; i++) { + STORE32H(md->sha256.state[i], out+(4*i)); + } +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int sha256_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[32]; + } tests[] = { + { "abc", + { 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, + 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, + 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, + 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad } + }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, + 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, + 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, + 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 } + }, + }; + + int i; + unsigned char tmp[32]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + sha256_init(&md); + sha256_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + sha256_done(&md, tmp); + if (XMEMCMP(tmp, tests[i].hash, 32) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#endif + + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/hashes/sha2/sha384.c b/src/ltc/hashes/sha2/sha384.c new file mode 100644 index 0000000..483784b --- /dev/null +++ b/src/ltc/hashes/sha2/sha384.c @@ -0,0 +1,136 @@ +/* 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://libtom.org + */ +/** + @param sha384.c + LTC_SHA384 hash included in sha512.c, Tom St Denis +*/ + +#include "tomcrypt.h" + +#if defined(LTC_SHA384) && defined(LTC_SHA512) + +const struct ltc_hash_descriptor sha384_desc = +{ + "sha384", + 4, + 48, + 128, + + /* OID */ + { 2, 16, 840, 1, 101, 3, 4, 2, 2, }, + 9, + + &sha384_init, + &sha512_process, + &sha384_done, + &sha384_test, + NULL +}; + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int sha384_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + + md->sha512.curlen = 0; + md->sha512.length = 0; + md->sha512.state[0] = CONST64(0xcbbb9d5dc1059ed8); + md->sha512.state[1] = CONST64(0x629a292a367cd507); + md->sha512.state[2] = CONST64(0x9159015a3070dd17); + md->sha512.state[3] = CONST64(0x152fecd8f70e5939); + md->sha512.state[4] = CONST64(0x67332667ffc00b31); + md->sha512.state[5] = CONST64(0x8eb44a8768581511); + md->sha512.state[6] = CONST64(0xdb0c2e0d64f98fa7); + md->sha512.state[7] = CONST64(0x47b5481dbefa4fa4); + return CRYPT_OK; +} + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (48 bytes) + @return CRYPT_OK if successful +*/ +int sha384_done(hash_state * md, unsigned char *out) +{ + unsigned char buf[64]; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->sha512.curlen >= sizeof(md->sha512.buf)) { + return CRYPT_INVALID_ARG; + } + + sha512_done(md, buf); + XMEMCPY(out, buf, 48); +#ifdef LTC_CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int sha384_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[48]; + } tests[] = { + { "abc", + { 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, + 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07, + 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63, + 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, + 0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23, + 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 } + }, + { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", + { 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8, + 0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47, + 0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2, + 0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12, + 0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9, + 0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39 } + }, + }; + + int i; + unsigned char tmp[48]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + sha384_init(&md); + sha384_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + sha384_done(&md, tmp); + if (XMEMCMP(tmp, tests[i].hash, 48) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#endif /* defined(LTC_SHA384) && defined(LTC_SHA512) */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/hashes/sha2/sha512.c b/src/ltc/hashes/sha2/sha512.c new file mode 100644 index 0000000..fbf14de --- /dev/null +++ b/src/ltc/hashes/sha2/sha512.c @@ -0,0 +1,315 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @param sha512.c + LTC_SHA512 by Tom St Denis +*/ + +#ifdef LTC_SHA512 + +const struct ltc_hash_descriptor sha512_desc = +{ + "sha512", + 5, + 64, + 128, + + /* OID */ + { 2, 16, 840, 1, 101, 3, 4, 2, 3, }, + 9, + + &sha512_init, + &sha512_process, + &sha512_done, + &sha512_test, + NULL +}; + +/* the K array */ +static const ulong64 K[80] = { +CONST64(0x428a2f98d728ae22), CONST64(0x7137449123ef65cd), +CONST64(0xb5c0fbcfec4d3b2f), CONST64(0xe9b5dba58189dbbc), +CONST64(0x3956c25bf348b538), CONST64(0x59f111f1b605d019), +CONST64(0x923f82a4af194f9b), CONST64(0xab1c5ed5da6d8118), +CONST64(0xd807aa98a3030242), CONST64(0x12835b0145706fbe), +CONST64(0x243185be4ee4b28c), CONST64(0x550c7dc3d5ffb4e2), +CONST64(0x72be5d74f27b896f), CONST64(0x80deb1fe3b1696b1), +CONST64(0x9bdc06a725c71235), CONST64(0xc19bf174cf692694), +CONST64(0xe49b69c19ef14ad2), CONST64(0xefbe4786384f25e3), +CONST64(0x0fc19dc68b8cd5b5), CONST64(0x240ca1cc77ac9c65), +CONST64(0x2de92c6f592b0275), CONST64(0x4a7484aa6ea6e483), +CONST64(0x5cb0a9dcbd41fbd4), CONST64(0x76f988da831153b5), +CONST64(0x983e5152ee66dfab), CONST64(0xa831c66d2db43210), +CONST64(0xb00327c898fb213f), CONST64(0xbf597fc7beef0ee4), +CONST64(0xc6e00bf33da88fc2), CONST64(0xd5a79147930aa725), +CONST64(0x06ca6351e003826f), CONST64(0x142929670a0e6e70), +CONST64(0x27b70a8546d22ffc), CONST64(0x2e1b21385c26c926), +CONST64(0x4d2c6dfc5ac42aed), CONST64(0x53380d139d95b3df), +CONST64(0x650a73548baf63de), CONST64(0x766a0abb3c77b2a8), +CONST64(0x81c2c92e47edaee6), CONST64(0x92722c851482353b), +CONST64(0xa2bfe8a14cf10364), CONST64(0xa81a664bbc423001), +CONST64(0xc24b8b70d0f89791), CONST64(0xc76c51a30654be30), +CONST64(0xd192e819d6ef5218), CONST64(0xd69906245565a910), +CONST64(0xf40e35855771202a), CONST64(0x106aa07032bbd1b8), +CONST64(0x19a4c116b8d2d0c8), CONST64(0x1e376c085141ab53), +CONST64(0x2748774cdf8eeb99), CONST64(0x34b0bcb5e19b48a8), +CONST64(0x391c0cb3c5c95a63), CONST64(0x4ed8aa4ae3418acb), +CONST64(0x5b9cca4f7763e373), CONST64(0x682e6ff3d6b2b8a3), +CONST64(0x748f82ee5defb2fc), CONST64(0x78a5636f43172f60), +CONST64(0x84c87814a1f0ab72), CONST64(0x8cc702081a6439ec), +CONST64(0x90befffa23631e28), CONST64(0xa4506cebde82bde9), +CONST64(0xbef9a3f7b2c67915), CONST64(0xc67178f2e372532b), +CONST64(0xca273eceea26619c), CONST64(0xd186b8c721c0c207), +CONST64(0xeada7dd6cde0eb1e), CONST64(0xf57d4f7fee6ed178), +CONST64(0x06f067aa72176fba), CONST64(0x0a637dc5a2c898a6), +CONST64(0x113f9804bef90dae), CONST64(0x1b710b35131c471b), +CONST64(0x28db77f523047d84), CONST64(0x32caab7b40c72493), +CONST64(0x3c9ebe0a15c9bebc), CONST64(0x431d67c49c100d4c), +CONST64(0x4cc5d4becb3e42b6), CONST64(0x597f299cfc657e2a), +CONST64(0x5fcb6fab3ad6faec), CONST64(0x6c44198c4a475817) +}; + +/* Various logical functions */ +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) (((x | y) & z) | (x & y)) +#define S(x, n) ROR64c(x, n) +#define R(x, n) (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)n)) +#define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39)) +#define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41)) +#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7)) +#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6)) + +/* compress 1024-bits */ +#ifdef LTC_CLEAN_STACK +static int _sha512_compress(hash_state * md, unsigned char *buf) +#else +static int sha512_compress(hash_state * md, unsigned char *buf) +#endif +{ + ulong64 S[8], W[80], t0, t1; + int i; + + /* copy state into S */ + for (i = 0; i < 8; i++) { + S[i] = md->sha512.state[i]; + } + + /* copy the state into 1024-bits into W[0..15] */ + for (i = 0; i < 16; i++) { + LOAD64H(W[i], buf + (8*i)); + } + + /* fill W[16..79] */ + for (i = 16; i < 80; i++) { + W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; + } + + /* Compress */ +#ifdef LTC_SMALL_CODE + for (i = 0; i < 80; i++) { + t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[i]; + t1 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]); + S[7] = S[6]; + S[6] = S[5]; + S[5] = S[4]; + S[4] = S[3] + t0; + S[3] = S[2]; + S[2] = S[1]; + S[1] = S[0]; + S[0] = t0 + t1; + } +#else +#define RND(a,b,c,d,e,f,g,h,i) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + + for (i = 0; i < 80; i += 8) { + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7); + } +#endif + + + /* feedback */ + for (i = 0; i < 8; i++) { + md->sha512.state[i] = md->sha512.state[i] + S[i]; + } + + return CRYPT_OK; +} + +/* compress 1024-bits */ +#ifdef LTC_CLEAN_STACK +static int sha512_compress(hash_state * md, unsigned char *buf) +{ + int err; + err = _sha512_compress(md, buf); + burn_stack(sizeof(ulong64) * 90 + sizeof(int)); + return err; +} +#endif + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int sha512_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + md->sha512.curlen = 0; + md->sha512.length = 0; + md->sha512.state[0] = CONST64(0x6a09e667f3bcc908); + md->sha512.state[1] = CONST64(0xbb67ae8584caa73b); + md->sha512.state[2] = CONST64(0x3c6ef372fe94f82b); + md->sha512.state[3] = CONST64(0xa54ff53a5f1d36f1); + md->sha512.state[4] = CONST64(0x510e527fade682d1); + md->sha512.state[5] = CONST64(0x9b05688c2b3e6c1f); + md->sha512.state[6] = CONST64(0x1f83d9abfb41bd6b); + md->sha512.state[7] = CONST64(0x5be0cd19137e2179); + return CRYPT_OK; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +HASH_PROCESS(sha512_process, sha512_compress, sha512, 128) + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (64 bytes) + @return CRYPT_OK if successful +*/ +int sha512_done(hash_state * md, unsigned char *out) +{ + int i; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->sha512.curlen >= sizeof(md->sha512.buf)) { + return CRYPT_INVALID_ARG; + } + + /* increase the length of the message */ + md->sha512.length += md->sha512.curlen * CONST64(8); + + /* append the '1' bit */ + md->sha512.buf[md->sha512.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 112 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->sha512.curlen > 112) { + while (md->sha512.curlen < 128) { + md->sha512.buf[md->sha512.curlen++] = (unsigned char)0; + } + sha512_compress(md, md->sha512.buf); + md->sha512.curlen = 0; + } + + /* pad upto 120 bytes of zeroes + * note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash + * > 2^64 bits of data... :-) + */ + while (md->sha512.curlen < 120) { + md->sha512.buf[md->sha512.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64H(md->sha512.length, md->sha512.buf+120); + sha512_compress(md, md->sha512.buf); + + /* copy output */ + for (i = 0; i < 8; i++) { + STORE64H(md->sha512.state[i], out+(8*i)); + } +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int sha512_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[64]; + } tests[] = { + { "abc", + { 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, + 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31, + 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, + 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, + 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, + 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd, + 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, + 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f } + }, + { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", + { 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda, + 0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f, + 0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1, + 0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18, + 0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4, + 0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a, + 0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54, + 0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 } + }, + }; + + int i; + unsigned char tmp[64]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + sha512_init(&md); + sha512_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + sha512_done(&md, tmp); + if (XMEMCMP(tmp, tests[i].hash, 64) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#endif + + + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/hashes/sha2/sha512_224.c b/src/ltc/hashes/sha2/sha512_224.c new file mode 100644 index 0000000..98fba3a --- /dev/null +++ b/src/ltc/hashes/sha2/sha512_224.c @@ -0,0 +1,132 @@ +/* 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://libtom.org + */ +/** + @param sha512_224.c + SHA512/224 hash included in sha512.c +*/ + +#include "tomcrypt.h" + +#if defined(LTC_SHA512_224) && defined(LTC_SHA512) + +const struct ltc_hash_descriptor sha512_224_desc = +{ + "sha512-224", + 15, + 28, + 128, + + /* OID */ + { 2, 16, 840, 1, 101, 3, 4, 2, 5, }, + 9, + + &sha512_224_init, + &sha512_process, + &sha512_224_done, + &sha512_224_test, + NULL +}; + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int sha512_224_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + + md->sha512.curlen = 0; + md->sha512.length = 0; + md->sha512.state[0] = CONST64(0x8C3D37C819544DA2); + md->sha512.state[1] = CONST64(0x73E1996689DCD4D6); + md->sha512.state[2] = CONST64(0x1DFAB7AE32FF9C82); + md->sha512.state[3] = CONST64(0x679DD514582F9FCF); + md->sha512.state[4] = CONST64(0x0F6D2B697BD44DA8); + md->sha512.state[5] = CONST64(0x77E36F7304C48942); + md->sha512.state[6] = CONST64(0x3F9D85A86A1D36C8); + md->sha512.state[7] = CONST64(0x1112E6AD91D692A1); + return CRYPT_OK; +} + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (48 bytes) + @return CRYPT_OK if successful +*/ +int sha512_224_done(hash_state * md, unsigned char *out) +{ + unsigned char buf[64]; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->sha512.curlen >= sizeof(md->sha512.buf)) { + return CRYPT_INVALID_ARG; + } + + sha512_done(md, buf); + XMEMCPY(out, buf, 28); +#ifdef LTC_CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int sha512_224_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[28]; + } tests[] = { + { "abc", + { 0x46, 0x34, 0x27, 0x0F, 0x70, 0x7B, 0x6A, 0x54, + 0xDA, 0xAE, 0x75, 0x30, 0x46, 0x08, 0x42, 0xE2, + 0x0E, 0x37, 0xED, 0x26, 0x5C, 0xEE, 0xE9, 0xA4, + 0x3E, 0x89, 0x24, 0xAA } + }, + { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", + { 0x23, 0xFE, 0xC5, 0xBB, 0x94, 0xD6, 0x0B, 0x23, + 0x30, 0x81, 0x92, 0x64, 0x0B, 0x0C, 0x45, 0x33, + 0x35, 0xD6, 0x64, 0x73, 0x4F, 0xE4, 0x0E, 0x72, + 0x68, 0x67, 0x4A, 0xF9 } + }, + }; + + int i; + unsigned char tmp[28]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + sha512_224_init(&md); + sha512_224_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + sha512_224_done(&md, tmp); + if (XMEMCMP(tmp, tests[i].hash, 28) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#endif /* defined(LTC_SHA384) && defined(LTC_SHA512) */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/hashes/sha2/sha512_256.c b/src/ltc/hashes/sha2/sha512_256.c new file mode 100644 index 0000000..86e4bac --- /dev/null +++ b/src/ltc/hashes/sha2/sha512_256.c @@ -0,0 +1,132 @@ +/* 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://libtom.org + */ +/** + @param sha512_256.c + SHA512/256 hash included in sha512.c +*/ + +#include "tomcrypt.h" + +#if defined(LTC_SHA512_256) && defined(LTC_SHA512) + +const struct ltc_hash_descriptor sha512_256_desc = +{ + "sha512-256", + 16, + 32, + 128, + + /* OID */ + { 2, 16, 840, 1, 101, 3, 4, 2, 6, }, + 9, + + &sha512_256_init, + &sha512_process, + &sha512_256_done, + &sha512_256_test, + NULL +}; + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int sha512_256_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + + md->sha512.curlen = 0; + md->sha512.length = 0; + md->sha512.state[0] = CONST64(0x22312194FC2BF72C); + md->sha512.state[1] = CONST64(0x9F555FA3C84C64C2); + md->sha512.state[2] = CONST64(0x2393B86B6F53B151); + md->sha512.state[3] = CONST64(0x963877195940EABD); + md->sha512.state[4] = CONST64(0x96283EE2A88EFFE3); + md->sha512.state[5] = CONST64(0xBE5E1E2553863992); + md->sha512.state[6] = CONST64(0x2B0199FC2C85B8AA); + md->sha512.state[7] = CONST64(0x0EB72DDC81C52CA2); + return CRYPT_OK; +} + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (48 bytes) + @return CRYPT_OK if successful +*/ +int sha512_256_done(hash_state * md, unsigned char *out) +{ + unsigned char buf[64]; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->sha512.curlen >= sizeof(md->sha512.buf)) { + return CRYPT_INVALID_ARG; + } + + sha512_done(md, buf); + XMEMCPY(out, buf, 32); +#ifdef LTC_CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int sha512_256_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[32]; + } tests[] = { + { "abc", + { 0x53, 0x04, 0x8E, 0x26, 0x81, 0x94, 0x1E, 0xF9, + 0x9B, 0x2E, 0x29, 0xB7, 0x6B, 0x4C, 0x7D, 0xAB, + 0xE4, 0xC2, 0xD0, 0xC6, 0x34, 0xFC, 0x6D, 0x46, + 0xE0, 0xE2, 0xF1, 0x31, 0x07, 0xE7, 0xAF, 0x23 } + }, + { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", + { 0x39, 0x28, 0xE1, 0x84, 0xFB, 0x86, 0x90, 0xF8, + 0x40, 0xDA, 0x39, 0x88, 0x12, 0x1D, 0x31, 0xBE, + 0x65, 0xCB, 0x9D, 0x3E, 0xF8, 0x3E, 0xE6, 0x14, + 0x6F, 0xEA, 0xC8, 0x61, 0xE1, 0x9B, 0x56, 0x3A } + }, + }; + + int i; + unsigned char tmp[32]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + sha512_256_init(&md); + sha512_256_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + sha512_256_done(&md, tmp); + if (XMEMCMP(tmp, tests[i].hash, 32) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#endif /* defined(LTC_SHA384) && defined(LTC_SHA512) */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/hashes/sha3.c b/src/ltc/hashes/sha3.c new file mode 100644 index 0000000..68dea0b --- /dev/null +++ b/src/ltc/hashes/sha3.c @@ -0,0 +1,296 @@ +/* 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. + */ + +/* based on https://github.com/brainhub/SHA3IUF (public domain) */ + +#include "tomcrypt.h" + +#ifdef LTC_SHA3 + +const struct ltc_hash_descriptor sha3_224_desc = +{ + "sha3-224", /* name of hash */ + 17, /* internal ID */ + 28, /* Size of digest in octets */ + 128, /* Input block size in octets */ + { 2,16,840,1,101,3,4,2,7 }, /* ASN.1 OID */ + 9, /* Length OID */ + &sha3_224_init, + &sha3_process, + &sha3_done, + &sha3_224_test, + NULL +}; + +const struct ltc_hash_descriptor sha3_256_desc = +{ + "sha3-256", /* name of hash */ + 18, /* internal ID */ + 32, /* Size of digest in octets */ + 128, /* Input block size in octets */ + { 2,16,840,1,101,3,4,2,8 }, /* ASN.1 OID */ + 9, /* Length OID */ + &sha3_256_init, + &sha3_process, + &sha3_done, + &sha3_256_test, + NULL +}; + +const struct ltc_hash_descriptor sha3_384_desc = +{ + "sha3-384", /* name of hash */ + 19, /* internal ID */ + 48, /* Size of digest in octets */ + 128, /* Input block size in octets */ + { 2,16,840,1,101,3,4,2,9 }, /* ASN.1 OID */ + 9, /* Length OID */ + &sha3_384_init, + &sha3_process, + &sha3_done, + &sha3_384_test, + NULL +}; + +const struct ltc_hash_descriptor sha3_512_desc = +{ + "sha3-512", /* name of hash */ + 20, /* internal ID */ + 64, /* Size of digest in octets */ + 128, /* Input block size in octets */ + { 2,16,840,1,101,3,4,2,10 }, /* ASN.1 OID */ + 9, /* Length OID */ + &sha3_512_init, + &sha3_process, + &sha3_done, + &sha3_512_test, + NULL +}; + +#define SHA3_KECCAK_SPONGE_WORDS 25 /* 1600 bits > 200 bytes > 25 x ulong64 */ +#define SHA3_KECCAK_ROUNDS 24 + +static const ulong64 keccakf_rndc[24] = { + CONST64(0x0000000000000001), CONST64(0x0000000000008082), + CONST64(0x800000000000808a), CONST64(0x8000000080008000), + CONST64(0x000000000000808b), CONST64(0x0000000080000001), + CONST64(0x8000000080008081), CONST64(0x8000000000008009), + CONST64(0x000000000000008a), CONST64(0x0000000000000088), + CONST64(0x0000000080008009), CONST64(0x000000008000000a), + CONST64(0x000000008000808b), CONST64(0x800000000000008b), + CONST64(0x8000000000008089), CONST64(0x8000000000008003), + CONST64(0x8000000000008002), CONST64(0x8000000000000080), + CONST64(0x000000000000800a), CONST64(0x800000008000000a), + CONST64(0x8000000080008081), CONST64(0x8000000000008080), + CONST64(0x0000000080000001), CONST64(0x8000000080008008) +}; + +static const unsigned keccakf_rotc[24] = { + 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 +}; + +static const unsigned keccakf_piln[24] = { + 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 +}; + +static void keccakf(ulong64 s[25]) +{ + int i, j, round; + ulong64 t, bc[5]; + + for(round = 0; round < SHA3_KECCAK_ROUNDS; round++) { + /* Theta */ + for(i = 0; i < 5; i++) + bc[i] = s[i] ^ s[i + 5] ^ s[i + 10] ^ s[i + 15] ^ s[i + 20]; + + for(i = 0; i < 5; i++) { + t = bc[(i + 4) % 5] ^ ROL64(bc[(i + 1) % 5], 1); + for(j = 0; j < 25; j += 5) + s[j + i] ^= t; + } + /* Rho Pi */ + t = s[1]; + for(i = 0; i < 24; i++) { + j = keccakf_piln[i]; + bc[0] = s[j]; + s[j] = ROL64(t, keccakf_rotc[i]); + t = bc[0]; + } + /* Chi */ + for(j = 0; j < 25; j += 5) { + for(i = 0; i < 5; i++) + bc[i] = s[j + i]; + for(i = 0; i < 5; i++) + s[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5]; + } + /* Iota */ + s[0] ^= keccakf_rndc[round]; + } +} + +/* Public Inteface */ + +int sha3_224_init(hash_state *md) +{ + LTC_ARGCHK(md != NULL); + XMEMSET(&md->sha3, 0, sizeof(md->sha3)); + md->sha3.capacity_words = 2 * 224 / (8 * sizeof(ulong64)); + return CRYPT_OK; +} + +int sha3_256_init(hash_state *md) +{ + LTC_ARGCHK(md != NULL); + XMEMSET(&md->sha3, 0, sizeof(md->sha3)); + md->sha3.capacity_words = 2 * 256 / (8 * sizeof(ulong64)); + return CRYPT_OK; +} + +int sha3_384_init(hash_state *md) +{ + LTC_ARGCHK(md != NULL); + XMEMSET(&md->sha3, 0, sizeof(md->sha3)); + md->sha3.capacity_words = 2 * 384 / (8 * sizeof(ulong64)); + return CRYPT_OK; +} + +int sha3_512_init(hash_state *md) +{ + LTC_ARGCHK(md != NULL); + XMEMSET(&md->sha3, 0, sizeof(md->sha3)); + md->sha3.capacity_words = 2 * 512 / (8 * sizeof(ulong64)); + return CRYPT_OK; +} + +int sha3_shake_init(hash_state *md, int num) +{ + LTC_ARGCHK(md != NULL); + if (num != 128 && num != 256) return CRYPT_INVALID_ARG; + XMEMSET(&md->sha3, 0, sizeof(md->sha3)); + md->sha3.capacity_words = (unsigned short)(2 * num / (8 * sizeof(ulong64))); + return CRYPT_OK; +} + +int sha3_process(hash_state *md, const unsigned char *in, unsigned long inlen) +{ + /* 0...7 -- how much is needed to have a word */ + unsigned old_tail = (8 - md->sha3.byte_index) & 7; + + unsigned long words; + unsigned tail; + unsigned long i; + + if (inlen == 0) return CRYPT_OK; /* nothing to do */ + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(in != NULL); + + if(inlen < old_tail) { /* have no complete word or haven't started the word yet */ + while (inlen--) md->sha3.saved |= (ulong64) (*(in++)) << ((md->sha3.byte_index++) * 8); + return CRYPT_OK; + } + + if(old_tail) { /* will have one word to process */ + inlen -= old_tail; + while (old_tail--) md->sha3.saved |= (ulong64) (*(in++)) << ((md->sha3.byte_index++) * 8); + /* now ready to add saved to the sponge */ + md->sha3.s[md->sha3.word_index] ^= md->sha3.saved; + md->sha3.byte_index = 0; + md->sha3.saved = 0; + if(++md->sha3.word_index == (SHA3_KECCAK_SPONGE_WORDS - md->sha3.capacity_words)) { + keccakf(md->sha3.s); + md->sha3.word_index = 0; + } + } + + /* now work in full words directly from input */ + words = inlen / sizeof(ulong64); + tail = inlen - words * sizeof(ulong64); + + for(i = 0; i < words; i++, in += sizeof(ulong64)) { + ulong64 t; + LOAD64L(t, in); + md->sha3.s[md->sha3.word_index] ^= t; + if(++md->sha3.word_index == (SHA3_KECCAK_SPONGE_WORDS - md->sha3.capacity_words)) { + keccakf(md->sha3.s); + md->sha3.word_index = 0; + } + } + + /* finally, save the partial word */ + while (tail--) { + md->sha3.saved |= (ulong64) (*(in++)) << ((md->sha3.byte_index++) * 8); + } + return CRYPT_OK; +} + +int sha3_done(hash_state *md, unsigned char *hash) +{ + unsigned i; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(hash != NULL); + + md->sha3.s[md->sha3.word_index] ^= (md->sha3.saved ^ (CONST64(0x06) << (md->sha3.byte_index * 8))); + md->sha3.s[SHA3_KECCAK_SPONGE_WORDS - md->sha3.capacity_words - 1] ^= CONST64(0x8000000000000000); + keccakf(md->sha3.s); + + /* store sha3.s[] as little-endian bytes into sha3.sb */ + for(i = 0; i < SHA3_KECCAK_SPONGE_WORDS; i++) STORE64L(md->sha3.s[i], md->sha3.sb + i * 8); + + XMEMCPY(hash, md->sha3.sb, md->sha3.capacity_words * 4); + return CRYPT_OK; +} + +int sha3_shake_done(hash_state *md, unsigned char *out, unsigned long outlen) +{ + /* IMPORTANT NOTE: sha3_shake_done can be called many times */ + unsigned long idx; + unsigned i; + + if (outlen == 0) return CRYPT_OK; /* nothing to do */ + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (!md->sha3.xof_flag) { + /* shake_xof operation must be done only once */ + md->sha3.s[md->sha3.word_index] ^= (md->sha3.saved ^ (CONST64(0x1F) << (md->sha3.byte_index * 8))); + md->sha3.s[SHA3_KECCAK_SPONGE_WORDS - md->sha3.capacity_words - 1] ^= CONST64(0x8000000000000000); + keccakf(md->sha3.s); + /* store sha3.s[] as little-endian bytes into sha3.sb */ + for(i = 0; i < SHA3_KECCAK_SPONGE_WORDS; i++) STORE64L(md->sha3.s[i], md->sha3.sb + i * 8); + md->sha3.byte_index = 0; + md->sha3.xof_flag = 1; + } + + for (idx = 0; idx < outlen; idx++) { + if(md->sha3.byte_index >= (SHA3_KECCAK_SPONGE_WORDS - md->sha3.capacity_words) * 8) { + keccakf(md->sha3.s); + /* store sha3.s[] as little-endian bytes into sha3.sb */ + for(i = 0; i < SHA3_KECCAK_SPONGE_WORDS; i++) STORE64L(md->sha3.s[i], md->sha3.sb + i * 8); + md->sha3.byte_index = 0; + } + out[idx] = md->sha3.sb[md->sha3.byte_index++]; + } + return CRYPT_OK; +} + +int sha3_shake_memory(int num, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) +{ + hash_state md; + int err; + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + if ((err = sha3_shake_init(&md, num)) != CRYPT_OK) return err; + if ((err = sha3_shake_process(&md, in, inlen)) != CRYPT_OK) return err; + if ((err = sha3_shake_done(&md, out, *outlen)) != CRYPT_OK) return err; + return CRYPT_OK; +} + +#endif diff --git a/src/ltc/hashes/sha3_test.c b/src/ltc/hashes/sha3_test.c new file mode 100644 index 0000000..b4b3d8d --- /dev/null +++ b/src/ltc/hashes/sha3_test.c @@ -0,0 +1,420 @@ +/* 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. + */ + +/* based on https://github.com/brainhub/SHA3IUF (public domain) */ + +#include "tomcrypt.h" + +#ifdef LTC_SHA3 + +int sha3_224_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + unsigned char buf[200], hash[200]; + int i; + hash_state c; + const unsigned char c1 = 0xa3; + + const unsigned char sha3_224_empty[224 / 8] = { + 0x6b, 0x4e, 0x03, 0x42, 0x36, 0x67, 0xdb, 0xb7, + 0x3b, 0x6e, 0x15, 0x45, 0x4f, 0x0e, 0xb1, 0xab, + 0xd4, 0x59, 0x7f, 0x9a, 0x1b, 0x07, 0x8e, 0x3f, + 0x5b, 0x5a, 0x6b, 0xc7 + }; + + const unsigned char sha3_224_0xa3_200_times[224 / 8] = { + 0x93, 0x76, 0x81, 0x6a, 0xba, 0x50, 0x3f, 0x72, + 0xf9, 0x6c, 0xe7, 0xeb, 0x65, 0xac, 0x09, 0x5d, + 0xee, 0xe3, 0xbe, 0x4b, 0xf9, 0xbb, 0xc2, 0xa1, + 0xcb, 0x7e, 0x11, 0xe0 + }; + + XMEMSET(buf, c1, sizeof(buf)); + + /* SHA3-224 on an empty buffer */ + sha3_224_init(&c); + sha3_done(&c, hash); + if(XMEMCMP(sha3_224_empty, hash, sizeof(sha3_224_empty)) != 0) { + printf("SHA3-224() failed\n"); + return CRYPT_FAIL_TESTVECTOR; + } + + /* SHA3-224 in two steps. [FIPS 202] */ + sha3_224_init(&c); + sha3_process(&c, buf, sizeof(buf) / 2); + sha3_process(&c, buf + sizeof(buf) / 2, sizeof(buf) / 2); + sha3_done(&c, hash); + if(XMEMCMP(sha3_224_0xa3_200_times, hash, sizeof(sha3_224_0xa3_200_times)) != 0) { + printf("SHA3-224( 0xa3 ... [200 times] ) failed (2 steps)\n"); + return CRYPT_FAIL_TESTVECTOR; + } + + /* SHA3-224 byte-by-byte: 200 steps. [FIPS 202] */ + i = 200; + sha3_224_init(&c); + while (i--) { + sha3_process(&c, &c1, 1); + } + sha3_done(&c, hash); + if(XMEMCMP(sha3_224_0xa3_200_times, hash, sizeof(sha3_224_0xa3_200_times)) != 0) { + printf("SHA3-224( 0xa3 ... [200 times] ) failed (200 steps)\n"); + return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; +#endif +} + +int sha3_256_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + unsigned char buf[200], hash[200]; + int i; + hash_state c; + const unsigned char c1 = 0xa3; + + const unsigned char sha3_256_empty[256 / 8] = { + 0xa7, 0xff, 0xc6, 0xf8, 0xbf, 0x1e, 0xd7, 0x66, + 0x51, 0xc1, 0x47, 0x56, 0xa0, 0x61, 0xd6, 0x62, + 0xf5, 0x80, 0xff, 0x4d, 0xe4, 0x3b, 0x49, 0xfa, + 0x82, 0xd8, 0x0a, 0x4b, 0x80, 0xf8, 0x43, 0x4a + }; + const unsigned char sha3_256_0xa3_200_times[256 / 8] = { + 0x79, 0xf3, 0x8a, 0xde, 0xc5, 0xc2, 0x03, 0x07, + 0xa9, 0x8e, 0xf7, 0x6e, 0x83, 0x24, 0xaf, 0xbf, + 0xd4, 0x6c, 0xfd, 0x81, 0xb2, 0x2e, 0x39, 0x73, + 0xc6, 0x5f, 0xa1, 0xbd, 0x9d, 0xe3, 0x17, 0x87 + }; + + XMEMSET(buf, c1, sizeof(buf)); + + /* SHA3-256 on an empty buffer */ + sha3_256_init(&c); + sha3_done(&c, hash); + if(XMEMCMP(sha3_256_empty, hash, sizeof(sha3_256_empty)) != 0) { + printf("SHA3-256() failed\n"); + return CRYPT_FAIL_TESTVECTOR; + } + + /* SHA3-256 as a single buffer. [FIPS 202] */ + sha3_256_init(&c); + sha3_process(&c, buf, sizeof(buf)); + sha3_done(&c, hash); + if(XMEMCMP(sha3_256_0xa3_200_times, hash, sizeof(sha3_256_0xa3_200_times)) != 0) { + printf("SHA3-256( 0xa3 ... [200 times] ) failed (1 buffer)\n"); + return CRYPT_FAIL_TESTVECTOR; + } + + /* SHA3-256 in two steps. [FIPS 202] */ + sha3_256_init(&c); + sha3_process(&c, buf, sizeof(buf) / 2); + sha3_process(&c, buf + sizeof(buf) / 2, sizeof(buf) / 2); + sha3_done(&c, hash); + if(XMEMCMP(sha3_256_0xa3_200_times, hash, sizeof(sha3_256_0xa3_200_times)) != 0) { + printf("SHA3-256( 0xa3 ... [200 times] ) failed (2 steps)\n"); + return CRYPT_FAIL_TESTVECTOR; + } + + /* SHA3-256 byte-by-byte: 200 steps. [FIPS 202] */ + i = 200; + sha3_256_init(&c); + while (i--) { + sha3_process(&c, &c1, 1); + } + sha3_done(&c, hash); + if(XMEMCMP(sha3_256_0xa3_200_times, hash, sizeof(sha3_256_0xa3_200_times)) != 0) { + printf("SHA3-256( 0xa3 ... [200 times] ) failed (200 steps)\n"); + return CRYPT_FAIL_TESTVECTOR; + } + + /* SHA3-256 byte-by-byte: 135 bytes. Input from [Keccak]. Output + * matched with sha3sum. */ + sha3_256_init(&c); + sha3_process(&c, (unsigned char*) + "\xb7\x71\xd5\xce\xf5\xd1\xa4\x1a" + "\x93\xd1\x56\x43\xd7\x18\x1d\x2a" + "\x2e\xf0\xa8\xe8\x4d\x91\x81\x2f" + "\x20\xed\x21\xf1\x47\xbe\xf7\x32" + "\xbf\x3a\x60\xef\x40\x67\xc3\x73" + "\x4b\x85\xbc\x8c\xd4\x71\x78\x0f" + "\x10\xdc\x9e\x82\x91\xb5\x83\x39" + "\xa6\x77\xb9\x60\x21\x8f\x71\xe7" + "\x93\xf2\x79\x7a\xea\x34\x94\x06" + "\x51\x28\x29\x06\x5d\x37\xbb\x55" + "\xea\x79\x6f\xa4\xf5\x6f\xd8\x89" + "\x6b\x49\xb2\xcd\x19\xb4\x32\x15" + "\xad\x96\x7c\x71\x2b\x24\xe5\x03" + "\x2d\x06\x52\x32\xe0\x2c\x12\x74" + "\x09\xd2\xed\x41\x46\xb9\xd7\x5d" + "\x76\x3d\x52\xdb\x98\xd9\x49\xd3" + "\xb0\xfe\xd6\xa8\x05\x2f\xbb", 1080 / 8); + sha3_done(&c, hash); + if(XMEMCMP(hash, "\xa1\x9e\xee\x92\xbb\x20\x97\xb6" + "\x4e\x82\x3d\x59\x77\x98\xaa\x18" + "\xbe\x9b\x7c\x73\x6b\x80\x59\xab" + "\xfd\x67\x79\xac\x35\xac\x81\xb5", 256 / 8) != 0) { + printf("SHA3-256( b771 ... ) doesn't match the known answer\n"); + return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; +#endif +} + +int sha3_384_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + unsigned char buf[200], hash[200]; + int i; + hash_state c; + const unsigned char c1 = 0xa3; + + const unsigned char sha3_384_0xa3_200_times[384 / 8] = { + 0x18, 0x81, 0xde, 0x2c, 0xa7, 0xe4, 0x1e, 0xf9, + 0x5d, 0xc4, 0x73, 0x2b, 0x8f, 0x5f, 0x00, 0x2b, + 0x18, 0x9c, 0xc1, 0xe4, 0x2b, 0x74, 0x16, 0x8e, + 0xd1, 0x73, 0x26, 0x49, 0xce, 0x1d, 0xbc, 0xdd, + 0x76, 0x19, 0x7a, 0x31, 0xfd, 0x55, 0xee, 0x98, + 0x9f, 0x2d, 0x70, 0x50, 0xdd, 0x47, 0x3e, 0x8f + }; + + XMEMSET(buf, c1, sizeof(buf)); + + /* SHA3-384 as a single buffer. [FIPS 202] */ + sha3_384_init(&c); + sha3_process(&c, buf, sizeof(buf)); + sha3_done(&c, hash); + if(XMEMCMP(sha3_384_0xa3_200_times, hash, sizeof(sha3_384_0xa3_200_times)) != 0) { + printf("SHA3-384( 0xa3 ... [200 times] ) failed (1 buffer)\n"); + return CRYPT_FAIL_TESTVECTOR; + } + + /* SHA3-384 in two steps. [FIPS 202] */ + sha3_384_init(&c); + sha3_process(&c, buf, sizeof(buf) / 2); + sha3_process(&c, buf + sizeof(buf) / 2, sizeof(buf) / 2); + sha3_done(&c, hash); + if(XMEMCMP(sha3_384_0xa3_200_times, hash, sizeof(sha3_384_0xa3_200_times)) != 0) { + printf("SHA3-384( 0xa3 ... [200 times] ) failed (2 steps)\n"); + return CRYPT_FAIL_TESTVECTOR; + } + + /* SHA3-384 byte-by-byte: 200 steps. [FIPS 202] */ + i = 200; + sha3_384_init(&c); + while (i--) { + sha3_process(&c, &c1, 1); + } + sha3_done(&c, hash); + if(XMEMCMP(sha3_384_0xa3_200_times, hash, sizeof(sha3_384_0xa3_200_times)) != 0) { + printf("SHA3-384( 0xa3 ... [200 times] ) failed (200 steps)\n"); + return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; +#endif +} + +int sha3_512_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + unsigned char buf[200], hash[200]; + int i; + hash_state c; + const unsigned char c1 = 0xa3; + + const unsigned char sha3_512_0xa3_200_times[512 / 8] = { + 0xe7, 0x6d, 0xfa, 0xd2, 0x20, 0x84, 0xa8, 0xb1, + 0x46, 0x7f, 0xcf, 0x2f, 0xfa, 0x58, 0x36, 0x1b, + 0xec, 0x76, 0x28, 0xed, 0xf5, 0xf3, 0xfd, 0xc0, + 0xe4, 0x80, 0x5d, 0xc4, 0x8c, 0xae, 0xec, 0xa8, + 0x1b, 0x7c, 0x13, 0xc3, 0x0a, 0xdf, 0x52, 0xa3, + 0x65, 0x95, 0x84, 0x73, 0x9a, 0x2d, 0xf4, 0x6b, + 0xe5, 0x89, 0xc5, 0x1c, 0xa1, 0xa4, 0xa8, 0x41, + 0x6d, 0xf6, 0x54, 0x5a, 0x1c, 0xe8, 0xba, 0x00 + }; + + XMEMSET(buf, c1, sizeof(buf)); + + /* SHA3-512 as a single buffer. [FIPS 202] */ + sha3_512_init(&c); + sha3_process(&c, buf, sizeof(buf)); + sha3_done(&c, hash); + if(XMEMCMP(sha3_512_0xa3_200_times, hash, sizeof(sha3_512_0xa3_200_times)) != 0) { + printf("SHA3-512( 0xa3 ... [200 times] ) failed (1 buffer)\n"); + return CRYPT_FAIL_TESTVECTOR; + } + + /* SHA3-512 in two steps. [FIPS 202] */ + sha3_512_init(&c); + sha3_process(&c, buf, sizeof(buf) / 2); + sha3_process(&c, buf + sizeof(buf) / 2, sizeof(buf) / 2); + sha3_done(&c, hash); + if(XMEMCMP(sha3_512_0xa3_200_times, hash, sizeof(sha3_512_0xa3_200_times)) != 0) { + printf("SHA3-512( 0xa3 ... [200 times] ) failed (2 steps)\n"); + return CRYPT_FAIL_TESTVECTOR; + } + + /* SHA3-512 byte-by-byte: 200 steps. [FIPS 202] */ + i = 200; + sha3_512_init(&c); + while (i--) { + sha3_process(&c, &c1, 1); + } + sha3_done(&c, hash); + if(XMEMCMP(sha3_512_0xa3_200_times, hash, sizeof(sha3_512_0xa3_200_times)) != 0) { + printf("SHA3-512( 0xa3 ... [200 times] ) failed (200 steps)\n"); + return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; +#endif +} + +int sha3_shake_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + unsigned char buf[200], hash[512]; + int i; + hash_state c; + const unsigned char c1 = 0xa3; + unsigned long len; + + const unsigned char shake256_empty[32] = { + 0xab, 0x0b, 0xae, 0x31, 0x63, 0x39, 0x89, 0x43, + 0x04, 0xe3, 0x58, 0x77, 0xb0, 0xc2, 0x8a, 0x9b, + 0x1f, 0xd1, 0x66, 0xc7, 0x96, 0xb9, 0xcc, 0x25, + 0x8a, 0x06, 0x4a, 0x8f, 0x57, 0xe2, 0x7f, 0x2a + }; + const unsigned char shake256_0xa3_200_times[32] = { + 0x6a, 0x1a, 0x9d, 0x78, 0x46, 0x43, 0x6e, 0x4d, + 0xca, 0x57, 0x28, 0xb6, 0xf7, 0x60, 0xee, 0xf0, + 0xca, 0x92, 0xbf, 0x0b, 0xe5, 0x61, 0x5e, 0x96, + 0x95, 0x9d, 0x76, 0x71, 0x97, 0xa0, 0xbe, 0xeb + }; + const unsigned char shake128_empty[32] = { + 0x43, 0xe4, 0x1b, 0x45, 0xa6, 0x53, 0xf2, 0xa5, + 0xc4, 0x49, 0x2c, 0x1a, 0xdd, 0x54, 0x45, 0x12, + 0xdd, 0xa2, 0x52, 0x98, 0x33, 0x46, 0x2b, 0x71, + 0xa4, 0x1a, 0x45, 0xbe, 0x97, 0x29, 0x0b, 0x6f + }; + const unsigned char shake128_0xa3_200_times[32] = { + 0x44, 0xc9, 0xfb, 0x35, 0x9f, 0xd5, 0x6a, 0xc0, + 0xa9, 0xa7, 0x5a, 0x74, 0x3c, 0xff, 0x68, 0x62, + 0xf1, 0x7d, 0x72, 0x59, 0xab, 0x07, 0x52, 0x16, + 0xc0, 0x69, 0x95, 0x11, 0x64, 0x3b, 0x64, 0x39 + }; + + XMEMSET(buf, c1, sizeof(buf)); + + /* SHAKE256 on an empty buffer */ + sha3_shake_init(&c, 256); + for (i = 0; i < 16; i++) sha3_shake_done(&c, hash, 32); /* get 512 bytes, keep in hash the last 32 */ + if(XMEMCMP(shake256_empty, hash, sizeof(shake256_empty)) != 0) { + printf("SHAKE256('') failed\n"); + return CRYPT_FAIL_TESTVECTOR; + } + + /* SHAKE256 via sha3_shake_memory [FIPS 202] */ + len = 512; + sha3_shake_memory(256, buf, sizeof(buf), hash, &len); + if(XMEMCMP(shake256_0xa3_200_times, hash + 480, sizeof(shake256_0xa3_200_times)) != 0) { + printf("SHAKE256( 0xa3 ... [200 times] ) failed (sha3_shake_memory)\n"); + return CRYPT_FAIL_TESTVECTOR; + } + + /* SHAKE256 as a single buffer. [FIPS 202] */ + sha3_shake_init(&c, 256); + sha3_shake_process(&c, buf, sizeof(buf)); + for (i = 0; i < 16; i++) sha3_shake_done(&c, hash, 32); /* get 512 bytes, keep in hash the last 32 */ + if(XMEMCMP(shake256_0xa3_200_times, hash, sizeof(shake256_0xa3_200_times)) != 0) { + printf("SHAKE256( 0xa3 ... [200 times] ) failed (1 buffer)\n"); + return CRYPT_FAIL_TESTVECTOR; + } + + /* SHAKE256 in two steps. [FIPS 202] */ + sha3_shake_init(&c, 256); + sha3_shake_process(&c, buf, sizeof(buf) / 2); + sha3_shake_process(&c, buf + sizeof(buf) / 2, sizeof(buf) / 2); + for (i = 0; i < 16; i++) sha3_shake_done(&c, hash, 32); /* get 512 bytes, keep in hash the last 32 */ + if(XMEMCMP(shake256_0xa3_200_times, hash, sizeof(shake256_0xa3_200_times)) != 0) { + printf("SHAKE256( 0xa3 ... [200 times] ) failed (2 steps)\n"); + return CRYPT_FAIL_TESTVECTOR; + } + + /* SHAKE256 byte-by-byte: 200 steps. [FIPS 202] */ + i = 200; + sha3_shake_init(&c, 256); + while (i--) sha3_shake_process(&c, &c1, 1); + for (i = 0; i < 16; i++) sha3_shake_done(&c, hash, 32); /* get 512 bytes, keep in hash the last 32 */ + if(XMEMCMP(shake256_0xa3_200_times, hash, sizeof(shake256_0xa3_200_times)) != 0) { + printf("SHAKE256( 0xa3 ... [200 times] ) failed (200 steps)\n"); + return CRYPT_FAIL_TESTVECTOR; + } + + /* SHAKE128 on an empty buffer */ + sha3_shake_init(&c, 128); + for (i = 0; i < 16; i++) sha3_shake_done(&c, hash, 32); /* get 512 bytes, keep in hash the last 32 */ + if(XMEMCMP(shake128_empty, hash, sizeof(shake128_empty)) != 0) { + printf("SHAKE128() failed\n"); + return CRYPT_FAIL_TESTVECTOR; + } + + /* SHAKE128 via sha3_shake_memory [FIPS 202] */ + len = 512; + sha3_shake_memory(128, buf, sizeof(buf), hash, &len); + if(XMEMCMP(shake128_0xa3_200_times, hash + 480, sizeof(shake128_0xa3_200_times)) != 0) { + printf("SHAKE128( 0xa3 ... [200 times] ) failed (sha3_shake_memory)\n"); + return CRYPT_FAIL_TESTVECTOR; + } + + /* SHAKE128 as a single buffer. [FIPS 202] */ + sha3_shake_init(&c, 128); + sha3_shake_process(&c, buf, sizeof(buf)); + for (i = 0; i < 16; i++) sha3_shake_done(&c, hash, 32); /* get 512 bytes, keep in hash the last 32 */ + if(XMEMCMP(shake128_0xa3_200_times, hash, sizeof(shake128_0xa3_200_times)) != 0) { + printf("SHAKE128( 0xa3 ... [200 times] ) failed (1 buffer)\n"); + return CRYPT_FAIL_TESTVECTOR; + } + + /* SHAKE128 in two steps. [FIPS 202] */ + sha3_shake_init(&c, 128); + sha3_shake_process(&c, buf, sizeof(buf) / 2); + sha3_shake_process(&c, buf + sizeof(buf) / 2, sizeof(buf) / 2); + for (i = 0; i < 16; i++) sha3_shake_done(&c, hash, 32); /* get 512 bytes, keep in hash the last 32 */ + if(XMEMCMP(shake128_0xa3_200_times, hash, sizeof(shake128_0xa3_200_times)) != 0) { + printf("SHAKE128( 0xa3 ... [200 times] ) failed (2 steps)\n"); + return CRYPT_FAIL_TESTVECTOR; + } + + /* SHAKE128 byte-by-byte: 200 steps. [FIPS 202] */ + i = 200; + sha3_shake_init(&c, 128); + while (i--) sha3_shake_process(&c, &c1, 1); + for (i = 0; i < 16; i++) sha3_shake_done(&c, hash, 32); /* get 512 bytes, keep in hash the last 32 */ + if(XMEMCMP(shake128_0xa3_200_times, hash, sizeof(shake128_0xa3_200_times)) != 0) { + printf("SHAKE128( 0xa3 ... [200 times] ) failed (200 steps)\n"); + return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; +#endif +} + +#endif diff --git a/src/ltc/hashes/tiger.c b/src/ltc/hashes/tiger.c new file mode 100644 index 0000000..dcacb64 --- /dev/null +++ b/src/ltc/hashes/tiger.c @@ -0,0 +1,814 @@ +/* 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://libtom.org + */ + +#include "tomcrypt.h" + +/** + @file tiger.c + Tiger hash function, Tom St Denis +*/ + +#ifdef LTC_TIGER + +const struct ltc_hash_descriptor tiger_desc = +{ + "tiger", + 1, + 24, + 64, + + /* OID */ + { 1, 3, 6, 1, 4, 1, 11591, 12, 2, }, + 9, + + &tiger_init, + &tiger_process, + &tiger_done, + &tiger_test, + NULL +}; + +#define t1 (table) +#define t2 (table+256) +#define t3 (table+256*2) +#define t4 (table+256*3) + +static const ulong64 table[4*256] = { + CONST64(0x02AAB17CF7E90C5E) /* 0 */, CONST64(0xAC424B03E243A8EC) /* 1 */, + CONST64(0x72CD5BE30DD5FCD3) /* 2 */, CONST64(0x6D019B93F6F97F3A) /* 3 */, + CONST64(0xCD9978FFD21F9193) /* 4 */, CONST64(0x7573A1C9708029E2) /* 5 */, + CONST64(0xB164326B922A83C3) /* 6 */, CONST64(0x46883EEE04915870) /* 7 */, + CONST64(0xEAACE3057103ECE6) /* 8 */, CONST64(0xC54169B808A3535C) /* 9 */, + CONST64(0x4CE754918DDEC47C) /* 10 */, CONST64(0x0AA2F4DFDC0DF40C) /* 11 */, + CONST64(0x10B76F18A74DBEFA) /* 12 */, CONST64(0xC6CCB6235AD1AB6A) /* 13 */, + CONST64(0x13726121572FE2FF) /* 14 */, CONST64(0x1A488C6F199D921E) /* 15 */, + CONST64(0x4BC9F9F4DA0007CA) /* 16 */, CONST64(0x26F5E6F6E85241C7) /* 17 */, + CONST64(0x859079DBEA5947B6) /* 18 */, CONST64(0x4F1885C5C99E8C92) /* 19 */, + CONST64(0xD78E761EA96F864B) /* 20 */, CONST64(0x8E36428C52B5C17D) /* 21 */, + CONST64(0x69CF6827373063C1) /* 22 */, CONST64(0xB607C93D9BB4C56E) /* 23 */, + CONST64(0x7D820E760E76B5EA) /* 24 */, CONST64(0x645C9CC6F07FDC42) /* 25 */, + CONST64(0xBF38A078243342E0) /* 26 */, CONST64(0x5F6B343C9D2E7D04) /* 27 */, + CONST64(0xF2C28AEB600B0EC6) /* 28 */, CONST64(0x6C0ED85F7254BCAC) /* 29 */, + CONST64(0x71592281A4DB4FE5) /* 30 */, CONST64(0x1967FA69CE0FED9F) /* 31 */, + CONST64(0xFD5293F8B96545DB) /* 32 */, CONST64(0xC879E9D7F2A7600B) /* 33 */, + CONST64(0x860248920193194E) /* 34 */, CONST64(0xA4F9533B2D9CC0B3) /* 35 */, + CONST64(0x9053836C15957613) /* 36 */, CONST64(0xDB6DCF8AFC357BF1) /* 37 */, + CONST64(0x18BEEA7A7A370F57) /* 38 */, CONST64(0x037117CA50B99066) /* 39 */, + CONST64(0x6AB30A9774424A35) /* 40 */, CONST64(0xF4E92F02E325249B) /* 41 */, + CONST64(0x7739DB07061CCAE1) /* 42 */, CONST64(0xD8F3B49CECA42A05) /* 43 */, + CONST64(0xBD56BE3F51382F73) /* 44 */, CONST64(0x45FAED5843B0BB28) /* 45 */, + CONST64(0x1C813D5C11BF1F83) /* 46 */, CONST64(0x8AF0E4B6D75FA169) /* 47 */, + CONST64(0x33EE18A487AD9999) /* 48 */, CONST64(0x3C26E8EAB1C94410) /* 49 */, + CONST64(0xB510102BC0A822F9) /* 50 */, CONST64(0x141EEF310CE6123B) /* 51 */, + CONST64(0xFC65B90059DDB154) /* 52 */, CONST64(0xE0158640C5E0E607) /* 53 */, + CONST64(0x884E079826C3A3CF) /* 54 */, CONST64(0x930D0D9523C535FD) /* 55 */, + CONST64(0x35638D754E9A2B00) /* 56 */, CONST64(0x4085FCCF40469DD5) /* 57 */, + CONST64(0xC4B17AD28BE23A4C) /* 58 */, CONST64(0xCAB2F0FC6A3E6A2E) /* 59 */, + CONST64(0x2860971A6B943FCD) /* 60 */, CONST64(0x3DDE6EE212E30446) /* 61 */, + CONST64(0x6222F32AE01765AE) /* 62 */, CONST64(0x5D550BB5478308FE) /* 63 */, + CONST64(0xA9EFA98DA0EDA22A) /* 64 */, CONST64(0xC351A71686C40DA7) /* 65 */, + CONST64(0x1105586D9C867C84) /* 66 */, CONST64(0xDCFFEE85FDA22853) /* 67 */, + CONST64(0xCCFBD0262C5EEF76) /* 68 */, CONST64(0xBAF294CB8990D201) /* 69 */, + CONST64(0xE69464F52AFAD975) /* 70 */, CONST64(0x94B013AFDF133E14) /* 71 */, + CONST64(0x06A7D1A32823C958) /* 72 */, CONST64(0x6F95FE5130F61119) /* 73 */, + CONST64(0xD92AB34E462C06C0) /* 74 */, CONST64(0xED7BDE33887C71D2) /* 75 */, + CONST64(0x79746D6E6518393E) /* 76 */, CONST64(0x5BA419385D713329) /* 77 */, + CONST64(0x7C1BA6B948A97564) /* 78 */, CONST64(0x31987C197BFDAC67) /* 79 */, + CONST64(0xDE6C23C44B053D02) /* 80 */, CONST64(0x581C49FED002D64D) /* 81 */, + CONST64(0xDD474D6338261571) /* 82 */, CONST64(0xAA4546C3E473D062) /* 83 */, + CONST64(0x928FCE349455F860) /* 84 */, CONST64(0x48161BBACAAB94D9) /* 85 */, + CONST64(0x63912430770E6F68) /* 86 */, CONST64(0x6EC8A5E602C6641C) /* 87 */, + CONST64(0x87282515337DDD2B) /* 88 */, CONST64(0x2CDA6B42034B701B) /* 89 */, + CONST64(0xB03D37C181CB096D) /* 90 */, CONST64(0xE108438266C71C6F) /* 91 */, + CONST64(0x2B3180C7EB51B255) /* 92 */, CONST64(0xDF92B82F96C08BBC) /* 93 */, + CONST64(0x5C68C8C0A632F3BA) /* 94 */, CONST64(0x5504CC861C3D0556) /* 95 */, + CONST64(0xABBFA4E55FB26B8F) /* 96 */, CONST64(0x41848B0AB3BACEB4) /* 97 */, + CONST64(0xB334A273AA445D32) /* 98 */, CONST64(0xBCA696F0A85AD881) /* 99 */, + CONST64(0x24F6EC65B528D56C) /* 100 */, CONST64(0x0CE1512E90F4524A) /* 101 */, + CONST64(0x4E9DD79D5506D35A) /* 102 */, CONST64(0x258905FAC6CE9779) /* 103 */, + CONST64(0x2019295B3E109B33) /* 104 */, CONST64(0xF8A9478B73A054CC) /* 105 */, + CONST64(0x2924F2F934417EB0) /* 106 */, CONST64(0x3993357D536D1BC4) /* 107 */, + CONST64(0x38A81AC21DB6FF8B) /* 108 */, CONST64(0x47C4FBF17D6016BF) /* 109 */, + CONST64(0x1E0FAADD7667E3F5) /* 110 */, CONST64(0x7ABCFF62938BEB96) /* 111 */, + CONST64(0xA78DAD948FC179C9) /* 112 */, CONST64(0x8F1F98B72911E50D) /* 113 */, + CONST64(0x61E48EAE27121A91) /* 114 */, CONST64(0x4D62F7AD31859808) /* 115 */, + CONST64(0xECEBA345EF5CEAEB) /* 116 */, CONST64(0xF5CEB25EBC9684CE) /* 117 */, + CONST64(0xF633E20CB7F76221) /* 118 */, CONST64(0xA32CDF06AB8293E4) /* 119 */, + CONST64(0x985A202CA5EE2CA4) /* 120 */, CONST64(0xCF0B8447CC8A8FB1) /* 121 */, + CONST64(0x9F765244979859A3) /* 122 */, CONST64(0xA8D516B1A1240017) /* 123 */, + CONST64(0x0BD7BA3EBB5DC726) /* 124 */, CONST64(0xE54BCA55B86ADB39) /* 125 */, + CONST64(0x1D7A3AFD6C478063) /* 126 */, CONST64(0x519EC608E7669EDD) /* 127 */, + CONST64(0x0E5715A2D149AA23) /* 128 */, CONST64(0x177D4571848FF194) /* 129 */, + CONST64(0xEEB55F3241014C22) /* 130 */, CONST64(0x0F5E5CA13A6E2EC2) /* 131 */, + CONST64(0x8029927B75F5C361) /* 132 */, CONST64(0xAD139FABC3D6E436) /* 133 */, + CONST64(0x0D5DF1A94CCF402F) /* 134 */, CONST64(0x3E8BD948BEA5DFC8) /* 135 */, + CONST64(0xA5A0D357BD3FF77E) /* 136 */, CONST64(0xA2D12E251F74F645) /* 137 */, + CONST64(0x66FD9E525E81A082) /* 138 */, CONST64(0x2E0C90CE7F687A49) /* 139 */, + CONST64(0xC2E8BCBEBA973BC5) /* 140 */, CONST64(0x000001BCE509745F) /* 141 */, + CONST64(0x423777BBE6DAB3D6) /* 142 */, CONST64(0xD1661C7EAEF06EB5) /* 143 */, + CONST64(0xA1781F354DAACFD8) /* 144 */, CONST64(0x2D11284A2B16AFFC) /* 145 */, + CONST64(0xF1FC4F67FA891D1F) /* 146 */, CONST64(0x73ECC25DCB920ADA) /* 147 */, + CONST64(0xAE610C22C2A12651) /* 148 */, CONST64(0x96E0A810D356B78A) /* 149 */, + CONST64(0x5A9A381F2FE7870F) /* 150 */, CONST64(0xD5AD62EDE94E5530) /* 151 */, + CONST64(0xD225E5E8368D1427) /* 152 */, CONST64(0x65977B70C7AF4631) /* 153 */, + CONST64(0x99F889B2DE39D74F) /* 154 */, CONST64(0x233F30BF54E1D143) /* 155 */, + CONST64(0x9A9675D3D9A63C97) /* 156 */, CONST64(0x5470554FF334F9A8) /* 157 */, + CONST64(0x166ACB744A4F5688) /* 158 */, CONST64(0x70C74CAAB2E4AEAD) /* 159 */, + CONST64(0xF0D091646F294D12) /* 160 */, CONST64(0x57B82A89684031D1) /* 161 */, + CONST64(0xEFD95A5A61BE0B6B) /* 162 */, CONST64(0x2FBD12E969F2F29A) /* 163 */, + CONST64(0x9BD37013FEFF9FE8) /* 164 */, CONST64(0x3F9B0404D6085A06) /* 165 */, + CONST64(0x4940C1F3166CFE15) /* 166 */, CONST64(0x09542C4DCDF3DEFB) /* 167 */, + CONST64(0xB4C5218385CD5CE3) /* 168 */, CONST64(0xC935B7DC4462A641) /* 169 */, + CONST64(0x3417F8A68ED3B63F) /* 170 */, CONST64(0xB80959295B215B40) /* 171 */, + CONST64(0xF99CDAEF3B8C8572) /* 172 */, CONST64(0x018C0614F8FCB95D) /* 173 */, + CONST64(0x1B14ACCD1A3ACDF3) /* 174 */, CONST64(0x84D471F200BB732D) /* 175 */, + CONST64(0xC1A3110E95E8DA16) /* 176 */, CONST64(0x430A7220BF1A82B8) /* 177 */, + CONST64(0xB77E090D39DF210E) /* 178 */, CONST64(0x5EF4BD9F3CD05E9D) /* 179 */, + CONST64(0x9D4FF6DA7E57A444) /* 180 */, CONST64(0xDA1D60E183D4A5F8) /* 181 */, + CONST64(0xB287C38417998E47) /* 182 */, CONST64(0xFE3EDC121BB31886) /* 183 */, + CONST64(0xC7FE3CCC980CCBEF) /* 184 */, CONST64(0xE46FB590189BFD03) /* 185 */, + CONST64(0x3732FD469A4C57DC) /* 186 */, CONST64(0x7EF700A07CF1AD65) /* 187 */, + CONST64(0x59C64468A31D8859) /* 188 */, CONST64(0x762FB0B4D45B61F6) /* 189 */, + CONST64(0x155BAED099047718) /* 190 */, CONST64(0x68755E4C3D50BAA6) /* 191 */, + CONST64(0xE9214E7F22D8B4DF) /* 192 */, CONST64(0x2ADDBF532EAC95F4) /* 193 */, + CONST64(0x32AE3909B4BD0109) /* 194 */, CONST64(0x834DF537B08E3450) /* 195 */, + CONST64(0xFA209DA84220728D) /* 196 */, CONST64(0x9E691D9B9EFE23F7) /* 197 */, + CONST64(0x0446D288C4AE8D7F) /* 198 */, CONST64(0x7B4CC524E169785B) /* 199 */, + CONST64(0x21D87F0135CA1385) /* 200 */, CONST64(0xCEBB400F137B8AA5) /* 201 */, + CONST64(0x272E2B66580796BE) /* 202 */, CONST64(0x3612264125C2B0DE) /* 203 */, + CONST64(0x057702BDAD1EFBB2) /* 204 */, CONST64(0xD4BABB8EACF84BE9) /* 205 */, + CONST64(0x91583139641BC67B) /* 206 */, CONST64(0x8BDC2DE08036E024) /* 207 */, + CONST64(0x603C8156F49F68ED) /* 208 */, CONST64(0xF7D236F7DBEF5111) /* 209 */, + CONST64(0x9727C4598AD21E80) /* 210 */, CONST64(0xA08A0896670A5FD7) /* 211 */, + CONST64(0xCB4A8F4309EBA9CB) /* 212 */, CONST64(0x81AF564B0F7036A1) /* 213 */, + CONST64(0xC0B99AA778199ABD) /* 214 */, CONST64(0x959F1EC83FC8E952) /* 215 */, + CONST64(0x8C505077794A81B9) /* 216 */, CONST64(0x3ACAAF8F056338F0) /* 217 */, + CONST64(0x07B43F50627A6778) /* 218 */, CONST64(0x4A44AB49F5ECCC77) /* 219 */, + CONST64(0x3BC3D6E4B679EE98) /* 220 */, CONST64(0x9CC0D4D1CF14108C) /* 221 */, + CONST64(0x4406C00B206BC8A0) /* 222 */, CONST64(0x82A18854C8D72D89) /* 223 */, + CONST64(0x67E366B35C3C432C) /* 224 */, CONST64(0xB923DD61102B37F2) /* 225 */, + CONST64(0x56AB2779D884271D) /* 226 */, CONST64(0xBE83E1B0FF1525AF) /* 227 */, + CONST64(0xFB7C65D4217E49A9) /* 228 */, CONST64(0x6BDBE0E76D48E7D4) /* 229 */, + CONST64(0x08DF828745D9179E) /* 230 */, CONST64(0x22EA6A9ADD53BD34) /* 231 */, + CONST64(0xE36E141C5622200A) /* 232 */, CONST64(0x7F805D1B8CB750EE) /* 233 */, + CONST64(0xAFE5C7A59F58E837) /* 234 */, CONST64(0xE27F996A4FB1C23C) /* 235 */, + CONST64(0xD3867DFB0775F0D0) /* 236 */, CONST64(0xD0E673DE6E88891A) /* 237 */, + CONST64(0x123AEB9EAFB86C25) /* 238 */, CONST64(0x30F1D5D5C145B895) /* 239 */, + CONST64(0xBB434A2DEE7269E7) /* 240 */, CONST64(0x78CB67ECF931FA38) /* 241 */, + CONST64(0xF33B0372323BBF9C) /* 242 */, CONST64(0x52D66336FB279C74) /* 243 */, + CONST64(0x505F33AC0AFB4EAA) /* 244 */, CONST64(0xE8A5CD99A2CCE187) /* 245 */, + CONST64(0x534974801E2D30BB) /* 246 */, CONST64(0x8D2D5711D5876D90) /* 247 */, + CONST64(0x1F1A412891BC038E) /* 248 */, CONST64(0xD6E2E71D82E56648) /* 249 */, + CONST64(0x74036C3A497732B7) /* 250 */, CONST64(0x89B67ED96361F5AB) /* 251 */, + CONST64(0xFFED95D8F1EA02A2) /* 252 */, CONST64(0xE72B3BD61464D43D) /* 253 */, + CONST64(0xA6300F170BDC4820) /* 254 */, CONST64(0xEBC18760ED78A77A) /* 255 */, + CONST64(0xE6A6BE5A05A12138) /* 256 */, CONST64(0xB5A122A5B4F87C98) /* 257 */, + CONST64(0x563C6089140B6990) /* 258 */, CONST64(0x4C46CB2E391F5DD5) /* 259 */, + CONST64(0xD932ADDBC9B79434) /* 260 */, CONST64(0x08EA70E42015AFF5) /* 261 */, + CONST64(0xD765A6673E478CF1) /* 262 */, CONST64(0xC4FB757EAB278D99) /* 263 */, + CONST64(0xDF11C6862D6E0692) /* 264 */, CONST64(0xDDEB84F10D7F3B16) /* 265 */, + CONST64(0x6F2EF604A665EA04) /* 266 */, CONST64(0x4A8E0F0FF0E0DFB3) /* 267 */, + CONST64(0xA5EDEEF83DBCBA51) /* 268 */, CONST64(0xFC4F0A2A0EA4371E) /* 269 */, + CONST64(0xE83E1DA85CB38429) /* 270 */, CONST64(0xDC8FF882BA1B1CE2) /* 271 */, + CONST64(0xCD45505E8353E80D) /* 272 */, CONST64(0x18D19A00D4DB0717) /* 273 */, + CONST64(0x34A0CFEDA5F38101) /* 274 */, CONST64(0x0BE77E518887CAF2) /* 275 */, + CONST64(0x1E341438B3C45136) /* 276 */, CONST64(0xE05797F49089CCF9) /* 277 */, + CONST64(0xFFD23F9DF2591D14) /* 278 */, CONST64(0x543DDA228595C5CD) /* 279 */, + CONST64(0x661F81FD99052A33) /* 280 */, CONST64(0x8736E641DB0F7B76) /* 281 */, + CONST64(0x15227725418E5307) /* 282 */, CONST64(0xE25F7F46162EB2FA) /* 283 */, + CONST64(0x48A8B2126C13D9FE) /* 284 */, CONST64(0xAFDC541792E76EEA) /* 285 */, + CONST64(0x03D912BFC6D1898F) /* 286 */, CONST64(0x31B1AAFA1B83F51B) /* 287 */, + CONST64(0xF1AC2796E42AB7D9) /* 288 */, CONST64(0x40A3A7D7FCD2EBAC) /* 289 */, + CONST64(0x1056136D0AFBBCC5) /* 290 */, CONST64(0x7889E1DD9A6D0C85) /* 291 */, + CONST64(0xD33525782A7974AA) /* 292 */, CONST64(0xA7E25D09078AC09B) /* 293 */, + CONST64(0xBD4138B3EAC6EDD0) /* 294 */, CONST64(0x920ABFBE71EB9E70) /* 295 */, + CONST64(0xA2A5D0F54FC2625C) /* 296 */, CONST64(0xC054E36B0B1290A3) /* 297 */, + CONST64(0xF6DD59FF62FE932B) /* 298 */, CONST64(0x3537354511A8AC7D) /* 299 */, + CONST64(0xCA845E9172FADCD4) /* 300 */, CONST64(0x84F82B60329D20DC) /* 301 */, + CONST64(0x79C62CE1CD672F18) /* 302 */, CONST64(0x8B09A2ADD124642C) /* 303 */, + CONST64(0xD0C1E96A19D9E726) /* 304 */, CONST64(0x5A786A9B4BA9500C) /* 305 */, + CONST64(0x0E020336634C43F3) /* 306 */, CONST64(0xC17B474AEB66D822) /* 307 */, + CONST64(0x6A731AE3EC9BAAC2) /* 308 */, CONST64(0x8226667AE0840258) /* 309 */, + CONST64(0x67D4567691CAECA5) /* 310 */, CONST64(0x1D94155C4875ADB5) /* 311 */, + CONST64(0x6D00FD985B813FDF) /* 312 */, CONST64(0x51286EFCB774CD06) /* 313 */, + CONST64(0x5E8834471FA744AF) /* 314 */, CONST64(0xF72CA0AEE761AE2E) /* 315 */, + CONST64(0xBE40E4CDAEE8E09A) /* 316 */, CONST64(0xE9970BBB5118F665) /* 317 */, + CONST64(0x726E4BEB33DF1964) /* 318 */, CONST64(0x703B000729199762) /* 319 */, + CONST64(0x4631D816F5EF30A7) /* 320 */, CONST64(0xB880B5B51504A6BE) /* 321 */, + CONST64(0x641793C37ED84B6C) /* 322 */, CONST64(0x7B21ED77F6E97D96) /* 323 */, + CONST64(0x776306312EF96B73) /* 324 */, CONST64(0xAE528948E86FF3F4) /* 325 */, + CONST64(0x53DBD7F286A3F8F8) /* 326 */, CONST64(0x16CADCE74CFC1063) /* 327 */, + CONST64(0x005C19BDFA52C6DD) /* 328 */, CONST64(0x68868F5D64D46AD3) /* 329 */, + CONST64(0x3A9D512CCF1E186A) /* 330 */, CONST64(0x367E62C2385660AE) /* 331 */, + CONST64(0xE359E7EA77DCB1D7) /* 332 */, CONST64(0x526C0773749ABE6E) /* 333 */, + CONST64(0x735AE5F9D09F734B) /* 334 */, CONST64(0x493FC7CC8A558BA8) /* 335 */, + CONST64(0xB0B9C1533041AB45) /* 336 */, CONST64(0x321958BA470A59BD) /* 337 */, + CONST64(0x852DB00B5F46C393) /* 338 */, CONST64(0x91209B2BD336B0E5) /* 339 */, + CONST64(0x6E604F7D659EF19F) /* 340 */, CONST64(0xB99A8AE2782CCB24) /* 341 */, + CONST64(0xCCF52AB6C814C4C7) /* 342 */, CONST64(0x4727D9AFBE11727B) /* 343 */, + CONST64(0x7E950D0C0121B34D) /* 344 */, CONST64(0x756F435670AD471F) /* 345 */, + CONST64(0xF5ADD442615A6849) /* 346 */, CONST64(0x4E87E09980B9957A) /* 347 */, + CONST64(0x2ACFA1DF50AEE355) /* 348 */, CONST64(0xD898263AFD2FD556) /* 349 */, + CONST64(0xC8F4924DD80C8FD6) /* 350 */, CONST64(0xCF99CA3D754A173A) /* 351 */, + CONST64(0xFE477BACAF91BF3C) /* 352 */, CONST64(0xED5371F6D690C12D) /* 353 */, + CONST64(0x831A5C285E687094) /* 354 */, CONST64(0xC5D3C90A3708A0A4) /* 355 */, + CONST64(0x0F7F903717D06580) /* 356 */, CONST64(0x19F9BB13B8FDF27F) /* 357 */, + CONST64(0xB1BD6F1B4D502843) /* 358 */, CONST64(0x1C761BA38FFF4012) /* 359 */, + CONST64(0x0D1530C4E2E21F3B) /* 360 */, CONST64(0x8943CE69A7372C8A) /* 361 */, + CONST64(0xE5184E11FEB5CE66) /* 362 */, CONST64(0x618BDB80BD736621) /* 363 */, + CONST64(0x7D29BAD68B574D0B) /* 364 */, CONST64(0x81BB613E25E6FE5B) /* 365 */, + CONST64(0x071C9C10BC07913F) /* 366 */, CONST64(0xC7BEEB7909AC2D97) /* 367 */, + CONST64(0xC3E58D353BC5D757) /* 368 */, CONST64(0xEB017892F38F61E8) /* 369 */, + CONST64(0xD4EFFB9C9B1CC21A) /* 370 */, CONST64(0x99727D26F494F7AB) /* 371 */, + CONST64(0xA3E063A2956B3E03) /* 372 */, CONST64(0x9D4A8B9A4AA09C30) /* 373 */, + CONST64(0x3F6AB7D500090FB4) /* 374 */, CONST64(0x9CC0F2A057268AC0) /* 375 */, + CONST64(0x3DEE9D2DEDBF42D1) /* 376 */, CONST64(0x330F49C87960A972) /* 377 */, + CONST64(0xC6B2720287421B41) /* 378 */, CONST64(0x0AC59EC07C00369C) /* 379 */, + CONST64(0xEF4EAC49CB353425) /* 380 */, CONST64(0xF450244EEF0129D8) /* 381 */, + CONST64(0x8ACC46E5CAF4DEB6) /* 382 */, CONST64(0x2FFEAB63989263F7) /* 383 */, + CONST64(0x8F7CB9FE5D7A4578) /* 384 */, CONST64(0x5BD8F7644E634635) /* 385 */, + CONST64(0x427A7315BF2DC900) /* 386 */, CONST64(0x17D0C4AA2125261C) /* 387 */, + CONST64(0x3992486C93518E50) /* 388 */, CONST64(0xB4CBFEE0A2D7D4C3) /* 389 */, + CONST64(0x7C75D6202C5DDD8D) /* 390 */, CONST64(0xDBC295D8E35B6C61) /* 391 */, + CONST64(0x60B369D302032B19) /* 392 */, CONST64(0xCE42685FDCE44132) /* 393 */, + CONST64(0x06F3DDB9DDF65610) /* 394 */, CONST64(0x8EA4D21DB5E148F0) /* 395 */, + CONST64(0x20B0FCE62FCD496F) /* 396 */, CONST64(0x2C1B912358B0EE31) /* 397 */, + CONST64(0xB28317B818F5A308) /* 398 */, CONST64(0xA89C1E189CA6D2CF) /* 399 */, + CONST64(0x0C6B18576AAADBC8) /* 400 */, CONST64(0xB65DEAA91299FAE3) /* 401 */, + CONST64(0xFB2B794B7F1027E7) /* 402 */, CONST64(0x04E4317F443B5BEB) /* 403 */, + CONST64(0x4B852D325939D0A6) /* 404 */, CONST64(0xD5AE6BEEFB207FFC) /* 405 */, + CONST64(0x309682B281C7D374) /* 406 */, CONST64(0xBAE309A194C3B475) /* 407 */, + CONST64(0x8CC3F97B13B49F05) /* 408 */, CONST64(0x98A9422FF8293967) /* 409 */, + CONST64(0x244B16B01076FF7C) /* 410 */, CONST64(0xF8BF571C663D67EE) /* 411 */, + CONST64(0x1F0D6758EEE30DA1) /* 412 */, CONST64(0xC9B611D97ADEB9B7) /* 413 */, + CONST64(0xB7AFD5887B6C57A2) /* 414 */, CONST64(0x6290AE846B984FE1) /* 415 */, + CONST64(0x94DF4CDEACC1A5FD) /* 416 */, CONST64(0x058A5BD1C5483AFF) /* 417 */, + CONST64(0x63166CC142BA3C37) /* 418 */, CONST64(0x8DB8526EB2F76F40) /* 419 */, + CONST64(0xE10880036F0D6D4E) /* 420 */, CONST64(0x9E0523C9971D311D) /* 421 */, + CONST64(0x45EC2824CC7CD691) /* 422 */, CONST64(0x575B8359E62382C9) /* 423 */, + CONST64(0xFA9E400DC4889995) /* 424 */, CONST64(0xD1823ECB45721568) /* 425 */, + CONST64(0xDAFD983B8206082F) /* 426 */, CONST64(0xAA7D29082386A8CB) /* 427 */, + CONST64(0x269FCD4403B87588) /* 428 */, CONST64(0x1B91F5F728BDD1E0) /* 429 */, + CONST64(0xE4669F39040201F6) /* 430 */, CONST64(0x7A1D7C218CF04ADE) /* 431 */, + CONST64(0x65623C29D79CE5CE) /* 432 */, CONST64(0x2368449096C00BB1) /* 433 */, + CONST64(0xAB9BF1879DA503BA) /* 434 */, CONST64(0xBC23ECB1A458058E) /* 435 */, + CONST64(0x9A58DF01BB401ECC) /* 436 */, CONST64(0xA070E868A85F143D) /* 437 */, + CONST64(0x4FF188307DF2239E) /* 438 */, CONST64(0x14D565B41A641183) /* 439 */, + CONST64(0xEE13337452701602) /* 440 */, CONST64(0x950E3DCF3F285E09) /* 441 */, + CONST64(0x59930254B9C80953) /* 442 */, CONST64(0x3BF299408930DA6D) /* 443 */, + CONST64(0xA955943F53691387) /* 444 */, CONST64(0xA15EDECAA9CB8784) /* 445 */, + CONST64(0x29142127352BE9A0) /* 446 */, CONST64(0x76F0371FFF4E7AFB) /* 447 */, + CONST64(0x0239F450274F2228) /* 448 */, CONST64(0xBB073AF01D5E868B) /* 449 */, + CONST64(0xBFC80571C10E96C1) /* 450 */, CONST64(0xD267088568222E23) /* 451 */, + CONST64(0x9671A3D48E80B5B0) /* 452 */, CONST64(0x55B5D38AE193BB81) /* 453 */, + CONST64(0x693AE2D0A18B04B8) /* 454 */, CONST64(0x5C48B4ECADD5335F) /* 455 */, + CONST64(0xFD743B194916A1CA) /* 456 */, CONST64(0x2577018134BE98C4) /* 457 */, + CONST64(0xE77987E83C54A4AD) /* 458 */, CONST64(0x28E11014DA33E1B9) /* 459 */, + CONST64(0x270CC59E226AA213) /* 460 */, CONST64(0x71495F756D1A5F60) /* 461 */, + CONST64(0x9BE853FB60AFEF77) /* 462 */, CONST64(0xADC786A7F7443DBF) /* 463 */, + CONST64(0x0904456173B29A82) /* 464 */, CONST64(0x58BC7A66C232BD5E) /* 465 */, + CONST64(0xF306558C673AC8B2) /* 466 */, CONST64(0x41F639C6B6C9772A) /* 467 */, + CONST64(0x216DEFE99FDA35DA) /* 468 */, CONST64(0x11640CC71C7BE615) /* 469 */, + CONST64(0x93C43694565C5527) /* 470 */, CONST64(0xEA038E6246777839) /* 471 */, + CONST64(0xF9ABF3CE5A3E2469) /* 472 */, CONST64(0x741E768D0FD312D2) /* 473 */, + CONST64(0x0144B883CED652C6) /* 474 */, CONST64(0xC20B5A5BA33F8552) /* 475 */, + CONST64(0x1AE69633C3435A9D) /* 476 */, CONST64(0x97A28CA4088CFDEC) /* 477 */, + CONST64(0x8824A43C1E96F420) /* 478 */, CONST64(0x37612FA66EEEA746) /* 479 */, + CONST64(0x6B4CB165F9CF0E5A) /* 480 */, CONST64(0x43AA1C06A0ABFB4A) /* 481 */, + CONST64(0x7F4DC26FF162796B) /* 482 */, CONST64(0x6CBACC8E54ED9B0F) /* 483 */, + CONST64(0xA6B7FFEFD2BB253E) /* 484 */, CONST64(0x2E25BC95B0A29D4F) /* 485 */, + CONST64(0x86D6A58BDEF1388C) /* 486 */, CONST64(0xDED74AC576B6F054) /* 487 */, + CONST64(0x8030BDBC2B45805D) /* 488 */, CONST64(0x3C81AF70E94D9289) /* 489 */, + CONST64(0x3EFF6DDA9E3100DB) /* 490 */, CONST64(0xB38DC39FDFCC8847) /* 491 */, + CONST64(0x123885528D17B87E) /* 492 */, CONST64(0xF2DA0ED240B1B642) /* 493 */, + CONST64(0x44CEFADCD54BF9A9) /* 494 */, CONST64(0x1312200E433C7EE6) /* 495 */, + CONST64(0x9FFCC84F3A78C748) /* 496 */, CONST64(0xF0CD1F72248576BB) /* 497 */, + CONST64(0xEC6974053638CFE4) /* 498 */, CONST64(0x2BA7B67C0CEC4E4C) /* 499 */, + CONST64(0xAC2F4DF3E5CE32ED) /* 500 */, CONST64(0xCB33D14326EA4C11) /* 501 */, + CONST64(0xA4E9044CC77E58BC) /* 502 */, CONST64(0x5F513293D934FCEF) /* 503 */, + CONST64(0x5DC9645506E55444) /* 504 */, CONST64(0x50DE418F317DE40A) /* 505 */, + CONST64(0x388CB31A69DDE259) /* 506 */, CONST64(0x2DB4A83455820A86) /* 507 */, + CONST64(0x9010A91E84711AE9) /* 508 */, CONST64(0x4DF7F0B7B1498371) /* 509 */, + CONST64(0xD62A2EABC0977179) /* 510 */, CONST64(0x22FAC097AA8D5C0E) /* 511 */, + CONST64(0xF49FCC2FF1DAF39B) /* 512 */, CONST64(0x487FD5C66FF29281) /* 513 */, + CONST64(0xE8A30667FCDCA83F) /* 514 */, CONST64(0x2C9B4BE3D2FCCE63) /* 515 */, + CONST64(0xDA3FF74B93FBBBC2) /* 516 */, CONST64(0x2FA165D2FE70BA66) /* 517 */, + CONST64(0xA103E279970E93D4) /* 518 */, CONST64(0xBECDEC77B0E45E71) /* 519 */, + CONST64(0xCFB41E723985E497) /* 520 */, CONST64(0xB70AAA025EF75017) /* 521 */, + CONST64(0xD42309F03840B8E0) /* 522 */, CONST64(0x8EFC1AD035898579) /* 523 */, + CONST64(0x96C6920BE2B2ABC5) /* 524 */, CONST64(0x66AF4163375A9172) /* 525 */, + CONST64(0x2174ABDCCA7127FB) /* 526 */, CONST64(0xB33CCEA64A72FF41) /* 527 */, + CONST64(0xF04A4933083066A5) /* 528 */, CONST64(0x8D970ACDD7289AF5) /* 529 */, + CONST64(0x8F96E8E031C8C25E) /* 530 */, CONST64(0xF3FEC02276875D47) /* 531 */, + CONST64(0xEC7BF310056190DD) /* 532 */, CONST64(0xF5ADB0AEBB0F1491) /* 533 */, + CONST64(0x9B50F8850FD58892) /* 534 */, CONST64(0x4975488358B74DE8) /* 535 */, + CONST64(0xA3354FF691531C61) /* 536 */, CONST64(0x0702BBE481D2C6EE) /* 537 */, + CONST64(0x89FB24057DEDED98) /* 538 */, CONST64(0xAC3075138596E902) /* 539 */, + CONST64(0x1D2D3580172772ED) /* 540 */, CONST64(0xEB738FC28E6BC30D) /* 541 */, + CONST64(0x5854EF8F63044326) /* 542 */, CONST64(0x9E5C52325ADD3BBE) /* 543 */, + CONST64(0x90AA53CF325C4623) /* 544 */, CONST64(0xC1D24D51349DD067) /* 545 */, + CONST64(0x2051CFEEA69EA624) /* 546 */, CONST64(0x13220F0A862E7E4F) /* 547 */, + CONST64(0xCE39399404E04864) /* 548 */, CONST64(0xD9C42CA47086FCB7) /* 549 */, + CONST64(0x685AD2238A03E7CC) /* 550 */, CONST64(0x066484B2AB2FF1DB) /* 551 */, + CONST64(0xFE9D5D70EFBF79EC) /* 552 */, CONST64(0x5B13B9DD9C481854) /* 553 */, + CONST64(0x15F0D475ED1509AD) /* 554 */, CONST64(0x0BEBCD060EC79851) /* 555 */, + CONST64(0xD58C6791183AB7F8) /* 556 */, CONST64(0xD1187C5052F3EEE4) /* 557 */, + CONST64(0xC95D1192E54E82FF) /* 558 */, CONST64(0x86EEA14CB9AC6CA2) /* 559 */, + CONST64(0x3485BEB153677D5D) /* 560 */, CONST64(0xDD191D781F8C492A) /* 561 */, + CONST64(0xF60866BAA784EBF9) /* 562 */, CONST64(0x518F643BA2D08C74) /* 563 */, + CONST64(0x8852E956E1087C22) /* 564 */, CONST64(0xA768CB8DC410AE8D) /* 565 */, + CONST64(0x38047726BFEC8E1A) /* 566 */, CONST64(0xA67738B4CD3B45AA) /* 567 */, + CONST64(0xAD16691CEC0DDE19) /* 568 */, CONST64(0xC6D4319380462E07) /* 569 */, + CONST64(0xC5A5876D0BA61938) /* 570 */, CONST64(0x16B9FA1FA58FD840) /* 571 */, + CONST64(0x188AB1173CA74F18) /* 572 */, CONST64(0xABDA2F98C99C021F) /* 573 */, + CONST64(0x3E0580AB134AE816) /* 574 */, CONST64(0x5F3B05B773645ABB) /* 575 */, + CONST64(0x2501A2BE5575F2F6) /* 576 */, CONST64(0x1B2F74004E7E8BA9) /* 577 */, + CONST64(0x1CD7580371E8D953) /* 578 */, CONST64(0x7F6ED89562764E30) /* 579 */, + CONST64(0xB15926FF596F003D) /* 580 */, CONST64(0x9F65293DA8C5D6B9) /* 581 */, + CONST64(0x6ECEF04DD690F84C) /* 582 */, CONST64(0x4782275FFF33AF88) /* 583 */, + CONST64(0xE41433083F820801) /* 584 */, CONST64(0xFD0DFE409A1AF9B5) /* 585 */, + CONST64(0x4325A3342CDB396B) /* 586 */, CONST64(0x8AE77E62B301B252) /* 587 */, + CONST64(0xC36F9E9F6655615A) /* 588 */, CONST64(0x85455A2D92D32C09) /* 589 */, + CONST64(0xF2C7DEA949477485) /* 590 */, CONST64(0x63CFB4C133A39EBA) /* 591 */, + CONST64(0x83B040CC6EBC5462) /* 592 */, CONST64(0x3B9454C8FDB326B0) /* 593 */, + CONST64(0x56F56A9E87FFD78C) /* 594 */, CONST64(0x2DC2940D99F42BC6) /* 595 */, + CONST64(0x98F7DF096B096E2D) /* 596 */, CONST64(0x19A6E01E3AD852BF) /* 597 */, + CONST64(0x42A99CCBDBD4B40B) /* 598 */, CONST64(0xA59998AF45E9C559) /* 599 */, + CONST64(0x366295E807D93186) /* 600 */, CONST64(0x6B48181BFAA1F773) /* 601 */, + CONST64(0x1FEC57E2157A0A1D) /* 602 */, CONST64(0x4667446AF6201AD5) /* 603 */, + CONST64(0xE615EBCACFB0F075) /* 604 */, CONST64(0xB8F31F4F68290778) /* 605 */, + CONST64(0x22713ED6CE22D11E) /* 606 */, CONST64(0x3057C1A72EC3C93B) /* 607 */, + CONST64(0xCB46ACC37C3F1F2F) /* 608 */, CONST64(0xDBB893FD02AAF50E) /* 609 */, + CONST64(0x331FD92E600B9FCF) /* 610 */, CONST64(0xA498F96148EA3AD6) /* 611 */, + CONST64(0xA8D8426E8B6A83EA) /* 612 */, CONST64(0xA089B274B7735CDC) /* 613 */, + CONST64(0x87F6B3731E524A11) /* 614 */, CONST64(0x118808E5CBC96749) /* 615 */, + CONST64(0x9906E4C7B19BD394) /* 616 */, CONST64(0xAFED7F7E9B24A20C) /* 617 */, + CONST64(0x6509EADEEB3644A7) /* 618 */, CONST64(0x6C1EF1D3E8EF0EDE) /* 619 */, + CONST64(0xB9C97D43E9798FB4) /* 620 */, CONST64(0xA2F2D784740C28A3) /* 621 */, + CONST64(0x7B8496476197566F) /* 622 */, CONST64(0x7A5BE3E6B65F069D) /* 623 */, + CONST64(0xF96330ED78BE6F10) /* 624 */, CONST64(0xEEE60DE77A076A15) /* 625 */, + CONST64(0x2B4BEE4AA08B9BD0) /* 626 */, CONST64(0x6A56A63EC7B8894E) /* 627 */, + CONST64(0x02121359BA34FEF4) /* 628 */, CONST64(0x4CBF99F8283703FC) /* 629 */, + CONST64(0x398071350CAF30C8) /* 630 */, CONST64(0xD0A77A89F017687A) /* 631 */, + CONST64(0xF1C1A9EB9E423569) /* 632 */, CONST64(0x8C7976282DEE8199) /* 633 */, + CONST64(0x5D1737A5DD1F7ABD) /* 634 */, CONST64(0x4F53433C09A9FA80) /* 635 */, + CONST64(0xFA8B0C53DF7CA1D9) /* 636 */, CONST64(0x3FD9DCBC886CCB77) /* 637 */, + CONST64(0xC040917CA91B4720) /* 638 */, CONST64(0x7DD00142F9D1DCDF) /* 639 */, + CONST64(0x8476FC1D4F387B58) /* 640 */, CONST64(0x23F8E7C5F3316503) /* 641 */, + CONST64(0x032A2244E7E37339) /* 642 */, CONST64(0x5C87A5D750F5A74B) /* 643 */, + CONST64(0x082B4CC43698992E) /* 644 */, CONST64(0xDF917BECB858F63C) /* 645 */, + CONST64(0x3270B8FC5BF86DDA) /* 646 */, CONST64(0x10AE72BB29B5DD76) /* 647 */, + CONST64(0x576AC94E7700362B) /* 648 */, CONST64(0x1AD112DAC61EFB8F) /* 649 */, + CONST64(0x691BC30EC5FAA427) /* 650 */, CONST64(0xFF246311CC327143) /* 651 */, + CONST64(0x3142368E30E53206) /* 652 */, CONST64(0x71380E31E02CA396) /* 653 */, + CONST64(0x958D5C960AAD76F1) /* 654 */, CONST64(0xF8D6F430C16DA536) /* 655 */, + CONST64(0xC8FFD13F1BE7E1D2) /* 656 */, CONST64(0x7578AE66004DDBE1) /* 657 */, + CONST64(0x05833F01067BE646) /* 658 */, CONST64(0xBB34B5AD3BFE586D) /* 659 */, + CONST64(0x095F34C9A12B97F0) /* 660 */, CONST64(0x247AB64525D60CA8) /* 661 */, + CONST64(0xDCDBC6F3017477D1) /* 662 */, CONST64(0x4A2E14D4DECAD24D) /* 663 */, + CONST64(0xBDB5E6D9BE0A1EEB) /* 664 */, CONST64(0x2A7E70F7794301AB) /* 665 */, + CONST64(0xDEF42D8A270540FD) /* 666 */, CONST64(0x01078EC0A34C22C1) /* 667 */, + CONST64(0xE5DE511AF4C16387) /* 668 */, CONST64(0x7EBB3A52BD9A330A) /* 669 */, + CONST64(0x77697857AA7D6435) /* 670 */, CONST64(0x004E831603AE4C32) /* 671 */, + CONST64(0xE7A21020AD78E312) /* 672 */, CONST64(0x9D41A70C6AB420F2) /* 673 */, + CONST64(0x28E06C18EA1141E6) /* 674 */, CONST64(0xD2B28CBD984F6B28) /* 675 */, + CONST64(0x26B75F6C446E9D83) /* 676 */, CONST64(0xBA47568C4D418D7F) /* 677 */, + CONST64(0xD80BADBFE6183D8E) /* 678 */, CONST64(0x0E206D7F5F166044) /* 679 */, + CONST64(0xE258A43911CBCA3E) /* 680 */, CONST64(0x723A1746B21DC0BC) /* 681 */, + CONST64(0xC7CAA854F5D7CDD3) /* 682 */, CONST64(0x7CAC32883D261D9C) /* 683 */, + CONST64(0x7690C26423BA942C) /* 684 */, CONST64(0x17E55524478042B8) /* 685 */, + CONST64(0xE0BE477656A2389F) /* 686 */, CONST64(0x4D289B5E67AB2DA0) /* 687 */, + CONST64(0x44862B9C8FBBFD31) /* 688 */, CONST64(0xB47CC8049D141365) /* 689 */, + CONST64(0x822C1B362B91C793) /* 690 */, CONST64(0x4EB14655FB13DFD8) /* 691 */, + CONST64(0x1ECBBA0714E2A97B) /* 692 */, CONST64(0x6143459D5CDE5F14) /* 693 */, + CONST64(0x53A8FBF1D5F0AC89) /* 694 */, CONST64(0x97EA04D81C5E5B00) /* 695 */, + CONST64(0x622181A8D4FDB3F3) /* 696 */, CONST64(0xE9BCD341572A1208) /* 697 */, + CONST64(0x1411258643CCE58A) /* 698 */, CONST64(0x9144C5FEA4C6E0A4) /* 699 */, + CONST64(0x0D33D06565CF620F) /* 700 */, CONST64(0x54A48D489F219CA1) /* 701 */, + CONST64(0xC43E5EAC6D63C821) /* 702 */, CONST64(0xA9728B3A72770DAF) /* 703 */, + CONST64(0xD7934E7B20DF87EF) /* 704 */, CONST64(0xE35503B61A3E86E5) /* 705 */, + CONST64(0xCAE321FBC819D504) /* 706 */, CONST64(0x129A50B3AC60BFA6) /* 707 */, + CONST64(0xCD5E68EA7E9FB6C3) /* 708 */, CONST64(0xB01C90199483B1C7) /* 709 */, + CONST64(0x3DE93CD5C295376C) /* 710 */, CONST64(0xAED52EDF2AB9AD13) /* 711 */, + CONST64(0x2E60F512C0A07884) /* 712 */, CONST64(0xBC3D86A3E36210C9) /* 713 */, + CONST64(0x35269D9B163951CE) /* 714 */, CONST64(0x0C7D6E2AD0CDB5FA) /* 715 */, + CONST64(0x59E86297D87F5733) /* 716 */, CONST64(0x298EF221898DB0E7) /* 717 */, + CONST64(0x55000029D1A5AA7E) /* 718 */, CONST64(0x8BC08AE1B5061B45) /* 719 */, + CONST64(0xC2C31C2B6C92703A) /* 720 */, CONST64(0x94CC596BAF25EF42) /* 721 */, + CONST64(0x0A1D73DB22540456) /* 722 */, CONST64(0x04B6A0F9D9C4179A) /* 723 */, + CONST64(0xEFFDAFA2AE3D3C60) /* 724 */, CONST64(0xF7C8075BB49496C4) /* 725 */, + CONST64(0x9CC5C7141D1CD4E3) /* 726 */, CONST64(0x78BD1638218E5534) /* 727 */, + CONST64(0xB2F11568F850246A) /* 728 */, CONST64(0xEDFABCFA9502BC29) /* 729 */, + CONST64(0x796CE5F2DA23051B) /* 730 */, CONST64(0xAAE128B0DC93537C) /* 731 */, + CONST64(0x3A493DA0EE4B29AE) /* 732 */, CONST64(0xB5DF6B2C416895D7) /* 733 */, + CONST64(0xFCABBD25122D7F37) /* 734 */, CONST64(0x70810B58105DC4B1) /* 735 */, + CONST64(0xE10FDD37F7882A90) /* 736 */, CONST64(0x524DCAB5518A3F5C) /* 737 */, + CONST64(0x3C9E85878451255B) /* 738 */, CONST64(0x4029828119BD34E2) /* 739 */, + CONST64(0x74A05B6F5D3CECCB) /* 740 */, CONST64(0xB610021542E13ECA) /* 741 */, + CONST64(0x0FF979D12F59E2AC) /* 742 */, CONST64(0x6037DA27E4F9CC50) /* 743 */, + CONST64(0x5E92975A0DF1847D) /* 744 */, CONST64(0xD66DE190D3E623FE) /* 745 */, + CONST64(0x5032D6B87B568048) /* 746 */, CONST64(0x9A36B7CE8235216E) /* 747 */, + CONST64(0x80272A7A24F64B4A) /* 748 */, CONST64(0x93EFED8B8C6916F7) /* 749 */, + CONST64(0x37DDBFF44CCE1555) /* 750 */, CONST64(0x4B95DB5D4B99BD25) /* 751 */, + CONST64(0x92D3FDA169812FC0) /* 752 */, CONST64(0xFB1A4A9A90660BB6) /* 753 */, + CONST64(0x730C196946A4B9B2) /* 754 */, CONST64(0x81E289AA7F49DA68) /* 755 */, + CONST64(0x64669A0F83B1A05F) /* 756 */, CONST64(0x27B3FF7D9644F48B) /* 757 */, + CONST64(0xCC6B615C8DB675B3) /* 758 */, CONST64(0x674F20B9BCEBBE95) /* 759 */, + CONST64(0x6F31238275655982) /* 760 */, CONST64(0x5AE488713E45CF05) /* 761 */, + CONST64(0xBF619F9954C21157) /* 762 */, CONST64(0xEABAC46040A8EAE9) /* 763 */, + CONST64(0x454C6FE9F2C0C1CD) /* 764 */, CONST64(0x419CF6496412691C) /* 765 */, + CONST64(0xD3DC3BEF265B0F70) /* 766 */, CONST64(0x6D0E60F5C3578A9E) /* 767 */, + CONST64(0x5B0E608526323C55) /* 768 */, CONST64(0x1A46C1A9FA1B59F5) /* 769 */, + CONST64(0xA9E245A17C4C8FFA) /* 770 */, CONST64(0x65CA5159DB2955D7) /* 771 */, + CONST64(0x05DB0A76CE35AFC2) /* 772 */, CONST64(0x81EAC77EA9113D45) /* 773 */, + CONST64(0x528EF88AB6AC0A0D) /* 774 */, CONST64(0xA09EA253597BE3FF) /* 775 */, + CONST64(0x430DDFB3AC48CD56) /* 776 */, CONST64(0xC4B3A67AF45CE46F) /* 777 */, + CONST64(0x4ECECFD8FBE2D05E) /* 778 */, CONST64(0x3EF56F10B39935F0) /* 779 */, + CONST64(0x0B22D6829CD619C6) /* 780 */, CONST64(0x17FD460A74DF2069) /* 781 */, + CONST64(0x6CF8CC8E8510ED40) /* 782 */, CONST64(0xD6C824BF3A6ECAA7) /* 783 */, + CONST64(0x61243D581A817049) /* 784 */, CONST64(0x048BACB6BBC163A2) /* 785 */, + CONST64(0xD9A38AC27D44CC32) /* 786 */, CONST64(0x7FDDFF5BAAF410AB) /* 787 */, + CONST64(0xAD6D495AA804824B) /* 788 */, CONST64(0xE1A6A74F2D8C9F94) /* 789 */, + CONST64(0xD4F7851235DEE8E3) /* 790 */, CONST64(0xFD4B7F886540D893) /* 791 */, + CONST64(0x247C20042AA4BFDA) /* 792 */, CONST64(0x096EA1C517D1327C) /* 793 */, + CONST64(0xD56966B4361A6685) /* 794 */, CONST64(0x277DA5C31221057D) /* 795 */, + CONST64(0x94D59893A43ACFF7) /* 796 */, CONST64(0x64F0C51CCDC02281) /* 797 */, + CONST64(0x3D33BCC4FF6189DB) /* 798 */, CONST64(0xE005CB184CE66AF1) /* 799 */, + CONST64(0xFF5CCD1D1DB99BEA) /* 800 */, CONST64(0xB0B854A7FE42980F) /* 801 */, + CONST64(0x7BD46A6A718D4B9F) /* 802 */, CONST64(0xD10FA8CC22A5FD8C) /* 803 */, + CONST64(0xD31484952BE4BD31) /* 804 */, CONST64(0xC7FA975FCB243847) /* 805 */, + CONST64(0x4886ED1E5846C407) /* 806 */, CONST64(0x28CDDB791EB70B04) /* 807 */, + CONST64(0xC2B00BE2F573417F) /* 808 */, CONST64(0x5C9590452180F877) /* 809 */, + CONST64(0x7A6BDDFFF370EB00) /* 810 */, CONST64(0xCE509E38D6D9D6A4) /* 811 */, + CONST64(0xEBEB0F00647FA702) /* 812 */, CONST64(0x1DCC06CF76606F06) /* 813 */, + CONST64(0xE4D9F28BA286FF0A) /* 814 */, CONST64(0xD85A305DC918C262) /* 815 */, + CONST64(0x475B1D8732225F54) /* 816 */, CONST64(0x2D4FB51668CCB5FE) /* 817 */, + CONST64(0xA679B9D9D72BBA20) /* 818 */, CONST64(0x53841C0D912D43A5) /* 819 */, + CONST64(0x3B7EAA48BF12A4E8) /* 820 */, CONST64(0x781E0E47F22F1DDF) /* 821 */, + CONST64(0xEFF20CE60AB50973) /* 822 */, CONST64(0x20D261D19DFFB742) /* 823 */, + CONST64(0x16A12B03062A2E39) /* 824 */, CONST64(0x1960EB2239650495) /* 825 */, + CONST64(0x251C16FED50EB8B8) /* 826 */, CONST64(0x9AC0C330F826016E) /* 827 */, + CONST64(0xED152665953E7671) /* 828 */, CONST64(0x02D63194A6369570) /* 829 */, + CONST64(0x5074F08394B1C987) /* 830 */, CONST64(0x70BA598C90B25CE1) /* 831 */, + CONST64(0x794A15810B9742F6) /* 832 */, CONST64(0x0D5925E9FCAF8C6C) /* 833 */, + CONST64(0x3067716CD868744E) /* 834 */, CONST64(0x910AB077E8D7731B) /* 835 */, + CONST64(0x6A61BBDB5AC42F61) /* 836 */, CONST64(0x93513EFBF0851567) /* 837 */, + CONST64(0xF494724B9E83E9D5) /* 838 */, CONST64(0xE887E1985C09648D) /* 839 */, + CONST64(0x34B1D3C675370CFD) /* 840 */, CONST64(0xDC35E433BC0D255D) /* 841 */, + CONST64(0xD0AAB84234131BE0) /* 842 */, CONST64(0x08042A50B48B7EAF) /* 843 */, + CONST64(0x9997C4EE44A3AB35) /* 844 */, CONST64(0x829A7B49201799D0) /* 845 */, + CONST64(0x263B8307B7C54441) /* 846 */, CONST64(0x752F95F4FD6A6CA6) /* 847 */, + CONST64(0x927217402C08C6E5) /* 848 */, CONST64(0x2A8AB754A795D9EE) /* 849 */, + CONST64(0xA442F7552F72943D) /* 850 */, CONST64(0x2C31334E19781208) /* 851 */, + CONST64(0x4FA98D7CEAEE6291) /* 852 */, CONST64(0x55C3862F665DB309) /* 853 */, + CONST64(0xBD0610175D53B1F3) /* 854 */, CONST64(0x46FE6CB840413F27) /* 855 */, + CONST64(0x3FE03792DF0CFA59) /* 856 */, CONST64(0xCFE700372EB85E8F) /* 857 */, + CONST64(0xA7BE29E7ADBCE118) /* 858 */, CONST64(0xE544EE5CDE8431DD) /* 859 */, + CONST64(0x8A781B1B41F1873E) /* 860 */, CONST64(0xA5C94C78A0D2F0E7) /* 861 */, + CONST64(0x39412E2877B60728) /* 862 */, CONST64(0xA1265EF3AFC9A62C) /* 863 */, + CONST64(0xBCC2770C6A2506C5) /* 864 */, CONST64(0x3AB66DD5DCE1CE12) /* 865 */, + CONST64(0xE65499D04A675B37) /* 866 */, CONST64(0x7D8F523481BFD216) /* 867 */, + CONST64(0x0F6F64FCEC15F389) /* 868 */, CONST64(0x74EFBE618B5B13C8) /* 869 */, + CONST64(0xACDC82B714273E1D) /* 870 */, CONST64(0xDD40BFE003199D17) /* 871 */, + CONST64(0x37E99257E7E061F8) /* 872 */, CONST64(0xFA52626904775AAA) /* 873 */, + CONST64(0x8BBBF63A463D56F9) /* 874 */, CONST64(0xF0013F1543A26E64) /* 875 */, + CONST64(0xA8307E9F879EC898) /* 876 */, CONST64(0xCC4C27A4150177CC) /* 877 */, + CONST64(0x1B432F2CCA1D3348) /* 878 */, CONST64(0xDE1D1F8F9F6FA013) /* 879 */, + CONST64(0x606602A047A7DDD6) /* 880 */, CONST64(0xD237AB64CC1CB2C7) /* 881 */, + CONST64(0x9B938E7225FCD1D3) /* 882 */, CONST64(0xEC4E03708E0FF476) /* 883 */, + CONST64(0xFEB2FBDA3D03C12D) /* 884 */, CONST64(0xAE0BCED2EE43889A) /* 885 */, + CONST64(0x22CB8923EBFB4F43) /* 886 */, CONST64(0x69360D013CF7396D) /* 887 */, + CONST64(0x855E3602D2D4E022) /* 888 */, CONST64(0x073805BAD01F784C) /* 889 */, + CONST64(0x33E17A133852F546) /* 890 */, CONST64(0xDF4874058AC7B638) /* 891 */, + CONST64(0xBA92B29C678AA14A) /* 892 */, CONST64(0x0CE89FC76CFAADCD) /* 893 */, + CONST64(0x5F9D4E0908339E34) /* 894 */, CONST64(0xF1AFE9291F5923B9) /* 895 */, + CONST64(0x6E3480F60F4A265F) /* 896 */, CONST64(0xEEBF3A2AB29B841C) /* 897 */, + CONST64(0xE21938A88F91B4AD) /* 898 */, CONST64(0x57DFEFF845C6D3C3) /* 899 */, + CONST64(0x2F006B0BF62CAAF2) /* 900 */, CONST64(0x62F479EF6F75EE78) /* 901 */, + CONST64(0x11A55AD41C8916A9) /* 902 */, CONST64(0xF229D29084FED453) /* 903 */, + CONST64(0x42F1C27B16B000E6) /* 904 */, CONST64(0x2B1F76749823C074) /* 905 */, + CONST64(0x4B76ECA3C2745360) /* 906 */, CONST64(0x8C98F463B91691BD) /* 907 */, + CONST64(0x14BCC93CF1ADE66A) /* 908 */, CONST64(0x8885213E6D458397) /* 909 */, + CONST64(0x8E177DF0274D4711) /* 910 */, CONST64(0xB49B73B5503F2951) /* 911 */, + CONST64(0x10168168C3F96B6B) /* 912 */, CONST64(0x0E3D963B63CAB0AE) /* 913 */, + CONST64(0x8DFC4B5655A1DB14) /* 914 */, CONST64(0xF789F1356E14DE5C) /* 915 */, + CONST64(0x683E68AF4E51DAC1) /* 916 */, CONST64(0xC9A84F9D8D4B0FD9) /* 917 */, + CONST64(0x3691E03F52A0F9D1) /* 918 */, CONST64(0x5ED86E46E1878E80) /* 919 */, + CONST64(0x3C711A0E99D07150) /* 920 */, CONST64(0x5A0865B20C4E9310) /* 921 */, + CONST64(0x56FBFC1FE4F0682E) /* 922 */, CONST64(0xEA8D5DE3105EDF9B) /* 923 */, + CONST64(0x71ABFDB12379187A) /* 924 */, CONST64(0x2EB99DE1BEE77B9C) /* 925 */, + CONST64(0x21ECC0EA33CF4523) /* 926 */, CONST64(0x59A4D7521805C7A1) /* 927 */, + CONST64(0x3896F5EB56AE7C72) /* 928 */, CONST64(0xAA638F3DB18F75DC) /* 929 */, + CONST64(0x9F39358DABE9808E) /* 930 */, CONST64(0xB7DEFA91C00B72AC) /* 931 */, + CONST64(0x6B5541FD62492D92) /* 932 */, CONST64(0x6DC6DEE8F92E4D5B) /* 933 */, + CONST64(0x353F57ABC4BEEA7E) /* 934 */, CONST64(0x735769D6DA5690CE) /* 935 */, + CONST64(0x0A234AA642391484) /* 936 */, CONST64(0xF6F9508028F80D9D) /* 937 */, + CONST64(0xB8E319A27AB3F215) /* 938 */, CONST64(0x31AD9C1151341A4D) /* 939 */, + CONST64(0x773C22A57BEF5805) /* 940 */, CONST64(0x45C7561A07968633) /* 941 */, + CONST64(0xF913DA9E249DBE36) /* 942 */, CONST64(0xDA652D9B78A64C68) /* 943 */, + CONST64(0x4C27A97F3BC334EF) /* 944 */, CONST64(0x76621220E66B17F4) /* 945 */, + CONST64(0x967743899ACD7D0B) /* 946 */, CONST64(0xF3EE5BCAE0ED6782) /* 947 */, + CONST64(0x409F753600C879FC) /* 948 */, CONST64(0x06D09A39B5926DB6) /* 949 */, + CONST64(0x6F83AEB0317AC588) /* 950 */, CONST64(0x01E6CA4A86381F21) /* 951 */, + CONST64(0x66FF3462D19F3025) /* 952 */, CONST64(0x72207C24DDFD3BFB) /* 953 */, + CONST64(0x4AF6B6D3E2ECE2EB) /* 954 */, CONST64(0x9C994DBEC7EA08DE) /* 955 */, + CONST64(0x49ACE597B09A8BC4) /* 956 */, CONST64(0xB38C4766CF0797BA) /* 957 */, + CONST64(0x131B9373C57C2A75) /* 958 */, CONST64(0xB1822CCE61931E58) /* 959 */, + CONST64(0x9D7555B909BA1C0C) /* 960 */, CONST64(0x127FAFDD937D11D2) /* 961 */, + CONST64(0x29DA3BADC66D92E4) /* 962 */, CONST64(0xA2C1D57154C2ECBC) /* 963 */, + CONST64(0x58C5134D82F6FE24) /* 964 */, CONST64(0x1C3AE3515B62274F) /* 965 */, + CONST64(0xE907C82E01CB8126) /* 966 */, CONST64(0xF8ED091913E37FCB) /* 967 */, + CONST64(0x3249D8F9C80046C9) /* 968 */, CONST64(0x80CF9BEDE388FB63) /* 969 */, + CONST64(0x1881539A116CF19E) /* 970 */, CONST64(0x5103F3F76BD52457) /* 971 */, + CONST64(0x15B7E6F5AE47F7A8) /* 972 */, CONST64(0xDBD7C6DED47E9CCF) /* 973 */, + CONST64(0x44E55C410228BB1A) /* 974 */, CONST64(0xB647D4255EDB4E99) /* 975 */, + CONST64(0x5D11882BB8AAFC30) /* 976 */, CONST64(0xF5098BBB29D3212A) /* 977 */, + CONST64(0x8FB5EA14E90296B3) /* 978 */, CONST64(0x677B942157DD025A) /* 979 */, + CONST64(0xFB58E7C0A390ACB5) /* 980 */, CONST64(0x89D3674C83BD4A01) /* 981 */, + CONST64(0x9E2DA4DF4BF3B93B) /* 982 */, CONST64(0xFCC41E328CAB4829) /* 983 */, + CONST64(0x03F38C96BA582C52) /* 984 */, CONST64(0xCAD1BDBD7FD85DB2) /* 985 */, + CONST64(0xBBB442C16082AE83) /* 986 */, CONST64(0xB95FE86BA5DA9AB0) /* 987 */, + CONST64(0xB22E04673771A93F) /* 988 */, CONST64(0x845358C9493152D8) /* 989 */, + CONST64(0xBE2A488697B4541E) /* 990 */, CONST64(0x95A2DC2DD38E6966) /* 991 */, + CONST64(0xC02C11AC923C852B) /* 992 */, CONST64(0x2388B1990DF2A87B) /* 993 */, + CONST64(0x7C8008FA1B4F37BE) /* 994 */, CONST64(0x1F70D0C84D54E503) /* 995 */, + CONST64(0x5490ADEC7ECE57D4) /* 996 */, CONST64(0x002B3C27D9063A3A) /* 997 */, + CONST64(0x7EAEA3848030A2BF) /* 998 */, CONST64(0xC602326DED2003C0) /* 999 */, + CONST64(0x83A7287D69A94086) /* 1000 */, CONST64(0xC57A5FCB30F57A8A) /* 1001 */, + CONST64(0xB56844E479EBE779) /* 1002 */, CONST64(0xA373B40F05DCBCE9) /* 1003 */, + CONST64(0xD71A786E88570EE2) /* 1004 */, CONST64(0x879CBACDBDE8F6A0) /* 1005 */, + CONST64(0x976AD1BCC164A32F) /* 1006 */, CONST64(0xAB21E25E9666D78B) /* 1007 */, + CONST64(0x901063AAE5E5C33C) /* 1008 */, CONST64(0x9818B34448698D90) /* 1009 */, + CONST64(0xE36487AE3E1E8ABB) /* 1010 */, CONST64(0xAFBDF931893BDCB4) /* 1011 */, + CONST64(0x6345A0DC5FBBD519) /* 1012 */, CONST64(0x8628FE269B9465CA) /* 1013 */, + CONST64(0x1E5D01603F9C51EC) /* 1014 */, CONST64(0x4DE44006A15049B7) /* 1015 */, + CONST64(0xBF6C70E5F776CBB1) /* 1016 */, CONST64(0x411218F2EF552BED) /* 1017 */, + CONST64(0xCB0C0708705A36A3) /* 1018 */, CONST64(0xE74D14754F986044) /* 1019 */, + CONST64(0xCD56D9430EA8280E) /* 1020 */, CONST64(0xC12591D7535F5065) /* 1021 */, + CONST64(0xC83223F1720AEF96) /* 1022 */, CONST64(0xC3A0396F7363A51F) /* 1023 */}; + +#ifdef _MSC_VER + #define INLINE __inline +#else + #define INLINE +#endif + +/* one round of the hash function */ +INLINE static void tiger_round(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 x, int mul) +{ + ulong64 tmp; + tmp = (*c ^= x); + *a -= t1[byte(tmp, 0)] ^ t2[byte(tmp, 2)] ^ t3[byte(tmp, 4)] ^ t4[byte(tmp, 6)]; + tmp = (*b += t4[byte(tmp, 1)] ^ t3[byte(tmp, 3)] ^ t2[byte(tmp,5)] ^ t1[byte(tmp,7)]); + switch (mul) { + case 5: *b = (tmp << 2) + tmp; break; + case 7: *b = (tmp << 3) - tmp; break; + case 9: *b = (tmp << 3) + tmp; break; + } +} + +/* one complete pass */ +static void pass(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 *x, int mul) +{ + tiger_round(a,b,c,x[0],mul); + tiger_round(b,c,a,x[1],mul); + tiger_round(c,a,b,x[2],mul); + tiger_round(a,b,c,x[3],mul); + tiger_round(b,c,a,x[4],mul); + tiger_round(c,a,b,x[5],mul); + tiger_round(a,b,c,x[6],mul); + tiger_round(b,c,a,x[7],mul); +} + +/* The key mixing schedule */ +static void key_schedule(ulong64 *x) +{ + x[0] -= x[7] ^ CONST64(0xA5A5A5A5A5A5A5A5); + x[1] ^= x[0]; + x[2] += x[1]; + x[3] -= x[2] ^ ((~x[1])<<19); + x[4] ^= x[3]; + x[5] += x[4]; + x[6] -= x[5] ^ ((~x[4])>>23); + x[7] ^= x[6]; + x[0] += x[7]; + x[1] -= x[0] ^ ((~x[7])<<19); + x[2] ^= x[1]; + x[3] += x[2]; + x[4] -= x[3] ^ ((~x[2])>>23); + x[5] ^= x[4]; + x[6] += x[5]; + x[7] -= x[6] ^ CONST64(0x0123456789ABCDEF); +} + +#ifdef LTC_CLEAN_STACK +static int _tiger_compress(hash_state *md, unsigned char *buf) +#else +static int tiger_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong64 a, b, c, x[8]; + unsigned long i; + + /* load words */ + for (i = 0; i < 8; i++) { + LOAD64L(x[i],&buf[8*i]); + } + a = md->tiger.state[0]; + b = md->tiger.state[1]; + c = md->tiger.state[2]; + + pass(&a,&b,&c,x,5); + key_schedule(x); + pass(&c,&a,&b,x,7); + key_schedule(x); + pass(&b,&c,&a,x,9); + + /* store state */ + md->tiger.state[0] = a ^ md->tiger.state[0]; + md->tiger.state[1] = b - md->tiger.state[1]; + md->tiger.state[2] = c + md->tiger.state[2]; + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +static int tiger_compress(hash_state *md, unsigned char *buf) +{ + int err; + err = _tiger_compress(md, buf); + burn_stack(sizeof(ulong64) * 11 + sizeof(unsigned long)); + return err; +} +#endif + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int tiger_init(hash_state *md) +{ + LTC_ARGCHK(md != NULL); + md->tiger.state[0] = CONST64(0x0123456789ABCDEF); + md->tiger.state[1] = CONST64(0xFEDCBA9876543210); + md->tiger.state[2] = CONST64(0xF096A5B4C3B2E187); + md->tiger.curlen = 0; + md->tiger.length = 0; + return CRYPT_OK; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +HASH_PROCESS(tiger_process, tiger_compress, tiger, 64) + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (24 bytes) + @return CRYPT_OK if successful +*/ +int tiger_done(hash_state * md, unsigned char *out) +{ + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->tiger.curlen >= sizeof(md->tiger.buf)) { + return CRYPT_INVALID_ARG; + } + + /* increase the length of the message */ + md->tiger.length += md->tiger.curlen * 8; + + /* append the '1' bit */ + md->tiger.buf[md->tiger.curlen++] = (unsigned char)0x01; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. */ + if (md->tiger.curlen > 56) { + while (md->tiger.curlen < 64) { + md->tiger.buf[md->tiger.curlen++] = (unsigned char)0; + } + tiger_compress(md, md->tiger.buf); + md->tiger.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->tiger.curlen < 56) { + md->tiger.buf[md->tiger.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->tiger.length, md->tiger.buf+56); + tiger_compress(md, md->tiger.buf); + + /* copy output */ + STORE64L(md->tiger.state[0], &out[0]); + STORE64L(md->tiger.state[1], &out[8]); + STORE64L(md->tiger.state[2], &out[16]); +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int tiger_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[24]; + } tests[] = { + { "", + { 0x32, 0x93, 0xac, 0x63, 0x0c, 0x13, 0xf0, 0x24, + 0x5f, 0x92, 0xbb, 0xb1, 0x76, 0x6e, 0x16, 0x16, + 0x7a, 0x4e, 0x58, 0x49, 0x2d, 0xde, 0x73, 0xf3 } + }, + { "abc", + { 0x2a, 0xab, 0x14, 0x84, 0xe8, 0xc1, 0x58, 0xf2, + 0xbf, 0xb8, 0xc5, 0xff, 0x41, 0xb5, 0x7a, 0x52, + 0x51, 0x29, 0x13, 0x1c, 0x95, 0x7b, 0x5f, 0x93 } + }, + { "Tiger", + { 0xdd, 0x00, 0x23, 0x07, 0x99, 0xf5, 0x00, 0x9f, + 0xec, 0x6d, 0xeb, 0xc8, 0x38, 0xbb, 0x6a, 0x27, + 0xdf, 0x2b, 0x9d, 0x6f, 0x11, 0x0c, 0x79, 0x37 } + }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-", + { 0xf7, 0x1c, 0x85, 0x83, 0x90, 0x2a, 0xfb, 0x87, + 0x9e, 0xdf, 0xe6, 0x10, 0xf8, 0x2c, 0x0d, 0x47, + 0x86, 0xa3, 0xa5, 0x34, 0x50, 0x44, 0x86, 0xb5 } + }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-", + { 0xc5, 0x40, 0x34, 0xe5, 0xb4, 0x3e, 0xb8, 0x00, + 0x58, 0x48, 0xa7, 0xe0, 0xae, 0x6a, 0xac, 0x76, + 0xe4, 0xff, 0x59, 0x0a, 0xe7, 0x15, 0xfd, 0x25 } + }, + }; + + int i; + unsigned char tmp[24]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + tiger_init(&md); + tiger_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + tiger_done(&md, tmp); + if (XMEMCMP(tmp, tests[i].hash, 24) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#endif + +/* +Hash of "": + 24F0130C63AC9332 16166E76B1BB925F F373DE2D49584E7A +Hash of "abc": + F258C1E88414AB2A 527AB541FFC5B8BF 935F7B951C132951 +Hash of "Tiger": + 9F00F599072300DD 276ABB38C8EB6DEC 37790C116F9D2BDF +Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-": + 87FB2A9083851CF7 470D2CF810E6DF9E B586445034A5A386 +Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789": + 467DB80863EBCE48 8DF1CD1261655DE9 57896565975F9197 +Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham": + 0C410A042968868A 1671DA5A3FD29A72 5EC1E457D3CDB303 +Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge.": + EBF591D5AFA655CE 7F22894FF87F54AC 89C811B6B0DA3193 +Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge, 1996.": + 3D9AEB03D1BD1A63 57B2774DFD6D5B24 DD68151D503974FC +Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-": + 00B83EB4E53440C5 76AC6AAEE0A74858 25FD15E70A59FFE4 +*/ + + + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/hashes/whirl/whirl.c b/src/ltc/hashes/whirl/whirl.c new file mode 100644 index 0000000..525d75b --- /dev/null +++ b/src/ltc/hashes/whirl/whirl.c @@ -0,0 +1,315 @@ +/* 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://libtom.org + */ + +/** + @file whirl.c + LTC_WHIRLPOOL (using their new sbox) hash function by Tom St Denis +*/ + +#include "tomcrypt.h" + +#ifdef LTC_WHIRLPOOL + +const struct ltc_hash_descriptor whirlpool_desc = +{ + "whirlpool", + 11, + 64, + 64, + + /* OID */ + { 1, 0, 10118, 3, 0, 55 }, + 6, + + &whirlpool_init, + &whirlpool_process, + &whirlpool_done, + &whirlpool_test, + NULL +}; + +/* the sboxes */ +#define __LTC_WHIRLTAB_C__ +#include "whirltab.c" + +/* get a_{i,j} */ +#define GB(a,i,j) ((a[(i) & 7] >> (8 * (j))) & 255) + +/* shortcut macro to perform three functions at once */ +#define theta_pi_gamma(a, i) \ + (SB0(GB(a, i-0, 7)) ^ \ + SB1(GB(a, i-1, 6)) ^ \ + SB2(GB(a, i-2, 5)) ^ \ + SB3(GB(a, i-3, 4)) ^ \ + SB4(GB(a, i-4, 3)) ^ \ + SB5(GB(a, i-5, 2)) ^ \ + SB6(GB(a, i-6, 1)) ^ \ + SB7(GB(a, i-7, 0))) + +#ifdef LTC_CLEAN_STACK +static int _whirlpool_compress(hash_state *md, unsigned char *buf) +#else +static int whirlpool_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong64 K[2][8], T[3][8]; + int x, y; + + /* load the block/state */ + for (x = 0; x < 8; x++) { + K[0][x] = md->whirlpool.state[x]; + + LOAD64H(T[0][x], buf + (8 * x)); + T[2][x] = T[0][x]; + T[0][x] ^= K[0][x]; + } + + /* do rounds 1..10 */ + for (x = 0; x < 10; x += 2) { + /* odd round */ + /* apply main transform to K[0] into K[1] */ + for (y = 0; y < 8; y++) { + K[1][y] = theta_pi_gamma(K[0], y); + } + /* xor the constant */ + K[1][0] ^= cont[x]; + + /* apply main transform to T[0] into T[1] */ + for (y = 0; y < 8; y++) { + T[1][y] = theta_pi_gamma(T[0], y) ^ K[1][y]; + } + + /* even round */ + /* apply main transform to K[1] into K[0] */ + for (y = 0; y < 8; y++) { + K[0][y] = theta_pi_gamma(K[1], y); + } + /* xor the constant */ + K[0][0] ^= cont[x+1]; + + /* apply main transform to T[1] into T[0] */ + for (y = 0; y < 8; y++) { + T[0][y] = theta_pi_gamma(T[1], y) ^ K[0][y]; + } + } + + /* store state */ + for (x = 0; x < 8; x++) { + md->whirlpool.state[x] ^= T[0][x] ^ T[2][x]; + } + + return CRYPT_OK; +} + + +#ifdef LTC_CLEAN_STACK +static int whirlpool_compress(hash_state *md, unsigned char *buf) +{ + int err; + err = _whirlpool_compress(md, buf); + burn_stack((5 * 8 * sizeof(ulong64)) + (2 * sizeof(int))); + return err; +} +#endif + + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int whirlpool_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + zeromem(&md->whirlpool, sizeof(md->whirlpool)); + return CRYPT_OK; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +HASH_PROCESS(whirlpool_process, whirlpool_compress, whirlpool, 64) + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (64 bytes) + @return CRYPT_OK if successful +*/ +int whirlpool_done(hash_state * md, unsigned char *out) +{ + int i; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->whirlpool.curlen >= sizeof(md->whirlpool.buf)) { + return CRYPT_INVALID_ARG; + } + + /* increase the length of the message */ + md->whirlpool.length += md->whirlpool.curlen * 8; + + /* append the '1' bit */ + md->whirlpool.buf[md->whirlpool.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 32 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->whirlpool.curlen > 32) { + while (md->whirlpool.curlen < 64) { + md->whirlpool.buf[md->whirlpool.curlen++] = (unsigned char)0; + } + whirlpool_compress(md, md->whirlpool.buf); + md->whirlpool.curlen = 0; + } + + /* pad upto 56 bytes of zeroes (should be 32 but we only support 64-bit lengths) */ + while (md->whirlpool.curlen < 56) { + md->whirlpool.buf[md->whirlpool.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64H(md->whirlpool.length, md->whirlpool.buf+56); + whirlpool_compress(md, md->whirlpool.buf); + + /* copy output */ + for (i = 0; i < 8; i++) { + STORE64H(md->whirlpool.state[i], out+(8*i)); + } +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(*md)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int whirlpool_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + int len; + unsigned char msg[128], hash[64]; + } tests[] = { + + /* NULL Message */ +{ + 0, + { 0x00 }, + { 0x19, 0xFA, 0x61, 0xD7, 0x55, 0x22, 0xA4, 0x66, 0x9B, 0x44, 0xE3, 0x9C, 0x1D, 0x2E, 0x17, 0x26, + 0xC5, 0x30, 0x23, 0x21, 0x30, 0xD4, 0x07, 0xF8, 0x9A, 0xFE, 0xE0, 0x96, 0x49, 0x97, 0xF7, 0xA7, + 0x3E, 0x83, 0xBE, 0x69, 0x8B, 0x28, 0x8F, 0xEB, 0xCF, 0x88, 0xE3, 0xE0, 0x3C, 0x4F, 0x07, 0x57, + 0xEA, 0x89, 0x64, 0xE5, 0x9B, 0x63, 0xD9, 0x37, 0x08, 0xB1, 0x38, 0xCC, 0x42, 0xA6, 0x6E, 0xB3 } +}, + + + /* 448-bits of 0 bits */ +{ + + 56, + { 0x00 }, + { 0x0B, 0x3F, 0x53, 0x78, 0xEB, 0xED, 0x2B, 0xF4, 0xD7, 0xBE, 0x3C, 0xFD, 0x81, 0x8C, 0x1B, 0x03, + 0xB6, 0xBB, 0x03, 0xD3, 0x46, 0x94, 0x8B, 0x04, 0xF4, 0xF4, 0x0C, 0x72, 0x6F, 0x07, 0x58, 0x70, + 0x2A, 0x0F, 0x1E, 0x22, 0x58, 0x80, 0xE3, 0x8D, 0xD5, 0xF6, 0xED, 0x6D, 0xE9, 0xB1, 0xE9, 0x61, + 0xE4, 0x9F, 0xC1, 0x31, 0x8D, 0x7C, 0xB7, 0x48, 0x22, 0xF3, 0xD0, 0xE2, 0xE9, 0xA7, 0xE7, 0xB0 } +}, + + /* 520-bits of 0 bits */ +{ + 65, + { 0x00 }, + { 0x85, 0xE1, 0x24, 0xC4, 0x41, 0x5B, 0xCF, 0x43, 0x19, 0x54, 0x3E, 0x3A, 0x63, 0xFF, 0x57, 0x1D, + 0x09, 0x35, 0x4C, 0xEE, 0xBE, 0xE1, 0xE3, 0x25, 0x30, 0x8C, 0x90, 0x69, 0xF4, 0x3E, 0x2A, 0xE4, + 0xD0, 0xE5, 0x1D, 0x4E, 0xB1, 0xE8, 0x64, 0x28, 0x70, 0x19, 0x4E, 0x95, 0x30, 0xD8, 0xD8, 0xAF, + 0x65, 0x89, 0xD1, 0xBF, 0x69, 0x49, 0xDD, 0xF9, 0x0A, 0x7F, 0x12, 0x08, 0x62, 0x37, 0x95, 0xB9 } +}, + + /* 512-bits, leading set */ +{ + 64, + { 0x80, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x10, 0x3E, 0x00, 0x55, 0xA9, 0xB0, 0x90, 0xE1, 0x1C, 0x8F, 0xDD, 0xEB, 0xBA, 0x06, 0xC0, 0x5A, + 0xCE, 0x8B, 0x64, 0xB8, 0x96, 0x12, 0x8F, 0x6E, 0xED, 0x30, 0x71, 0xFC, 0xF3, 0xDC, 0x16, 0x94, + 0x67, 0x78, 0xE0, 0x72, 0x23, 0x23, 0x3F, 0xD1, 0x80, 0xFC, 0x40, 0xCC, 0xDB, 0x84, 0x30, 0xA6, + 0x40, 0xE3, 0x76, 0x34, 0x27, 0x1E, 0x65, 0x5C, 0xA1, 0x67, 0x4E, 0xBF, 0xF5, 0x07, 0xF8, 0xCB } +}, + + /* 512-bits, leading set of second byte */ +{ + 64, + { 0x00, 0x80, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x35, 0x7B, 0x42, 0xEA, 0x79, 0xBC, 0x97, 0x86, 0x97, 0x5A, 0x3C, 0x44, 0x70, 0xAA, 0xB2, 0x3E, + 0x62, 0x29, 0x79, 0x7B, 0xAD, 0xBD, 0x54, 0x36, 0x5B, 0x54, 0x96, 0xE5, 0x5D, 0x9D, 0xD7, 0x9F, + 0xE9, 0x62, 0x4F, 0xB4, 0x22, 0x66, 0x93, 0x0A, 0x62, 0x8E, 0xD4, 0xDB, 0x08, 0xF9, 0xDD, 0x35, + 0xEF, 0x1B, 0xE1, 0x04, 0x53, 0xFC, 0x18, 0xF4, 0x2C, 0x7F, 0x5E, 0x1F, 0x9B, 0xAE, 0x55, 0xE0 } +}, + + /* 512-bits, leading set of last byte */ +{ + 64, + { 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 }, + { 0x8B, 0x39, 0x04, 0xDD, 0x19, 0x81, 0x41, 0x26, 0xFD, 0x02, 0x74, 0xAB, 0x49, 0xC5, 0x97, 0xF6, + 0xD7, 0x75, 0x33, 0x52, 0xA2, 0xDD, 0x91, 0xFD, 0x8F, 0x9F, 0x54, 0x05, 0x4C, 0x54, 0xBF, 0x0F, + 0x06, 0xDB, 0x4F, 0xF7, 0x08, 0xA3, 0xA2, 0x8B, 0xC3, 0x7A, 0x92, 0x1E, 0xEE, 0x11, 0xED, 0x7B, + 0x6A, 0x53, 0x79, 0x32, 0xCC, 0x5E, 0x94, 0xEE, 0x1E, 0xA6, 0x57, 0x60, 0x7E, 0x36, 0xC9, 0xF7 } +}, + +}; + + int i; + unsigned char tmp[64]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { + whirlpool_init(&md); + whirlpool_process(&md, (unsigned char *)tests[i].msg, tests[i].len); + whirlpool_done(&md, tmp); + if (XMEMCMP(tmp, tests[i].hash, 64) != 0) { +#if 0 + printf("\nFailed test %d\n", i); + for (i = 0; i < 64; ) { + printf("%02x ", tmp[i]); + if (!(++i & 15)) printf("\n"); + } +#endif + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/hashes/whirl/whirltab.c b/src/ltc/hashes/whirl/whirltab.c new file mode 100644 index 0000000..bb4b77a --- /dev/null +++ b/src/ltc/hashes/whirl/whirltab.c @@ -0,0 +1,587 @@ +/** + @file whirltab.c + LTC_WHIRLPOOL tables, Tom St Denis +*/ + +#ifdef __LTC_WHIRLTAB_C__ + +static const ulong64 sbox0[] = { +CONST64(0x18186018c07830d8), CONST64(0x23238c2305af4626), CONST64(0xc6c63fc67ef991b8), CONST64(0xe8e887e8136fcdfb), +CONST64(0x878726874ca113cb), CONST64(0xb8b8dab8a9626d11), CONST64(0x0101040108050209), CONST64(0x4f4f214f426e9e0d), +CONST64(0x3636d836adee6c9b), CONST64(0xa6a6a2a6590451ff), CONST64(0xd2d26fd2debdb90c), CONST64(0xf5f5f3f5fb06f70e), +CONST64(0x7979f979ef80f296), CONST64(0x6f6fa16f5fcede30), CONST64(0x91917e91fcef3f6d), CONST64(0x52525552aa07a4f8), +CONST64(0x60609d6027fdc047), CONST64(0xbcbccabc89766535), CONST64(0x9b9b569baccd2b37), CONST64(0x8e8e028e048c018a), +CONST64(0xa3a3b6a371155bd2), CONST64(0x0c0c300c603c186c), CONST64(0x7b7bf17bff8af684), CONST64(0x3535d435b5e16a80), +CONST64(0x1d1d741de8693af5), CONST64(0xe0e0a7e05347ddb3), CONST64(0xd7d77bd7f6acb321), CONST64(0xc2c22fc25eed999c), +CONST64(0x2e2eb82e6d965c43), CONST64(0x4b4b314b627a9629), CONST64(0xfefedffea321e15d), CONST64(0x575741578216aed5), +CONST64(0x15155415a8412abd), CONST64(0x7777c1779fb6eee8), CONST64(0x3737dc37a5eb6e92), CONST64(0xe5e5b3e57b56d79e), +CONST64(0x9f9f469f8cd92313), CONST64(0xf0f0e7f0d317fd23), CONST64(0x4a4a354a6a7f9420), CONST64(0xdada4fda9e95a944), +CONST64(0x58587d58fa25b0a2), CONST64(0xc9c903c906ca8fcf), CONST64(0x2929a429558d527c), CONST64(0x0a0a280a5022145a), +CONST64(0xb1b1feb1e14f7f50), CONST64(0xa0a0baa0691a5dc9), CONST64(0x6b6bb16b7fdad614), CONST64(0x85852e855cab17d9), +CONST64(0xbdbdcebd8173673c), CONST64(0x5d5d695dd234ba8f), CONST64(0x1010401080502090), CONST64(0xf4f4f7f4f303f507), +CONST64(0xcbcb0bcb16c08bdd), CONST64(0x3e3ef83eedc67cd3), CONST64(0x0505140528110a2d), CONST64(0x676781671fe6ce78), +CONST64(0xe4e4b7e47353d597), CONST64(0x27279c2725bb4e02), CONST64(0x4141194132588273), CONST64(0x8b8b168b2c9d0ba7), +CONST64(0xa7a7a6a7510153f6), CONST64(0x7d7de97dcf94fab2), CONST64(0x95956e95dcfb3749), CONST64(0xd8d847d88e9fad56), +CONST64(0xfbfbcbfb8b30eb70), CONST64(0xeeee9fee2371c1cd), CONST64(0x7c7ced7cc791f8bb), CONST64(0x6666856617e3cc71), +CONST64(0xdddd53dda68ea77b), CONST64(0x17175c17b84b2eaf), CONST64(0x4747014702468e45), CONST64(0x9e9e429e84dc211a), +CONST64(0xcaca0fca1ec589d4), CONST64(0x2d2db42d75995a58), CONST64(0xbfbfc6bf9179632e), CONST64(0x07071c07381b0e3f), +CONST64(0xadad8ead012347ac), CONST64(0x5a5a755aea2fb4b0), CONST64(0x838336836cb51bef), CONST64(0x3333cc3385ff66b6), +CONST64(0x636391633ff2c65c), CONST64(0x02020802100a0412), CONST64(0xaaaa92aa39384993), CONST64(0x7171d971afa8e2de), +CONST64(0xc8c807c80ecf8dc6), CONST64(0x19196419c87d32d1), CONST64(0x494939497270923b), CONST64(0xd9d943d9869aaf5f), +CONST64(0xf2f2eff2c31df931), CONST64(0xe3e3abe34b48dba8), CONST64(0x5b5b715be22ab6b9), CONST64(0x88881a8834920dbc), +CONST64(0x9a9a529aa4c8293e), CONST64(0x262698262dbe4c0b), CONST64(0x3232c8328dfa64bf), CONST64(0xb0b0fab0e94a7d59), +CONST64(0xe9e983e91b6acff2), CONST64(0x0f0f3c0f78331e77), CONST64(0xd5d573d5e6a6b733), CONST64(0x80803a8074ba1df4), +CONST64(0xbebec2be997c6127), CONST64(0xcdcd13cd26de87eb), CONST64(0x3434d034bde46889), CONST64(0x48483d487a759032), +CONST64(0xffffdbffab24e354), CONST64(0x7a7af57af78ff48d), CONST64(0x90907a90f4ea3d64), CONST64(0x5f5f615fc23ebe9d), +CONST64(0x202080201da0403d), CONST64(0x6868bd6867d5d00f), CONST64(0x1a1a681ad07234ca), CONST64(0xaeae82ae192c41b7), +CONST64(0xb4b4eab4c95e757d), CONST64(0x54544d549a19a8ce), CONST64(0x93937693ece53b7f), CONST64(0x222288220daa442f), +CONST64(0x64648d6407e9c863), CONST64(0xf1f1e3f1db12ff2a), CONST64(0x7373d173bfa2e6cc), CONST64(0x12124812905a2482), +CONST64(0x40401d403a5d807a), CONST64(0x0808200840281048), CONST64(0xc3c32bc356e89b95), CONST64(0xecec97ec337bc5df), +CONST64(0xdbdb4bdb9690ab4d), CONST64(0xa1a1bea1611f5fc0), CONST64(0x8d8d0e8d1c830791), CONST64(0x3d3df43df5c97ac8), +CONST64(0x97976697ccf1335b), CONST64(0x0000000000000000), CONST64(0xcfcf1bcf36d483f9), CONST64(0x2b2bac2b4587566e), +CONST64(0x7676c57697b3ece1), CONST64(0x8282328264b019e6), CONST64(0xd6d67fd6fea9b128), CONST64(0x1b1b6c1bd87736c3), +CONST64(0xb5b5eeb5c15b7774), CONST64(0xafaf86af112943be), CONST64(0x6a6ab56a77dfd41d), CONST64(0x50505d50ba0da0ea), +CONST64(0x45450945124c8a57), CONST64(0xf3f3ebf3cb18fb38), CONST64(0x3030c0309df060ad), CONST64(0xefef9bef2b74c3c4), +CONST64(0x3f3ffc3fe5c37eda), CONST64(0x55554955921caac7), CONST64(0xa2a2b2a2791059db), CONST64(0xeaea8fea0365c9e9), +CONST64(0x656589650fecca6a), CONST64(0xbabad2bab9686903), CONST64(0x2f2fbc2f65935e4a), CONST64(0xc0c027c04ee79d8e), +CONST64(0xdede5fdebe81a160), CONST64(0x1c1c701ce06c38fc), CONST64(0xfdfdd3fdbb2ee746), CONST64(0x4d4d294d52649a1f), +CONST64(0x92927292e4e03976), CONST64(0x7575c9758fbceafa), CONST64(0x06061806301e0c36), CONST64(0x8a8a128a249809ae), +CONST64(0xb2b2f2b2f940794b), CONST64(0xe6e6bfe66359d185), CONST64(0x0e0e380e70361c7e), CONST64(0x1f1f7c1ff8633ee7), +CONST64(0x6262956237f7c455), CONST64(0xd4d477d4eea3b53a), CONST64(0xa8a89aa829324d81), CONST64(0x96966296c4f43152), +CONST64(0xf9f9c3f99b3aef62), CONST64(0xc5c533c566f697a3), CONST64(0x2525942535b14a10), CONST64(0x59597959f220b2ab), +CONST64(0x84842a8454ae15d0), CONST64(0x7272d572b7a7e4c5), CONST64(0x3939e439d5dd72ec), CONST64(0x4c4c2d4c5a619816), +CONST64(0x5e5e655eca3bbc94), CONST64(0x7878fd78e785f09f), CONST64(0x3838e038ddd870e5), CONST64(0x8c8c0a8c14860598), +CONST64(0xd1d163d1c6b2bf17), CONST64(0xa5a5aea5410b57e4), CONST64(0xe2e2afe2434dd9a1), CONST64(0x616199612ff8c24e), +CONST64(0xb3b3f6b3f1457b42), CONST64(0x2121842115a54234), CONST64(0x9c9c4a9c94d62508), CONST64(0x1e1e781ef0663cee), +CONST64(0x4343114322528661), CONST64(0xc7c73bc776fc93b1), CONST64(0xfcfcd7fcb32be54f), CONST64(0x0404100420140824), +CONST64(0x51515951b208a2e3), CONST64(0x99995e99bcc72f25), CONST64(0x6d6da96d4fc4da22), CONST64(0x0d0d340d68391a65), +CONST64(0xfafacffa8335e979), CONST64(0xdfdf5bdfb684a369), CONST64(0x7e7ee57ed79bfca9), CONST64(0x242490243db44819), +CONST64(0x3b3bec3bc5d776fe), CONST64(0xabab96ab313d4b9a), CONST64(0xcece1fce3ed181f0), CONST64(0x1111441188552299), +CONST64(0x8f8f068f0c890383), CONST64(0x4e4e254e4a6b9c04), CONST64(0xb7b7e6b7d1517366), CONST64(0xebeb8beb0b60cbe0), +CONST64(0x3c3cf03cfdcc78c1), CONST64(0x81813e817cbf1ffd), CONST64(0x94946a94d4fe3540), CONST64(0xf7f7fbf7eb0cf31c), +CONST64(0xb9b9deb9a1676f18), CONST64(0x13134c13985f268b), CONST64(0x2c2cb02c7d9c5851), CONST64(0xd3d36bd3d6b8bb05), +CONST64(0xe7e7bbe76b5cd38c), CONST64(0x6e6ea56e57cbdc39), CONST64(0xc4c437c46ef395aa), CONST64(0x03030c03180f061b), +CONST64(0x565645568a13acdc), CONST64(0x44440d441a49885e), CONST64(0x7f7fe17fdf9efea0), CONST64(0xa9a99ea921374f88), +CONST64(0x2a2aa82a4d825467), CONST64(0xbbbbd6bbb16d6b0a), CONST64(0xc1c123c146e29f87), CONST64(0x53535153a202a6f1), +CONST64(0xdcdc57dcae8ba572), CONST64(0x0b0b2c0b58271653), CONST64(0x9d9d4e9d9cd32701), CONST64(0x6c6cad6c47c1d82b), +CONST64(0x3131c43195f562a4), CONST64(0x7474cd7487b9e8f3), CONST64(0xf6f6fff6e309f115), CONST64(0x464605460a438c4c), +CONST64(0xacac8aac092645a5), CONST64(0x89891e893c970fb5), CONST64(0x14145014a04428b4), CONST64(0xe1e1a3e15b42dfba), +CONST64(0x16165816b04e2ca6), CONST64(0x3a3ae83acdd274f7), CONST64(0x6969b9696fd0d206), CONST64(0x09092409482d1241), +CONST64(0x7070dd70a7ade0d7), CONST64(0xb6b6e2b6d954716f), CONST64(0xd0d067d0ceb7bd1e), CONST64(0xeded93ed3b7ec7d6), +CONST64(0xcccc17cc2edb85e2), CONST64(0x424215422a578468), CONST64(0x98985a98b4c22d2c), CONST64(0xa4a4aaa4490e55ed), +CONST64(0x2828a0285d885075), CONST64(0x5c5c6d5cda31b886), CONST64(0xf8f8c7f8933fed6b), CONST64(0x8686228644a411c2) +}; + +#ifdef LTC_SMALL_CODE + +#define SB0(x) sbox0[x] +#define SB1(x) ROR64c(sbox0[x], 8) +#define SB2(x) ROR64c(sbox0[x], 16) +#define SB3(x) ROR64c(sbox0[x], 24) +#define SB4(x) ROR64c(sbox0[x], 32) +#define SB5(x) ROR64c(sbox0[x], 40) +#define SB6(x) ROR64c(sbox0[x], 48) +#define SB7(x) ROR64c(sbox0[x], 56) + +#else + +#define SB0(x) sbox0[x] +#define SB1(x) sbox1[x] +#define SB2(x) sbox2[x] +#define SB3(x) sbox3[x] +#define SB4(x) sbox4[x] +#define SB5(x) sbox5[x] +#define SB6(x) sbox6[x] +#define SB7(x) sbox7[x] + + +static const ulong64 sbox1[] = { +CONST64(0xd818186018c07830), CONST64(0x2623238c2305af46), CONST64(0xb8c6c63fc67ef991), CONST64(0xfbe8e887e8136fcd), +CONST64(0xcb878726874ca113), CONST64(0x11b8b8dab8a9626d), CONST64(0x0901010401080502), CONST64(0x0d4f4f214f426e9e), +CONST64(0x9b3636d836adee6c), CONST64(0xffa6a6a2a6590451), CONST64(0x0cd2d26fd2debdb9), CONST64(0x0ef5f5f3f5fb06f7), +CONST64(0x967979f979ef80f2), CONST64(0x306f6fa16f5fcede), CONST64(0x6d91917e91fcef3f), CONST64(0xf852525552aa07a4), +CONST64(0x4760609d6027fdc0), CONST64(0x35bcbccabc897665), CONST64(0x379b9b569baccd2b), CONST64(0x8a8e8e028e048c01), +CONST64(0xd2a3a3b6a371155b), CONST64(0x6c0c0c300c603c18), CONST64(0x847b7bf17bff8af6), CONST64(0x803535d435b5e16a), +CONST64(0xf51d1d741de8693a), CONST64(0xb3e0e0a7e05347dd), CONST64(0x21d7d77bd7f6acb3), CONST64(0x9cc2c22fc25eed99), +CONST64(0x432e2eb82e6d965c), CONST64(0x294b4b314b627a96), CONST64(0x5dfefedffea321e1), CONST64(0xd5575741578216ae), +CONST64(0xbd15155415a8412a), CONST64(0xe87777c1779fb6ee), CONST64(0x923737dc37a5eb6e), CONST64(0x9ee5e5b3e57b56d7), +CONST64(0x139f9f469f8cd923), CONST64(0x23f0f0e7f0d317fd), CONST64(0x204a4a354a6a7f94), CONST64(0x44dada4fda9e95a9), +CONST64(0xa258587d58fa25b0), CONST64(0xcfc9c903c906ca8f), CONST64(0x7c2929a429558d52), CONST64(0x5a0a0a280a502214), +CONST64(0x50b1b1feb1e14f7f), CONST64(0xc9a0a0baa0691a5d), CONST64(0x146b6bb16b7fdad6), CONST64(0xd985852e855cab17), +CONST64(0x3cbdbdcebd817367), CONST64(0x8f5d5d695dd234ba), CONST64(0x9010104010805020), CONST64(0x07f4f4f7f4f303f5), +CONST64(0xddcbcb0bcb16c08b), CONST64(0xd33e3ef83eedc67c), CONST64(0x2d0505140528110a), CONST64(0x78676781671fe6ce), +CONST64(0x97e4e4b7e47353d5), CONST64(0x0227279c2725bb4e), CONST64(0x7341411941325882), CONST64(0xa78b8b168b2c9d0b), +CONST64(0xf6a7a7a6a7510153), CONST64(0xb27d7de97dcf94fa), CONST64(0x4995956e95dcfb37), CONST64(0x56d8d847d88e9fad), +CONST64(0x70fbfbcbfb8b30eb), CONST64(0xcdeeee9fee2371c1), CONST64(0xbb7c7ced7cc791f8), CONST64(0x716666856617e3cc), +CONST64(0x7bdddd53dda68ea7), CONST64(0xaf17175c17b84b2e), CONST64(0x454747014702468e), CONST64(0x1a9e9e429e84dc21), +CONST64(0xd4caca0fca1ec589), CONST64(0x582d2db42d75995a), CONST64(0x2ebfbfc6bf917963), CONST64(0x3f07071c07381b0e), +CONST64(0xacadad8ead012347), CONST64(0xb05a5a755aea2fb4), CONST64(0xef838336836cb51b), CONST64(0xb63333cc3385ff66), +CONST64(0x5c636391633ff2c6), CONST64(0x1202020802100a04), CONST64(0x93aaaa92aa393849), CONST64(0xde7171d971afa8e2), +CONST64(0xc6c8c807c80ecf8d), CONST64(0xd119196419c87d32), CONST64(0x3b49493949727092), CONST64(0x5fd9d943d9869aaf), +CONST64(0x31f2f2eff2c31df9), CONST64(0xa8e3e3abe34b48db), CONST64(0xb95b5b715be22ab6), CONST64(0xbc88881a8834920d), +CONST64(0x3e9a9a529aa4c829), CONST64(0x0b262698262dbe4c), CONST64(0xbf3232c8328dfa64), CONST64(0x59b0b0fab0e94a7d), +CONST64(0xf2e9e983e91b6acf), CONST64(0x770f0f3c0f78331e), CONST64(0x33d5d573d5e6a6b7), CONST64(0xf480803a8074ba1d), +CONST64(0x27bebec2be997c61), CONST64(0xebcdcd13cd26de87), CONST64(0x893434d034bde468), CONST64(0x3248483d487a7590), +CONST64(0x54ffffdbffab24e3), CONST64(0x8d7a7af57af78ff4), CONST64(0x6490907a90f4ea3d), CONST64(0x9d5f5f615fc23ebe), +CONST64(0x3d202080201da040), CONST64(0x0f6868bd6867d5d0), CONST64(0xca1a1a681ad07234), CONST64(0xb7aeae82ae192c41), +CONST64(0x7db4b4eab4c95e75), CONST64(0xce54544d549a19a8), CONST64(0x7f93937693ece53b), CONST64(0x2f222288220daa44), +CONST64(0x6364648d6407e9c8), CONST64(0x2af1f1e3f1db12ff), CONST64(0xcc7373d173bfa2e6), CONST64(0x8212124812905a24), +CONST64(0x7a40401d403a5d80), CONST64(0x4808082008402810), CONST64(0x95c3c32bc356e89b), CONST64(0xdfecec97ec337bc5), +CONST64(0x4ddbdb4bdb9690ab), CONST64(0xc0a1a1bea1611f5f), CONST64(0x918d8d0e8d1c8307), CONST64(0xc83d3df43df5c97a), +CONST64(0x5b97976697ccf133), CONST64(0x0000000000000000), CONST64(0xf9cfcf1bcf36d483), CONST64(0x6e2b2bac2b458756), +CONST64(0xe17676c57697b3ec), CONST64(0xe68282328264b019), CONST64(0x28d6d67fd6fea9b1), CONST64(0xc31b1b6c1bd87736), +CONST64(0x74b5b5eeb5c15b77), CONST64(0xbeafaf86af112943), CONST64(0x1d6a6ab56a77dfd4), CONST64(0xea50505d50ba0da0), +CONST64(0x5745450945124c8a), CONST64(0x38f3f3ebf3cb18fb), CONST64(0xad3030c0309df060), CONST64(0xc4efef9bef2b74c3), +CONST64(0xda3f3ffc3fe5c37e), CONST64(0xc755554955921caa), CONST64(0xdba2a2b2a2791059), CONST64(0xe9eaea8fea0365c9), +CONST64(0x6a656589650fecca), CONST64(0x03babad2bab96869), CONST64(0x4a2f2fbc2f65935e), CONST64(0x8ec0c027c04ee79d), +CONST64(0x60dede5fdebe81a1), CONST64(0xfc1c1c701ce06c38), CONST64(0x46fdfdd3fdbb2ee7), CONST64(0x1f4d4d294d52649a), +CONST64(0x7692927292e4e039), CONST64(0xfa7575c9758fbcea), CONST64(0x3606061806301e0c), CONST64(0xae8a8a128a249809), +CONST64(0x4bb2b2f2b2f94079), CONST64(0x85e6e6bfe66359d1), CONST64(0x7e0e0e380e70361c), CONST64(0xe71f1f7c1ff8633e), +CONST64(0x556262956237f7c4), CONST64(0x3ad4d477d4eea3b5), CONST64(0x81a8a89aa829324d), CONST64(0x5296966296c4f431), +CONST64(0x62f9f9c3f99b3aef), CONST64(0xa3c5c533c566f697), CONST64(0x102525942535b14a), CONST64(0xab59597959f220b2), +CONST64(0xd084842a8454ae15), CONST64(0xc57272d572b7a7e4), CONST64(0xec3939e439d5dd72), CONST64(0x164c4c2d4c5a6198), +CONST64(0x945e5e655eca3bbc), CONST64(0x9f7878fd78e785f0), CONST64(0xe53838e038ddd870), CONST64(0x988c8c0a8c148605), +CONST64(0x17d1d163d1c6b2bf), CONST64(0xe4a5a5aea5410b57), CONST64(0xa1e2e2afe2434dd9), CONST64(0x4e616199612ff8c2), +CONST64(0x42b3b3f6b3f1457b), CONST64(0x342121842115a542), CONST64(0x089c9c4a9c94d625), CONST64(0xee1e1e781ef0663c), +CONST64(0x6143431143225286), CONST64(0xb1c7c73bc776fc93), CONST64(0x4ffcfcd7fcb32be5), CONST64(0x2404041004201408), +CONST64(0xe351515951b208a2), CONST64(0x2599995e99bcc72f), CONST64(0x226d6da96d4fc4da), CONST64(0x650d0d340d68391a), +CONST64(0x79fafacffa8335e9), CONST64(0x69dfdf5bdfb684a3), CONST64(0xa97e7ee57ed79bfc), CONST64(0x19242490243db448), +CONST64(0xfe3b3bec3bc5d776), CONST64(0x9aabab96ab313d4b), CONST64(0xf0cece1fce3ed181), CONST64(0x9911114411885522), +CONST64(0x838f8f068f0c8903), CONST64(0x044e4e254e4a6b9c), CONST64(0x66b7b7e6b7d15173), CONST64(0xe0ebeb8beb0b60cb), +CONST64(0xc13c3cf03cfdcc78), CONST64(0xfd81813e817cbf1f), CONST64(0x4094946a94d4fe35), CONST64(0x1cf7f7fbf7eb0cf3), +CONST64(0x18b9b9deb9a1676f), CONST64(0x8b13134c13985f26), CONST64(0x512c2cb02c7d9c58), CONST64(0x05d3d36bd3d6b8bb), +CONST64(0x8ce7e7bbe76b5cd3), CONST64(0x396e6ea56e57cbdc), CONST64(0xaac4c437c46ef395), CONST64(0x1b03030c03180f06), +CONST64(0xdc565645568a13ac), CONST64(0x5e44440d441a4988), CONST64(0xa07f7fe17fdf9efe), CONST64(0x88a9a99ea921374f), +CONST64(0x672a2aa82a4d8254), CONST64(0x0abbbbd6bbb16d6b), CONST64(0x87c1c123c146e29f), CONST64(0xf153535153a202a6), +CONST64(0x72dcdc57dcae8ba5), CONST64(0x530b0b2c0b582716), CONST64(0x019d9d4e9d9cd327), CONST64(0x2b6c6cad6c47c1d8), +CONST64(0xa43131c43195f562), CONST64(0xf37474cd7487b9e8), CONST64(0x15f6f6fff6e309f1), CONST64(0x4c464605460a438c), +CONST64(0xa5acac8aac092645), CONST64(0xb589891e893c970f), CONST64(0xb414145014a04428), CONST64(0xbae1e1a3e15b42df), +CONST64(0xa616165816b04e2c), CONST64(0xf73a3ae83acdd274), CONST64(0x066969b9696fd0d2), CONST64(0x4109092409482d12), +CONST64(0xd77070dd70a7ade0), CONST64(0x6fb6b6e2b6d95471), CONST64(0x1ed0d067d0ceb7bd), CONST64(0xd6eded93ed3b7ec7), +CONST64(0xe2cccc17cc2edb85), CONST64(0x68424215422a5784), CONST64(0x2c98985a98b4c22d), CONST64(0xeda4a4aaa4490e55), +CONST64(0x752828a0285d8850), CONST64(0x865c5c6d5cda31b8), CONST64(0x6bf8f8c7f8933fed), CONST64(0xc28686228644a411) +}; + +static const ulong64 sbox2[] = { +CONST64(0x30d818186018c078), CONST64(0x462623238c2305af), CONST64(0x91b8c6c63fc67ef9), CONST64(0xcdfbe8e887e8136f), +CONST64(0x13cb878726874ca1), CONST64(0x6d11b8b8dab8a962), CONST64(0x0209010104010805), CONST64(0x9e0d4f4f214f426e), +CONST64(0x6c9b3636d836adee), CONST64(0x51ffa6a6a2a65904), CONST64(0xb90cd2d26fd2debd), CONST64(0xf70ef5f5f3f5fb06), +CONST64(0xf2967979f979ef80), CONST64(0xde306f6fa16f5fce), CONST64(0x3f6d91917e91fcef), CONST64(0xa4f852525552aa07), +CONST64(0xc04760609d6027fd), CONST64(0x6535bcbccabc8976), CONST64(0x2b379b9b569baccd), CONST64(0x018a8e8e028e048c), +CONST64(0x5bd2a3a3b6a37115), CONST64(0x186c0c0c300c603c), CONST64(0xf6847b7bf17bff8a), CONST64(0x6a803535d435b5e1), +CONST64(0x3af51d1d741de869), CONST64(0xddb3e0e0a7e05347), CONST64(0xb321d7d77bd7f6ac), CONST64(0x999cc2c22fc25eed), +CONST64(0x5c432e2eb82e6d96), CONST64(0x96294b4b314b627a), CONST64(0xe15dfefedffea321), CONST64(0xaed5575741578216), +CONST64(0x2abd15155415a841), CONST64(0xeee87777c1779fb6), CONST64(0x6e923737dc37a5eb), CONST64(0xd79ee5e5b3e57b56), +CONST64(0x23139f9f469f8cd9), CONST64(0xfd23f0f0e7f0d317), CONST64(0x94204a4a354a6a7f), CONST64(0xa944dada4fda9e95), +CONST64(0xb0a258587d58fa25), CONST64(0x8fcfc9c903c906ca), CONST64(0x527c2929a429558d), CONST64(0x145a0a0a280a5022), +CONST64(0x7f50b1b1feb1e14f), CONST64(0x5dc9a0a0baa0691a), CONST64(0xd6146b6bb16b7fda), CONST64(0x17d985852e855cab), +CONST64(0x673cbdbdcebd8173), CONST64(0xba8f5d5d695dd234), CONST64(0x2090101040108050), CONST64(0xf507f4f4f7f4f303), +CONST64(0x8bddcbcb0bcb16c0), CONST64(0x7cd33e3ef83eedc6), CONST64(0x0a2d050514052811), CONST64(0xce78676781671fe6), +CONST64(0xd597e4e4b7e47353), CONST64(0x4e0227279c2725bb), CONST64(0x8273414119413258), CONST64(0x0ba78b8b168b2c9d), +CONST64(0x53f6a7a7a6a75101), CONST64(0xfab27d7de97dcf94), CONST64(0x374995956e95dcfb), CONST64(0xad56d8d847d88e9f), +CONST64(0xeb70fbfbcbfb8b30), CONST64(0xc1cdeeee9fee2371), CONST64(0xf8bb7c7ced7cc791), CONST64(0xcc716666856617e3), +CONST64(0xa77bdddd53dda68e), CONST64(0x2eaf17175c17b84b), CONST64(0x8e45474701470246), CONST64(0x211a9e9e429e84dc), +CONST64(0x89d4caca0fca1ec5), CONST64(0x5a582d2db42d7599), CONST64(0x632ebfbfc6bf9179), CONST64(0x0e3f07071c07381b), +CONST64(0x47acadad8ead0123), CONST64(0xb4b05a5a755aea2f), CONST64(0x1bef838336836cb5), CONST64(0x66b63333cc3385ff), +CONST64(0xc65c636391633ff2), CONST64(0x041202020802100a), CONST64(0x4993aaaa92aa3938), CONST64(0xe2de7171d971afa8), +CONST64(0x8dc6c8c807c80ecf), CONST64(0x32d119196419c87d), CONST64(0x923b494939497270), CONST64(0xaf5fd9d943d9869a), +CONST64(0xf931f2f2eff2c31d), CONST64(0xdba8e3e3abe34b48), CONST64(0xb6b95b5b715be22a), CONST64(0x0dbc88881a883492), +CONST64(0x293e9a9a529aa4c8), CONST64(0x4c0b262698262dbe), CONST64(0x64bf3232c8328dfa), CONST64(0x7d59b0b0fab0e94a), +CONST64(0xcff2e9e983e91b6a), CONST64(0x1e770f0f3c0f7833), CONST64(0xb733d5d573d5e6a6), CONST64(0x1df480803a8074ba), +CONST64(0x6127bebec2be997c), CONST64(0x87ebcdcd13cd26de), CONST64(0x68893434d034bde4), CONST64(0x903248483d487a75), +CONST64(0xe354ffffdbffab24), CONST64(0xf48d7a7af57af78f), CONST64(0x3d6490907a90f4ea), CONST64(0xbe9d5f5f615fc23e), +CONST64(0x403d202080201da0), CONST64(0xd00f6868bd6867d5), CONST64(0x34ca1a1a681ad072), CONST64(0x41b7aeae82ae192c), +CONST64(0x757db4b4eab4c95e), CONST64(0xa8ce54544d549a19), CONST64(0x3b7f93937693ece5), CONST64(0x442f222288220daa), +CONST64(0xc86364648d6407e9), CONST64(0xff2af1f1e3f1db12), CONST64(0xe6cc7373d173bfa2), CONST64(0x248212124812905a), +CONST64(0x807a40401d403a5d), CONST64(0x1048080820084028), CONST64(0x9b95c3c32bc356e8), CONST64(0xc5dfecec97ec337b), +CONST64(0xab4ddbdb4bdb9690), CONST64(0x5fc0a1a1bea1611f), CONST64(0x07918d8d0e8d1c83), CONST64(0x7ac83d3df43df5c9), +CONST64(0x335b97976697ccf1), CONST64(0x0000000000000000), CONST64(0x83f9cfcf1bcf36d4), CONST64(0x566e2b2bac2b4587), +CONST64(0xece17676c57697b3), CONST64(0x19e68282328264b0), CONST64(0xb128d6d67fd6fea9), CONST64(0x36c31b1b6c1bd877), +CONST64(0x7774b5b5eeb5c15b), CONST64(0x43beafaf86af1129), CONST64(0xd41d6a6ab56a77df), CONST64(0xa0ea50505d50ba0d), +CONST64(0x8a5745450945124c), CONST64(0xfb38f3f3ebf3cb18), CONST64(0x60ad3030c0309df0), CONST64(0xc3c4efef9bef2b74), +CONST64(0x7eda3f3ffc3fe5c3), CONST64(0xaac755554955921c), CONST64(0x59dba2a2b2a27910), CONST64(0xc9e9eaea8fea0365), +CONST64(0xca6a656589650fec), CONST64(0x6903babad2bab968), CONST64(0x5e4a2f2fbc2f6593), CONST64(0x9d8ec0c027c04ee7), +CONST64(0xa160dede5fdebe81), CONST64(0x38fc1c1c701ce06c), CONST64(0xe746fdfdd3fdbb2e), CONST64(0x9a1f4d4d294d5264), +CONST64(0x397692927292e4e0), CONST64(0xeafa7575c9758fbc), CONST64(0x0c3606061806301e), CONST64(0x09ae8a8a128a2498), +CONST64(0x794bb2b2f2b2f940), CONST64(0xd185e6e6bfe66359), CONST64(0x1c7e0e0e380e7036), CONST64(0x3ee71f1f7c1ff863), +CONST64(0xc4556262956237f7), CONST64(0xb53ad4d477d4eea3), CONST64(0x4d81a8a89aa82932), CONST64(0x315296966296c4f4), +CONST64(0xef62f9f9c3f99b3a), CONST64(0x97a3c5c533c566f6), CONST64(0x4a102525942535b1), CONST64(0xb2ab59597959f220), +CONST64(0x15d084842a8454ae), CONST64(0xe4c57272d572b7a7), CONST64(0x72ec3939e439d5dd), CONST64(0x98164c4c2d4c5a61), +CONST64(0xbc945e5e655eca3b), CONST64(0xf09f7878fd78e785), CONST64(0x70e53838e038ddd8), CONST64(0x05988c8c0a8c1486), +CONST64(0xbf17d1d163d1c6b2), CONST64(0x57e4a5a5aea5410b), CONST64(0xd9a1e2e2afe2434d), CONST64(0xc24e616199612ff8), +CONST64(0x7b42b3b3f6b3f145), CONST64(0x42342121842115a5), CONST64(0x25089c9c4a9c94d6), CONST64(0x3cee1e1e781ef066), +CONST64(0x8661434311432252), CONST64(0x93b1c7c73bc776fc), CONST64(0xe54ffcfcd7fcb32b), CONST64(0x0824040410042014), +CONST64(0xa2e351515951b208), CONST64(0x2f2599995e99bcc7), CONST64(0xda226d6da96d4fc4), CONST64(0x1a650d0d340d6839), +CONST64(0xe979fafacffa8335), CONST64(0xa369dfdf5bdfb684), CONST64(0xfca97e7ee57ed79b), CONST64(0x4819242490243db4), +CONST64(0x76fe3b3bec3bc5d7), CONST64(0x4b9aabab96ab313d), CONST64(0x81f0cece1fce3ed1), CONST64(0x2299111144118855), +CONST64(0x03838f8f068f0c89), CONST64(0x9c044e4e254e4a6b), CONST64(0x7366b7b7e6b7d151), CONST64(0xcbe0ebeb8beb0b60), +CONST64(0x78c13c3cf03cfdcc), CONST64(0x1ffd81813e817cbf), CONST64(0x354094946a94d4fe), CONST64(0xf31cf7f7fbf7eb0c), +CONST64(0x6f18b9b9deb9a167), CONST64(0x268b13134c13985f), CONST64(0x58512c2cb02c7d9c), CONST64(0xbb05d3d36bd3d6b8), +CONST64(0xd38ce7e7bbe76b5c), CONST64(0xdc396e6ea56e57cb), CONST64(0x95aac4c437c46ef3), CONST64(0x061b03030c03180f), +CONST64(0xacdc565645568a13), CONST64(0x885e44440d441a49), CONST64(0xfea07f7fe17fdf9e), CONST64(0x4f88a9a99ea92137), +CONST64(0x54672a2aa82a4d82), CONST64(0x6b0abbbbd6bbb16d), CONST64(0x9f87c1c123c146e2), CONST64(0xa6f153535153a202), +CONST64(0xa572dcdc57dcae8b), CONST64(0x16530b0b2c0b5827), CONST64(0x27019d9d4e9d9cd3), CONST64(0xd82b6c6cad6c47c1), +CONST64(0x62a43131c43195f5), CONST64(0xe8f37474cd7487b9), CONST64(0xf115f6f6fff6e309), CONST64(0x8c4c464605460a43), +CONST64(0x45a5acac8aac0926), CONST64(0x0fb589891e893c97), CONST64(0x28b414145014a044), CONST64(0xdfbae1e1a3e15b42), +CONST64(0x2ca616165816b04e), CONST64(0x74f73a3ae83acdd2), CONST64(0xd2066969b9696fd0), CONST64(0x124109092409482d), +CONST64(0xe0d77070dd70a7ad), CONST64(0x716fb6b6e2b6d954), CONST64(0xbd1ed0d067d0ceb7), CONST64(0xc7d6eded93ed3b7e), +CONST64(0x85e2cccc17cc2edb), CONST64(0x8468424215422a57), CONST64(0x2d2c98985a98b4c2), CONST64(0x55eda4a4aaa4490e), +CONST64(0x50752828a0285d88), CONST64(0xb8865c5c6d5cda31), CONST64(0xed6bf8f8c7f8933f), CONST64(0x11c28686228644a4) +}; + +static const ulong64 sbox3[] = { +CONST64(0x7830d818186018c0), CONST64(0xaf462623238c2305), CONST64(0xf991b8c6c63fc67e), CONST64(0x6fcdfbe8e887e813), +CONST64(0xa113cb878726874c), CONST64(0x626d11b8b8dab8a9), CONST64(0x0502090101040108), CONST64(0x6e9e0d4f4f214f42), +CONST64(0xee6c9b3636d836ad), CONST64(0x0451ffa6a6a2a659), CONST64(0xbdb90cd2d26fd2de), CONST64(0x06f70ef5f5f3f5fb), +CONST64(0x80f2967979f979ef), CONST64(0xcede306f6fa16f5f), CONST64(0xef3f6d91917e91fc), CONST64(0x07a4f852525552aa), +CONST64(0xfdc04760609d6027), CONST64(0x766535bcbccabc89), CONST64(0xcd2b379b9b569bac), CONST64(0x8c018a8e8e028e04), +CONST64(0x155bd2a3a3b6a371), CONST64(0x3c186c0c0c300c60), CONST64(0x8af6847b7bf17bff), CONST64(0xe16a803535d435b5), +CONST64(0x693af51d1d741de8), CONST64(0x47ddb3e0e0a7e053), CONST64(0xacb321d7d77bd7f6), CONST64(0xed999cc2c22fc25e), +CONST64(0x965c432e2eb82e6d), CONST64(0x7a96294b4b314b62), CONST64(0x21e15dfefedffea3), CONST64(0x16aed55757415782), +CONST64(0x412abd15155415a8), CONST64(0xb6eee87777c1779f), CONST64(0xeb6e923737dc37a5), CONST64(0x56d79ee5e5b3e57b), +CONST64(0xd923139f9f469f8c), CONST64(0x17fd23f0f0e7f0d3), CONST64(0x7f94204a4a354a6a), CONST64(0x95a944dada4fda9e), +CONST64(0x25b0a258587d58fa), CONST64(0xca8fcfc9c903c906), CONST64(0x8d527c2929a42955), CONST64(0x22145a0a0a280a50), +CONST64(0x4f7f50b1b1feb1e1), CONST64(0x1a5dc9a0a0baa069), CONST64(0xdad6146b6bb16b7f), CONST64(0xab17d985852e855c), +CONST64(0x73673cbdbdcebd81), CONST64(0x34ba8f5d5d695dd2), CONST64(0x5020901010401080), CONST64(0x03f507f4f4f7f4f3), +CONST64(0xc08bddcbcb0bcb16), CONST64(0xc67cd33e3ef83eed), CONST64(0x110a2d0505140528), CONST64(0xe6ce78676781671f), +CONST64(0x53d597e4e4b7e473), CONST64(0xbb4e0227279c2725), CONST64(0x5882734141194132), CONST64(0x9d0ba78b8b168b2c), +CONST64(0x0153f6a7a7a6a751), CONST64(0x94fab27d7de97dcf), CONST64(0xfb374995956e95dc), CONST64(0x9fad56d8d847d88e), +CONST64(0x30eb70fbfbcbfb8b), CONST64(0x71c1cdeeee9fee23), CONST64(0x91f8bb7c7ced7cc7), CONST64(0xe3cc716666856617), +CONST64(0x8ea77bdddd53dda6), CONST64(0x4b2eaf17175c17b8), CONST64(0x468e454747014702), CONST64(0xdc211a9e9e429e84), +CONST64(0xc589d4caca0fca1e), CONST64(0x995a582d2db42d75), CONST64(0x79632ebfbfc6bf91), CONST64(0x1b0e3f07071c0738), +CONST64(0x2347acadad8ead01), CONST64(0x2fb4b05a5a755aea), CONST64(0xb51bef838336836c), CONST64(0xff66b63333cc3385), +CONST64(0xf2c65c636391633f), CONST64(0x0a04120202080210), CONST64(0x384993aaaa92aa39), CONST64(0xa8e2de7171d971af), +CONST64(0xcf8dc6c8c807c80e), CONST64(0x7d32d119196419c8), CONST64(0x70923b4949394972), CONST64(0x9aaf5fd9d943d986), +CONST64(0x1df931f2f2eff2c3), CONST64(0x48dba8e3e3abe34b), CONST64(0x2ab6b95b5b715be2), CONST64(0x920dbc88881a8834), +CONST64(0xc8293e9a9a529aa4), CONST64(0xbe4c0b262698262d), CONST64(0xfa64bf3232c8328d), CONST64(0x4a7d59b0b0fab0e9), +CONST64(0x6acff2e9e983e91b), CONST64(0x331e770f0f3c0f78), CONST64(0xa6b733d5d573d5e6), CONST64(0xba1df480803a8074), +CONST64(0x7c6127bebec2be99), CONST64(0xde87ebcdcd13cd26), CONST64(0xe468893434d034bd), CONST64(0x75903248483d487a), +CONST64(0x24e354ffffdbffab), CONST64(0x8ff48d7a7af57af7), CONST64(0xea3d6490907a90f4), CONST64(0x3ebe9d5f5f615fc2), +CONST64(0xa0403d202080201d), CONST64(0xd5d00f6868bd6867), CONST64(0x7234ca1a1a681ad0), CONST64(0x2c41b7aeae82ae19), +CONST64(0x5e757db4b4eab4c9), CONST64(0x19a8ce54544d549a), CONST64(0xe53b7f93937693ec), CONST64(0xaa442f222288220d), +CONST64(0xe9c86364648d6407), CONST64(0x12ff2af1f1e3f1db), CONST64(0xa2e6cc7373d173bf), CONST64(0x5a24821212481290), +CONST64(0x5d807a40401d403a), CONST64(0x2810480808200840), CONST64(0xe89b95c3c32bc356), CONST64(0x7bc5dfecec97ec33), +CONST64(0x90ab4ddbdb4bdb96), CONST64(0x1f5fc0a1a1bea161), CONST64(0x8307918d8d0e8d1c), CONST64(0xc97ac83d3df43df5), +CONST64(0xf1335b97976697cc), CONST64(0x0000000000000000), CONST64(0xd483f9cfcf1bcf36), CONST64(0x87566e2b2bac2b45), +CONST64(0xb3ece17676c57697), CONST64(0xb019e68282328264), CONST64(0xa9b128d6d67fd6fe), CONST64(0x7736c31b1b6c1bd8), +CONST64(0x5b7774b5b5eeb5c1), CONST64(0x2943beafaf86af11), CONST64(0xdfd41d6a6ab56a77), CONST64(0x0da0ea50505d50ba), +CONST64(0x4c8a574545094512), CONST64(0x18fb38f3f3ebf3cb), CONST64(0xf060ad3030c0309d), CONST64(0x74c3c4efef9bef2b), +CONST64(0xc37eda3f3ffc3fe5), CONST64(0x1caac75555495592), CONST64(0x1059dba2a2b2a279), CONST64(0x65c9e9eaea8fea03), +CONST64(0xecca6a656589650f), CONST64(0x686903babad2bab9), CONST64(0x935e4a2f2fbc2f65), CONST64(0xe79d8ec0c027c04e), +CONST64(0x81a160dede5fdebe), CONST64(0x6c38fc1c1c701ce0), CONST64(0x2ee746fdfdd3fdbb), CONST64(0x649a1f4d4d294d52), +CONST64(0xe0397692927292e4), CONST64(0xbceafa7575c9758f), CONST64(0x1e0c360606180630), CONST64(0x9809ae8a8a128a24), +CONST64(0x40794bb2b2f2b2f9), CONST64(0x59d185e6e6bfe663), CONST64(0x361c7e0e0e380e70), CONST64(0x633ee71f1f7c1ff8), +CONST64(0xf7c4556262956237), CONST64(0xa3b53ad4d477d4ee), CONST64(0x324d81a8a89aa829), CONST64(0xf4315296966296c4), +CONST64(0x3aef62f9f9c3f99b), CONST64(0xf697a3c5c533c566), CONST64(0xb14a102525942535), CONST64(0x20b2ab59597959f2), +CONST64(0xae15d084842a8454), CONST64(0xa7e4c57272d572b7), CONST64(0xdd72ec3939e439d5), CONST64(0x6198164c4c2d4c5a), +CONST64(0x3bbc945e5e655eca), CONST64(0x85f09f7878fd78e7), CONST64(0xd870e53838e038dd), CONST64(0x8605988c8c0a8c14), +CONST64(0xb2bf17d1d163d1c6), CONST64(0x0b57e4a5a5aea541), CONST64(0x4dd9a1e2e2afe243), CONST64(0xf8c24e616199612f), +CONST64(0x457b42b3b3f6b3f1), CONST64(0xa542342121842115), CONST64(0xd625089c9c4a9c94), CONST64(0x663cee1e1e781ef0), +CONST64(0x5286614343114322), CONST64(0xfc93b1c7c73bc776), CONST64(0x2be54ffcfcd7fcb3), CONST64(0x1408240404100420), +CONST64(0x08a2e351515951b2), CONST64(0xc72f2599995e99bc), CONST64(0xc4da226d6da96d4f), CONST64(0x391a650d0d340d68), +CONST64(0x35e979fafacffa83), CONST64(0x84a369dfdf5bdfb6), CONST64(0x9bfca97e7ee57ed7), CONST64(0xb44819242490243d), +CONST64(0xd776fe3b3bec3bc5), CONST64(0x3d4b9aabab96ab31), CONST64(0xd181f0cece1fce3e), CONST64(0x5522991111441188), +CONST64(0x8903838f8f068f0c), CONST64(0x6b9c044e4e254e4a), CONST64(0x517366b7b7e6b7d1), CONST64(0x60cbe0ebeb8beb0b), +CONST64(0xcc78c13c3cf03cfd), CONST64(0xbf1ffd81813e817c), CONST64(0xfe354094946a94d4), CONST64(0x0cf31cf7f7fbf7eb), +CONST64(0x676f18b9b9deb9a1), CONST64(0x5f268b13134c1398), CONST64(0x9c58512c2cb02c7d), CONST64(0xb8bb05d3d36bd3d6), +CONST64(0x5cd38ce7e7bbe76b), CONST64(0xcbdc396e6ea56e57), CONST64(0xf395aac4c437c46e), CONST64(0x0f061b03030c0318), +CONST64(0x13acdc565645568a), CONST64(0x49885e44440d441a), CONST64(0x9efea07f7fe17fdf), CONST64(0x374f88a9a99ea921), +CONST64(0x8254672a2aa82a4d), CONST64(0x6d6b0abbbbd6bbb1), CONST64(0xe29f87c1c123c146), CONST64(0x02a6f153535153a2), +CONST64(0x8ba572dcdc57dcae), CONST64(0x2716530b0b2c0b58), CONST64(0xd327019d9d4e9d9c), CONST64(0xc1d82b6c6cad6c47), +CONST64(0xf562a43131c43195), CONST64(0xb9e8f37474cd7487), CONST64(0x09f115f6f6fff6e3), CONST64(0x438c4c464605460a), +CONST64(0x2645a5acac8aac09), CONST64(0x970fb589891e893c), CONST64(0x4428b414145014a0), CONST64(0x42dfbae1e1a3e15b), +CONST64(0x4e2ca616165816b0), CONST64(0xd274f73a3ae83acd), CONST64(0xd0d2066969b9696f), CONST64(0x2d12410909240948), +CONST64(0xade0d77070dd70a7), CONST64(0x54716fb6b6e2b6d9), CONST64(0xb7bd1ed0d067d0ce), CONST64(0x7ec7d6eded93ed3b), +CONST64(0xdb85e2cccc17cc2e), CONST64(0x578468424215422a), CONST64(0xc22d2c98985a98b4), CONST64(0x0e55eda4a4aaa449), +CONST64(0x8850752828a0285d), CONST64(0x31b8865c5c6d5cda), CONST64(0x3fed6bf8f8c7f893), CONST64(0xa411c28686228644) +}; + +static const ulong64 sbox4[] = { +CONST64(0xc07830d818186018), CONST64(0x05af462623238c23), CONST64(0x7ef991b8c6c63fc6), CONST64(0x136fcdfbe8e887e8), +CONST64(0x4ca113cb87872687), CONST64(0xa9626d11b8b8dab8), CONST64(0x0805020901010401), CONST64(0x426e9e0d4f4f214f), +CONST64(0xadee6c9b3636d836), CONST64(0x590451ffa6a6a2a6), CONST64(0xdebdb90cd2d26fd2), CONST64(0xfb06f70ef5f5f3f5), +CONST64(0xef80f2967979f979), CONST64(0x5fcede306f6fa16f), CONST64(0xfcef3f6d91917e91), CONST64(0xaa07a4f852525552), +CONST64(0x27fdc04760609d60), CONST64(0x89766535bcbccabc), CONST64(0xaccd2b379b9b569b), CONST64(0x048c018a8e8e028e), +CONST64(0x71155bd2a3a3b6a3), CONST64(0x603c186c0c0c300c), CONST64(0xff8af6847b7bf17b), CONST64(0xb5e16a803535d435), +CONST64(0xe8693af51d1d741d), CONST64(0x5347ddb3e0e0a7e0), CONST64(0xf6acb321d7d77bd7), CONST64(0x5eed999cc2c22fc2), +CONST64(0x6d965c432e2eb82e), CONST64(0x627a96294b4b314b), CONST64(0xa321e15dfefedffe), CONST64(0x8216aed557574157), +CONST64(0xa8412abd15155415), CONST64(0x9fb6eee87777c177), CONST64(0xa5eb6e923737dc37), CONST64(0x7b56d79ee5e5b3e5), +CONST64(0x8cd923139f9f469f), CONST64(0xd317fd23f0f0e7f0), CONST64(0x6a7f94204a4a354a), CONST64(0x9e95a944dada4fda), +CONST64(0xfa25b0a258587d58), CONST64(0x06ca8fcfc9c903c9), CONST64(0x558d527c2929a429), CONST64(0x5022145a0a0a280a), +CONST64(0xe14f7f50b1b1feb1), CONST64(0x691a5dc9a0a0baa0), CONST64(0x7fdad6146b6bb16b), CONST64(0x5cab17d985852e85), +CONST64(0x8173673cbdbdcebd), CONST64(0xd234ba8f5d5d695d), CONST64(0x8050209010104010), CONST64(0xf303f507f4f4f7f4), +CONST64(0x16c08bddcbcb0bcb), CONST64(0xedc67cd33e3ef83e), CONST64(0x28110a2d05051405), CONST64(0x1fe6ce7867678167), +CONST64(0x7353d597e4e4b7e4), CONST64(0x25bb4e0227279c27), CONST64(0x3258827341411941), CONST64(0x2c9d0ba78b8b168b), +CONST64(0x510153f6a7a7a6a7), CONST64(0xcf94fab27d7de97d), CONST64(0xdcfb374995956e95), CONST64(0x8e9fad56d8d847d8), +CONST64(0x8b30eb70fbfbcbfb), CONST64(0x2371c1cdeeee9fee), CONST64(0xc791f8bb7c7ced7c), CONST64(0x17e3cc7166668566), +CONST64(0xa68ea77bdddd53dd), CONST64(0xb84b2eaf17175c17), CONST64(0x02468e4547470147), CONST64(0x84dc211a9e9e429e), +CONST64(0x1ec589d4caca0fca), CONST64(0x75995a582d2db42d), CONST64(0x9179632ebfbfc6bf), CONST64(0x381b0e3f07071c07), +CONST64(0x012347acadad8ead), CONST64(0xea2fb4b05a5a755a), CONST64(0x6cb51bef83833683), CONST64(0x85ff66b63333cc33), +CONST64(0x3ff2c65c63639163), CONST64(0x100a041202020802), CONST64(0x39384993aaaa92aa), CONST64(0xafa8e2de7171d971), +CONST64(0x0ecf8dc6c8c807c8), CONST64(0xc87d32d119196419), CONST64(0x7270923b49493949), CONST64(0x869aaf5fd9d943d9), +CONST64(0xc31df931f2f2eff2), CONST64(0x4b48dba8e3e3abe3), CONST64(0xe22ab6b95b5b715b), CONST64(0x34920dbc88881a88), +CONST64(0xa4c8293e9a9a529a), CONST64(0x2dbe4c0b26269826), CONST64(0x8dfa64bf3232c832), CONST64(0xe94a7d59b0b0fab0), +CONST64(0x1b6acff2e9e983e9), CONST64(0x78331e770f0f3c0f), CONST64(0xe6a6b733d5d573d5), CONST64(0x74ba1df480803a80), +CONST64(0x997c6127bebec2be), CONST64(0x26de87ebcdcd13cd), CONST64(0xbde468893434d034), CONST64(0x7a75903248483d48), +CONST64(0xab24e354ffffdbff), CONST64(0xf78ff48d7a7af57a), CONST64(0xf4ea3d6490907a90), CONST64(0xc23ebe9d5f5f615f), +CONST64(0x1da0403d20208020), CONST64(0x67d5d00f6868bd68), CONST64(0xd07234ca1a1a681a), CONST64(0x192c41b7aeae82ae), +CONST64(0xc95e757db4b4eab4), CONST64(0x9a19a8ce54544d54), CONST64(0xece53b7f93937693), CONST64(0x0daa442f22228822), +CONST64(0x07e9c86364648d64), CONST64(0xdb12ff2af1f1e3f1), CONST64(0xbfa2e6cc7373d173), CONST64(0x905a248212124812), +CONST64(0x3a5d807a40401d40), CONST64(0x4028104808082008), CONST64(0x56e89b95c3c32bc3), CONST64(0x337bc5dfecec97ec), +CONST64(0x9690ab4ddbdb4bdb), CONST64(0x611f5fc0a1a1bea1), CONST64(0x1c8307918d8d0e8d), CONST64(0xf5c97ac83d3df43d), +CONST64(0xccf1335b97976697), CONST64(0x0000000000000000), CONST64(0x36d483f9cfcf1bcf), CONST64(0x4587566e2b2bac2b), +CONST64(0x97b3ece17676c576), CONST64(0x64b019e682823282), CONST64(0xfea9b128d6d67fd6), CONST64(0xd87736c31b1b6c1b), +CONST64(0xc15b7774b5b5eeb5), CONST64(0x112943beafaf86af), CONST64(0x77dfd41d6a6ab56a), CONST64(0xba0da0ea50505d50), +CONST64(0x124c8a5745450945), CONST64(0xcb18fb38f3f3ebf3), CONST64(0x9df060ad3030c030), CONST64(0x2b74c3c4efef9bef), +CONST64(0xe5c37eda3f3ffc3f), CONST64(0x921caac755554955), CONST64(0x791059dba2a2b2a2), CONST64(0x0365c9e9eaea8fea), +CONST64(0x0fecca6a65658965), CONST64(0xb9686903babad2ba), CONST64(0x65935e4a2f2fbc2f), CONST64(0x4ee79d8ec0c027c0), +CONST64(0xbe81a160dede5fde), CONST64(0xe06c38fc1c1c701c), CONST64(0xbb2ee746fdfdd3fd), CONST64(0x52649a1f4d4d294d), +CONST64(0xe4e0397692927292), CONST64(0x8fbceafa7575c975), CONST64(0x301e0c3606061806), CONST64(0x249809ae8a8a128a), +CONST64(0xf940794bb2b2f2b2), CONST64(0x6359d185e6e6bfe6), CONST64(0x70361c7e0e0e380e), CONST64(0xf8633ee71f1f7c1f), +CONST64(0x37f7c45562629562), CONST64(0xeea3b53ad4d477d4), CONST64(0x29324d81a8a89aa8), CONST64(0xc4f4315296966296), +CONST64(0x9b3aef62f9f9c3f9), CONST64(0x66f697a3c5c533c5), CONST64(0x35b14a1025259425), CONST64(0xf220b2ab59597959), +CONST64(0x54ae15d084842a84), CONST64(0xb7a7e4c57272d572), CONST64(0xd5dd72ec3939e439), CONST64(0x5a6198164c4c2d4c), +CONST64(0xca3bbc945e5e655e), CONST64(0xe785f09f7878fd78), CONST64(0xddd870e53838e038), CONST64(0x148605988c8c0a8c), +CONST64(0xc6b2bf17d1d163d1), CONST64(0x410b57e4a5a5aea5), CONST64(0x434dd9a1e2e2afe2), CONST64(0x2ff8c24e61619961), +CONST64(0xf1457b42b3b3f6b3), CONST64(0x15a5423421218421), CONST64(0x94d625089c9c4a9c), CONST64(0xf0663cee1e1e781e), +CONST64(0x2252866143431143), CONST64(0x76fc93b1c7c73bc7), CONST64(0xb32be54ffcfcd7fc), CONST64(0x2014082404041004), +CONST64(0xb208a2e351515951), CONST64(0xbcc72f2599995e99), CONST64(0x4fc4da226d6da96d), CONST64(0x68391a650d0d340d), +CONST64(0x8335e979fafacffa), CONST64(0xb684a369dfdf5bdf), CONST64(0xd79bfca97e7ee57e), CONST64(0x3db4481924249024), +CONST64(0xc5d776fe3b3bec3b), CONST64(0x313d4b9aabab96ab), CONST64(0x3ed181f0cece1fce), CONST64(0x8855229911114411), +CONST64(0x0c8903838f8f068f), CONST64(0x4a6b9c044e4e254e), CONST64(0xd1517366b7b7e6b7), CONST64(0x0b60cbe0ebeb8beb), +CONST64(0xfdcc78c13c3cf03c), CONST64(0x7cbf1ffd81813e81), CONST64(0xd4fe354094946a94), CONST64(0xeb0cf31cf7f7fbf7), +CONST64(0xa1676f18b9b9deb9), CONST64(0x985f268b13134c13), CONST64(0x7d9c58512c2cb02c), CONST64(0xd6b8bb05d3d36bd3), +CONST64(0x6b5cd38ce7e7bbe7), CONST64(0x57cbdc396e6ea56e), CONST64(0x6ef395aac4c437c4), CONST64(0x180f061b03030c03), +CONST64(0x8a13acdc56564556), CONST64(0x1a49885e44440d44), CONST64(0xdf9efea07f7fe17f), CONST64(0x21374f88a9a99ea9), +CONST64(0x4d8254672a2aa82a), CONST64(0xb16d6b0abbbbd6bb), CONST64(0x46e29f87c1c123c1), CONST64(0xa202a6f153535153), +CONST64(0xae8ba572dcdc57dc), CONST64(0x582716530b0b2c0b), CONST64(0x9cd327019d9d4e9d), CONST64(0x47c1d82b6c6cad6c), +CONST64(0x95f562a43131c431), CONST64(0x87b9e8f37474cd74), CONST64(0xe309f115f6f6fff6), CONST64(0x0a438c4c46460546), +CONST64(0x092645a5acac8aac), CONST64(0x3c970fb589891e89), CONST64(0xa04428b414145014), CONST64(0x5b42dfbae1e1a3e1), +CONST64(0xb04e2ca616165816), CONST64(0xcdd274f73a3ae83a), CONST64(0x6fd0d2066969b969), CONST64(0x482d124109092409), +CONST64(0xa7ade0d77070dd70), CONST64(0xd954716fb6b6e2b6), CONST64(0xceb7bd1ed0d067d0), CONST64(0x3b7ec7d6eded93ed), +CONST64(0x2edb85e2cccc17cc), CONST64(0x2a57846842421542), CONST64(0xb4c22d2c98985a98), CONST64(0x490e55eda4a4aaa4), +CONST64(0x5d8850752828a028), CONST64(0xda31b8865c5c6d5c), CONST64(0x933fed6bf8f8c7f8), CONST64(0x44a411c286862286) +}; + +static const ulong64 sbox5[] = { +CONST64(0x18c07830d8181860), CONST64(0x2305af462623238c), CONST64(0xc67ef991b8c6c63f), CONST64(0xe8136fcdfbe8e887), +CONST64(0x874ca113cb878726), CONST64(0xb8a9626d11b8b8da), CONST64(0x0108050209010104), CONST64(0x4f426e9e0d4f4f21), +CONST64(0x36adee6c9b3636d8), CONST64(0xa6590451ffa6a6a2), CONST64(0xd2debdb90cd2d26f), CONST64(0xf5fb06f70ef5f5f3), +CONST64(0x79ef80f2967979f9), CONST64(0x6f5fcede306f6fa1), CONST64(0x91fcef3f6d91917e), CONST64(0x52aa07a4f8525255), +CONST64(0x6027fdc04760609d), CONST64(0xbc89766535bcbcca), CONST64(0x9baccd2b379b9b56), CONST64(0x8e048c018a8e8e02), +CONST64(0xa371155bd2a3a3b6), CONST64(0x0c603c186c0c0c30), CONST64(0x7bff8af6847b7bf1), CONST64(0x35b5e16a803535d4), +CONST64(0x1de8693af51d1d74), CONST64(0xe05347ddb3e0e0a7), CONST64(0xd7f6acb321d7d77b), CONST64(0xc25eed999cc2c22f), +CONST64(0x2e6d965c432e2eb8), CONST64(0x4b627a96294b4b31), CONST64(0xfea321e15dfefedf), CONST64(0x578216aed5575741), +CONST64(0x15a8412abd151554), CONST64(0x779fb6eee87777c1), CONST64(0x37a5eb6e923737dc), CONST64(0xe57b56d79ee5e5b3), +CONST64(0x9f8cd923139f9f46), CONST64(0xf0d317fd23f0f0e7), CONST64(0x4a6a7f94204a4a35), CONST64(0xda9e95a944dada4f), +CONST64(0x58fa25b0a258587d), CONST64(0xc906ca8fcfc9c903), CONST64(0x29558d527c2929a4), CONST64(0x0a5022145a0a0a28), +CONST64(0xb1e14f7f50b1b1fe), CONST64(0xa0691a5dc9a0a0ba), CONST64(0x6b7fdad6146b6bb1), CONST64(0x855cab17d985852e), +CONST64(0xbd8173673cbdbdce), CONST64(0x5dd234ba8f5d5d69), CONST64(0x1080502090101040), CONST64(0xf4f303f507f4f4f7), +CONST64(0xcb16c08bddcbcb0b), CONST64(0x3eedc67cd33e3ef8), CONST64(0x0528110a2d050514), CONST64(0x671fe6ce78676781), +CONST64(0xe47353d597e4e4b7), CONST64(0x2725bb4e0227279c), CONST64(0x4132588273414119), CONST64(0x8b2c9d0ba78b8b16), +CONST64(0xa7510153f6a7a7a6), CONST64(0x7dcf94fab27d7de9), CONST64(0x95dcfb374995956e), CONST64(0xd88e9fad56d8d847), +CONST64(0xfb8b30eb70fbfbcb), CONST64(0xee2371c1cdeeee9f), CONST64(0x7cc791f8bb7c7ced), CONST64(0x6617e3cc71666685), +CONST64(0xdda68ea77bdddd53), CONST64(0x17b84b2eaf17175c), CONST64(0x4702468e45474701), CONST64(0x9e84dc211a9e9e42), +CONST64(0xca1ec589d4caca0f), CONST64(0x2d75995a582d2db4), CONST64(0xbf9179632ebfbfc6), CONST64(0x07381b0e3f07071c), +CONST64(0xad012347acadad8e), CONST64(0x5aea2fb4b05a5a75), CONST64(0x836cb51bef838336), CONST64(0x3385ff66b63333cc), +CONST64(0x633ff2c65c636391), CONST64(0x02100a0412020208), CONST64(0xaa39384993aaaa92), CONST64(0x71afa8e2de7171d9), +CONST64(0xc80ecf8dc6c8c807), CONST64(0x19c87d32d1191964), CONST64(0x497270923b494939), CONST64(0xd9869aaf5fd9d943), +CONST64(0xf2c31df931f2f2ef), CONST64(0xe34b48dba8e3e3ab), CONST64(0x5be22ab6b95b5b71), CONST64(0x8834920dbc88881a), +CONST64(0x9aa4c8293e9a9a52), CONST64(0x262dbe4c0b262698), CONST64(0x328dfa64bf3232c8), CONST64(0xb0e94a7d59b0b0fa), +CONST64(0xe91b6acff2e9e983), CONST64(0x0f78331e770f0f3c), CONST64(0xd5e6a6b733d5d573), CONST64(0x8074ba1df480803a), +CONST64(0xbe997c6127bebec2), CONST64(0xcd26de87ebcdcd13), CONST64(0x34bde468893434d0), CONST64(0x487a75903248483d), +CONST64(0xffab24e354ffffdb), CONST64(0x7af78ff48d7a7af5), CONST64(0x90f4ea3d6490907a), CONST64(0x5fc23ebe9d5f5f61), +CONST64(0x201da0403d202080), CONST64(0x6867d5d00f6868bd), CONST64(0x1ad07234ca1a1a68), CONST64(0xae192c41b7aeae82), +CONST64(0xb4c95e757db4b4ea), CONST64(0x549a19a8ce54544d), CONST64(0x93ece53b7f939376), CONST64(0x220daa442f222288), +CONST64(0x6407e9c86364648d), CONST64(0xf1db12ff2af1f1e3), CONST64(0x73bfa2e6cc7373d1), CONST64(0x12905a2482121248), +CONST64(0x403a5d807a40401d), CONST64(0x0840281048080820), CONST64(0xc356e89b95c3c32b), CONST64(0xec337bc5dfecec97), +CONST64(0xdb9690ab4ddbdb4b), CONST64(0xa1611f5fc0a1a1be), CONST64(0x8d1c8307918d8d0e), CONST64(0x3df5c97ac83d3df4), +CONST64(0x97ccf1335b979766), CONST64(0x0000000000000000), CONST64(0xcf36d483f9cfcf1b), CONST64(0x2b4587566e2b2bac), +CONST64(0x7697b3ece17676c5), CONST64(0x8264b019e6828232), CONST64(0xd6fea9b128d6d67f), CONST64(0x1bd87736c31b1b6c), +CONST64(0xb5c15b7774b5b5ee), CONST64(0xaf112943beafaf86), CONST64(0x6a77dfd41d6a6ab5), CONST64(0x50ba0da0ea50505d), +CONST64(0x45124c8a57454509), CONST64(0xf3cb18fb38f3f3eb), CONST64(0x309df060ad3030c0), CONST64(0xef2b74c3c4efef9b), +CONST64(0x3fe5c37eda3f3ffc), CONST64(0x55921caac7555549), CONST64(0xa2791059dba2a2b2), CONST64(0xea0365c9e9eaea8f), +CONST64(0x650fecca6a656589), CONST64(0xbab9686903babad2), CONST64(0x2f65935e4a2f2fbc), CONST64(0xc04ee79d8ec0c027), +CONST64(0xdebe81a160dede5f), CONST64(0x1ce06c38fc1c1c70), CONST64(0xfdbb2ee746fdfdd3), CONST64(0x4d52649a1f4d4d29), +CONST64(0x92e4e03976929272), CONST64(0x758fbceafa7575c9), CONST64(0x06301e0c36060618), CONST64(0x8a249809ae8a8a12), +CONST64(0xb2f940794bb2b2f2), CONST64(0xe66359d185e6e6bf), CONST64(0x0e70361c7e0e0e38), CONST64(0x1ff8633ee71f1f7c), +CONST64(0x6237f7c455626295), CONST64(0xd4eea3b53ad4d477), CONST64(0xa829324d81a8a89a), CONST64(0x96c4f43152969662), +CONST64(0xf99b3aef62f9f9c3), CONST64(0xc566f697a3c5c533), CONST64(0x2535b14a10252594), CONST64(0x59f220b2ab595979), +CONST64(0x8454ae15d084842a), CONST64(0x72b7a7e4c57272d5), CONST64(0x39d5dd72ec3939e4), CONST64(0x4c5a6198164c4c2d), +CONST64(0x5eca3bbc945e5e65), CONST64(0x78e785f09f7878fd), CONST64(0x38ddd870e53838e0), CONST64(0x8c148605988c8c0a), +CONST64(0xd1c6b2bf17d1d163), CONST64(0xa5410b57e4a5a5ae), CONST64(0xe2434dd9a1e2e2af), CONST64(0x612ff8c24e616199), +CONST64(0xb3f1457b42b3b3f6), CONST64(0x2115a54234212184), CONST64(0x9c94d625089c9c4a), CONST64(0x1ef0663cee1e1e78), +CONST64(0x4322528661434311), CONST64(0xc776fc93b1c7c73b), CONST64(0xfcb32be54ffcfcd7), CONST64(0x0420140824040410), +CONST64(0x51b208a2e3515159), CONST64(0x99bcc72f2599995e), CONST64(0x6d4fc4da226d6da9), CONST64(0x0d68391a650d0d34), +CONST64(0xfa8335e979fafacf), CONST64(0xdfb684a369dfdf5b), CONST64(0x7ed79bfca97e7ee5), CONST64(0x243db44819242490), +CONST64(0x3bc5d776fe3b3bec), CONST64(0xab313d4b9aabab96), CONST64(0xce3ed181f0cece1f), CONST64(0x1188552299111144), +CONST64(0x8f0c8903838f8f06), CONST64(0x4e4a6b9c044e4e25), CONST64(0xb7d1517366b7b7e6), CONST64(0xeb0b60cbe0ebeb8b), +CONST64(0x3cfdcc78c13c3cf0), CONST64(0x817cbf1ffd81813e), CONST64(0x94d4fe354094946a), CONST64(0xf7eb0cf31cf7f7fb), +CONST64(0xb9a1676f18b9b9de), CONST64(0x13985f268b13134c), CONST64(0x2c7d9c58512c2cb0), CONST64(0xd3d6b8bb05d3d36b), +CONST64(0xe76b5cd38ce7e7bb), CONST64(0x6e57cbdc396e6ea5), CONST64(0xc46ef395aac4c437), CONST64(0x03180f061b03030c), +CONST64(0x568a13acdc565645), CONST64(0x441a49885e44440d), CONST64(0x7fdf9efea07f7fe1), CONST64(0xa921374f88a9a99e), +CONST64(0x2a4d8254672a2aa8), CONST64(0xbbb16d6b0abbbbd6), CONST64(0xc146e29f87c1c123), CONST64(0x53a202a6f1535351), +CONST64(0xdcae8ba572dcdc57), CONST64(0x0b582716530b0b2c), CONST64(0x9d9cd327019d9d4e), CONST64(0x6c47c1d82b6c6cad), +CONST64(0x3195f562a43131c4), CONST64(0x7487b9e8f37474cd), CONST64(0xf6e309f115f6f6ff), CONST64(0x460a438c4c464605), +CONST64(0xac092645a5acac8a), CONST64(0x893c970fb589891e), CONST64(0x14a04428b4141450), CONST64(0xe15b42dfbae1e1a3), +CONST64(0x16b04e2ca6161658), CONST64(0x3acdd274f73a3ae8), CONST64(0x696fd0d2066969b9), CONST64(0x09482d1241090924), +CONST64(0x70a7ade0d77070dd), CONST64(0xb6d954716fb6b6e2), CONST64(0xd0ceb7bd1ed0d067), CONST64(0xed3b7ec7d6eded93), +CONST64(0xcc2edb85e2cccc17), CONST64(0x422a578468424215), CONST64(0x98b4c22d2c98985a), CONST64(0xa4490e55eda4a4aa), +CONST64(0x285d8850752828a0), CONST64(0x5cda31b8865c5c6d), CONST64(0xf8933fed6bf8f8c7), CONST64(0x8644a411c2868622) +}; + +static const ulong64 sbox6[] = { +CONST64(0x6018c07830d81818), CONST64(0x8c2305af46262323), CONST64(0x3fc67ef991b8c6c6), CONST64(0x87e8136fcdfbe8e8), +CONST64(0x26874ca113cb8787), CONST64(0xdab8a9626d11b8b8), CONST64(0x0401080502090101), CONST64(0x214f426e9e0d4f4f), +CONST64(0xd836adee6c9b3636), CONST64(0xa2a6590451ffa6a6), CONST64(0x6fd2debdb90cd2d2), CONST64(0xf3f5fb06f70ef5f5), +CONST64(0xf979ef80f2967979), CONST64(0xa16f5fcede306f6f), CONST64(0x7e91fcef3f6d9191), CONST64(0x5552aa07a4f85252), +CONST64(0x9d6027fdc0476060), CONST64(0xcabc89766535bcbc), CONST64(0x569baccd2b379b9b), CONST64(0x028e048c018a8e8e), +CONST64(0xb6a371155bd2a3a3), CONST64(0x300c603c186c0c0c), CONST64(0xf17bff8af6847b7b), CONST64(0xd435b5e16a803535), +CONST64(0x741de8693af51d1d), CONST64(0xa7e05347ddb3e0e0), CONST64(0x7bd7f6acb321d7d7), CONST64(0x2fc25eed999cc2c2), +CONST64(0xb82e6d965c432e2e), CONST64(0x314b627a96294b4b), CONST64(0xdffea321e15dfefe), CONST64(0x41578216aed55757), +CONST64(0x5415a8412abd1515), CONST64(0xc1779fb6eee87777), CONST64(0xdc37a5eb6e923737), CONST64(0xb3e57b56d79ee5e5), +CONST64(0x469f8cd923139f9f), CONST64(0xe7f0d317fd23f0f0), CONST64(0x354a6a7f94204a4a), CONST64(0x4fda9e95a944dada), +CONST64(0x7d58fa25b0a25858), CONST64(0x03c906ca8fcfc9c9), CONST64(0xa429558d527c2929), CONST64(0x280a5022145a0a0a), +CONST64(0xfeb1e14f7f50b1b1), CONST64(0xbaa0691a5dc9a0a0), CONST64(0xb16b7fdad6146b6b), CONST64(0x2e855cab17d98585), +CONST64(0xcebd8173673cbdbd), CONST64(0x695dd234ba8f5d5d), CONST64(0x4010805020901010), CONST64(0xf7f4f303f507f4f4), +CONST64(0x0bcb16c08bddcbcb), CONST64(0xf83eedc67cd33e3e), CONST64(0x140528110a2d0505), CONST64(0x81671fe6ce786767), +CONST64(0xb7e47353d597e4e4), CONST64(0x9c2725bb4e022727), CONST64(0x1941325882734141), CONST64(0x168b2c9d0ba78b8b), +CONST64(0xa6a7510153f6a7a7), CONST64(0xe97dcf94fab27d7d), CONST64(0x6e95dcfb37499595), CONST64(0x47d88e9fad56d8d8), +CONST64(0xcbfb8b30eb70fbfb), CONST64(0x9fee2371c1cdeeee), CONST64(0xed7cc791f8bb7c7c), CONST64(0x856617e3cc716666), +CONST64(0x53dda68ea77bdddd), CONST64(0x5c17b84b2eaf1717), CONST64(0x014702468e454747), CONST64(0x429e84dc211a9e9e), +CONST64(0x0fca1ec589d4caca), CONST64(0xb42d75995a582d2d), CONST64(0xc6bf9179632ebfbf), CONST64(0x1c07381b0e3f0707), +CONST64(0x8ead012347acadad), CONST64(0x755aea2fb4b05a5a), CONST64(0x36836cb51bef8383), CONST64(0xcc3385ff66b63333), +CONST64(0x91633ff2c65c6363), CONST64(0x0802100a04120202), CONST64(0x92aa39384993aaaa), CONST64(0xd971afa8e2de7171), +CONST64(0x07c80ecf8dc6c8c8), CONST64(0x6419c87d32d11919), CONST64(0x39497270923b4949), CONST64(0x43d9869aaf5fd9d9), +CONST64(0xeff2c31df931f2f2), CONST64(0xabe34b48dba8e3e3), CONST64(0x715be22ab6b95b5b), CONST64(0x1a8834920dbc8888), +CONST64(0x529aa4c8293e9a9a), CONST64(0x98262dbe4c0b2626), CONST64(0xc8328dfa64bf3232), CONST64(0xfab0e94a7d59b0b0), +CONST64(0x83e91b6acff2e9e9), CONST64(0x3c0f78331e770f0f), CONST64(0x73d5e6a6b733d5d5), CONST64(0x3a8074ba1df48080), +CONST64(0xc2be997c6127bebe), CONST64(0x13cd26de87ebcdcd), CONST64(0xd034bde468893434), CONST64(0x3d487a7590324848), +CONST64(0xdbffab24e354ffff), CONST64(0xf57af78ff48d7a7a), CONST64(0x7a90f4ea3d649090), CONST64(0x615fc23ebe9d5f5f), +CONST64(0x80201da0403d2020), CONST64(0xbd6867d5d00f6868), CONST64(0x681ad07234ca1a1a), CONST64(0x82ae192c41b7aeae), +CONST64(0xeab4c95e757db4b4), CONST64(0x4d549a19a8ce5454), CONST64(0x7693ece53b7f9393), CONST64(0x88220daa442f2222), +CONST64(0x8d6407e9c8636464), CONST64(0xe3f1db12ff2af1f1), CONST64(0xd173bfa2e6cc7373), CONST64(0x4812905a24821212), +CONST64(0x1d403a5d807a4040), CONST64(0x2008402810480808), CONST64(0x2bc356e89b95c3c3), CONST64(0x97ec337bc5dfecec), +CONST64(0x4bdb9690ab4ddbdb), CONST64(0xbea1611f5fc0a1a1), CONST64(0x0e8d1c8307918d8d), CONST64(0xf43df5c97ac83d3d), +CONST64(0x6697ccf1335b9797), CONST64(0x0000000000000000), CONST64(0x1bcf36d483f9cfcf), CONST64(0xac2b4587566e2b2b), +CONST64(0xc57697b3ece17676), CONST64(0x328264b019e68282), CONST64(0x7fd6fea9b128d6d6), CONST64(0x6c1bd87736c31b1b), +CONST64(0xeeb5c15b7774b5b5), CONST64(0x86af112943beafaf), CONST64(0xb56a77dfd41d6a6a), CONST64(0x5d50ba0da0ea5050), +CONST64(0x0945124c8a574545), CONST64(0xebf3cb18fb38f3f3), CONST64(0xc0309df060ad3030), CONST64(0x9bef2b74c3c4efef), +CONST64(0xfc3fe5c37eda3f3f), CONST64(0x4955921caac75555), CONST64(0xb2a2791059dba2a2), CONST64(0x8fea0365c9e9eaea), +CONST64(0x89650fecca6a6565), CONST64(0xd2bab9686903baba), CONST64(0xbc2f65935e4a2f2f), CONST64(0x27c04ee79d8ec0c0), +CONST64(0x5fdebe81a160dede), CONST64(0x701ce06c38fc1c1c), CONST64(0xd3fdbb2ee746fdfd), CONST64(0x294d52649a1f4d4d), +CONST64(0x7292e4e039769292), CONST64(0xc9758fbceafa7575), CONST64(0x1806301e0c360606), CONST64(0x128a249809ae8a8a), +CONST64(0xf2b2f940794bb2b2), CONST64(0xbfe66359d185e6e6), CONST64(0x380e70361c7e0e0e), CONST64(0x7c1ff8633ee71f1f), +CONST64(0x956237f7c4556262), CONST64(0x77d4eea3b53ad4d4), CONST64(0x9aa829324d81a8a8), CONST64(0x6296c4f431529696), +CONST64(0xc3f99b3aef62f9f9), CONST64(0x33c566f697a3c5c5), CONST64(0x942535b14a102525), CONST64(0x7959f220b2ab5959), +CONST64(0x2a8454ae15d08484), CONST64(0xd572b7a7e4c57272), CONST64(0xe439d5dd72ec3939), CONST64(0x2d4c5a6198164c4c), +CONST64(0x655eca3bbc945e5e), CONST64(0xfd78e785f09f7878), CONST64(0xe038ddd870e53838), CONST64(0x0a8c148605988c8c), +CONST64(0x63d1c6b2bf17d1d1), CONST64(0xaea5410b57e4a5a5), CONST64(0xafe2434dd9a1e2e2), CONST64(0x99612ff8c24e6161), +CONST64(0xf6b3f1457b42b3b3), CONST64(0x842115a542342121), CONST64(0x4a9c94d625089c9c), CONST64(0x781ef0663cee1e1e), +CONST64(0x1143225286614343), CONST64(0x3bc776fc93b1c7c7), CONST64(0xd7fcb32be54ffcfc), CONST64(0x1004201408240404), +CONST64(0x5951b208a2e35151), CONST64(0x5e99bcc72f259999), CONST64(0xa96d4fc4da226d6d), CONST64(0x340d68391a650d0d), +CONST64(0xcffa8335e979fafa), CONST64(0x5bdfb684a369dfdf), CONST64(0xe57ed79bfca97e7e), CONST64(0x90243db448192424), +CONST64(0xec3bc5d776fe3b3b), CONST64(0x96ab313d4b9aabab), CONST64(0x1fce3ed181f0cece), CONST64(0x4411885522991111), +CONST64(0x068f0c8903838f8f), CONST64(0x254e4a6b9c044e4e), CONST64(0xe6b7d1517366b7b7), CONST64(0x8beb0b60cbe0ebeb), +CONST64(0xf03cfdcc78c13c3c), CONST64(0x3e817cbf1ffd8181), CONST64(0x6a94d4fe35409494), CONST64(0xfbf7eb0cf31cf7f7), +CONST64(0xdeb9a1676f18b9b9), CONST64(0x4c13985f268b1313), CONST64(0xb02c7d9c58512c2c), CONST64(0x6bd3d6b8bb05d3d3), +CONST64(0xbbe76b5cd38ce7e7), CONST64(0xa56e57cbdc396e6e), CONST64(0x37c46ef395aac4c4), CONST64(0x0c03180f061b0303), +CONST64(0x45568a13acdc5656), CONST64(0x0d441a49885e4444), CONST64(0xe17fdf9efea07f7f), CONST64(0x9ea921374f88a9a9), +CONST64(0xa82a4d8254672a2a), CONST64(0xd6bbb16d6b0abbbb), CONST64(0x23c146e29f87c1c1), CONST64(0x5153a202a6f15353), +CONST64(0x57dcae8ba572dcdc), CONST64(0x2c0b582716530b0b), CONST64(0x4e9d9cd327019d9d), CONST64(0xad6c47c1d82b6c6c), +CONST64(0xc43195f562a43131), CONST64(0xcd7487b9e8f37474), CONST64(0xfff6e309f115f6f6), CONST64(0x05460a438c4c4646), +CONST64(0x8aac092645a5acac), CONST64(0x1e893c970fb58989), CONST64(0x5014a04428b41414), CONST64(0xa3e15b42dfbae1e1), +CONST64(0x5816b04e2ca61616), CONST64(0xe83acdd274f73a3a), CONST64(0xb9696fd0d2066969), CONST64(0x2409482d12410909), +CONST64(0xdd70a7ade0d77070), CONST64(0xe2b6d954716fb6b6), CONST64(0x67d0ceb7bd1ed0d0), CONST64(0x93ed3b7ec7d6eded), +CONST64(0x17cc2edb85e2cccc), CONST64(0x15422a5784684242), CONST64(0x5a98b4c22d2c9898), CONST64(0xaaa4490e55eda4a4), +CONST64(0xa0285d8850752828), CONST64(0x6d5cda31b8865c5c), CONST64(0xc7f8933fed6bf8f8), CONST64(0x228644a411c28686) +}; + +static const ulong64 sbox7[] = { +CONST64(0x186018c07830d818), CONST64(0x238c2305af462623), CONST64(0xc63fc67ef991b8c6), CONST64(0xe887e8136fcdfbe8), +CONST64(0x8726874ca113cb87), CONST64(0xb8dab8a9626d11b8), CONST64(0x0104010805020901), CONST64(0x4f214f426e9e0d4f), +CONST64(0x36d836adee6c9b36), CONST64(0xa6a2a6590451ffa6), CONST64(0xd26fd2debdb90cd2), CONST64(0xf5f3f5fb06f70ef5), +CONST64(0x79f979ef80f29679), CONST64(0x6fa16f5fcede306f), CONST64(0x917e91fcef3f6d91), CONST64(0x525552aa07a4f852), +CONST64(0x609d6027fdc04760), CONST64(0xbccabc89766535bc), CONST64(0x9b569baccd2b379b), CONST64(0x8e028e048c018a8e), +CONST64(0xa3b6a371155bd2a3), CONST64(0x0c300c603c186c0c), CONST64(0x7bf17bff8af6847b), CONST64(0x35d435b5e16a8035), +CONST64(0x1d741de8693af51d), CONST64(0xe0a7e05347ddb3e0), CONST64(0xd77bd7f6acb321d7), CONST64(0xc22fc25eed999cc2), +CONST64(0x2eb82e6d965c432e), CONST64(0x4b314b627a96294b), CONST64(0xfedffea321e15dfe), CONST64(0x5741578216aed557), +CONST64(0x155415a8412abd15), CONST64(0x77c1779fb6eee877), CONST64(0x37dc37a5eb6e9237), CONST64(0xe5b3e57b56d79ee5), +CONST64(0x9f469f8cd923139f), CONST64(0xf0e7f0d317fd23f0), CONST64(0x4a354a6a7f94204a), CONST64(0xda4fda9e95a944da), +CONST64(0x587d58fa25b0a258), CONST64(0xc903c906ca8fcfc9), CONST64(0x29a429558d527c29), CONST64(0x0a280a5022145a0a), +CONST64(0xb1feb1e14f7f50b1), CONST64(0xa0baa0691a5dc9a0), CONST64(0x6bb16b7fdad6146b), CONST64(0x852e855cab17d985), +CONST64(0xbdcebd8173673cbd), CONST64(0x5d695dd234ba8f5d), CONST64(0x1040108050209010), CONST64(0xf4f7f4f303f507f4), +CONST64(0xcb0bcb16c08bddcb), CONST64(0x3ef83eedc67cd33e), CONST64(0x05140528110a2d05), CONST64(0x6781671fe6ce7867), +CONST64(0xe4b7e47353d597e4), CONST64(0x279c2725bb4e0227), CONST64(0x4119413258827341), CONST64(0x8b168b2c9d0ba78b), +CONST64(0xa7a6a7510153f6a7), CONST64(0x7de97dcf94fab27d), CONST64(0x956e95dcfb374995), CONST64(0xd847d88e9fad56d8), +CONST64(0xfbcbfb8b30eb70fb), CONST64(0xee9fee2371c1cdee), CONST64(0x7ced7cc791f8bb7c), CONST64(0x66856617e3cc7166), +CONST64(0xdd53dda68ea77bdd), CONST64(0x175c17b84b2eaf17), CONST64(0x47014702468e4547), CONST64(0x9e429e84dc211a9e), +CONST64(0xca0fca1ec589d4ca), CONST64(0x2db42d75995a582d), CONST64(0xbfc6bf9179632ebf), CONST64(0x071c07381b0e3f07), +CONST64(0xad8ead012347acad), CONST64(0x5a755aea2fb4b05a), CONST64(0x8336836cb51bef83), CONST64(0x33cc3385ff66b633), +CONST64(0x6391633ff2c65c63), CONST64(0x020802100a041202), CONST64(0xaa92aa39384993aa), CONST64(0x71d971afa8e2de71), +CONST64(0xc807c80ecf8dc6c8), CONST64(0x196419c87d32d119), CONST64(0x4939497270923b49), CONST64(0xd943d9869aaf5fd9), +CONST64(0xf2eff2c31df931f2), CONST64(0xe3abe34b48dba8e3), CONST64(0x5b715be22ab6b95b), CONST64(0x881a8834920dbc88), +CONST64(0x9a529aa4c8293e9a), CONST64(0x2698262dbe4c0b26), CONST64(0x32c8328dfa64bf32), CONST64(0xb0fab0e94a7d59b0), +CONST64(0xe983e91b6acff2e9), CONST64(0x0f3c0f78331e770f), CONST64(0xd573d5e6a6b733d5), CONST64(0x803a8074ba1df480), +CONST64(0xbec2be997c6127be), CONST64(0xcd13cd26de87ebcd), CONST64(0x34d034bde4688934), CONST64(0x483d487a75903248), +CONST64(0xffdbffab24e354ff), CONST64(0x7af57af78ff48d7a), CONST64(0x907a90f4ea3d6490), CONST64(0x5f615fc23ebe9d5f), +CONST64(0x2080201da0403d20), CONST64(0x68bd6867d5d00f68), CONST64(0x1a681ad07234ca1a), CONST64(0xae82ae192c41b7ae), +CONST64(0xb4eab4c95e757db4), CONST64(0x544d549a19a8ce54), CONST64(0x937693ece53b7f93), CONST64(0x2288220daa442f22), +CONST64(0x648d6407e9c86364), CONST64(0xf1e3f1db12ff2af1), CONST64(0x73d173bfa2e6cc73), CONST64(0x124812905a248212), +CONST64(0x401d403a5d807a40), CONST64(0x0820084028104808), CONST64(0xc32bc356e89b95c3), CONST64(0xec97ec337bc5dfec), +CONST64(0xdb4bdb9690ab4ddb), CONST64(0xa1bea1611f5fc0a1), CONST64(0x8d0e8d1c8307918d), CONST64(0x3df43df5c97ac83d), +CONST64(0x976697ccf1335b97), CONST64(0x0000000000000000), CONST64(0xcf1bcf36d483f9cf), CONST64(0x2bac2b4587566e2b), +CONST64(0x76c57697b3ece176), CONST64(0x82328264b019e682), CONST64(0xd67fd6fea9b128d6), CONST64(0x1b6c1bd87736c31b), +CONST64(0xb5eeb5c15b7774b5), CONST64(0xaf86af112943beaf), CONST64(0x6ab56a77dfd41d6a), CONST64(0x505d50ba0da0ea50), +CONST64(0x450945124c8a5745), CONST64(0xf3ebf3cb18fb38f3), CONST64(0x30c0309df060ad30), CONST64(0xef9bef2b74c3c4ef), +CONST64(0x3ffc3fe5c37eda3f), CONST64(0x554955921caac755), CONST64(0xa2b2a2791059dba2), CONST64(0xea8fea0365c9e9ea), +CONST64(0x6589650fecca6a65), CONST64(0xbad2bab9686903ba), CONST64(0x2fbc2f65935e4a2f), CONST64(0xc027c04ee79d8ec0), +CONST64(0xde5fdebe81a160de), CONST64(0x1c701ce06c38fc1c), CONST64(0xfdd3fdbb2ee746fd), CONST64(0x4d294d52649a1f4d), +CONST64(0x927292e4e0397692), CONST64(0x75c9758fbceafa75), CONST64(0x061806301e0c3606), CONST64(0x8a128a249809ae8a), +CONST64(0xb2f2b2f940794bb2), CONST64(0xe6bfe66359d185e6), CONST64(0x0e380e70361c7e0e), CONST64(0x1f7c1ff8633ee71f), +CONST64(0x62956237f7c45562), CONST64(0xd477d4eea3b53ad4), CONST64(0xa89aa829324d81a8), CONST64(0x966296c4f4315296), +CONST64(0xf9c3f99b3aef62f9), CONST64(0xc533c566f697a3c5), CONST64(0x25942535b14a1025), CONST64(0x597959f220b2ab59), +CONST64(0x842a8454ae15d084), CONST64(0x72d572b7a7e4c572), CONST64(0x39e439d5dd72ec39), CONST64(0x4c2d4c5a6198164c), +CONST64(0x5e655eca3bbc945e), CONST64(0x78fd78e785f09f78), CONST64(0x38e038ddd870e538), CONST64(0x8c0a8c148605988c), +CONST64(0xd163d1c6b2bf17d1), CONST64(0xa5aea5410b57e4a5), CONST64(0xe2afe2434dd9a1e2), CONST64(0x6199612ff8c24e61), +CONST64(0xb3f6b3f1457b42b3), CONST64(0x21842115a5423421), CONST64(0x9c4a9c94d625089c), CONST64(0x1e781ef0663cee1e), +CONST64(0x4311432252866143), CONST64(0xc73bc776fc93b1c7), CONST64(0xfcd7fcb32be54ffc), CONST64(0x0410042014082404), +CONST64(0x515951b208a2e351), CONST64(0x995e99bcc72f2599), CONST64(0x6da96d4fc4da226d), CONST64(0x0d340d68391a650d), +CONST64(0xfacffa8335e979fa), CONST64(0xdf5bdfb684a369df), CONST64(0x7ee57ed79bfca97e), CONST64(0x2490243db4481924), +CONST64(0x3bec3bc5d776fe3b), CONST64(0xab96ab313d4b9aab), CONST64(0xce1fce3ed181f0ce), CONST64(0x1144118855229911), +CONST64(0x8f068f0c8903838f), CONST64(0x4e254e4a6b9c044e), CONST64(0xb7e6b7d1517366b7), CONST64(0xeb8beb0b60cbe0eb), +CONST64(0x3cf03cfdcc78c13c), CONST64(0x813e817cbf1ffd81), CONST64(0x946a94d4fe354094), CONST64(0xf7fbf7eb0cf31cf7), +CONST64(0xb9deb9a1676f18b9), CONST64(0x134c13985f268b13), CONST64(0x2cb02c7d9c58512c), CONST64(0xd36bd3d6b8bb05d3), +CONST64(0xe7bbe76b5cd38ce7), CONST64(0x6ea56e57cbdc396e), CONST64(0xc437c46ef395aac4), CONST64(0x030c03180f061b03), +CONST64(0x5645568a13acdc56), CONST64(0x440d441a49885e44), CONST64(0x7fe17fdf9efea07f), CONST64(0xa99ea921374f88a9), +CONST64(0x2aa82a4d8254672a), CONST64(0xbbd6bbb16d6b0abb), CONST64(0xc123c146e29f87c1), CONST64(0x535153a202a6f153), +CONST64(0xdc57dcae8ba572dc), CONST64(0x0b2c0b582716530b), CONST64(0x9d4e9d9cd327019d), CONST64(0x6cad6c47c1d82b6c), +CONST64(0x31c43195f562a431), CONST64(0x74cd7487b9e8f374), CONST64(0xf6fff6e309f115f6), CONST64(0x4605460a438c4c46), +CONST64(0xac8aac092645a5ac), CONST64(0x891e893c970fb589), CONST64(0x145014a04428b414), CONST64(0xe1a3e15b42dfbae1), +CONST64(0x165816b04e2ca616), CONST64(0x3ae83acdd274f73a), CONST64(0x69b9696fd0d20669), CONST64(0x092409482d124109), +CONST64(0x70dd70a7ade0d770), CONST64(0xb6e2b6d954716fb6), CONST64(0xd067d0ceb7bd1ed0), CONST64(0xed93ed3b7ec7d6ed), +CONST64(0xcc17cc2edb85e2cc), CONST64(0x4215422a57846842), CONST64(0x985a98b4c22d2c98), CONST64(0xa4aaa4490e55eda4), +CONST64(0x28a0285d88507528), CONST64(0x5c6d5cda31b8865c), CONST64(0xf8c7f8933fed6bf8), CONST64(0x86228644a411c286) +}; + +#endif + +static const ulong64 cont[] = { +CONST64(0x1823c6e887b8014f), +CONST64(0x36a6d2f5796f9152), +CONST64(0x60bc9b8ea30c7b35), +CONST64(0x1de0d7c22e4bfe57), +CONST64(0x157737e59ff04ada), +CONST64(0x58c9290ab1a06b85), +CONST64(0xbd5d10f4cb3e0567), +CONST64(0xe427418ba77d95d8), +CONST64(0xfbee7c66dd17479e), +CONST64(0xca2dbf07ad5a8333), +CONST64(0x6302aa71c81949d9), +}; + +#endif /* __LTC_WHIRLTAB_C__ */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/headers/tomcrypt.h b/src/ltc/headers/tomcrypt.h new file mode 100644 index 0000000..40584e7 --- /dev/null +++ b/src/ltc/headers/tomcrypt.h @@ -0,0 +1,93 @@ +#ifndef TOMCRYPT_H_ +#define TOMCRYPT_H_ +#include +#include +#include +#include +#include +#include +#include +#include + +/* use configuration data */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* version */ +#define CRYPT 0x0117 +#define SCRYPT "1.17" + +/* max size of either a cipher/hash block or symmetric key [largest of the two] */ +#define MAXBLOCKSIZE 128 + +/* descriptor table size */ +#define TAB_SIZE 32 + +/* error codes [will be expanded in future releases] */ +enum { + CRYPT_OK=0, /* Result OK */ + CRYPT_ERROR, /* Generic Error */ + CRYPT_NOP, /* Not a failure but no operation was performed */ + + CRYPT_INVALID_KEYSIZE, /* Invalid key size given */ + CRYPT_INVALID_ROUNDS, /* Invalid number of rounds */ + CRYPT_FAIL_TESTVECTOR, /* Algorithm failed test vectors */ + + CRYPT_BUFFER_OVERFLOW, /* Not enough space for output */ + CRYPT_INVALID_PACKET, /* Invalid input packet given */ + + CRYPT_INVALID_PRNGSIZE, /* Invalid number of bits for a PRNG */ + CRYPT_ERROR_READPRNG, /* Could not read enough from PRNG */ + + CRYPT_INVALID_CIPHER, /* Invalid cipher specified */ + CRYPT_INVALID_HASH, /* Invalid hash specified */ + CRYPT_INVALID_PRNG, /* Invalid PRNG specified */ + + CRYPT_MEM, /* Out of memory */ + + CRYPT_PK_TYPE_MISMATCH, /* Not equivalent types of PK keys */ + CRYPT_PK_NOT_PRIVATE, /* Requires a private PK key */ + + CRYPT_INVALID_ARG, /* Generic invalid argument */ + CRYPT_FILE_NOTFOUND, /* File Not Found */ + + CRYPT_PK_INVALID_TYPE, /* Invalid type of PK key */ + + CRYPT_OVERFLOW, /* An overflow of a value was detected/prevented */ + + CRYPT_UNUSED1, /* UNUSED1 */ + CRYPT_UNUSED2, /* UNUSED2 */ + + CRYPT_PK_INVALID_SIZE, /* Invalid size input for PK parameters */ + + CRYPT_INVALID_PRIME_SIZE,/* Invalid size of prime requested */ + CRYPT_PK_INVALID_PADDING, /* Invalid padding on input */ + + CRYPT_HASH_OVERFLOW /* Hash applied to too many bits */ +}; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus + } +#endif + +#endif /* TOMCRYPT_H_ */ + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/headers/tomcrypt_argchk.h b/src/ltc/headers/tomcrypt_argchk.h new file mode 100644 index 0000000..5cefc2d --- /dev/null +++ b/src/ltc/headers/tomcrypt_argchk.h @@ -0,0 +1,44 @@ +/* Defines the LTC_ARGCHK macro used within the library */ +/* ARGTYPE is defined in tomcrypt_cfg.h */ +#if ARGTYPE == 0 + +#include + +/* this is the default LibTomCrypt macro */ +#if defined(__clang__) || defined(__GNUC_MINOR__) +#define NORETURN __attribute__ ((noreturn)) +#else +#define NORETURN +#endif + +void crypt_argchk(char *v, char *s, int d) NORETURN; +#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0) +#define LTC_ARGCHKVD(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0) + +#elif ARGTYPE == 1 + +/* fatal type of error */ +#define LTC_ARGCHK(x) assert((x)) +#define LTC_ARGCHKVD(x) LTC_ARGCHK(x) + +#elif ARGTYPE == 2 + +#define LTC_ARGCHK(x) if (!(x)) { fprintf(stderr, "\nwarning: ARGCHK failed at %s:%d\n", __FILE__, __LINE__); } +#define LTC_ARGCHKVD(x) LTC_ARGCHK(x) + +#elif ARGTYPE == 3 + +#define LTC_ARGCHK(x) +#define LTC_ARGCHKVD(x) LTC_ARGCHK(x) + +#elif ARGTYPE == 4 + +#define LTC_ARGCHK(x) if (!(x)) return CRYPT_INVALID_ARG; +#define LTC_ARGCHKVD(x) if (!(x)) return; + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/headers/tomcrypt_cfg.h b/src/ltc/headers/tomcrypt_cfg.h new file mode 100644 index 0000000..ccfb78b --- /dev/null +++ b/src/ltc/headers/tomcrypt_cfg.h @@ -0,0 +1,268 @@ +/* This is the build config file. + * + * With this you can setup what to inlcude/exclude automatically during any build. Just comment + * out the line that #define's the word for the thing you want to remove. phew! + */ + +#ifndef TOMCRYPT_CFG_H +#define TOMCRYPT_CFG_H + +#if defined(_WIN32) || defined(_MSC_VER) + #define LTC_CALL __cdecl +#elif !defined(LTC_CALL) + #define LTC_CALL +#endif + +#ifndef LTC_EXPORT + #define LTC_EXPORT +#endif + +/* certain platforms use macros for these, making the prototypes broken */ +#ifndef LTC_NO_PROTOTYPES + +/* you can change how memory allocation works ... */ +LTC_EXPORT void * LTC_CALL XMALLOC(size_t n); +LTC_EXPORT void * LTC_CALL XREALLOC(void *p, size_t n); +LTC_EXPORT void * LTC_CALL XCALLOC(size_t n, size_t s); +LTC_EXPORT void LTC_CALL XFREE(void *p); + +LTC_EXPORT void LTC_CALL XQSORT(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *)); + + +/* change the clock function too */ +LTC_EXPORT clock_t LTC_CALL XCLOCK(void); + +/* various other functions */ +LTC_EXPORT void * LTC_CALL XMEMCPY(void *dest, const void *src, size_t n); +LTC_EXPORT int LTC_CALL XMEMCMP(const void *s1, const void *s2, size_t n); +LTC_EXPORT void * LTC_CALL XMEMSET(void *s, int c, size_t n); + +LTC_EXPORT int LTC_CALL XSTRCMP(const char *s1, const char *s2); + +#endif + +/* some compilers do not like "inline" */ +#if defined(__HP_cc) + #define LTC_INLINE +#elif defined(_MSC_VER) + #define LTC_INLINE __inline +#else + #define LTC_INLINE inline +#endif + +/* type of argument checking, 0=default, 1=fatal and 2=error+continue, 3=nothing */ +#ifndef ARGTYPE + #define ARGTYPE 0 +#endif + +/* Controls endianess and size of registers. Leave uncommented to get platform neutral [slower] code + * + * Note: in order to use the optimized macros your platform must support unaligned 32 and 64 bit read/writes. + * The x86 platforms allow this but some others [ARM for instance] do not. On those platforms you **MUST** + * use the portable [slower] macros. + */ +/* detect x86/i386 32bit */ +#if defined(__i386__) || defined(__i386) || defined(_M_IX86) + #define ENDIAN_LITTLE + #define ENDIAN_32BITWORD + #define LTC_FAST +#endif + +/* detect amd64/x64 */ +#if defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64) + #define ENDIAN_LITTLE + #define ENDIAN_64BITWORD + #define LTC_FAST +#endif + +/* detect PPC32 */ +#if defined(LTC_PPC32) + #define ENDIAN_BIG + #define ENDIAN_32BITWORD + #define LTC_FAST +#endif + +/* detects MIPS R5900 processors (PS2) */ +#if (defined(__R5900) || defined(R5900) || defined(__R5900__)) && (defined(_mips) || defined(__mips__) || defined(mips)) + #define ENDIAN_64BITWORD + #if defined(_MIPSEB) || defined(__MIPSEB) || defined(__MIPSEB__) + #define ENDIAN_BIG + #endif + #define ENDIAN_LITTLE + #endif +#endif + +/* detect AIX */ +#if defined(_AIX) && defined(_BIG_ENDIAN) + #define ENDIAN_BIG + #if defined(__LP64__) || defined(_ARCH_PPC64) + #define ENDIAN_64BITWORD + #else + #define ENDIAN_32BITWORD + #endif +#endif + +/* detect HP-UX */ +#if defined(__hpux) || defined(__hpux__) + #define ENDIAN_BIG + #if defined(__ia64) || defined(__ia64__) || defined(__LP64__) + #define ENDIAN_64BITWORD + #else + #define ENDIAN_32BITWORD + #endif +#endif + +/* detect Apple OS X */ +#if defined(__APPLE__) && defined(__MACH__) + #if defined(__LITTLE_ENDIAN__) || defined(__x86_64__) + #define ENDIAN_LITTLE + #else + #define ENDIAN_BIG + #endif + #if defined(__LP64__) || defined(__x86_64__) + #define ENDIAN_64BITWORD + #else + #define ENDIAN_32BITWORD + #endif +#endif + +/* detect SPARC and SPARC64 */ +#if defined(__sparc__) || defined(__sparc) + #define ENDIAN_BIG + #if defined(__arch64__) || defined(__sparcv9) || defined(__sparc_v9__) + #define ENDIAN_64BITWORD + #else + #define ENDIAN_32BITWORD + #endif +#endif + +/* detect IBM S390(x) */ +#if defined(__s390x__) || defined(__s390__) + #define ENDIAN_BIG + #if defined(__s390x__) + #define ENDIAN_64BITWORD + #else + #define ENDIAN_32BITWORD + #endif +#endif + +/* detect PPC64 */ +#if defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) + #define ENDIAN_64BITWORD + #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + #define ENDIAN_BIG + #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + #define ENDIAN_LITTLE + #endif + #define LTC_FAST +#endif + +/* endianness fallback */ +#if !defined(ENDIAN_BIG) && !defined(ENDIAN_LITTLE) + #if defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN || \ + defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ || \ + defined(__BIG_ENDIAN__) || defined(_BIG_ENDIAN) || \ + defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || \ + defined(_MIPSEB) || defined(__MIPSEB) || defined(__MIPSEB__) + #define ENDIAN_BIG + #elif defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN || \ + defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ || \ + defined(__LITTLE_ENDIAN__) || defined(_LITTLE_ENDIAN) || \ + defined(__ARMEL__) || defined(__THUMBEL__) || defined(__AARCH64EL__) || \ + defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__) + #define ENDIAN_LITTLE + #else + #error Cannot detect endianness + #endif +#endif + +/* ulong64: 64-bit data type */ +#ifdef _MSC_VER + #define CONST64(n) n ## ui64 + typedef unsigned __int64 ulong64; +#else + #define CONST64(n) n ## ULL + typedef unsigned long long ulong64; +#endif + +/* ulong32: "32-bit at least" data type */ +#if defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64) || \ + defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) || \ + defined(__s390x__) || defined(__arch64__) || defined(__aarch64__) || \ + defined(__sparcv9) || defined(__sparc_v9__) || defined(__sparc64__) || \ + defined(__ia64) || defined(__ia64__) || defined(__itanium__) || defined(_M_IA64) || \ + defined(__LP64__) || defined(_LP64) || defined(__64BIT__) + typedef unsigned ulong32; + #if !defined(ENDIAN_64BITWORD) && !defined(ENDIAN_32BITWORD) + #define ENDIAN_64BITWORD + #endif +#else + typedef unsigned long ulong32; + #if !defined(ENDIAN_64BITWORD) && !defined(ENDIAN_32BITWORD) + #define ENDIAN_32BITWORD + #endif +#endif + +/* No LTC_FAST if: explicitly disabled OR non-gcc/non-clang compiler OR old gcc OR using -ansi -std=c99 */ +#if defined(LTC_NO_FAST) || (__GNUC__ < 4) || defined(__STRICT_ANSI__) + #undef LTC_FAST +#endif + +#ifdef LTC_FAST + #define LTC_FAST_TYPE_PTR_CAST(x) ((LTC_FAST_TYPE*)(void*)(x)) + #ifdef ENDIAN_64BITWORD + typedef ulong64 __attribute__((__may_alias__)) LTC_FAST_TYPE; + #else + typedef ulong32 __attribute__((__may_alias__)) LTC_FAST_TYPE; + #endif +#endif + +#ifdef ENDIAN_64BITWORD +typedef ulong64 ltc_mp_digit; +#else +typedef ulong32 ltc_mp_digit; +#endif + +/* No asm is a quick way to disable anything "not portable" */ +#ifdef LTC_NO_ASM + #define ENDIAN_NEUTRAL + #undef ENDIAN_32BITWORD + #undef ENDIAN_64BITWORD + #undef LTC_FAST + #undef LTC_FAST_TYPE + #define LTC_NO_ROLC + #define LTC_NO_BSWAP +#endif + +#if !defined(ENDIAN_NEUTRAL) && (defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE)) && !(defined(ENDIAN_32BITWORD) || defined(ENDIAN_64BITWORD)) + #error You must specify a word size as well as endianess in tomcrypt_cfg.h +#endif + +#if !(defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE)) + #define ENDIAN_NEUTRAL +#endif + +#if (defined(ENDIAN_32BITWORD) && defined(ENDIAN_64BITWORD)) + #error Cannot be 32 and 64 bit words... +#endif + +/* gcc 4.3 and up has a bswap builtin; detect it by gcc version. + * clang also supports the bswap builtin, and although clang pretends + * to be gcc (macro-wise, anyway), clang pretends to be a version + * prior to gcc 4.3, so we can't detect bswap that way. Instead, + * clang has a __has_builtin mechanism that can be used to check + * for builtins: + * http://clang.llvm.org/docs/LanguageExtensions.html#feature_check */ +#ifndef __has_builtin + #define __has_builtin(x) 0 +#endif +#if !defined(LTC_NO_BSWAP) && defined(__GNUC__) && \ + ((__GNUC__ * 100 + __GNUC_MINOR__ >= 403) || \ + (__has_builtin(__builtin_bswap32) && __has_builtin(__builtin_bswap64))) + #define LTC_HAVE_BSWAP_BUILTIN +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/headers/tomcrypt_cipher.h b/src/ltc/headers/tomcrypt_cipher.h new file mode 100644 index 0000000..58f02db --- /dev/null +++ b/src/ltc/headers/tomcrypt_cipher.h @@ -0,0 +1,998 @@ +/* ---- SYMMETRIC KEY STUFF ----- + * + * We put each of the ciphers scheduled keys in their own structs then we put all of + * the key formats in one union. This makes the function prototypes easier to use. + */ +#ifdef LTC_BLOWFISH +struct blowfish_key { + ulong32 S[4][256]; + ulong32 K[18]; +}; +#endif + +#ifdef LTC_RC5 +struct rc5_key { + int rounds; + ulong32 K[50]; +}; +#endif + +#ifdef LTC_RC6 +struct rc6_key { + ulong32 K[44]; +}; +#endif + +#ifdef LTC_SAFERP +struct saferp_key { + unsigned char K[33][16]; + long rounds; +}; +#endif + +#ifdef LTC_RIJNDAEL +struct rijndael_key { + ulong32 eK[60], dK[60]; + int Nr; +}; +#endif + +#ifdef LTC_KSEED +struct kseed_key { + ulong32 K[32], dK[32]; +}; +#endif + +#ifdef LTC_KASUMI +struct kasumi_key { + ulong32 KLi1[8], KLi2[8], + KOi1[8], KOi2[8], KOi3[8], + KIi1[8], KIi2[8], KIi3[8]; +}; +#endif + +#ifdef LTC_XTEA +struct xtea_key { + unsigned long A[32], B[32]; +}; +#endif + +#ifdef LTC_TWOFISH +#ifndef LTC_TWOFISH_SMALL + struct twofish_key { + ulong32 S[4][256], K[40]; + }; +#else + struct twofish_key { + ulong32 K[40]; + unsigned char S[32], start; + }; +#endif +#endif + +#ifdef LTC_SAFER +#define LTC_SAFER_K64_DEFAULT_NOF_ROUNDS 6 +#define LTC_SAFER_K128_DEFAULT_NOF_ROUNDS 10 +#define LTC_SAFER_SK64_DEFAULT_NOF_ROUNDS 8 +#define LTC_SAFER_SK128_DEFAULT_NOF_ROUNDS 10 +#define LTC_SAFER_MAX_NOF_ROUNDS 13 +#define LTC_SAFER_BLOCK_LEN 8 +#define LTC_SAFER_KEY_LEN (1 + LTC_SAFER_BLOCK_LEN * (1 + 2 * LTC_SAFER_MAX_NOF_ROUNDS)) +typedef unsigned char safer_block_t[LTC_SAFER_BLOCK_LEN]; +typedef unsigned char safer_key_t[LTC_SAFER_KEY_LEN]; +struct safer_key { safer_key_t key; }; +#endif + +#ifdef LTC_RC2 +struct rc2_key { unsigned xkey[64]; }; +#endif + +#ifdef LTC_DES +struct des_key { + ulong32 ek[32], dk[32]; +}; + +struct des3_key { + ulong32 ek[3][32], dk[3][32]; +}; +#endif + +#ifdef LTC_CAST5 +struct cast5_key { + ulong32 K[32], keylen; +}; +#endif + +#ifdef LTC_NOEKEON +struct noekeon_key { + ulong32 K[4], dK[4]; +}; +#endif + +#ifdef LTC_SKIPJACK +struct skipjack_key { + unsigned char key[10]; +}; +#endif + +#ifdef LTC_KHAZAD +struct khazad_key { + ulong64 roundKeyEnc[8 + 1]; + ulong64 roundKeyDec[8 + 1]; +}; +#endif + +#ifdef LTC_ANUBIS +struct anubis_key { + int keyBits; + int R; + ulong32 roundKeyEnc[18 + 1][4]; + ulong32 roundKeyDec[18 + 1][4]; +}; +#endif + +#ifdef LTC_MULTI2 +struct multi2_key { + int N; + ulong32 uk[8]; +}; +#endif + +#ifdef LTC_CAMELLIA +struct camellia_key { + int R; + ulong64 kw[4], k[24], kl[6]; +}; +#endif + +typedef union Symmetric_key { +#ifdef LTC_DES + struct des_key des; + struct des3_key des3; +#endif +#ifdef LTC_RC2 + struct rc2_key rc2; +#endif +#ifdef LTC_SAFER + struct safer_key safer; +#endif +#ifdef LTC_TWOFISH + struct twofish_key twofish; +#endif +#ifdef LTC_BLOWFISH + struct blowfish_key blowfish; +#endif +#ifdef LTC_RC5 + struct rc5_key rc5; +#endif +#ifdef LTC_RC6 + struct rc6_key rc6; +#endif +#ifdef LTC_SAFERP + struct saferp_key saferp; +#endif +#ifdef LTC_RIJNDAEL + struct rijndael_key rijndael; +#endif +#ifdef LTC_XTEA + struct xtea_key xtea; +#endif +#ifdef LTC_CAST5 + struct cast5_key cast5; +#endif +#ifdef LTC_NOEKEON + struct noekeon_key noekeon; +#endif +#ifdef LTC_SKIPJACK + struct skipjack_key skipjack; +#endif +#ifdef LTC_KHAZAD + struct khazad_key khazad; +#endif +#ifdef LTC_ANUBIS + struct anubis_key anubis; +#endif +#ifdef LTC_KSEED + struct kseed_key kseed; +#endif +#ifdef LTC_KASUMI + struct kasumi_key kasumi; +#endif +#ifdef LTC_MULTI2 + struct multi2_key multi2; +#endif +#ifdef LTC_CAMELLIA + struct camellia_key camellia; +#endif + void *data; +} symmetric_key; + +#ifdef LTC_ECB_MODE +/** A block cipher ECB structure */ +typedef struct { + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen; + /** The scheduled key */ + symmetric_key key; +} symmetric_ECB; +#endif + +#ifdef LTC_CFB_MODE +/** A block cipher CFB structure */ +typedef struct { + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen, + /** The padding offset */ + padlen; + /** The current IV */ + unsigned char IV[MAXBLOCKSIZE], + /** The pad used to encrypt/decrypt */ + pad[MAXBLOCKSIZE]; + /** The scheduled key */ + symmetric_key key; +} symmetric_CFB; +#endif + +#ifdef LTC_OFB_MODE +/** A block cipher OFB structure */ +typedef struct { + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen, + /** The padding offset */ + padlen; + /** The current IV */ + unsigned char IV[MAXBLOCKSIZE]; + /** The scheduled key */ + symmetric_key key; +} symmetric_OFB; +#endif + +#ifdef LTC_CBC_MODE +/** A block cipher CBC structure */ +typedef struct { + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen; + /** The current IV */ + unsigned char IV[MAXBLOCKSIZE]; + /** The scheduled key */ + symmetric_key key; +} symmetric_CBC; +#endif + + +#ifdef LTC_CTR_MODE +/** A block cipher CTR structure */ +typedef struct { + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen, + /** The padding offset */ + padlen, + /** The mode (endianess) of the CTR, 0==little, 1==big */ + mode, + /** counter width */ + ctrlen; + + /** The counter */ + unsigned char ctr[MAXBLOCKSIZE], + /** The pad used to encrypt/decrypt */ + pad[MAXBLOCKSIZE]; + /** The scheduled key */ + symmetric_key key; +} symmetric_CTR; +#endif + + +#ifdef LTC_LRW_MODE +/** A LRW structure */ +typedef struct { + /** The index of the cipher chosen (must be a 128-bit block cipher) */ + int cipher; + + /** The current IV */ + unsigned char IV[16], + + /** the tweak key */ + tweak[16], + + /** The current pad, it's the product of the first 15 bytes against the tweak key */ + pad[16]; + + /** The scheduled symmetric key */ + symmetric_key key; + +#ifdef LTC_LRW_TABLES + /** The pre-computed multiplication table */ + unsigned char PC[16][256][16]; +#endif +} symmetric_LRW; +#endif + +#ifdef LTC_F8_MODE +/** A block cipher F8 structure */ +typedef struct { + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen, + /** The padding offset */ + padlen; + /** The current IV */ + unsigned char IV[MAXBLOCKSIZE], + MIV[MAXBLOCKSIZE]; + /** Current block count */ + ulong32 blockcnt; + /** The scheduled key */ + symmetric_key key; +} symmetric_F8; +#endif + + +/** cipher descriptor table, last entry has "name == NULL" to mark the end of table */ +extern 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 + @return CRYPT_OK if successful + */ + int (*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 + @return CRYPT_OK if successful + */ + int (*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); + + /** 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 + @return CRYPT_OK if successful + */ + int (*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 + @return CRYPT_OK if successful + */ + int (*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 + @return CRYPT_OK if successful + */ + int (*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 + @return CRYPT_OK if successful + */ + int (*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 + @return CRYPT_OK if successful + */ + int (*accel_ctr_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, int mode, symmetric_key *skey); + + /** Accelerated LRW + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param IV The initial value (input/output) + @param tweak The LRW tweak + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_lrw_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, symmetric_key *skey); + + /** Accelerated LRW + @param ct Ciphertext + @param pt Plaintext + @param blocks The number of complete blocks to process + @param IV The initial value (input/output) + @param tweak The LRW tweak + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_lrw_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, 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 uskey A previously scheduled key [optional can be NULL] + @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 (*accel_ccm_memory)( + const unsigned char *key, unsigned long keylen, + symmetric_key *uskey, + 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) + @return CRYPT_OK on success + */ + int (*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); + + /** Accelerated one shot LTC_OMAC + @param key The secret key + @param keylen The key length (octets) + @param in The message + @param inlen Length of message (octets) + @param out [out] Destination for tag + @param outlen [in/out] Initial and final size of out + @return CRYPT_OK on success + */ + int (*omac_memory)( + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + + /** Accelerated one shot XCBC + @param key The secret key + @param keylen The key length (octets) + @param in The message + @param inlen Length of message (octets) + @param out [out] Destination for tag + @param outlen [in/out] Initial and final size of out + @return CRYPT_OK on success + */ + int (*xcbc_memory)( + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + + /** Accelerated one shot F9 + @param key The secret key + @param keylen The key length (octets) + @param in The message + @param inlen Length of message (octets) + @param out [out] Destination for tag + @param outlen [in/out] Initial and final size of out + @return CRYPT_OK on success + @remark Requires manual padding + */ + int (*f9_memory)( + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + + /** Accelerated XTS encryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param tweak The 128-bit encryption tweak (input/output). + The tweak should not be encrypted on input, but + next tweak will be copied encrypted on output. + @param skey1 The first scheduled key context + @param skey2 The second scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_xts_encrypt)(const unsigned char *pt, unsigned char *ct, + unsigned long blocks, unsigned char *tweak, symmetric_key *skey1, + symmetric_key *skey2); + + /** Accelerated XTS decryption + @param ct Ciphertext + @param pt Plaintext + @param blocks The number of complete blocks to process + @param tweak The 128-bit encryption tweak (input/output). + The tweak should not be encrypted on input, but + next tweak will be copied encrypted on output. + @param skey1 The first scheduled key context + @param skey2 The second scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_xts_decrypt)(const unsigned char *ct, unsigned char *pt, + unsigned long blocks, unsigned char *tweak, symmetric_key *skey1, + symmetric_key *skey2); +} cipher_descriptor[]; + +#ifdef LTC_BLOWFISH +int blowfish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int 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 + +#ifdef LTC_RC5 +int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int 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 + +#ifdef LTC_RC6 +int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int 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 + +#ifdef LTC_RC2 +int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int rc2_setup_ex(const unsigned char *key, int keylen, int bits, int num_rounds, symmetric_key *skey); +int rc2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int 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 + +#ifdef LTC_SAFERP +int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int 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 + +#ifdef LTC_SAFER +int safer_k64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int safer_sk64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int safer_k128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int safer_sk128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int safer_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +int safer_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *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; +#endif + +#ifdef LTC_RIJNDAEL + +/* make aes an alias */ +#define aes_setup rijndael_setup +#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 +#define aes_enc_ecb_encrypt rijndael_enc_ecb_encrypt +#define aes_enc_keysize rijndael_enc_keysize + +int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int 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); +int 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; +#endif + +#ifdef LTC_XTEA +int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int 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 + +#ifdef LTC_TWOFISH +int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int 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 + +#ifdef LTC_DES +int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int 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); +int des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int 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 + +#ifdef LTC_CAST5 +int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int 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 + +#ifdef LTC_NOEKEON +int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int 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 + +#ifdef LTC_SKIPJACK +int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int 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 + +#ifdef LTC_KHAZAD +int khazad_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int 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 + +#ifdef LTC_ANUBIS +int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int 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 + +#ifdef LTC_KSEED +int kseed_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int kseed_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int kseed_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int kseed_test(void); +void kseed_done(symmetric_key *skey); +int kseed_keysize(int *keysize); +extern const struct ltc_cipher_descriptor kseed_desc; +#endif + +#ifdef LTC_KASUMI +int kasumi_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int kasumi_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int kasumi_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int kasumi_test(void); +void kasumi_done(symmetric_key *skey); +int kasumi_keysize(int *keysize); +extern const struct ltc_cipher_descriptor kasumi_desc; +#endif + + +#ifdef LTC_MULTI2 +int multi2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int multi2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int multi2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int multi2_test(void); +void multi2_done(symmetric_key *skey); +int multi2_keysize(int *keysize); +extern const struct ltc_cipher_descriptor multi2_desc; +#endif + +#ifdef LTC_CAMELLIA +int camellia_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int camellia_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int camellia_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int camellia_test(void); +void camellia_done(symmetric_key *skey); +int camellia_keysize(int *keysize); +extern const struct ltc_cipher_descriptor camellia_desc; +#endif + +#ifdef LTC_ECB_MODE +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, 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 LTC_CFB_MODE +int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_CFB *cfb); +int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CFB *cfb); +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 LTC_OFB_MODE +int ofb_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_OFB *ofb); +int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_OFB *ofb); +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 LTC_CBC_MODE +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, 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 LTC_CTR_MODE + +#define CTR_COUNTER_LITTLE_ENDIAN 0x0000 +#define CTR_COUNTER_BIG_ENDIAN 0x1000 +#define LTC_CTR_RFC3686 0x2000 + +int ctr_start( int cipher, + const unsigned char *IV, + const unsigned char *key, int keylen, + int num_rounds, int ctr_mode, + symmetric_CTR *ctr); +int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr); +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); +int ctr_test(void); +#endif + +#ifdef LTC_LRW_MODE + +#define LRW_ENCRYPT 0 +#define LRW_DECRYPT 1 + +int lrw_start( int cipher, + const unsigned char *IV, + const unsigned char *key, int keylen, + const unsigned char *tweak, + int num_rounds, + symmetric_LRW *lrw); +int lrw_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_LRW *lrw); +int lrw_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_LRW *lrw); +int lrw_getiv(unsigned char *IV, unsigned long *len, symmetric_LRW *lrw); +int lrw_setiv(const unsigned char *IV, unsigned long len, symmetric_LRW *lrw); +int lrw_done(symmetric_LRW *lrw); +int lrw_test(void); + +/* don't call */ +int lrw_process(const unsigned char *pt, unsigned char *ct, unsigned long len, int mode, symmetric_LRW *lrw); +#endif + +#ifdef LTC_F8_MODE +int f8_start( int cipher, const unsigned char *IV, + const unsigned char *key, int keylen, + const unsigned char *salt_key, int skeylen, + int num_rounds, symmetric_F8 *f8); +int f8_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_F8 *f8); +int f8_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_F8 *f8); +int f8_getiv(unsigned char *IV, unsigned long *len, symmetric_F8 *f8); +int f8_setiv(const unsigned char *IV, unsigned long len, symmetric_F8 *f8); +int f8_done(symmetric_F8 *f8); +int f8_test_mode(void); +#endif + +#ifdef LTC_XTS_MODE +typedef struct { + symmetric_key key1, key2; + int cipher; +} symmetric_xts; + +int xts_start( int cipher, + const unsigned char *key1, + const unsigned char *key2, + unsigned long keylen, + int num_rounds, + symmetric_xts *xts); + +int xts_encrypt( + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tweak, + symmetric_xts *xts); +int xts_decrypt( + const unsigned char *ct, unsigned long ptlen, + unsigned char *pt, + unsigned char *tweak, + symmetric_xts *xts); + +void xts_done(symmetric_xts *xts); +int xts_test(void); +void xts_mult_x(unsigned char *I); +#endif + +int find_cipher(const char *name); +int find_cipher_any(const char *name, int blocklen, int keylen); +int find_cipher_id(unsigned char ID); +int register_cipher(const struct ltc_cipher_descriptor *cipher); +int unregister_cipher(const struct ltc_cipher_descriptor *cipher); +int cipher_is_valid(int idx); + +LTC_MUTEX_PROTO(ltc_cipher_mutex) + +/* ---- stream ciphers ---- */ + +#ifdef LTC_CHACHA + +typedef struct { + ulong32 input[16]; + unsigned char kstream[64]; + unsigned long ksleft; + unsigned long ivlen; + int rounds; +} chacha_state; + +int chacha_setup(chacha_state *st, const unsigned char *key, unsigned long keylen, int rounds); +int chacha_ivctr32(chacha_state *st, const unsigned char *iv, unsigned long ivlen, ulong32 counter); +int chacha_ivctr64(chacha_state *st, const unsigned char *iv, unsigned long ivlen, ulong64 counter); +int chacha_crypt(chacha_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out); +int chacha_keystream(chacha_state *st, unsigned char *out, unsigned long outlen); +int chacha_done(chacha_state *st); +int chacha_test(void); + +#endif /* LTC_CHACHA */ + +#ifdef LTC_RC4_STREAM + +typedef struct { + unsigned int x, y; + unsigned char buf[256]; +} rc4_state; + +int rc4_stream_setup(rc4_state *st, const unsigned char *key, unsigned long keylen); +int rc4_stream_crypt(rc4_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out); +int rc4_stream_keystream(rc4_state *st, unsigned char *out, unsigned long outlen); +int rc4_stream_done(rc4_state *st); +int rc4_stream_test(void); + +#endif /* LTC_RC4_STREAM */ + +#ifdef LTC_SOBER128_STREAM + +typedef struct { + ulong32 R[17], /* Working storage for the shift register */ + initR[17], /* saved register contents */ + konst, /* key dependent constant */ + sbuf; /* partial word encryption buffer */ + int nbuf; /* number of part-word stream bits buffered */ +} sober128_state; + +int sober128_stream_setup(sober128_state *st, const unsigned char *key, unsigned long keylen); +int sober128_stream_setiv(sober128_state *st, const unsigned char *iv, unsigned long ivlen); +int sober128_stream_crypt(sober128_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out); +int sober128_stream_keystream(sober128_state *st, unsigned char *out, unsigned long outlen); +int sober128_stream_done(sober128_state *st); +int sober128_stream_test(void); + +#endif /* LTC_SOBER128_STREAM */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/headers/tomcrypt_custom.h b/src/ltc/headers/tomcrypt_custom.h new file mode 100644 index 0000000..085a562 --- /dev/null +++ b/src/ltc/headers/tomcrypt_custom.h @@ -0,0 +1,616 @@ +#ifndef TOMCRYPT_CUSTOM_H_ +#define TOMCRYPT_CUSTOM_H_ + +/* macros for various libc functions you can change for embedded targets */ +#ifndef XMALLOC +#define XMALLOC malloc +#endif +#ifndef XREALLOC +#define XREALLOC realloc +#endif +#ifndef XCALLOC +#define XCALLOC calloc +#endif +#ifndef XFREE +#define XFREE free +#endif + +#ifndef XMEMSET +#define XMEMSET memset +#endif +#ifndef XMEMCPY +#define XMEMCPY memcpy +#endif +#ifndef XMEMCMP +#define XMEMCMP memcmp +#endif +#ifndef XMEMMOVE +#define XMEMMOVE memmove +#endif +#ifndef XMEM_NEQ +#define XMEM_NEQ mem_neq +#endif +#ifndef XSTRCMP +#define XSTRCMP strcmp +#endif + +#ifndef XCLOCK +#define XCLOCK clock +#endif + +#ifndef XQSORT +#define XQSORT qsort +#endif + +#if ( defined(malloc) || defined(realloc) || defined(calloc) || defined(free) || \ + defined(memset) || defined(memcpy) || defined(memcmp) || defined(strcmp) || \ + defined(clock) || defined(qsort) ) && !defined(LTC_NO_PROTOTYPES) +#define LTC_NO_PROTOTYPES +#endif + +/* shortcut to disable automatic inclusion */ +#if defined LTC_NOTHING && !defined LTC_EASY + #define LTC_NO_MATH + #define LTC_NO_CIPHERS + #define LTC_NO_MODES + #define LTC_NO_HASHES + #define LTC_NO_MACS + #define LTC_NO_PRNGS + #define LTC_NO_PK + #define LTC_NO_PKCS + #define LTC_NO_MISC + #define LTC_NO_FILE +#endif /* LTC_NOTHING */ + +/* Easy button? */ +#ifdef LTC_EASY + #define LTC_NO_CIPHERS + #define LTC_RIJNDAEL + #define LTC_BLOWFISH + #define LTC_DES + #define LTC_CAST5 + + #define LTC_NO_MODES + #define LTC_ECB_MODE + #define LTC_CBC_MODE + #define LTC_CTR_MODE + + #define LTC_NO_HASHES + #define LTC_SHA1 + #define LTC_SHA3 + #define LTC_SHA512 + #define LTC_SHA384 + #define LTC_SHA256 + #define LTC_SHA224 + #define LTC_HASH_HELPERS + + #define LTC_NO_MACS + #define LTC_HMAC + #define LTC_OMAC + #define LTC_CCM_MODE + + #define LTC_NO_PRNGS + #define LTC_SPRNG + #define LTC_YARROW + #define LTC_DEVRANDOM + #define LTC_TRY_URANDOM_FIRST + #define LTC_RNG_GET_BYTES + #define LTC_RNG_MAKE_PRNG + + #define LTC_NO_PK + #define LTC_MRSA + #define LTC_MECC + + #define LTC_NO_MISC + #define LTC_BASE64 +#endif + +/* The minimal set of functionality to run the tests */ +#ifdef LTC_MINIMAL + #define LTC_RIJNDAEL + #define LTC_SHA256 + #define LTC_YARROW + #define LTC_CTR_MODE + + #define LTC_RNG_MAKE_PRNG + #define LTC_RNG_GET_BYTES + #define LTC_DEVRANDOM + #define LTC_TRY_URANDOM_FIRST + + #undef LTC_NO_FILE +#endif + +/* Enable self-test test vector checking */ +#ifndef LTC_NO_TEST + #define LTC_TEST +#endif +/* Enable extended self-tests */ +/* #define LTC_TEST_EXT */ + +/* Use small code where possible */ +/* #define LTC_SMALL_CODE */ + +/* clean the stack of functions which put private information on stack */ +/* #define LTC_CLEAN_STACK */ + +/* disable all file related functions */ +/* #define LTC_NO_FILE */ + +/* disable all forms of ASM */ +/* #define LTC_NO_ASM */ + +/* disable FAST mode */ +/* #define LTC_NO_FAST */ + +/* disable BSWAP on x86 */ +/* #define LTC_NO_BSWAP */ + +/* ---> math provider? <--- */ +#ifndef LTC_NO_MATH + +/* LibTomMath */ +/* #define LTM_DESC */ + +/* TomsFastMath */ +/* #define TFM_DESC */ + +/* GNU Multiple Precision Arithmetic Library */ +/* #define GMP_DESC */ + +#endif /* LTC_NO_MATH */ + +/* ---> Symmetric Block Ciphers <--- */ +#ifndef LTC_NO_CIPHERS + +#define LTC_BLOWFISH +#define LTC_RC2 +#define LTC_RC5 +#define LTC_RC6 +#define LTC_SAFERP +#define LTC_RIJNDAEL +#define LTC_XTEA +/* _TABLES tells it to use tables during setup, _SMALL means to use the smaller scheduled key format + * (saves 4KB of ram), _ALL_TABLES enables all tables during setup */ +#define LTC_TWOFISH +#ifndef LTC_NO_TABLES + #define LTC_TWOFISH_TABLES + /* #define LTC_TWOFISH_ALL_TABLES */ +#else + #define LTC_TWOFISH_SMALL +#endif +/* #define LTC_TWOFISH_SMALL */ +/* LTC_DES includes EDE triple-DES */ +#define LTC_DES +#define LTC_CAST5 +#define LTC_NOEKEON +#define LTC_SKIPJACK +#define LTC_SAFER +#define LTC_KHAZAD +#define LTC_ANUBIS +#define LTC_ANUBIS_TWEAK +#define LTC_KSEED +#define LTC_KASUMI +#define LTC_MULTI2 +#define LTC_CAMELLIA + +/* stream ciphers */ +#define LTC_CHACHA +#define LTC_RC4_STREAM +#define LTC_SOBER128_STREAM + +#endif /* LTC_NO_CIPHERS */ + + +/* ---> Block Cipher Modes of Operation <--- */ +#ifndef LTC_NO_MODES + +#define LTC_CFB_MODE +#define LTC_OFB_MODE +#define LTC_ECB_MODE +#define LTC_CBC_MODE +#define LTC_CTR_MODE + +/* F8 chaining mode */ +#define LTC_F8_MODE + +/* LRW mode */ +#define LTC_LRW_MODE +#ifndef LTC_NO_TABLES + /* like GCM mode this will enable 16 8x128 tables [64KB] that make + * seeking very fast. + */ + #define LTC_LRW_TABLES +#endif + +/* XTS mode */ +#define LTC_XTS_MODE + +#endif /* LTC_NO_MODES */ + +/* ---> One-Way Hash Functions <--- */ +#ifndef LTC_NO_HASHES + +#define LTC_CHC_HASH +#define LTC_WHIRLPOOL +#define LTC_SHA3 +#define LTC_SHA512 +#define LTC_SHA512_256 +#define LTC_SHA512_224 +#define LTC_SHA384 +#define LTC_SHA256 +#define LTC_SHA224 +#define LTC_TIGER +#define LTC_SHA1 +#define LTC_MD5 +#define LTC_MD4 +#define LTC_MD2 +#define LTC_RIPEMD128 +#define LTC_RIPEMD160 +#define LTC_RIPEMD256 +#define LTC_RIPEMD320 +#define LTC_BLAKE2S +#define LTC_BLAKE2B + +#define LTC_HASH_HELPERS + +#endif /* LTC_NO_HASHES */ + + +/* ---> MAC functions <--- */ +#ifndef LTC_NO_MACS + +#define LTC_HMAC +#define LTC_OMAC +#define LTC_PMAC +#define LTC_XCBC +#define LTC_F9_MODE +#define LTC_PELICAN +#define LTC_POLY1305 +#define LTC_BLAKE2SMAC +#define LTC_BLAKE2BMAC + +/* ---> Encrypt + Authenticate Modes <--- */ + +#define LTC_EAX_MODE + +#define LTC_OCB_MODE +#define LTC_OCB3_MODE +#define LTC_CCM_MODE +#define LTC_GCM_MODE +#define LTC_CHACHA20POLY1305_MODE + +/* Use 64KiB tables */ +#ifndef LTC_NO_TABLES + #define LTC_GCM_TABLES +#endif + +/* USE SSE2? requires GCC works on x86_32 and x86_64*/ +#ifdef LTC_GCM_TABLES +/* #define LTC_GCM_TABLES_SSE2 */ +#endif + +#endif /* LTC_NO_MACS */ + + +/* --> Pseudo Random Number Generators <--- */ +#ifndef LTC_NO_PRNGS + +/* Yarrow */ +#define LTC_YARROW + +/* a PRNG that simply reads from an available system source */ +#define LTC_SPRNG + +/* The RC4 stream cipher based PRNG */ +#define LTC_RC4 + +/* The ChaCha20 stream cipher based PRNG */ +#define LTC_CHACHA20_PRNG + +/* Fortuna PRNG */ +#define LTC_FORTUNA + +/* Greg's SOBER128 stream cipher based PRNG */ +#define LTC_SOBER128 + +/* the *nix style /dev/random device */ +#define LTC_DEVRANDOM +/* try /dev/urandom before trying /dev/random + * are you sure you want to disable this? http://www.2uo.de/myths-about-urandom/ */ +#define LTC_TRY_URANDOM_FIRST +/* rng_get_bytes() */ +#define LTC_RNG_GET_BYTES +/* rng_make_prng() */ +#define LTC_RNG_MAKE_PRNG + +/* enable the ltc_rng hook to integrate e.g. embedded hardware RNG's easily */ +/* #define LTC_PRNG_ENABLE_LTC_RNG */ + +#endif /* LTC_NO_PRNGS */ + +#ifdef LTC_YARROW + +/* which descriptor of AES to use? */ +/* 0 = rijndael_enc 1 = aes_enc, 2 = rijndael [full], 3 = aes [full] */ +#ifdef ENCRYPT_ONLY + #define LTC_YARROW_AES 0 +#else + #define LTC_YARROW_AES 2 +#endif + +#endif + +#ifdef LTC_FORTUNA + +#ifndef LTC_FORTUNA_WD +/* reseed every N calls to the read function */ +#define LTC_FORTUNA_WD 10 +#endif + +#ifndef LTC_FORTUNA_POOLS +/* number of pools (4..32) can save a bit of ram by lowering the count */ +#define LTC_FORTUNA_POOLS 32 +#endif + +#endif /* LTC_FORTUNA */ + + +/* ---> Public Key Crypto <--- */ +#ifndef LTC_NO_PK + +/* Include RSA support */ +#define LTC_MRSA + +/* Include Diffie-Hellman support */ +/* is_prime fails for GMP */ +#define LTC_MDH +/* Supported Key Sizes */ +#define LTC_DH768 +#define LTC_DH1024 +#define LTC_DH1280 +#define LTC_DH1536 +#define LTC_DH1792 +#define LTC_DH2048 + +#ifndef TFM_DESC +/* tfm has a problem in fp_isprime for larger key sizes */ +#define LTC_DH2560 +#define LTC_DH3072 +#define LTC_DH4096 +#endif + +/* Include Katja (a Rabin variant like RSA) */ +/* #define LTC_MKAT */ + +/* Digital Signature Algorithm */ +#define LTC_MDSA + +/* ECC */ +#define LTC_MECC + +/* use Shamir's trick for point mul (speeds up signature verification) */ +#define LTC_ECC_SHAMIR + +#if defined(TFM_DESC) && defined(LTC_MECC) + #define LTC_MECC_ACCEL +#endif + +/* do we want fixed point ECC */ +/* #define LTC_MECC_FP */ + +#endif /* LTC_NO_PK */ + +#if defined(LTC_MRSA) && !defined(LTC_NO_RSA_BLINDING) +/* Enable RSA blinding when doing private key operations by default */ +#define LTC_RSA_BLINDING +#endif /* LTC_NO_RSA_BLINDING */ + +#if defined(LTC_MRSA) && !defined(LTC_NO_RSA_CRT_HARDENING) +/* Enable RSA CRT hardening when doing private key operations by default */ +#define LTC_RSA_CRT_HARDENING +#endif /* LTC_NO_RSA_CRT_HARDENING */ + +#if defined(LTC_MECC) && !defined(LTC_NO_ECC_TIMING_RESISTANT) +/* Enable ECC timing resistant version by default */ +#define LTC_ECC_TIMING_RESISTANT +#endif + +/* define these PK sizes out of LTC_NO_PK + * to have them always defined + */ +#if defined(LTC_MRSA) +/* Min and Max RSA key sizes (in bits) */ +#ifndef MIN_RSA_SIZE +#define MIN_RSA_SIZE 1024 +#endif +#ifndef MAX_RSA_SIZE +#define MAX_RSA_SIZE 4096 +#endif +#endif + +/* in cases where you want ASN.1/DER functionality, but no + * RSA, you can define this externally if 1024 is not enough + */ +#if defined(LTC_MRSA) +#define LTC_DER_MAX_PUBKEY_SIZE MAX_RSA_SIZE +#elif !defined(LTC_DER_MAX_PUBKEY_SIZE) +/* this includes DSA */ +#define LTC_DER_MAX_PUBKEY_SIZE 1024 +#endif + + +/* PKCS #1 (RSA) and #5 (Password Handling) stuff */ +#ifndef LTC_NO_PKCS + +#define LTC_PKCS_1 +#define LTC_PKCS_5 + +/* Include ASN.1 DER (required by DSA/RSA) */ +#define LTC_DER + +#endif /* LTC_NO_PKCS */ + +/* misc stuff */ +#ifndef LTC_NO_MISC + +/* Various tidbits of modern neatoness */ +#define LTC_BASE64 +/* ... and it's URL safe version */ +#define LTC_BASE64_URL + +/* Keep LTC_NO_HKDF for compatibility reasons + * superseeded by LTC_NO_MISC*/ +#ifndef LTC_NO_HKDF +/* HKDF Key Derivation/Expansion stuff */ +#define LTC_HKDF +#endif /* LTC_NO_HKDF */ + +#define LTC_ADLER32 + +#define LTC_CRC32 + +#endif /* LTC_NO_MISC */ + +/* cleanup */ + +#ifdef LTC_MECC +/* Supported ECC Key Sizes */ +#ifndef LTC_NO_CURVES + #define LTC_ECC_SECP112R1 + #define LTC_ECC_SECP112R2 + #define LTC_ECC_SECP128R1 + #define LTC_ECC_SECP128R2 + #define LTC_ECC_SECP160R1 + #define LTC_ECC_SECP160R2 + #define LTC_ECC_SECP160K1 + #define LTC_ECC_BRAINPOOLP160R1 + #define LTC_ECC_SECP192R1 + #define LTC_ECC_PRIME192V2 + #define LTC_ECC_PRIME192V3 + #define LTC_ECC_SECP192K1 + #define LTC_ECC_BRAINPOOLP192R1 + #define LTC_ECC_SECP224R1 + #define LTC_ECC_SECP224K1 + #define LTC_ECC_BRAINPOOLP224R1 + #define LTC_ECC_PRIME239V1 + #define LTC_ECC_PRIME239V2 + #define LTC_ECC_PRIME239V3 + #define LTC_ECC_SECP256R1 + #define LTC_ECC_SECP256K1 + #define LTC_ECC_BRAINPOOLP256R1 + #define LTC_ECC_BRAINPOOLP320R1 + #define LTC_ECC_SECP384R1 + #define LTC_ECC_BRAINPOOLP384R1 + #define LTC_ECC_BRAINPOOLP512R1 + #define LTC_ECC_SECP521R1 + /* OLD deprecated (but still working) defines */ + #define LTC_ECC112 + #define LTC_ECC128 + #define LTC_ECC160 + #define LTC_ECC192 + #define LTC_ECC224 + #define LTC_ECC256 + #define LTC_ECC384 + #define LTC_ECC521 +#endif +#endif + +#if defined(LTC_MECC) || defined(LTC_MRSA) || defined(LTC_MDSA) || defined(LTC_MKAT) + /* Include the MPI functionality? (required by the PK algorithms) */ + #define LTC_MPI +#endif + +#ifdef LTC_MRSA + #define LTC_PKCS_1 +#endif + +#if defined(TFM_DESC) && defined(LTC_RSA_BLINDING) + #warning RSA blinding currently not supported in combination with TFM + #undef LTC_RSA_BLINDING +#endif + +#if defined(LTC_PELICAN) && !defined(LTC_RIJNDAEL) + #error Pelican-MAC requires LTC_RIJNDAEL +#endif + +#if defined(LTC_EAX_MODE) && !(defined(LTC_CTR_MODE) && defined(LTC_OMAC)) + #error LTC_EAX_MODE requires CTR and LTC_OMAC mode +#endif + +#if defined(LTC_YARROW) && !defined(LTC_CTR_MODE) + #error LTC_YARROW requires LTC_CTR_MODE chaining mode to be defined! +#endif + +#if defined(LTC_DER) && !defined(LTC_MPI) + #error ASN.1 DER requires MPI functionality +#endif + +#if (defined(LTC_MDSA) || defined(LTC_MRSA) || defined(LTC_MECC) || defined(LTC_MKAT)) && !defined(LTC_DER) + #error PK requires ASN.1 DER functionality, make sure LTC_DER is enabled +#endif + +#if defined(LTC_CHACHA20POLY1305_MODE) && (!defined(LTC_CHACHA) || !defined(LTC_POLY1305)) + #error LTC_CHACHA20POLY1305_MODE requires LTC_CHACHA + LTC_POLY1305 +#endif + +#if defined(LTC_CHACHA20_PRNG) && !defined(LTC_CHACHA) + #error LTC_CHACHA20_PRNG requires LTC_CHACHA +#endif + +#if defined(LTC_RC4) && !defined(LTC_RC4_STREAM) + #error LTC_RC4 requires LTC_RC4_STREAM +#endif + +#if defined(LTC_SOBER128) && !defined(LTC_SOBER128_STREAM) + #error LTC_SOBER128 requires LTC_SOBER128_STREAM +#endif + +#if defined(LTC_BLAKE2SMAC) && !defined(LTC_BLAKE2S) + #error LTC_BLAKE2SMAC requires LTC_BLAKE2S +#endif + +#if defined(LTC_BLAKE2BMAC) && !defined(LTC_BLAKE2B) + #error LTC_BLAKE2BMAC requires LTC_BLAKE2B +#endif + +/* THREAD management */ +#ifdef LTC_PTHREAD + +#include + +#define LTC_MUTEX_GLOBAL(x) pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER; +#define LTC_MUTEX_PROTO(x) extern pthread_mutex_t x; +#define LTC_MUTEX_TYPE(x) pthread_mutex_t x; +#define LTC_MUTEX_INIT(x) pthread_mutex_init(x, NULL); +#define LTC_MUTEX_LOCK(x) pthread_mutex_lock(x); +#define LTC_MUTEX_UNLOCK(x) pthread_mutex_unlock(x); + +#else + +/* default no functions */ +#define LTC_MUTEX_GLOBAL(x) +#define LTC_MUTEX_PROTO(x) +#define LTC_MUTEX_TYPE(x) +#define LTC_MUTEX_INIT(x) +#define LTC_MUTEX_LOCK(x) +#define LTC_MUTEX_UNLOCK(x) + +#endif + +/* Debuggers */ + +/* define this if you use Valgrind, note: it CHANGES the way SOBER-128 and RC4 work (see the code) */ +/* #define LTC_VALGRIND */ + +#endif + +#ifndef LTC_NO_FILE + /* buffer size for reading from a file via fread(..) */ + #ifndef LTC_FILE_READ_BUFSIZE + #define LTC_FILE_READ_BUFSIZE 8192 + #endif +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/headers/tomcrypt_hash.h b/src/ltc/headers/tomcrypt_hash.h new file mode 100644 index 0000000..c73d387 --- /dev/null +++ b/src/ltc/headers/tomcrypt_hash.h @@ -0,0 +1,521 @@ +/* ---- HASH FUNCTIONS ---- */ +#ifdef LTC_SHA3 +struct sha3_state { + ulong64 saved; /* the portion of the input message that we didn't consume yet */ + ulong64 s[25]; + unsigned char sb[25 * 8]; /* used for storing `ulong64 s[25]` as little-endian bytes */ + unsigned short byte_index; /* 0..7--the next byte after the set one (starts from 0; 0--none are buffered) */ + unsigned short word_index; /* 0..24--the next word to integrate input (starts from 0) */ + unsigned short capacity_words; /* the double size of the hash output in words (e.g. 16 for Keccak 512) */ + unsigned short xof_flag; +}; +#endif + +#ifdef LTC_SHA512 +struct sha512_state { + ulong64 length, state[8]; + unsigned long curlen; + unsigned char buf[128]; +}; +#endif + +#ifdef LTC_SHA256 +struct sha256_state { + ulong64 length; + ulong32 state[8], curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef LTC_SHA1 +struct sha1_state { + ulong64 length; + ulong32 state[5], curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef LTC_MD5 +struct md5_state { + ulong64 length; + ulong32 state[4], curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef LTC_MD4 +struct md4_state { + ulong64 length; + ulong32 state[4], curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef LTC_TIGER +struct tiger_state { + ulong64 state[3], length; + unsigned long curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef LTC_MD2 +struct md2_state { + unsigned char chksum[16], X[48], buf[16]; + unsigned long curlen; +}; +#endif + +#ifdef LTC_RIPEMD128 +struct rmd128_state { + ulong64 length; + unsigned char buf[64]; + ulong32 curlen, state[4]; +}; +#endif + +#ifdef LTC_RIPEMD160 +struct rmd160_state { + ulong64 length; + unsigned char buf[64]; + ulong32 curlen, state[5]; +}; +#endif + +#ifdef LTC_RIPEMD256 +struct rmd256_state { + ulong64 length; + unsigned char buf[64]; + ulong32 curlen, state[8]; +}; +#endif + +#ifdef LTC_RIPEMD320 +struct rmd320_state { + ulong64 length; + unsigned char buf[64]; + ulong32 curlen, state[10]; +}; +#endif + +#ifdef LTC_WHIRLPOOL +struct whirlpool_state { + ulong64 length, state[8]; + unsigned char buf[64]; + ulong32 curlen; +}; +#endif + +#ifdef LTC_CHC_HASH +struct chc_state { + ulong64 length; + unsigned char state[MAXBLOCKSIZE], buf[MAXBLOCKSIZE]; + ulong32 curlen; +}; +#endif + +#ifdef LTC_BLAKE2S +struct blake2s_state { + ulong32 h[8]; + ulong32 t[2]; + ulong32 f[2]; + unsigned char buf[64]; + unsigned long curlen; + unsigned long outlen; + unsigned char last_node; +}; +#endif + +#ifdef LTC_BLAKE2B +struct blake2b_state { + ulong64 h[8]; + ulong64 t[2]; + ulong64 f[2]; + unsigned char buf[128]; + unsigned long curlen; + unsigned long outlen; + unsigned char last_node; +}; +#endif + +typedef union Hash_state { + char dummy[1]; +#ifdef LTC_CHC_HASH + struct chc_state chc; +#endif +#ifdef LTC_WHIRLPOOL + struct whirlpool_state whirlpool; +#endif +#ifdef LTC_SHA3 + struct sha3_state sha3; +#endif +#ifdef LTC_SHA512 + struct sha512_state sha512; +#endif +#ifdef LTC_SHA256 + struct sha256_state sha256; +#endif +#ifdef LTC_SHA1 + struct sha1_state sha1; +#endif +#ifdef LTC_MD5 + struct md5_state md5; +#endif +#ifdef LTC_MD4 + struct md4_state md4; +#endif +#ifdef LTC_MD2 + struct md2_state md2; +#endif +#ifdef LTC_TIGER + struct tiger_state tiger; +#endif +#ifdef LTC_RIPEMD128 + struct rmd128_state rmd128; +#endif +#ifdef LTC_RIPEMD160 + struct rmd160_state rmd160; +#endif +#ifdef LTC_RIPEMD256 + struct rmd256_state rmd256; +#endif +#ifdef LTC_RIPEMD320 + struct rmd320_state rmd320; +#endif +#ifdef LTC_BLAKE2S + struct blake2s_state blake2s; +#endif +#ifdef LTC_BLAKE2B + struct blake2b_state blake2b; +#endif + + void *data; +} hash_state; + +/** hash descriptor */ +extern 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 OID */ + unsigned long OID[16]; + /** Length of DER encoding */ + unsigned long OIDlen; + + /** 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); + + /* accelerated hmac callback: if you need to-do multiple packets just use the generic hmac_memory and provide a hash callback */ + int (*hmac_block)(const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +} hash_descriptor[]; + +#ifdef LTC_CHC_HASH +int chc_register(int cipher); +int chc_init(hash_state * md); +int chc_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int chc_done(hash_state * md, unsigned char *hash); +int chc_test(void); +extern const struct ltc_hash_descriptor chc_desc; +#endif + +#ifdef LTC_WHIRLPOOL +int whirlpool_init(hash_state * md); +int whirlpool_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int whirlpool_done(hash_state * md, unsigned char *hash); +int whirlpool_test(void); +extern const struct ltc_hash_descriptor whirlpool_desc; +#endif + +#ifdef LTC_SHA3 +int sha3_512_init(hash_state * md); +int sha3_512_test(void); +extern const struct ltc_hash_descriptor sha3_512_desc; +int sha3_384_init(hash_state * md); +int sha3_384_test(void); +extern const struct ltc_hash_descriptor sha3_384_desc; +int sha3_256_init(hash_state * md); +int sha3_256_test(void); +extern const struct ltc_hash_descriptor sha3_256_desc; +int sha3_224_init(hash_state * md); +int sha3_224_test(void); +extern const struct ltc_hash_descriptor sha3_224_desc; +/* process + done are the same for all variants */ +int sha3_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int sha3_done(hash_state *md, unsigned char *hash); +/* SHAKE128 + SHAKE256 */ +int sha3_shake_init(hash_state *md, int num); +#define sha3_shake_process(a,b,c) sha3_process(a,b,c) +int sha3_shake_done(hash_state *md, unsigned char *out, unsigned long outlen); +int sha3_shake_test(void); +int sha3_shake_memory(int num, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); +#endif + +#ifdef LTC_SHA512 +int sha512_init(hash_state * md); +int sha512_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int sha512_done(hash_state * md, unsigned char *hash); +int sha512_test(void); +extern const struct ltc_hash_descriptor sha512_desc; +#endif + +#ifdef LTC_SHA384 +#ifndef LTC_SHA512 + #error LTC_SHA512 is required for LTC_SHA384 +#endif +int sha384_init(hash_state * md); +#define sha384_process sha512_process +int sha384_done(hash_state * md, unsigned char *hash); +int sha384_test(void); +extern const struct ltc_hash_descriptor sha384_desc; +#endif + +#ifdef LTC_SHA512_256 +#ifndef LTC_SHA512 + #error LTC_SHA512 is required for LTC_SHA512_256 +#endif +int sha512_256_init(hash_state * md); +#define sha512_256_process sha512_process +int sha512_256_done(hash_state * md, unsigned char *hash); +int sha512_256_test(void); +extern const struct ltc_hash_descriptor sha512_256_desc; +#endif + +#ifdef LTC_SHA512_224 +#ifndef LTC_SHA512 + #error LTC_SHA512 is required for LTC_SHA512_224 +#endif +int sha512_224_init(hash_state * md); +#define sha512_224_process sha512_process +int sha512_224_done(hash_state * md, unsigned char *hash); +int sha512_224_test(void); +extern const struct ltc_hash_descriptor sha512_224_desc; +#endif + +#ifdef LTC_SHA256 +int sha256_init(hash_state * md); +int sha256_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int sha256_done(hash_state * md, unsigned char *hash); +int sha256_test(void); +extern const struct ltc_hash_descriptor sha256_desc; + +#ifdef LTC_SHA224 +#ifndef LTC_SHA256 + #error LTC_SHA256 is required for LTC_SHA224 +#endif +int sha224_init(hash_state * md); +#define sha224_process sha256_process +int sha224_done(hash_state * md, unsigned char *hash); +int sha224_test(void); +extern const struct ltc_hash_descriptor sha224_desc; +#endif +#endif + +#ifdef LTC_SHA1 +int sha1_init(hash_state * md); +int sha1_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int sha1_done(hash_state * md, unsigned char *hash); +int sha1_test(void); +extern const struct ltc_hash_descriptor sha1_desc; +#endif + +#ifdef LTC_BLAKE2S +extern const struct ltc_hash_descriptor blake2s_256_desc; +int blake2s_256_init(hash_state * md); +int blake2s_256_test(void); + +extern const struct ltc_hash_descriptor blake2s_224_desc; +int blake2s_224_init(hash_state * md); +int blake2s_224_test(void); + +extern const struct ltc_hash_descriptor blake2s_160_desc; +int blake2s_160_init(hash_state * md); +int blake2s_160_test(void); + +extern const struct ltc_hash_descriptor blake2s_128_desc; +int blake2s_128_init(hash_state * md); +int blake2s_128_test(void); + +int blake2s_init(hash_state * md, unsigned long outlen, const unsigned char *key, unsigned long keylen); +int blake2s_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int blake2s_done(hash_state * md, unsigned char *hash); +#endif + +#ifdef LTC_BLAKE2B +extern const struct ltc_hash_descriptor blake2b_512_desc; +int blake2b_512_init(hash_state * md); +int blake2b_512_test(void); + +extern const struct ltc_hash_descriptor blake2b_384_desc; +int blake2b_384_init(hash_state * md); +int blake2b_384_test(void); + +extern const struct ltc_hash_descriptor blake2b_256_desc; +int blake2b_256_init(hash_state * md); +int blake2b_256_test(void); + +extern const struct ltc_hash_descriptor blake2b_160_desc; +int blake2b_160_init(hash_state * md); +int blake2b_160_test(void); + +int blake2b_init(hash_state * md, unsigned long outlen, const unsigned char *key, unsigned long keylen); +int blake2b_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int blake2b_done(hash_state * md, unsigned char *hash); +#endif + +#ifdef LTC_MD5 +int md5_init(hash_state * md); +int md5_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int md5_done(hash_state * md, unsigned char *hash); +int md5_test(void); +extern const struct ltc_hash_descriptor md5_desc; +#endif + +#ifdef LTC_MD4 +int md4_init(hash_state * md); +int md4_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int md4_done(hash_state * md, unsigned char *hash); +int md4_test(void); +extern const struct ltc_hash_descriptor md4_desc; +#endif + +#ifdef LTC_MD2 +int md2_init(hash_state * md); +int md2_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int md2_done(hash_state * md, unsigned char *hash); +int md2_test(void); +extern const struct ltc_hash_descriptor md2_desc; +#endif + +#ifdef LTC_TIGER +int tiger_init(hash_state * md); +int tiger_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int tiger_done(hash_state * md, unsigned char *hash); +int tiger_test(void); +extern const struct ltc_hash_descriptor tiger_desc; +#endif + +#ifdef LTC_RIPEMD128 +int rmd128_init(hash_state * md); +int rmd128_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int rmd128_done(hash_state * md, unsigned char *hash); +int rmd128_test(void); +extern const struct ltc_hash_descriptor rmd128_desc; +#endif + +#ifdef LTC_RIPEMD160 +int rmd160_init(hash_state * md); +int rmd160_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int rmd160_done(hash_state * md, unsigned char *hash); +int rmd160_test(void); +extern const struct ltc_hash_descriptor rmd160_desc; +#endif + +#ifdef LTC_RIPEMD256 +int rmd256_init(hash_state * md); +int rmd256_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int rmd256_done(hash_state * md, unsigned char *hash); +int rmd256_test(void); +extern const struct ltc_hash_descriptor rmd256_desc; +#endif + +#ifdef LTC_RIPEMD320 +int rmd320_init(hash_state * md); +int rmd320_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int rmd320_done(hash_state * md, unsigned char *hash); +int rmd320_test(void); +extern const struct ltc_hash_descriptor rmd320_desc; +#endif + + +int find_hash(const char *name); +int find_hash_id(unsigned char ID); +int find_hash_oid(const unsigned long *ID, unsigned long IDlen); +int find_hash_any(const char *name, int digestlen); +int register_hash(const struct ltc_hash_descriptor *hash); +int unregister_hash(const struct ltc_hash_descriptor *hash); +int hash_is_valid(int idx); + +LTC_MUTEX_PROTO(ltc_hash_mutex) + +int hash_memory(int hash, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int hash_memory_multi(int hash, unsigned char *out, unsigned long *outlen, + const unsigned char *in, unsigned long inlen, ...); + +#ifndef LTC_NO_FILE +int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned long *outlen); +int hash_file(int hash, const char *fname, unsigned char *out, unsigned long *outlen); +#endif + +/* a simple macro for making hash "process" functions */ +#define HASH_PROCESS(func_name, compress_name, state_var, block_size) \ +int func_name (hash_state * md, const unsigned char *in, unsigned long inlen) \ +{ \ + unsigned long n; \ + int err; \ + LTC_ARGCHK(md != NULL); \ + LTC_ARGCHK(in != NULL); \ + if (md-> state_var .curlen > sizeof(md-> state_var .buf)) { \ + return CRYPT_INVALID_ARG; \ + } \ + if ((md-> state_var .length + inlen) < md-> state_var .length) { \ + return CRYPT_HASH_OVERFLOW; \ + } \ + while (inlen > 0) { \ + if (md-> state_var .curlen == 0 && inlen >= block_size) { \ + if ((err = compress_name (md, (unsigned char *)in)) != CRYPT_OK) { \ + return err; \ + } \ + md-> state_var .length += block_size * 8; \ + in += block_size; \ + inlen -= block_size; \ + } else { \ + n = MIN(inlen, (block_size - md-> state_var .curlen)); \ + XMEMCPY(md-> state_var .buf + md-> state_var.curlen, in, (size_t)n); \ + md-> state_var .curlen += n; \ + in += n; \ + inlen -= n; \ + if (md-> state_var .curlen == block_size) { \ + if ((err = compress_name (md, md-> state_var .buf)) != CRYPT_OK) { \ + return err; \ + } \ + md-> state_var .length += 8*block_size; \ + md-> state_var .curlen = 0; \ + } \ + } \ + } \ + return CRYPT_OK; \ +} + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/headers/tomcrypt_mac.h b/src/ltc/headers/tomcrypt_mac.h new file mode 100644 index 0000000..5e5f84c --- /dev/null +++ b/src/ltc/headers/tomcrypt_mac.h @@ -0,0 +1,557 @@ +#ifdef LTC_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 LTC_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 /* LTC_OMAC */ + +#ifdef LTC_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 LTC_POLY1305 +typedef struct { + ulong32 r[5]; + ulong32 h[5]; + ulong32 pad[4]; + unsigned long leftover; + unsigned char buffer[16]; + int final; +} poly1305_state; + +int poly1305_init(poly1305_state *st, const unsigned char *key, unsigned long keylen); +int poly1305_process(poly1305_state *st, const unsigned char *in, unsigned long inlen); +int poly1305_done(poly1305_state *st, unsigned char *mac, unsigned long *maclen); +int poly1305_test(void); +int poly1305_memory(const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *mac, unsigned long *maclen); +int poly1305_memory_multi(const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen, const unsigned char *in, unsigned long inlen, ...); +int poly1305_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen); +int poly1305_test(void); +#endif /* LTC_POLY1305 */ + +#ifdef LTC_BLAKE2SMAC +typedef hash_state blake2smac_state; +int blake2smac_init(blake2smac_state *st, unsigned long outlen, const unsigned char *key, unsigned long keylen); +int blake2smac_process(blake2smac_state *st, const unsigned char *in, unsigned long inlen); +int blake2smac_done(blake2smac_state *st, unsigned char *mac, unsigned long *maclen); +int blake2smac_test(void); +int blake2smac_memory(const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *mac, unsigned long *maclen); +int blake2smac_memory_multi(const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen, const unsigned char *in, unsigned long inlen, ...); +int blake2smac_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen); +int blake2smac_test(void); +#endif /* LTC_BLAKE2SMAC */ + +#ifdef LTC_BLAKE2BMAC +typedef hash_state blake2bmac_state; +int blake2bmac_init(blake2bmac_state *st, unsigned long outlen, const unsigned char *key, unsigned long keylen); +int blake2bmac_process(blake2bmac_state *st, const unsigned char *in, unsigned long inlen); +int blake2bmac_done(blake2bmac_state *st, unsigned char *mac, unsigned long *maclen); +int blake2bmac_test(void); +int blake2bmac_memory(const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *mac, unsigned long *maclen); +int blake2bmac_memory_multi(const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen, const unsigned char *in, unsigned long inlen, ...); +int blake2bmac_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen); +int blake2bmac_test(void); +#endif /* LTC_BLAKE2BMAC */ + +#ifdef LTC_EAX_MODE + +#if !(defined(LTC_OMAC) && defined(LTC_CTR_MODE)) + #error LTC_EAX_MODE requires LTC_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 LTC_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 /* LTC_OCB_MODE */ + +#ifdef LTC_OCB3_MODE +typedef struct { + unsigned char Offset_0[MAXBLOCKSIZE], /* Offset_0 value */ + Offset_current[MAXBLOCKSIZE], /* Offset_{current_block_index} value */ + L_dollar[MAXBLOCKSIZE], /* L_$ value */ + L_star[MAXBLOCKSIZE], /* L_* value */ + L_[32][MAXBLOCKSIZE], /* L_{i} values */ + tag_part[MAXBLOCKSIZE], /* intermediate result of tag calculation */ + checksum[MAXBLOCKSIZE]; /* current checksum */ + + /* AAD related members */ + unsigned char aSum_current[MAXBLOCKSIZE], /* AAD related helper variable */ + aOffset_current[MAXBLOCKSIZE], /* AAD related helper variable */ + adata_buffer[MAXBLOCKSIZE]; /* AAD buffer */ + int adata_buffer_bytes; /* bytes in AAD buffer */ + unsigned long ablock_index; /* index # for current adata (AAD) block */ + + symmetric_key key; /* scheduled key for cipher */ + unsigned long block_index; /* index # for current data block */ + int cipher, /* cipher idx */ + block_len; /* length of block */ +} ocb3_state; + +int ocb3_init(ocb3_state *ocb, int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen); + +int ocb3_encrypt(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct); +int ocb3_decrypt(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt); +int ocb3_encrypt_last(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct); +int ocb3_decrypt_last(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt); +int ocb3_add_aad(ocb3_state *ocb, const unsigned char *aad, unsigned long aadlen); +int ocb3_done(ocb3_state *ocb, unsigned char *tag, unsigned long *taglen); + +int ocb3_encrypt_authenticate_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *adata, unsigned long adatalen, + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen); + +int ocb3_decrypt_verify_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *adata, unsigned long adatalen, + const unsigned char *ct, unsigned long ctlen, + unsigned char *pt, + const unsigned char *tag, unsigned long taglen, + int *stat); + +int ocb3_test(void); + +/* internal helper functions */ +int ocb3_int_aad_add_block(ocb3_state *ocb, const unsigned char *aad_block); +void ocb3_int_calc_offset_zero(ocb3_state *ocb, const unsigned char *nonce, unsigned long noncelen); +int ocb3_int_ntz(unsigned long x); +void ocb3_int_xor_blocks(unsigned char *out, const unsigned char *block_a, const unsigned char *block_b, unsigned long block_len); + +#endif /* LTC_OCB3_MODE */ + +#ifdef LTC_CCM_MODE + +#define CCM_ENCRYPT 0 +#define CCM_DECRYPT 1 + +typedef struct { + symmetric_key K; + int cipher, /* which cipher */ + taglen, /* length of the tag */ + x; /* index in PAD */ + + unsigned long L, /* L value */ + ptlen, /* length that will be enc / dec */ + current_ptlen, /* current processed length */ + aadlen, /* length of the aad */ + current_aadlen, /* length of the currently provided add */ + noncelen; /* length of the nonce */ + + unsigned char PAD[16], + ctr[16], + CTRPAD[16], + CTRlen; +} ccm_state; + +int ccm_init(ccm_state *ccm, int cipher, + const unsigned char *key, int keylen, int ptlen, int taglen, int aad_len); + +int ccm_reset(ccm_state *ccm); + +int ccm_add_nonce(ccm_state *ccm, + const unsigned char *nonce, unsigned long noncelen); + +int ccm_add_aad(ccm_state *ccm, + const unsigned char *adata, unsigned long adatalen); + +int ccm_process(ccm_state *ccm, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + int direction); + +int ccm_done(ccm_state *ccm, + unsigned char *tag, unsigned long *taglen); + +int ccm_memory(int cipher, + const unsigned char *key, unsigned long keylen, + symmetric_key *uskey, + 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 /* LTC_CCM_MODE */ + +#if defined(LRW_MODE) || defined(LTC_GCM_MODE) +void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c); +#endif + + +/* table shared between GCM and LRW */ +#if defined(LTC_GCM_TABLES) || defined(LTC_LRW_TABLES) || ((defined(LTC_GCM_MODE) || defined(LTC_GCM_MODE)) && defined(LTC_FAST)) +extern const unsigned char gcm_shift_table[]; +#endif + +#ifdef LTC_GCM_MODE + +#define GCM_ENCRYPT 0 +#define GCM_DECRYPT 1 + +#define LTC_GCM_MODE_IV 0 +#define LTC_GCM_MODE_AAD 1 +#define LTC_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 LTC_GCM_TABLES + unsigned char PC[16][256][16] /* 16 tables of 8x128 */ +#ifdef LTC_GCM_TABLES_SSE2 +__attribute__ ((aligned (16))) +#endif +; +#endif +} gcm_state; + +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 /* LTC_GCM_MODE */ + +#ifdef LTC_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 + +#ifdef LTC_XCBC + +/* add this to "keylen" to xcbc_init to use a pure three-key XCBC MAC */ +#define LTC_XCBC_PURE 0x8000UL + +typedef struct { + unsigned char K[3][MAXBLOCKSIZE], + IV[MAXBLOCKSIZE]; + + symmetric_key key; + + int cipher, + buflen, + blocksize; +} xcbc_state; + +int xcbc_init(xcbc_state *xcbc, int cipher, const unsigned char *key, unsigned long keylen); +int xcbc_process(xcbc_state *xcbc, const unsigned char *in, unsigned long inlen); +int xcbc_done(xcbc_state *xcbc, unsigned char *out, unsigned long *outlen); +int xcbc_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int xcbc_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 xcbc_file(int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen); +int xcbc_test(void); + +#endif + +#ifdef LTC_F9_MODE + +typedef struct { + unsigned char akey[MAXBLOCKSIZE], + ACC[MAXBLOCKSIZE], + IV[MAXBLOCKSIZE]; + + symmetric_key key; + + int cipher, + buflen, + keylen, + blocksize; +} f9_state; + +int f9_init(f9_state *f9, int cipher, const unsigned char *key, unsigned long keylen); +int f9_process(f9_state *f9, const unsigned char *in, unsigned long inlen); +int f9_done(f9_state *f9, unsigned char *out, unsigned long *outlen); +int f9_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int f9_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 f9_file(int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen); +int f9_test(void); + +#endif + +#ifdef LTC_CHACHA20POLY1305_MODE + +typedef struct { + poly1305_state poly; + chacha_state chacha; + ulong64 aadlen; + ulong64 ctlen; + int aadflg; +} chacha20poly1305_state; + +#define CHCHA20POLY1305_ENCRYPT 0 +#define CHCHA20POLY1305_DECRYPT 1 + +int chacha20poly1305_init(chacha20poly1305_state *st, const unsigned char *key, unsigned long keylen); +int chacha20poly1305_setiv(chacha20poly1305_state *st, const unsigned char *iv, unsigned long ivlen); +int chacha20poly1305_setiv_rfc7905(chacha20poly1305_state *st, const unsigned char *iv, unsigned long ivlen, ulong64 sequence_number); +int chacha20poly1305_add_aad(chacha20poly1305_state *st, const unsigned char *in, unsigned long inlen); +int chacha20poly1305_encrypt(chacha20poly1305_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out); +int chacha20poly1305_decrypt(chacha20poly1305_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out); +int chacha20poly1305_done(chacha20poly1305_state *st, unsigned char *tag, unsigned long *taglen); +int chacha20poly1305_memory(const unsigned char *key, unsigned long keylen, + const unsigned char *iv, unsigned long ivlen, + const unsigned char *aad, unsigned long aadlen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, + unsigned char *tag, unsigned long *taglen, + int direction); +int chacha20poly1305_test(void); + +#endif /* LTC_CHACHA20POLY1305_MODE */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/headers/tomcrypt_macros.h b/src/ltc/headers/tomcrypt_macros.h new file mode 100644 index 0000000..27d76d1 --- /dev/null +++ b/src/ltc/headers/tomcrypt_macros.h @@ -0,0 +1,438 @@ + +/* ---- HELPER MACROS ---- */ +#ifdef ENDIAN_NEUTRAL + +#define STORE32L(x, y) \ + do { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0) + +#define LOAD32L(x, y) \ + do { x = ((ulong32)((y)[3] & 255)<<24) | \ + ((ulong32)((y)[2] & 255)<<16) | \ + ((ulong32)((y)[1] & 255)<<8) | \ + ((ulong32)((y)[0] & 255)); } while(0) + +#define STORE64L(x, y) \ + do { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ + (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ + (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0) + +#define LOAD64L(x, y) \ + do { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \ + (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \ + (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \ + (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } while(0) + +#define STORE32H(x, y) \ + do { (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); } while(0) + +#define LOAD32H(x, y) \ + do { x = ((ulong32)((y)[0] & 255)<<24) | \ + ((ulong32)((y)[1] & 255)<<16) | \ + ((ulong32)((y)[2] & 255)<<8) | \ + ((ulong32)((y)[3] & 255)); } while(0) + +#define STORE64H(x, y) \ +do { (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); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } while(0) + +#define LOAD64H(x, y) \ +do { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \ + (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \ + (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \ + (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } while(0) + + +#elif defined(ENDIAN_LITTLE) + +#ifdef LTC_HAVE_BSWAP_BUILTIN + +#define STORE32H(x, y) \ +do { ulong32 __t = __builtin_bswap32 ((x)); \ + XMEMCPY ((y), &__t, 4); } while(0) + +#define LOAD32H(x, y) \ +do { XMEMCPY (&(x), (y), 4); \ + (x) = __builtin_bswap32 ((x)); } while(0) + +#elif !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,(%1)\n\t" \ + "bswapl %0 \n\t" \ + ::"r"(x), "r"(y)); + +#define LOAD32H(x, y) \ +asm __volatile__ ( \ + "movl (%1),%0\n\t" \ + "bswapl %0\n\t" \ + :"=r"(x): "r"(y)); + +#else + +#define STORE32H(x, y) \ + do { (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); } while(0) + +#define LOAD32H(x, y) \ + do { x = ((ulong32)((y)[0] & 255)<<24) | \ + ((ulong32)((y)[1] & 255)<<16) | \ + ((ulong32)((y)[2] & 255)<<8) | \ + ((ulong32)((y)[3] & 255)); } while(0) + +#endif + +#ifdef LTC_HAVE_BSWAP_BUILTIN + +#define STORE64H(x, y) \ +do { ulong64 __t = __builtin_bswap64 ((x)); \ + XMEMCPY ((y), &__t, 8); } while(0) + +#define LOAD64H(x, y) \ +do { XMEMCPY (&(x), (y), 8); \ + (x) = __builtin_bswap64 ((x)); } while(0) + +/* x86_64 processor */ +#elif !defined(LTC_NO_BSWAP) && (defined(__GNUC__) && defined(__x86_64__)) + +#define STORE64H(x, y) \ +asm __volatile__ ( \ + "bswapq %0 \n\t" \ + "movq %0,(%1)\n\t" \ + "bswapq %0 \n\t" \ + ::"r"(x), "r"(y): "memory"); + +#define LOAD64H(x, y) \ +asm __volatile__ ( \ + "movq (%1),%0\n\t" \ + "bswapq %0\n\t" \ + :"=r"(x): "r"(y): "memory"); + +#else + +#define STORE64H(x, y) \ +do { (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); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } while(0) + +#define LOAD64H(x, y) \ +do { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \ + (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \ + (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \ + (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } while(0) + +#endif + +#ifdef ENDIAN_32BITWORD + +#define STORE32L(x, y) \ + do { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } while(0) + +#define LOAD32L(x, y) \ + do { XMEMCPY(&(x), y, 4); } while(0) + +#define STORE64L(x, y) \ + do { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ + (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ + (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0) + +#define LOAD64L(x, y) \ + do { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \ + (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \ + (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \ + (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } while(0) + +#else /* 64-bit words then */ + +#define STORE32L(x, y) \ + do { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } while(0) + +#define LOAD32L(x, y) \ + do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0) + +#define STORE64L(x, y) \ + do { ulong64 __t = (x); XMEMCPY(y, &__t, 8); } while(0) + +#define LOAD64L(x, y) \ + do { XMEMCPY(&(x), y, 8); } while(0) + +#endif /* ENDIAN_64BITWORD */ + +#elif defined(ENDIAN_BIG) + +#define STORE32L(x, y) \ + do { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0) + +#define LOAD32L(x, y) \ + do { x = ((ulong32)((y)[3] & 255)<<24) | \ + ((ulong32)((y)[2] & 255)<<16) | \ + ((ulong32)((y)[1] & 255)<<8) | \ + ((ulong32)((y)[0] & 255)); } while(0) + +#define STORE64L(x, y) \ +do { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ + (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ + (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0) + +#define LOAD64L(x, y) \ +do { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48) | \ + (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32) | \ + (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16) | \ + (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } while(0) + +#ifdef ENDIAN_32BITWORD + +#define STORE32H(x, y) \ + do { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } while(0) + +#define LOAD32H(x, y) \ + do { XMEMCPY(&(x), y, 4); } while(0) + +#define STORE64H(x, y) \ + do { (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); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } while(0) + +#define LOAD64H(x, y) \ + do { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48)| \ + (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32)| \ + (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16)| \ + (((ulong64)((y)[6] & 255))<<8)| (((ulong64)((y)[7] & 255))); } while(0) + +#else /* 64-bit words then */ + +#define STORE32H(x, y) \ + do { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } while(0) + +#define LOAD32H(x, y) \ + do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0) + +#define STORE64H(x, y) \ + do { ulong64 __t = (x); XMEMCPY(y, &__t, 8); } while(0) + +#define LOAD64H(x, y) \ + do { XMEMCPY(&(x), y, 8); } while(0) + +#endif /* ENDIAN_64BITWORD */ +#endif /* ENDIAN_BIG */ + +#define BSWAP(x) ( ((x>>24)&0x000000FFUL) | ((x<<24)&0xFF000000UL) | \ + ((x>>8)&0x0000FF00UL) | ((x<<8)&0x00FF0000UL) ) + + +/* 32-bit Rotates */ +#if defined(_MSC_VER) +#define LTC_ROx_ASM + +/* instrinsic rotate */ +#include +#pragma intrinsic(_lrotr,_lrotl) +#define ROR(x,n) _lrotr(x,n) +#define ROL(x,n) _lrotl(x,n) +#define RORc(x,n) _lrotr(x,n) +#define ROLc(x,n) _lrotl(x,n) + +#elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && !defined(INTEL_CC) && !defined(LTC_NO_ASM) +#define LTC_ROx_ASM + +static inline ulong32 ROL(ulong32 word, int i) +{ + asm ("roll %%cl,%0" + :"=r" (word) + :"0" (word),"c" (i)); + return word; +} + +static inline ulong32 ROR(ulong32 word, int i) +{ + asm ("rorl %%cl,%0" + :"=r" (word) + :"0" (word),"c" (i)); + return word; +} + +#ifndef LTC_NO_ROLC + +#define ROLc(word,i) ({ \ + ulong32 __ROLc_tmp = (word); \ + __asm__ ("roll %2, %0" : \ + "=r" (__ROLc_tmp) : \ + "0" (__ROLc_tmp), \ + "I" (i)); \ + __ROLc_tmp; \ + }) +#define RORc(word,i) ({ \ + ulong32 __RORc_tmp = (word); \ + __asm__ ("rorl %2, %0" : \ + "=r" (__RORc_tmp) : \ + "0" (__RORc_tmp), \ + "I" (i)); \ + __RORc_tmp; \ + }) + +#else + +#define ROLc ROL +#define RORc ROR + +#endif + +#elif !defined(__STRICT_ANSI__) && defined(LTC_PPC32) +#define LTC_ROx_ASM + +static inline ulong32 ROL(ulong32 word, int i) +{ + asm ("rotlw %0,%0,%2" + :"=r" (word) + :"0" (word),"r" (i)); + return word; +} + +static inline ulong32 ROR(ulong32 word, int i) +{ + asm ("rotlw %0,%0,%2" + :"=r" (word) + :"0" (word),"r" (32-i)); + return word; +} + +#ifndef LTC_NO_ROLC + +static inline ulong32 ROLc(ulong32 word, const int i) +{ + asm ("rotlwi %0,%0,%2" + :"=r" (word) + :"0" (word),"I" (i)); + return word; +} + +static inline ulong32 RORc(ulong32 word, const int i) +{ + asm ("rotrwi %0,%0,%2" + :"=r" (word) + :"0" (word),"I" (i)); + return word; +} + +#else + +#define ROLc ROL +#define RORc ROR + +#endif + + +#else + +/* rotates the hard way */ +#define ROL(x, y) ( (((ulong32)(x)<<(ulong32)((y)&31)) | (((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((32-((y)&31))&31))) & 0xFFFFFFFFUL) +#define ROR(x, y) ( ((((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((y)&31)) | ((ulong32)(x)<<(ulong32)((32-((y)&31))&31))) & 0xFFFFFFFFUL) +#define ROLc(x, y) ( (((ulong32)(x)<<(ulong32)((y)&31)) | (((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((32-((y)&31))&31))) & 0xFFFFFFFFUL) +#define RORc(x, y) ( ((((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((y)&31)) | ((ulong32)(x)<<(ulong32)((32-((y)&31))&31))) & 0xFFFFFFFFUL) + +#endif + + +/* 64-bit Rotates */ +#if !defined(__STRICT_ANSI__) && defined(__GNUC__) && defined(__x86_64__) && !defined(_WIN64) && !defined(LTC_NO_ASM) + +static inline ulong64 ROL64(ulong64 word, int i) +{ + asm("rolq %%cl,%0" + :"=r" (word) + :"0" (word),"c" (i)); + return word; +} + +static inline ulong64 ROR64(ulong64 word, int i) +{ + asm("rorq %%cl,%0" + :"=r" (word) + :"0" (word),"c" (i)); + return word; +} + +#ifndef LTC_NO_ROLC + +#define ROL64c(word,i) ({ \ + ulong64 __ROL64c_tmp = word; \ + __asm__ ("rolq %2, %0" : \ + "=r" (__ROL64c_tmp) : \ + "0" (__ROL64c_tmp), \ + "J" (i)); \ + __ROL64c_tmp; \ + }) +#define ROR64c(word,i) ({ \ + ulong64 __ROR64c_tmp = word; \ + __asm__ ("rorq %2, %0" : \ + "=r" (__ROR64c_tmp) : \ + "0" (__ROR64c_tmp), \ + "J" (i)); \ + __ROR64c_tmp; \ + }) + +#else /* LTC_NO_ROLC */ + +#define ROL64c ROL64 +#define ROR64c ROR64 + +#endif + +#else /* Not x86_64 */ + +#define ROL64(x, y) \ + ( (((x)<<((ulong64)(y)&63)) | \ + (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>(((ulong64)64-((y)&63))&63))) & CONST64(0xFFFFFFFFFFFFFFFF)) + +#define ROR64(x, y) \ + ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \ + ((x)<<(((ulong64)64-((y)&63))&63))) & CONST64(0xFFFFFFFFFFFFFFFF)) + +#define ROL64c(x, y) \ + ( (((x)<<((ulong64)(y)&63)) | \ + (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>(((ulong64)64-((y)&63))&63))) & CONST64(0xFFFFFFFFFFFFFFFF)) + +#define ROR64c(x, y) \ + ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \ + ((x)<<(((ulong64)64-((y)&63))&63))) & CONST64(0xFFFFFFFFFFFFFFFF)) + +#endif + +#ifndef MAX + #define MAX(x, y) ( ((x)>(y))?(x):(y) ) +#endif + +#ifndef MIN + #define MIN(x, y) ( ((x)<(y))?(x):(y) ) +#endif + +#ifndef LTC_UNUSED_PARAM + #define LTC_UNUSED_PARAM(x) (void)(x) +#endif + +/* extract a byte portably */ +#ifdef _MSC_VER + #define byte(x, n) ((unsigned char)((x) >> (8 * (n)))) +#else + #define byte(x, n) (((x) >> (8 * (n))) & 255) +#endif + +/* there is no snprintf before Visual C++ 2015 */ +#if defined(_MSC_VER) && _MSC_VER < 1900 +#define snprintf _snprintf +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/headers/tomcrypt_math.h b/src/ltc/headers/tomcrypt_math.h new file mode 100644 index 0000000..e9905d9 --- /dev/null +++ b/src/ltc/headers/tomcrypt_math.h @@ -0,0 +1,547 @@ +/** math functions **/ + +#define LTC_MP_LT -1 +#define LTC_MP_EQ 0 +#define LTC_MP_GT 1 + +#define LTC_MP_NO 0 +#define LTC_MP_YES 1 + +#ifndef LTC_MECC + typedef void ecc_point; +#endif + +#ifndef LTC_MRSA + typedef void rsa_key; +#endif + +/** math descriptor */ +typedef struct { + /** Name of the math provider */ + char *name; + + /** Bits per digit, amount of bits must fit in an unsigned long */ + int bits_per_digit; + +/* ---- init/deinit functions ---- */ + + /** initialize a bignum + @param a The number to initialize + @return CRYPT_OK on success + */ + int (*init)(void **a); + + /** init copy + @param dst The number to initialize and write to + @param src The number to copy from + @return CRYPT_OK on success + */ + int (*init_copy)(void **dst, void *src); + + /** deinit + @param a The number to free + @return CRYPT_OK on success + */ + void (*deinit)(void *a); + +/* ---- data movement ---- */ + + /** negate + @param src The number to negate + @param dst The destination + @return CRYPT_OK on success + */ + int (*neg)(void *src, void *dst); + + /** copy + @param src The number to copy from + @param dst The number to write to + @return CRYPT_OK on success + */ + int (*copy)(void *src, void *dst); + +/* ---- trivial low level functions ---- */ + + /** set small constant + @param a Number to write to + @param n Source upto bits_per_digit (actually meant for very small constants) + @return CRYPT_OK on succcess + */ + int (*set_int)(void *a, unsigned long n); + + /** get small constant + @param a Number to read, only fetches upto bits_per_digit from the number + @return The lower bits_per_digit of the integer (unsigned) + */ + unsigned long (*get_int)(void *a); + + /** get digit n + @param a The number to read from + @param n The number of the digit to fetch + @return The bits_per_digit sized n'th digit of a + */ + ltc_mp_digit (*get_digit)(void *a, int n); + + /** Get the number of digits that represent the number + @param a The number to count + @return The number of digits used to represent the number + */ + int (*get_digit_count)(void *a); + + /** compare two integers + @param a The left side integer + @param b The right side integer + @return LTC_MP_LT if a < b, LTC_MP_GT if a > b and LTC_MP_EQ otherwise. (signed comparison) + */ + int (*compare)(void *a, void *b); + + /** compare against int + @param a The left side integer + @param b The right side integer (upto bits_per_digit) + @return LTC_MP_LT if a < b, LTC_MP_GT if a > b and LTC_MP_EQ otherwise. (signed comparison) + */ + int (*compare_d)(void *a, unsigned long n); + + /** Count the number of bits used to represent the integer + @param a The integer to count + @return The number of bits required to represent the integer + */ + int (*count_bits)(void * a); + + /** Count the number of LSB bits which are zero + @param a The integer to count + @return The number of contiguous zero LSB bits + */ + int (*count_lsb_bits)(void *a); + + /** Compute a power of two + @param a The integer to store the power in + @param n The power of two you want to store (a = 2^n) + @return CRYPT_OK on success + */ + int (*twoexpt)(void *a , int n); + +/* ---- radix conversions ---- */ + + /** read ascii string + @param a The integer to store into + @param str The string to read + @param radix The radix the integer has been represented in (2-64) + @return CRYPT_OK on success + */ + int (*read_radix)(void *a, const char *str, int radix); + + /** write number to string + @param a The integer to store + @param str The destination for the string + @param radix The radix the integer is to be represented in (2-64) + @return CRYPT_OK on success + */ + int (*write_radix)(void *a, char *str, int radix); + + /** get size as unsigned char string + @param a The integer to get the size (when stored in array of octets) + @return The length of the integer + */ + unsigned long (*unsigned_size)(void *a); + + /** store an integer as an array of octets + @param src The integer to store + @param dst The buffer to store the integer in + @return CRYPT_OK on success + */ + int (*unsigned_write)(void *src, unsigned char *dst); + + /** read an array of octets and store as integer + @param dst The integer to load + @param src The array of octets + @param len The number of octets + @return CRYPT_OK on success + */ + int (*unsigned_read)(void *dst, unsigned char *src, unsigned long len); + +/* ---- basic math ---- */ + + /** add two integers + @param a The first source integer + @param b The second source integer + @param c The destination of "a + b" + @return CRYPT_OK on success + */ + int (*add)(void *a, void *b, void *c); + + + /** add two integers + @param a The first source integer + @param b The second source integer (single digit of upto bits_per_digit in length) + @param c The destination of "a + b" + @return CRYPT_OK on success + */ + int (*addi)(void *a, unsigned long b, void *c); + + /** subtract two integers + @param a The first source integer + @param b The second source integer + @param c The destination of "a - b" + @return CRYPT_OK on success + */ + int (*sub)(void *a, void *b, void *c); + + /** subtract two integers + @param a The first source integer + @param b The second source integer (single digit of upto bits_per_digit in length) + @param c The destination of "a - b" + @return CRYPT_OK on success + */ + int (*subi)(void *a, unsigned long b, void *c); + + /** multiply two integers + @param a The first source integer + @param b The second source integer (single digit of upto bits_per_digit in length) + @param c The destination of "a * b" + @return CRYPT_OK on success + */ + int (*mul)(void *a, void *b, void *c); + + /** multiply two integers + @param a The first source integer + @param b The second source integer (single digit of upto bits_per_digit in length) + @param c The destination of "a * b" + @return CRYPT_OK on success + */ + int (*muli)(void *a, unsigned long b, void *c); + + /** Square an integer + @param a The integer to square + @param b The destination + @return CRYPT_OK on success + */ + int (*sqr)(void *a, void *b); + + /** Square root (mod prime) + @param a The integer to compute square root mod prime from + @param b The prime + @param c The destination + @return CRYPT_OK on success + */ + int (*sqrtmod_prime)(void *a, void *b, void *c); + + /** Divide an integer + @param a The dividend + @param b The divisor + @param c The quotient (can be NULL to signify don't care) + @param d The remainder (can be NULL to signify don't care) + @return CRYPT_OK on success + */ + int (*mpdiv)(void *a, void *b, void *c, void *d); + + /** divide by two + @param a The integer to divide (shift right) + @param b The destination + @return CRYPT_OK on success + */ + int (*div_2)(void *a, void *b); + + /** Get remainder (small value) + @param a The integer to reduce + @param b The modulus (upto bits_per_digit in length) + @param c The destination for the residue + @return CRYPT_OK on success + */ + int (*modi)(void *a, unsigned long b, unsigned long *c); + + /** gcd + @param a The first integer + @param b The second integer + @param c The destination for (a, b) + @return CRYPT_OK on success + */ + int (*gcd)(void *a, void *b, void *c); + + /** lcm + @param a The first integer + @param b The second integer + @param c The destination for [a, b] + @return CRYPT_OK on success + */ + int (*lcm)(void *a, void *b, void *c); + + /** Modular multiplication + @param a The first source + @param b The second source + @param c The modulus + @param d The destination (a*b mod c) + @return CRYPT_OK on success + */ + int (*mulmod)(void *a, void *b, void *c, void *d); + + /** Modular squaring + @param a The first source + @param b The modulus + @param c The destination (a*a mod b) + @return CRYPT_OK on success + */ + int (*sqrmod)(void *a, void *b, void *c); + + /** Modular inversion + @param a The value to invert + @param b The modulus + @param c The destination (1/a mod b) + @return CRYPT_OK on success + */ + int (*invmod)(void *, void *, void *); + +/* ---- reduction ---- */ + + /** setup montgomery + @param a The modulus + @param b The destination for the reduction digit + @return CRYPT_OK on success + */ + int (*montgomery_setup)(void *a, void **b); + + /** get normalization value + @param a The destination for the normalization value + @param b The modulus + @return CRYPT_OK on success + */ + int (*montgomery_normalization)(void *a, void *b); + + /** reduce a number + @param a The number [and dest] to reduce + @param b The modulus + @param c The value "b" from montgomery_setup() + @return CRYPT_OK on success + */ + int (*montgomery_reduce)(void *a, void *b, void *c); + + /** clean up (frees memory) + @param a The value "b" from montgomery_setup() + @return CRYPT_OK on success + */ + void (*montgomery_deinit)(void *a); + +/* ---- exponentiation ---- */ + + /** Modular exponentiation + @param a The base integer + @param b The power (can be negative) integer + @param c The modulus integer + @param d The destination + @return CRYPT_OK on success + */ + int (*exptmod)(void *a, void *b, void *c, void *d); + + /** Primality testing + @param a The integer to test + @param b The number of tests that shall be executed + @param c The destination of the result (FP_YES if prime) + @return CRYPT_OK on success + */ + int (*isprime)(void *a, int b, int *c); + +/* ---- (optional) ecc point math ---- */ + + /** ECC GF(p) point multiplication (from the NIST curves) + @param k The integer to multiply the point by + @param G The point to multiply + @param R The destination for kG + @param a ECC curve parameter a (if NULL we assume a == -3) + @param modulus The modulus for the field + @param map Boolean indicated whether to map back to affine or not (can be ignored if you work in affine only) + @return CRYPT_OK on success + */ + int (*ecc_ptmul)(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map); + + /** ECC GF(p) point addition + @param P The first point + @param Q The second point + @param R The destination of P + Q + @param a ECC curve parameter a (if NULL we assume a == -3) + @param modulus The modulus + @param mp The "b" value from montgomery_setup() + @return CRYPT_OK on success + */ + int (*ecc_ptadd)(ecc_point *P, ecc_point *Q, ecc_point *R, void *a, void *modulus, void *mp); + + /** ECC GF(p) point double + @param P The first point + @param R The destination of 2P + @param a ECC curve parameter a (if NULL we assume a == -3) + @param modulus The modulus + @param mp The "b" value from montgomery_setup() + @return CRYPT_OK on success + */ + int (*ecc_ptdbl)(ecc_point *P, ecc_point *R, void *a, void *modulus, void *mp); + + /** ECC mapping from projective to affine, currently uses (x,y,z) => (x/z^2, y/z^3, 1) + @param P The point to map + @param modulus The modulus + @param mp The "b" value from montgomery_setup() + @return CRYPT_OK on success + @remark The mapping can be different but keep in mind a ecc_point only has three + integers (x,y,z) so if you use a different mapping you have to make it fit. + */ + int (*ecc_map)(ecc_point *P, void *modulus, void *mp); + + /** Computes kA*A + kB*B = C using Shamir's Trick + @param A First point to multiply + @param kA What to multiple A by + @param B Second point to multiply + @param kB What to multiple B by + @param C [out] Destination point (can overlap with A or B + @param modulus Modulus for curve + @return CRYPT_OK on success + */ + int (*ecc_mul2add)(ecc_point *A, void *kA, + ecc_point *B, void *kB, + ecc_point *C, + void *a, + void *modulus); + +/* ---- (optional) rsa optimized math (for internal CRT) ---- */ + + /** RSA Key Generation + @param prng An active PRNG state + @param wprng The index of the PRNG desired + @param size The size of the modulus (key size) desired (octets) + @param e The "e" value (public key). e==65537 is a good choice + @param key [out] Destination of a newly created private key pair + @return CRYPT_OK if successful, upon error all allocated ram is freed + */ + int (*rsa_keygen)(prng_state *prng, int wprng, int size, long e, rsa_key *key); + + + /** RSA exponentiation + @param in The octet array representing the base + @param inlen The length of the input + @param out The destination (to be stored in an octet array format) + @param outlen The length of the output buffer and the resulting size (zero padded to the size of the modulus) + @param which PK_PUBLIC for public RSA and PK_PRIVATE for private RSA + @param key The RSA key to use + @return CRYPT_OK on success + */ + int (*rsa_me)(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int which, + rsa_key *key); + +/* ---- basic math continued ---- */ + + /** Modular addition + @param a The first source + @param b The second source + @param c The modulus + @param d The destination (a + b mod c) + @return CRYPT_OK on success + */ + int (*addmod)(void *a, void *b, void *c, void *d); + + /** Modular substraction + @param a The first source + @param b The second source + @param c The modulus + @param d The destination (a - b mod c) + @return CRYPT_OK on success + */ + int (*submod)(void *a, void *b, void *c, void *d); + +/* ---- misc stuff ---- */ + /** Make a pseudo-random mpi + @param a The mpi to make random + @param size The desired length + @return CRYPT_OK on success + */ + int (*rand)(void *a, int size); + +} ltc_math_descriptor; + +extern ltc_math_descriptor ltc_mp; + +int ltc_init_multi(void **a, ...); +void ltc_deinit_multi(void *a, ...); + +#ifdef LTM_DESC +extern const ltc_math_descriptor ltm_desc; +#endif + +#ifdef TFM_DESC +extern const ltc_math_descriptor tfm_desc; +#endif + +#ifdef GMP_DESC +extern const ltc_math_descriptor gmp_desc; +#endif + +#if !defined(DESC_DEF_ONLY) && defined(LTC_SOURCE) + +#define MP_DIGIT_BIT ltc_mp.bits_per_digit + +/* some handy macros */ +#define mp_init(a) ltc_mp.init(a) +#define mp_init_multi ltc_init_multi +#define mp_clear(a) ltc_mp.deinit(a) +#define mp_clear_multi ltc_deinit_multi +#define mp_init_copy(a, b) ltc_mp.init_copy(a, b) + +#define mp_neg(a, b) ltc_mp.neg(a, b) +#define mp_copy(a, b) ltc_mp.copy(a, b) + +#define mp_set(a, b) ltc_mp.set_int(a, b) +#define mp_set_int(a, b) ltc_mp.set_int(a, b) +#define mp_get_int(a) ltc_mp.get_int(a) +#define mp_get_digit(a, n) ltc_mp.get_digit(a, n) +#define mp_get_digit_count(a) ltc_mp.get_digit_count(a) +#define mp_cmp(a, b) ltc_mp.compare(a, b) +#define mp_cmp_d(a, b) ltc_mp.compare_d(a, b) +#define mp_count_bits(a) ltc_mp.count_bits(a) +#define mp_cnt_lsb(a) ltc_mp.count_lsb_bits(a) +#define mp_2expt(a, b) ltc_mp.twoexpt(a, b) + +#define mp_read_radix(a, b, c) ltc_mp.read_radix(a, b, c) +#define mp_toradix(a, b, c) ltc_mp.write_radix(a, b, c) +#define mp_unsigned_bin_size(a) ltc_mp.unsigned_size(a) +#define mp_to_unsigned_bin(a, b) ltc_mp.unsigned_write(a, b) +#define mp_read_unsigned_bin(a, b, c) ltc_mp.unsigned_read(a, b, c) + +#define mp_add(a, b, c) ltc_mp.add(a, b, c) +#define mp_add_d(a, b, c) ltc_mp.addi(a, b, c) +#define mp_sub(a, b, c) ltc_mp.sub(a, b, c) +#define mp_sub_d(a, b, c) ltc_mp.subi(a, b, c) +#define mp_mul(a, b, c) ltc_mp.mul(a, b, c) +#define mp_mul_d(a, b, c) ltc_mp.muli(a, b, c) +#define mp_sqr(a, b) ltc_mp.sqr(a, b) +#define mp_sqrtmod_prime(a, b, c) ltc_mp.sqrtmod_prime(a, b, c) +#define mp_div(a, b, c, d) ltc_mp.mpdiv(a, b, c, d) +#define mp_div_2(a, b) ltc_mp.div_2(a, b) +#define mp_mod(a, b, c) ltc_mp.mpdiv(a, b, NULL, c) +#define mp_mod_d(a, b, c) ltc_mp.modi(a, b, c) +#define mp_gcd(a, b, c) ltc_mp.gcd(a, b, c) +#define mp_lcm(a, b, c) ltc_mp.lcm(a, b, c) + +#define mp_addmod(a, b, c, d) ltc_mp.addmod(a, b, c, d) +#define mp_submod(a, b, c, d) ltc_mp.submod(a, b, c, d) +#define mp_mulmod(a, b, c, d) ltc_mp.mulmod(a, b, c, d) +#define mp_sqrmod(a, b, c) ltc_mp.sqrmod(a, b, c) +#define mp_invmod(a, b, c) ltc_mp.invmod(a, b, c) + +#define mp_montgomery_setup(a, b) ltc_mp.montgomery_setup(a, b) +#define mp_montgomery_normalization(a, b) ltc_mp.montgomery_normalization(a, b) +#define mp_montgomery_reduce(a, b, c) ltc_mp.montgomery_reduce(a, b, c) +#define mp_montgomery_free(a) ltc_mp.montgomery_deinit(a) + +#define mp_exptmod(a,b,c,d) ltc_mp.exptmod(a,b,c,d) +#define mp_prime_is_prime(a, b, c) ltc_mp.isprime(a, b, c) + +#define mp_iszero(a) (mp_cmp_d(a, 0) == LTC_MP_EQ ? LTC_MP_YES : LTC_MP_NO) +#define mp_isodd(a) (mp_get_digit_count(a) > 0 ? (mp_get_digit(a, 0) & 1 ? LTC_MP_YES : LTC_MP_NO) : LTC_MP_NO) +#define mp_exch(a, b) do { void *ABC__tmp = a; a = b; b = ABC__tmp; } while(0) + +#define mp_tohex(a, b) mp_toradix(a, b, 16) + +#define mp_rand(a, b) ltc_mp.rand(a, b) + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/headers/tomcrypt_misc.h b/src/ltc/headers/tomcrypt_misc.h new file mode 100644 index 0000000..76f4f6b --- /dev/null +++ b/src/ltc/headers/tomcrypt_misc.h @@ -0,0 +1,113 @@ +/* ---- LTC_BASE64 Routines ---- */ +#ifdef LTC_BASE64 +int base64_encode(const unsigned char *in, unsigned long len, + unsigned char *out, unsigned long *outlen); + +int base64_decode(const unsigned char *in, unsigned long len, + unsigned char *out, unsigned long *outlen); +int base64_strict_decode(const unsigned char *in, unsigned long len, + unsigned char *out, unsigned long *outlen); +#endif + +#ifdef LTC_BASE64_URL +int base64url_encode(const unsigned char *in, unsigned long len, + unsigned char *out, unsigned long *outlen); +int base64url_strict_encode(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +int base64url_decode(const unsigned char *in, unsigned long len, + unsigned char *out, unsigned long *outlen); +int base64url_strict_decode(const unsigned char *in, unsigned long len, + unsigned char *out, unsigned long *outlen); +#endif + +/* ===> LTC_HKDF -- RFC5869 HMAC-based Key Derivation Function <=== */ +#ifdef LTC_HKDF + +int hkdf_test(void); + +int hkdf_extract(int hash_idx, + const unsigned char *salt, unsigned long saltlen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +int hkdf_expand(int hash_idx, + const unsigned char *info, unsigned long infolen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long outlen); + +int hkdf(int hash_idx, + const unsigned char *salt, unsigned long saltlen, + const unsigned char *info, unsigned long infolen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long outlen); + +#endif /* LTC_HKDF */ + +/* ---- MEM routines ---- */ +int mem_neq(const void *a, const void *b, size_t len); +void zeromem(volatile void *dst, size_t len); +void burn_stack(unsigned long len); + +const char *error_to_string(int err); + +extern const char *crypt_build_settings; + +/* ---- HMM ---- */ +int crypt_fsa(void *mp, ...); + +/* ---- Dynamic language support ---- */ +int crypt_get_constant(const char* namein, int *valueout); +int crypt_list_all_constants(char *names_list, unsigned int *names_list_size); + +int crypt_get_size(const char* namein, unsigned int *sizeout); +int crypt_list_all_sizes(char *names_list, unsigned int *names_list_size); + +#ifdef LTM_DESC +void init_LTM(void); +#endif +#ifdef TFM_DESC +void init_TFM(void); +#endif +/* *** use of GMP is untested *** +#ifdef GMP_DESC +void init_GMP(void); +#endif +*/ + +#ifdef LTC_ADLER32 +typedef struct adler32_state_s +{ + unsigned short s[2]; +} adler32_state; + +void adler32_init(adler32_state *ctx); +void adler32_update(adler32_state *ctx, const unsigned char *input, unsigned long length); +void adler32_finish(adler32_state *ctx, void *hash, unsigned long size); +int adler32_test(void); +#endif + +#ifdef LTC_CRC32 +typedef struct crc32_state_s +{ + ulong32 crc; +} crc32_state; + +void crc32_init(crc32_state *ctx); +void crc32_update(crc32_state *ctx, const unsigned char *input, unsigned long length); +void crc32_finish(crc32_state *ctx, void *hash, unsigned long size); +int crc32_test(void); +#endif + +/* yeah it's not exactly in misc in the library, but in testprof/x86_prof.c */ +#if defined(LTC_TEST) && defined(LTC_TEST_DBG) +void print_hex(const char* what, const void* v, const unsigned long l); +int compare_testvector(const void* is, const unsigned long is_len, const void* should, const unsigned long should_len, const char* what, int which); +#else +#define compare_testvector(is, is_len, should, should_len, what, which) \ + ((((is_len) != (should_len)) || (XMEMCMP((is), (should), (is_len)) != 0)) ? 1 : 0) +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/headers/tomcrypt_pk.h b/src/ltc/headers/tomcrypt_pk.h new file mode 100644 index 0000000..fd40f17 --- /dev/null +++ b/src/ltc/headers/tomcrypt_pk.h @@ -0,0 +1,749 @@ +/* ---- NUMBER THEORY ---- */ + +enum { + PK_PUBLIC=0, + PK_PRIVATE=1, + PK_PUBLIC_COMPRESSED=2, /* used only when exporting public ECC key */ + PK_CURVEOID=4 /* used only when exporting public ECC key */ +}; + +/* Indicates standard output formats that can be read e.g. by OpenSSL or GnuTLS */ +#define PK_STD 0x1000 + +int rand_prime(void *N, long len, prng_state *prng, int wprng); +int rand_bn_bits(void *N, int bits, prng_state *prng, int wprng); +int rand_bn_range(void *N, void *limit, prng_state *prng, int wprng); + +enum public_key_algorithms { + PKA_RSA, + PKA_DSA, + PKA_EC, + EC_PRIME_FIELD +}; + +typedef struct Oid { + unsigned long OID[16]; + /** Length of DER encoding */ + unsigned long OIDlen; +} oid_st; + +int pk_get_oid(int pk, oid_st *st); + +/* ---- RSA ---- */ +#ifdef LTC_MRSA + +/** RSA PKCS style key */ +typedef struct Rsa_key { + /** Type of key, PK_PRIVATE or PK_PUBLIC */ + int type; + /** The public exponent */ + void *e; + /** The private exponent */ + void *d; + /** The modulus */ + void *N; + /** The p factor of N */ + void *p; + /** The q factor of N */ + void *q; + /** The 1/q mod p CRT param */ + void *qP; + /** The d mod (p - 1) CRT param */ + void *dP; + /** The d mod (q - 1) CRT param */ + void *dQ; +} rsa_key; + +int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key); + +int rsa_get_size(rsa_key *key); + +int rsa_exptmod(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int which, + rsa_key *key); + +void rsa_free(rsa_key *key); + +/* These use PKCS #1 v2.0 padding */ +#define rsa_encrypt_key(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _prng, _prng_idx, _hash_idx, _key) \ + rsa_encrypt_key_ex(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _prng, _prng_idx, _hash_idx, LTC_PKCS_1_OAEP, _key) + +#define rsa_decrypt_key(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _hash_idx, _stat, _key) \ + rsa_decrypt_key_ex(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _hash_idx, LTC_PKCS_1_OAEP, _stat, _key) + +#define rsa_sign_hash(_in, _inlen, _out, _outlen, _prng, _prng_idx, _hash_idx, _saltlen, _key) \ + rsa_sign_hash_ex(_in, _inlen, _out, _outlen, LTC_PKCS_1_PSS, _prng, _prng_idx, _hash_idx, _saltlen, _key) + +#define rsa_verify_hash(_sig, _siglen, _hash, _hashlen, _hash_idx, _saltlen, _stat, _key) \ + rsa_verify_hash_ex(_sig, _siglen, _hash, _hashlen, LTC_PKCS_1_PSS, _hash_idx, _saltlen, _stat, _key) + +#define rsa_sign_saltlen_get_max(_hash_idx, _key) \ + rsa_sign_saltlen_get_max_ex(LTC_PKCS_1_PSS, _hash_idx, _key) + +/* These can be switched between PKCS #1 v2.x and PKCS #1 v1.5 paddings */ +int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const unsigned char *lparam, unsigned long lparamlen, + prng_state *prng, int prng_idx, int hash_idx, int padding, rsa_key *key); + +int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const unsigned char *lparam, unsigned long lparamlen, + int hash_idx, int padding, + int *stat, rsa_key *key); + +int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + int padding, + prng_state *prng, int prng_idx, + int hash_idx, unsigned long saltlen, + rsa_key *key); + +int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int padding, + int hash_idx, unsigned long saltlen, + int *stat, rsa_key *key); + +int rsa_sign_saltlen_get_max_ex(int padding, int hash_idx, rsa_key *key); + +/* PKCS #1 import/export */ +int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key); +int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key); + +int rsa_import_x509(const unsigned char *in, unsigned long inlen, rsa_key *key); +int rsa_import_pkcs8(const unsigned char *in, unsigned long inlen, + const void *passwd, unsigned long passwdlen, rsa_key *key); +int rsa_import_radix(int radix, char *N, char *e, char *d, char *p, char *q, char *dP, char *dQ, char *qP, rsa_key *key); +#endif + +/* ---- Katja ---- */ +#ifdef LTC_MKAT + +/* Min and Max KAT key sizes (in bits) */ +#define MIN_KAT_SIZE 1024 +#define MAX_KAT_SIZE 4096 + +/** Katja PKCS style key */ +typedef struct KAT_key { + /** Type of key, PK_PRIVATE or PK_PUBLIC */ + int type; + /** The private exponent */ + void *d; + /** The modulus */ + void *N; + /** The p factor of N */ + void *p; + /** The q factor of N */ + void *q; + /** The 1/q mod p CRT param */ + void *qP; + /** The d mod (p - 1) CRT param */ + void *dP; + /** The d mod (q - 1) CRT param */ + void *dQ; + /** The pq param */ + void *pq; +} katja_key; + +int katja_make_key(prng_state *prng, int wprng, int size, katja_key *key); + +int katja_exptmod(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int which, + katja_key *key); + +void katja_free(katja_key *key); + +/* These use PKCS #1 v2.0 padding */ +int katja_encrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const unsigned char *lparam, unsigned long lparamlen, + prng_state *prng, int prng_idx, int hash_idx, katja_key *key); + +int katja_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const unsigned char *lparam, unsigned long lparamlen, + int hash_idx, int *stat, + katja_key *key); + +/* PKCS #1 import/export */ +int katja_export(unsigned char *out, unsigned long *outlen, int type, katja_key *key); +int katja_import(const unsigned char *in, unsigned long inlen, katja_key *key); + +#endif + +/* ---- DH Routines ---- */ +#ifdef LTC_MDH + +typedef struct Dh_key { + int idx, type; + void *x; + void *y; + void *base; + void *prime; +} dh_key; + +int dh_compat_test(void); +void dh_sizes(int *low, int *high); +int dh_get_size(dh_key *key); + +int dh_make_key_internal(prng_state *prng, int wprng, dh_key *key); /* for internal use only */ +int dh_make_key_ex(prng_state *prng, int wprng, const char *base_hex, const char *prime_hex, dh_key *key); +int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key); +void dh_free(dh_key *key); + +int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_key *key); +int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key); +int dh_import_raw(unsigned char *in, unsigned long inlen, int type, + const char *base_hex, const char *prime_hex, dh_key *key); + +int dh_shared_secret(dh_key *private_key, dh_key *public_key, + unsigned char *out, unsigned long *outlen); + +int dh_encrypt_key(const unsigned char *in, unsigned long keylen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, int hash, + dh_key *key); + +int dh_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + dh_key *key); + +int dh_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, dh_key *key); + +int dh_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, dh_key *key); + + +#endif + + +/* ---- ECC Routines ---- */ +#ifdef LTC_MECC + +/* size of our temp buffers for exported keys */ +#define ECC_BUF_SIZE 256 + +/* max private key size */ +#define ECC_MAXSIZE 66 + +/** Structure defines a NIST GF(p) curve */ +typedef struct { + /** The size of the curve in octets */ + int size; + + /** name of curve */ + char *name; + + /** The prime that defines the field the curve is in (encoded in hex) */ + char *prime; + + /** The fields A param (hex) */ + char *A; + + /** The fields B param (hex) */ + char *B; + + /** The order of the curve (hex) */ + char *order; + + /** The x co-ordinate of the base point on the curve (hex) */ + char *Gx; + + /** The y co-ordinate of the base point on the curve (hex) */ + char *Gy; + + /** The co-factor */ + unsigned long cofactor; + + /** The OID stucture */ + oid_st oid; +} ltc_ecc_set_type; + +/** A point on a ECC curve, stored in Jacbobian format such that (x,y,z) => (x/z^2, y/z^3, 1) when interpretted as affine */ +typedef struct { + /** The x co-ordinate */ + void *x; + + /** The y co-ordinate */ + void *y; + + /** The z co-ordinate */ + void *z; +} ecc_point; + +/** An ECC key */ +typedef struct { + /** Type of key, PK_PRIVATE or PK_PUBLIC */ + int type; + + /** Index into the ltc_ecc_sets[] for the parameters of this curve; if -1, then this key is using user supplied curve in dp */ + int idx; + + /** pointer to domain parameters; either points to NIST curves (identified by idx >= 0) or user supplied curve */ + const ltc_ecc_set_type *dp; + + /** The public key */ + ecc_point pubkey; + + /** The private key */ + void *k; +} ecc_key; + +/** the ECC params provided */ +extern const ltc_ecc_set_type ltc_ecc_sets[]; + +int ecc_test(void); +void ecc_sizes(int *low, int *high); +int ecc_get_size(ecc_key *key); + +int ecc_dp_init(ltc_ecc_set_type *dp); +int ecc_dp_set(ltc_ecc_set_type *dp, char *ch_prime, char *ch_A, char *ch_B, char *ch_order, char *ch_Gx, char *ch_Gy, unsigned long cofactor, char *ch_name, char *oid); +int ecc_dp_set_bn(ltc_ecc_set_type *dp, void *a, void *b, void *prime, void *order, void *gx, void *gy, unsigned long cofactor); +int ecc_dp_set_by_oid(ltc_ecc_set_type *dp, unsigned long *oid, unsigned long oidsize); +int ecc_dp_fill_from_sets(ltc_ecc_set_type *dp); +int ecc_dp_clear(ltc_ecc_set_type *dp); + +int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key); +int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_set_type *dp); +void ecc_free(ecc_key *key); + +int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key); +int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key); +int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp); +int ecc_import_pkcs8(const unsigned char *in, unsigned long inlen, const void *pwd, unsigned long pwdlen, ecc_key *key, ltc_ecc_set_type *dp); +int ecc_export_full(unsigned char *out, unsigned long *outlen, int type, ecc_key *key); +int ecc_import_full(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp); +int ecc_export_raw(unsigned char *out, unsigned long *outlen, int type, ecc_key *key); +int ecc_import_raw(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp); + +int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen); +int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, ecc_key *key); +int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp); + +int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, + unsigned char *out, unsigned long *outlen); + +int ecc_encrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, int hash, + ecc_key *key); + +int ecc_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + ecc_key *key); + +int ecc_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, ecc_key *key); + +int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, ecc_key *key); + +int ecc_sign_hash_rfc7518(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, ecc_key *key); + +int ecc_verify_hash_rfc7518(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, ecc_key *key); + +int ecc_verify_key(ecc_key *key); + +/* low level functions */ +ecc_point *ltc_ecc_new_point(void); +void ltc_ecc_del_point(ecc_point *p); +int ltc_ecc_is_valid_idx(int n); +int ltc_ecc_is_point(const ltc_ecc_set_type *dp, void *x, void *y); +int ltc_ecc_is_point_at_infinity(ecc_point *p, void *modulus); +int ltc_ecc_import_point(const unsigned char *in, unsigned long inlen, void *prime, void *a, void *b, void *x, void *y); +int ltc_ecc_export_point(unsigned char *out, unsigned long *outlen, void *x, void *y, unsigned long size, int compressed); + +/* point ops (mp == montgomery digit) */ +#if !defined(LTC_MECC_ACCEL) || defined(LTM_DESC) || defined(GMP_DESC) +/* R = 2P */ +int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *a, void *modulus, void *mp); + +/* R = P + Q */ +int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *a, void *modulus, void *mp); +#endif + +#if defined(LTC_MECC_FP) +/* optimized point multiplication using fixed point cache (HAC algorithm 14.117) */ +int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map); + +/* functions for saving/loading/freeing/adding to fixed point cache */ +int ltc_ecc_fp_save_state(unsigned char **out, unsigned long *outlen); +int ltc_ecc_fp_restore_state(unsigned char *in, unsigned long inlen); +void ltc_ecc_fp_free(void); +int ltc_ecc_fp_add_point(ecc_point *g, void *modulus, int lock); + +/* lock/unlock all points currently in fixed point cache */ +void ltc_ecc_fp_tablelock(int lock); +#endif + +/* R = kG */ +int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map); + +#ifdef LTC_ECC_SHAMIR +/* kA*A + kB*B = C */ +int ltc_ecc_mul2add(ecc_point *A, void *kA, + ecc_point *B, void *kB, + ecc_point *C, + void *a, + void *modulus); + +#ifdef LTC_MECC_FP +/* Shamir's trick with optimized point multiplication using fixed point cache */ +int ltc_ecc_fp_mul2add(ecc_point *A, void *kA, + ecc_point *B, void *kB, + ecc_point *C, + void *a, + void *modulus); +#endif + +#endif + + +/* map P to affine from projective */ +int ltc_ecc_map(ecc_point *P, void *modulus, void *mp); + +#endif + +#ifdef LTC_MDSA + +/* Max diff between group and modulus size in bytes */ +#define LTC_MDSA_DELTA 512 + +/* Max DSA group size in bytes (default allows 4k-bit groups) */ +#define LTC_MDSA_MAX_GROUP 512 + +/** DSA key structure */ +typedef struct { + /** The key type, PK_PRIVATE or PK_PUBLIC */ + int type; + + /** The order of the sub-group used in octets */ + int qord; + + /** The generator */ + void *g; + + /** The prime used to generate the sub-group */ + void *q; + + /** The large prime that generats the field the contains the sub-group */ + void *p; + + /** The private key */ + void *x; + + /** The public key */ + void *y; +} dsa_key; + +int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key); + +int dsa_make_key_ex(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key, char* p_hex, char* q_hex, char* g_hex); + +int dsa_make_params(prng_state *prng, int wprng, int group_size, int modulus_size, void *p, void *q, void *g); + +void dsa_free(dsa_key *key); + +int dsa_sign_hash_raw(const unsigned char *in, unsigned long inlen, + void *r, void *s, + prng_state *prng, int wprng, dsa_key *key); + +int dsa_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, dsa_key *key); + +int dsa_verify_hash_raw( void *r, void *s, + const unsigned char *hash, unsigned long hashlen, + int *stat, dsa_key *key); + +int dsa_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, dsa_key *key); + +int dsa_encrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, int hash, + dsa_key *key); + +int dsa_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + dsa_key *key); + +int dsa_import_radix(int radix, char *p, char *q, char *g, char *x, char *y, dsa_key *key); +int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key); +int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key); +int dsa_verify_key(dsa_key *key, int *stat); + +int dsa_shared_secret(void *private_key, void *base, + dsa_key *public_key, + unsigned char *out, unsigned long *outlen); +#endif + +#ifdef LTC_DER +/* DER handling */ + +typedef enum ltc_asn1_type_ { + /* 0 */ + LTC_ASN1_EOL, + LTC_ASN1_BOOLEAN, + LTC_ASN1_INTEGER, + LTC_ASN1_SHORT_INTEGER, + LTC_ASN1_BIT_STRING, + /* 5 */ + LTC_ASN1_OCTET_STRING, + LTC_ASN1_NULL, + LTC_ASN1_OBJECT_IDENTIFIER, + LTC_ASN1_IA5_STRING, + LTC_ASN1_PRINTABLE_STRING, + /* 10 */ + LTC_ASN1_UTF8_STRING, + LTC_ASN1_UTCTIME, + LTC_ASN1_CHOICE, + LTC_ASN1_SEQUENCE, + LTC_ASN1_SET, + /* 15 */ + LTC_ASN1_SETOF, + LTC_ASN1_RAW_BIT_STRING, + LTC_ASN1_TELETEX_STRING, + LTC_ASN1_CONSTRUCTED, + LTC_ASN1_CONTEXT_SPECIFIC, + /* 20 */ + LTC_ASN1_GENERALIZEDTIME, +} ltc_asn1_type; + +/** A LTC ASN.1 list type */ +typedef struct ltc_asn1_list_ { + /** The LTC ASN.1 enumerated type identifier */ + ltc_asn1_type type; + /** The data to encode or place for decoding */ + void *data; + /** The size of the input or resulting output */ + unsigned long size; + /** The used flag, this is used by the CHOICE ASN.1 type to indicate which choice was made */ + int used; + /** Flag used to indicate optional items in ASN.1 sequences */ + int optional; + /** Flag used to indicate context specific tags on ASN.1 sequence items */ + unsigned char tag; + /** prev/next entry in the list */ + struct ltc_asn1_list_ *prev, *next, *child, *parent; +} ltc_asn1_list; + +#define LTC_SET_ASN1(list, index, Type, Data, Size) \ + do { \ + int LTC_MACRO_temp = (index); \ + ltc_asn1_list *LTC_MACRO_list = (list); \ + LTC_MACRO_list[LTC_MACRO_temp].type = (Type); \ + LTC_MACRO_list[LTC_MACRO_temp].data = (void*)(Data); \ + LTC_MACRO_list[LTC_MACRO_temp].size = (Size); \ + LTC_MACRO_list[LTC_MACRO_temp].used = 0; \ + LTC_MACRO_list[LTC_MACRO_temp].tag = 0; \ + LTC_MACRO_list[LTC_MACRO_temp].optional = 0; \ + } while (0) + +/* SEQUENCE */ +int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int type_of); + +#define der_encode_sequence(list, inlen, out, outlen) der_encode_sequence_ex(list, inlen, out, outlen, LTC_ASN1_SEQUENCE) + +int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen, + ltc_asn1_list *list, unsigned long outlen, int ordered); + +#define der_decode_sequence(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 1) + +int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, + unsigned long *outlen); +int der_length_sequence_ex(ltc_asn1_list *list, unsigned long inlen, + unsigned long *outlen, unsigned long *payloadlen); + +/* SUBJECT PUBLIC KEY INFO */ +int der_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen, + unsigned int algorithm, void* public_key, unsigned long public_key_len, + unsigned long parameters_type, void* parameters, unsigned long parameters_len); + +int der_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen, + unsigned int algorithm, void* public_key, unsigned long* public_key_len, + unsigned long parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len); + +int der_decode_subject_public_key_info_ex(const unsigned char *in, unsigned long inlen, + unsigned int algorithm, void* public_key, unsigned long* public_key_len, + unsigned long parameters_type, void* parameters, unsigned long parameters_len, + unsigned long *parameters_outsize); + +/* SET */ +#define der_decode_set(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 0) +#define der_length_set der_length_sequence +int der_encode_set(ltc_asn1_list *list, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +int der_encode_setof(ltc_asn1_list *list, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +/* VA list handy helpers with triplets of */ +int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...); +int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...); + +/* FLEXI DECODER handle unknown list decoder */ +int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out); +#define der_free_sequence_flexi der_sequence_free +void der_sequence_free(ltc_asn1_list *in); +void der_sequence_shrink(ltc_asn1_list *in); + +/* BOOLEAN */ +int der_length_boolean(unsigned long *outlen); +int der_encode_boolean(int in, + unsigned char *out, unsigned long *outlen); +int der_decode_boolean(const unsigned char *in, unsigned long inlen, + int *out); +/* INTEGER */ +int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen); +int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num); +int der_length_integer(void *num, unsigned long *len); + +/* INTEGER -- handy for 0..2^32-1 values */ +int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsigned long *num); +int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned long *outlen); +int der_length_short_integer(unsigned long num, unsigned long *outlen); + +/* BIT STRING */ +int der_encode_bit_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_decode_bit_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_encode_raw_bit_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_decode_raw_bit_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_length_bit_string(unsigned long nbits, unsigned long *outlen); + +/* OCTET STRING */ +int der_encode_octet_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_decode_octet_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_length_octet_string(unsigned long noctets, unsigned long *outlen); + +/* OBJECT IDENTIFIER */ +int der_encode_object_identifier(unsigned long *words, unsigned long nwords, + unsigned char *out, unsigned long *outlen); +int der_decode_object_identifier(const unsigned char *in, unsigned long inlen, + unsigned long *words, unsigned long *outlen); +int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen); +unsigned long der_object_identifier_bits(unsigned long x); + +/* IA5 STRING */ +int der_encode_ia5_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_decode_ia5_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen); + +int der_ia5_char_encode(int c); +int der_ia5_value_decode(int v); + +/* TELETEX STRING */ +int der_decode_teletex_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_length_teletex_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen); + +int der_teletex_char_encode(int c); +int der_teletex_value_decode(int v); + +/* PRINTABLE STRING */ +int der_encode_printable_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_decode_printable_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen); + +int der_printable_char_encode(int c); +int der_printable_value_decode(int v); + +/* UTF-8 */ +#if (defined(SIZE_MAX) || __STDC_VERSION__ >= 199901L || defined(WCHAR_MAX) || defined(__WCHAR_MAX__) || defined(_WCHAR_T) || defined(_WCHAR_T_DEFINED) || defined (__WCHAR_TYPE__)) && !defined(LTC_NO_WCHAR) +#include +#if defined(__WCHAR_MAX__) +#define LTC_WCHAR_MAX __WCHAR_MAX__ +#elif defined(WCHAR_MAX) +#define LTC_WCHAR_MAX WCHAR_MAX +#endif +/* please note that it might happen that LTC_WCHAR_MAX is undefined */ +#else +typedef ulong32 wchar_t; +#define LTC_WCHAR_MAX 0xFFFFFFFF +#endif + +int der_encode_utf8_string(const wchar_t *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +int der_decode_utf8_string(const unsigned char *in, unsigned long inlen, + wchar_t *out, unsigned long *outlen); +unsigned long der_utf8_charsize(const wchar_t c); +int der_utf8_valid_char(const wchar_t c); +int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned long *outlen); + + +/* CHOICE */ +int der_decode_choice(const unsigned char *in, unsigned long *inlen, + ltc_asn1_list *list, unsigned long outlen); + +/* UTCTime */ +typedef struct { + unsigned YY, /* year */ + MM, /* month */ + DD, /* day */ + hh, /* hour */ + mm, /* minute */ + ss, /* second */ + off_dir, /* timezone offset direction 0 == +, 1 == - */ + off_hh, /* timezone offset hours */ + off_mm; /* timezone offset minutes */ +} ltc_utctime; + +int der_encode_utctime(ltc_utctime *utctime, + unsigned char *out, unsigned long *outlen); + +int der_decode_utctime(const unsigned char *in, unsigned long *inlen, + ltc_utctime *out); + +int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen); + +/* GeneralizedTime */ +typedef struct { + unsigned YYYY, /* year */ + MM, /* month */ + DD, /* day */ + hh, /* hour */ + mm, /* minute */ + ss, /* second */ + fs, /* fractional seconds */ + off_dir, /* timezone offset direction 0 == +, 1 == - */ + off_hh, /* timezone offset hours */ + off_mm; /* timezone offset minutes */ +} ltc_generalizedtime; + +int der_encode_generalizedtime(ltc_generalizedtime *gtime, + unsigned char *out, unsigned long *outlen); + +int der_decode_generalizedtime(const unsigned char *in, unsigned long *inlen, + ltc_generalizedtime *out); + +int der_length_generalizedtime(ltc_generalizedtime *gtime, unsigned long *outlen); + + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/headers/tomcrypt_pkcs.h b/src/ltc/headers/tomcrypt_pkcs.h new file mode 100644 index 0000000..dae3490 --- /dev/null +++ b/src/ltc/headers/tomcrypt_pkcs.h @@ -0,0 +1,98 @@ +/* PKCS Header Info */ + +/* ===> PKCS #1 -- RSA Cryptography <=== */ +#ifdef LTC_PKCS_1 + +enum ltc_pkcs_1_v1_5_blocks +{ + LTC_PKCS_1_EMSA = 1, /* Block type 1 (PKCS #1 v1.5 signature padding) */ + LTC_PKCS_1_EME = 2 /* Block type 2 (PKCS #1 v1.5 encryption padding) */ +}; + +enum ltc_pkcs_1_paddings +{ + LTC_PKCS_1_V1_5 = 1, /* PKCS #1 v1.5 padding (\sa ltc_pkcs_1_v1_5_blocks) */ + LTC_PKCS_1_OAEP = 2, /* PKCS #1 v2.0 encryption padding */ + LTC_PKCS_1_PSS = 3 /* PKCS #1 v2.1 signature padding */ +}; + +int pkcs_1_mgf1( int hash_idx, + const unsigned char *seed, unsigned long seedlen, + unsigned char *mask, unsigned long masklen); + +int pkcs_1_i2osp(void *n, unsigned long modulus_len, unsigned char *out); +int pkcs_1_os2ip(void *n, unsigned char *in, unsigned long inlen); + +/* *** v1.5 padding */ +int pkcs_1_v1_5_encode(const unsigned char *msg, + unsigned long msglen, + int block_type, + unsigned long modulus_bitlen, + prng_state *prng, + int prng_idx, + unsigned char *out, + unsigned long *outlen); + +int pkcs_1_v1_5_decode(const unsigned char *msg, + unsigned long msglen, + int block_type, + unsigned long modulus_bitlen, + unsigned char *out, + unsigned long *outlen, + int *is_valid); + +/* *** v2.1 padding */ +int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, + const unsigned char *lparam, unsigned long lparamlen, + unsigned long modulus_bitlen, prng_state *prng, + int prng_idx, int hash_idx, + unsigned char *out, unsigned long *outlen); + +int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, + const unsigned char *lparam, unsigned long lparamlen, + unsigned long modulus_bitlen, int hash_idx, + unsigned char *out, unsigned long *outlen, + int *res); + +int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, + unsigned long saltlen, prng_state *prng, + int prng_idx, int hash_idx, + unsigned long modulus_bitlen, + unsigned char *out, unsigned long *outlen); + +int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, + const unsigned char *sig, unsigned long siglen, + unsigned long saltlen, int hash_idx, + unsigned long modulus_bitlen, int *res); + +#endif /* LTC_PKCS_1 */ + +/* ===> PKCS #5 -- Password Based Cryptography <=== */ +#ifdef LTC_PKCS_5 + +/* Algorithm #1 (old) */ +int pkcs_5_alg1(const unsigned char *password, unsigned long password_len, + const unsigned char *salt, + int iteration_count, int hash_idx, + unsigned char *out, unsigned long *outlen); + +/* Algorithm #1 - OpenSSL-compatible variant for arbitrarily-long keys. + Compatible with EVP_BytesToKey() */ +int pkcs_5_alg1_openssl(const unsigned char *password, + unsigned long password_len, + const unsigned char *salt, + int iteration_count, int hash_idx, + unsigned char *out, unsigned long *outlen); + +/* Algorithm #2 (new) */ +int pkcs_5_alg2(const unsigned char *password, unsigned long password_len, + const unsigned char *salt, unsigned long salt_len, + int iteration_count, int hash_idx, + unsigned char *out, unsigned long *outlen); + +int pkcs_5_test (void); +#endif /* LTC_PKCS_5 */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/headers/tomcrypt_prng.h b/src/ltc/headers/tomcrypt_prng.h new file mode 100644 index 0000000..e06c68b --- /dev/null +++ b/src/ltc/headers/tomcrypt_prng.h @@ -0,0 +1,222 @@ +/* ---- PRNG Stuff ---- */ +#ifdef LTC_YARROW +struct yarrow_prng { + int cipher, hash; + unsigned char pool[MAXBLOCKSIZE]; + symmetric_CTR ctr; +}; +#endif + +#ifdef LTC_RC4 +struct rc4_prng { + rc4_state s; +}; +#endif + +#ifdef LTC_CHACHA20_PRNG +struct chacha20_prng { + chacha_state s; /* chacha state */ + unsigned char ent[40]; /* entropy buffer */ + unsigned long idx; /* entropy counter */ +}; +#endif + +#ifdef LTC_FORTUNA +struct fortuna_prng { + hash_state pool[LTC_FORTUNA_POOLS]; /* the pools */ + + symmetric_key skey; + + unsigned char K[32], /* the current key */ + IV[16]; /* IV for CTR mode */ + + unsigned long pool_idx, /* current pool we will add to */ + pool0_len, /* length of 0'th pool */ + wd; + + ulong64 reset_cnt; /* number of times we have reset */ +}; +#endif + +#ifdef LTC_SOBER128 +struct sober128_prng { + sober128_state s; /* sober128 state */ + unsigned char ent[40]; /* entropy buffer */ + unsigned long idx; /* entropy counter */ +}; +#endif + +typedef struct { + union { + char dummy[1]; +#ifdef LTC_YARROW + struct yarrow_prng yarrow; +#endif +#ifdef LTC_RC4 + struct rc4_prng rc4; +#endif +#ifdef LTC_CHACHA20_PRNG + struct chacha20_prng chacha; +#endif +#ifdef LTC_FORTUNA + struct fortuna_prng fortuna; +#endif +#ifdef LTC_SOBER128 + struct sober128_prng sober128; +#endif + }; + short ready; /* ready flag 0-1 */ + LTC_MUTEX_TYPE(lock) /* lock */ +} prng_state; + +/** PRNG descriptor */ +extern 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); +} prng_descriptor[]; + +#ifdef LTC_YARROW +int yarrow_start(prng_state *prng); +int yarrow_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); +int yarrow_ready(prng_state *prng); +unsigned long yarrow_read(unsigned char *out, unsigned long outlen, prng_state *prng); +int yarrow_done(prng_state *prng); +int yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng); +int yarrow_import(const unsigned char *in, unsigned long inlen, prng_state *prng); +int yarrow_test(void); +extern const struct ltc_prng_descriptor yarrow_desc; +#endif + +#ifdef LTC_FORTUNA +int fortuna_start(prng_state *prng); +int fortuna_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); +int fortuna_ready(prng_state *prng); +unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state *prng); +int fortuna_done(prng_state *prng); +int fortuna_export(unsigned char *out, unsigned long *outlen, prng_state *prng); +int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prng); +int fortuna_test(void); +extern const struct ltc_prng_descriptor fortuna_desc; +#endif + +#ifdef LTC_RC4 +int rc4_start(prng_state *prng); +int rc4_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); +int rc4_ready(prng_state *prng); +unsigned long rc4_read(unsigned char *out, unsigned long outlen, prng_state *prng); +int rc4_done(prng_state *prng); +int rc4_export(unsigned char *out, unsigned long *outlen, prng_state *prng); +int rc4_import(const unsigned char *in, unsigned long inlen, prng_state *prng); +int rc4_test(void); +extern const struct ltc_prng_descriptor rc4_desc; +#endif + +#ifdef LTC_CHACHA20_PRNG +int chacha20_prng_start(prng_state *prng); +int chacha20_prng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); +int chacha20_prng_ready(prng_state *prng); +unsigned long chacha20_prng_read(unsigned char *out, unsigned long outlen, prng_state *prng); +int chacha20_prng_done(prng_state *prng); +int chacha20_prng_export(unsigned char *out, unsigned long *outlen, prng_state *prng); +int chacha20_prng_import(const unsigned char *in, unsigned long inlen, prng_state *prng); +int chacha20_prng_test(void); +extern const struct ltc_prng_descriptor chacha20_prng_desc; +#endif + +#ifdef LTC_SPRNG +int sprng_start(prng_state *prng); +int sprng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); +int sprng_ready(prng_state *prng); +unsigned long sprng_read(unsigned char *out, unsigned long outlen, prng_state *prng); +int sprng_done(prng_state *prng); +int sprng_export(unsigned char *out, unsigned long *outlen, prng_state *prng); +int sprng_import(const unsigned char *in, unsigned long inlen, prng_state *prng); +int sprng_test(void); +extern const struct ltc_prng_descriptor sprng_desc; +#endif + +#ifdef LTC_SOBER128 +int sober128_start(prng_state *prng); +int sober128_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); +int sober128_ready(prng_state *prng); +unsigned long sober128_read(unsigned char *out, unsigned long outlen, prng_state *prng); +int sober128_done(prng_state *prng); +int sober128_export(unsigned char *out, unsigned long *outlen, prng_state *prng); +int sober128_import(const unsigned char *in, unsigned long inlen, prng_state *prng); +int sober128_test(void); +extern const struct ltc_prng_descriptor sober128_desc; +#endif + +int find_prng(const char *name); +int register_prng(const struct ltc_prng_descriptor *prng); +int unregister_prng(const struct ltc_prng_descriptor *prng); +int prng_is_valid(int idx); +LTC_MUTEX_PROTO(ltc_prng_mutex) + +/* Slow RNG you **might** be able to use to seed a PRNG with. Be careful as this + * might not work on all platforms as planned + */ +unsigned long rng_get_bytes(unsigned char *out, + unsigned long outlen, + void (*callback)(void)); + +int rng_make_prng(int bits, int wprng, prng_state *prng, void (*callback)(void)); + +#ifdef LTC_PRNG_ENABLE_LTC_RNG +extern unsigned long (*ltc_rng)(unsigned char *out, unsigned long outlen, + void (*callback)(void)); +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/mac/blake2/blake2bmac.c b/src/ltc/mac/blake2/blake2bmac.c new file mode 100644 index 0000000..63ebd41 --- /dev/null +++ b/src/ltc/mac/blake2/blake2bmac.c @@ -0,0 +1,61 @@ +/* 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. + */ + +#include "tomcrypt.h" + +#ifdef LTC_BLAKE2BMAC + +/** + Initialize an BLAKE2B MAC context. + @param st The BLAKE2B MAC state + @param key The secret key + @param keylen The length of the secret key (octets) + @return CRYPT_OK if successful +*/ +int blake2bmac_init(blake2bmac_state *st, unsigned long outlen, const unsigned char *key, unsigned long keylen) +{ + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(key != NULL); + return blake2b_init(st, outlen, key, keylen); +} + +/** + Process data through BLAKE2B MAC + @param st The BLAKE2B MAC state + @param in The data to send through HMAC + @param inlen The length of the data to HMAC (octets) + @return CRYPT_OK if successful +*/ +int blake2bmac_process(blake2bmac_state *st, const unsigned char *in, unsigned long inlen) +{ + if (inlen == 0) return CRYPT_OK; /* nothing to do */ + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(in != NULL); + return blake2b_process(st, in, inlen); +} + +/** + Terminate a BLAKE2B MAC session + @param st The BLAKE2B MAC state + @param mac [out] The destination of the BLAKE2B MAC authentication tag + @param maclen [in/out] The max size and resulting size of the BLAKE2B MAC authentication tag + @return CRYPT_OK if successful +*/ +int blake2bmac_done(blake2bmac_state *st, unsigned char *mac, unsigned long *maclen) +{ + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(mac != NULL); + LTC_ARGCHK(maclen != NULL); + LTC_ARGCHK(*maclen >= st->blake2b.outlen); + + *maclen = st->blake2b.outlen; + return blake2b_done(st, mac); +} + +#endif diff --git a/src/ltc/mac/blake2/blake2bmac_file.c b/src/ltc/mac/blake2/blake2bmac_file.c new file mode 100644 index 0000000..3722138 --- /dev/null +++ b/src/ltc/mac/blake2/blake2bmac_file.c @@ -0,0 +1,79 @@ +/* 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. + */ + +#include "tomcrypt.h" + +#ifdef LTC_BLAKE2BMAC + +/** + BLAKE2B MAC a file + @param fname The name of the file you wish to BLAKE2B MAC + @param key The secret key + @param keylen The length of the secret key + @param mac [out] The BLAKE2B MAC authentication tag + @param maclen [in/out] The max size and resulting size of the authentication tag + @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled +*/ +int blake2bmac_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen) +{ +#ifdef LTC_NO_FILE + return CRYPT_NOP; +#else + blake2bmac_state st; + FILE *in; + unsigned char *buf; + size_t x; + int err; + + LTC_ARGCHK(fname != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(mac != NULL); + LTC_ARGCHK(maclen != NULL); + + if ((buf = XMALLOC(LTC_FILE_READ_BUFSIZE)) == NULL) { + return CRYPT_MEM; + } + + if ((err = blake2bmac_init(&st, *maclen, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + + in = fopen(fname, "rb"); + if (in == NULL) { + err = CRYPT_FILE_NOTFOUND; + goto LBL_ERR; + } + + do { + x = fread(buf, 1, LTC_FILE_READ_BUFSIZE, in); + if ((err = blake2bmac_process(&st, buf, (unsigned long)x)) != CRYPT_OK) { + fclose(in); + goto LBL_CLEANBUF; + } + } while (x == LTC_FILE_READ_BUFSIZE); + + if (fclose(in) != 0) { + err = CRYPT_ERROR; + goto LBL_CLEANBUF; + } + + err = blake2bmac_done(&st, mac, maclen); + +LBL_CLEANBUF: + zeromem(buf, LTC_FILE_READ_BUFSIZE); +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(&st, sizeof(blake2bmac_state)); +#endif + XFREE(buf); + return err; +#endif +} + +#endif diff --git a/src/ltc/mac/blake2/blake2bmac_memory.c b/src/ltc/mac/blake2/blake2bmac_memory.c new file mode 100644 index 0000000..bdf5562 --- /dev/null +++ b/src/ltc/mac/blake2/blake2bmac_memory.c @@ -0,0 +1,44 @@ +/* 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. + */ + +#include "tomcrypt.h" + +#ifdef LTC_BLAKE2BMAC + +/** + BLAKE2B MAC a block of memory to produce the authentication tag + @param key The secret key + @param keylen The length of the secret key (octets) + @param in The data to BLAKE2B MAC + @param inlen The length of the data to BLAKE2B MAC (octets) + @param mac [out] Destination of the authentication tag + @param maclen [in/out] Max size and resulting size of authentication tag + @return CRYPT_OK if successful +*/ +int blake2bmac_memory(const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *mac, unsigned long *maclen) +{ + blake2bmac_state st; + int err; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(mac != NULL); + LTC_ARGCHK(maclen != NULL); + + if ((err = blake2bmac_init(&st, *maclen, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = blake2bmac_process(&st, in, inlen)) != CRYPT_OK) { goto LBL_ERR; } + err = blake2bmac_done(&st, mac, maclen); +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(&st, sizeof(blake2bmac_state)); +#endif + return err; +} + +#endif diff --git a/src/ltc/mac/blake2/blake2bmac_memory_multi.c b/src/ltc/mac/blake2/blake2bmac_memory_multi.c new file mode 100644 index 0000000..4e8f66f --- /dev/null +++ b/src/ltc/mac/blake2/blake2bmac_memory_multi.c @@ -0,0 +1,58 @@ +/* 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. + */ + +#include "tomcrypt.h" +#include + +#ifdef LTC_BLAKE2BMAC + +/** + BLAKE2B MAC multiple blocks of memory to produce the authentication tag + @param key The secret key + @param keylen The length of the secret key (octets) + @param out [out] Destination of the authentication tag + @param outlen [in/out] Max size and resulting size of authentication tag + @param in The data to BLAKE2B MAC + @param inlen The length of the data to BLAKE2B MAC (octets) + @param ... tuples of (data,len) pairs to BLAKE2B MAC, terminated with a (NULL,x) (x=don't care) + @return CRYPT_OK if successful +*/ +int blake2bmac_memory_multi(const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen, const unsigned char *in, unsigned long inlen, ...) +{ + blake2bmac_state st; + int err; + va_list args; + const unsigned char *curptr; + unsigned long curlen; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(mac != NULL); + LTC_ARGCHK(maclen != NULL); + + va_start(args, inlen); + curptr = in; + curlen = inlen; + if ((err = blake2bmac_init(&st, *maclen, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } + for (;;) { + if ((err = blake2bmac_process(&st, curptr, curlen)) != CRYPT_OK) { goto LBL_ERR; } + curptr = va_arg(args, const unsigned char*); + if (curptr == NULL) break; + curlen = va_arg(args, unsigned long); + } + err = blake2bmac_done(&st, mac, maclen); +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(&st, sizeof(blake2bmac_state)); +#endif + va_end(args); + return err; +} + +#endif diff --git a/src/ltc/mac/blake2/blake2smac.c b/src/ltc/mac/blake2/blake2smac.c new file mode 100644 index 0000000..741cf72 --- /dev/null +++ b/src/ltc/mac/blake2/blake2smac.c @@ -0,0 +1,61 @@ +/* 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. + */ + +#include "tomcrypt.h" + +#ifdef LTC_BLAKE2SMAC + +/** + Initialize an BLAKE2S MAC context. + @param st The BLAKE2S MAC state + @param key The secret key + @param keylen The length of the secret key (octets) + @return CRYPT_OK if successful +*/ +int blake2smac_init(blake2smac_state *st, unsigned long outlen, const unsigned char *key, unsigned long keylen) +{ + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(key != NULL); + return blake2s_init(st, outlen, key, keylen); +} + +/** + Process data through BLAKE2S MAC + @param st The BLAKE2S MAC state + @param in The data to send through HMAC + @param inlen The length of the data to HMAC (octets) + @return CRYPT_OK if successful +*/ +int blake2smac_process(blake2smac_state *st, const unsigned char *in, unsigned long inlen) +{ + if (inlen == 0) return CRYPT_OK; /* nothing to do */ + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(in != NULL); + return blake2s_process(st, in, inlen); +} + +/** + Terminate a BLAKE2S MAC session + @param st The BLAKE2S MAC state + @param mac [out] The destination of the BLAKE2S MAC authentication tag + @param maclen [in/out] The max size and resulting size of the BLAKE2S MAC authentication tag + @return CRYPT_OK if successful +*/ +int blake2smac_done(blake2smac_state *st, unsigned char *mac, unsigned long *maclen) +{ + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(mac != NULL); + LTC_ARGCHK(maclen != NULL); + LTC_ARGCHK(*maclen >= st->blake2s.outlen); + + *maclen = st->blake2s.outlen; + return blake2s_done(st, mac); +} + +#endif diff --git a/src/ltc/mac/blake2/blake2smac_file.c b/src/ltc/mac/blake2/blake2smac_file.c new file mode 100644 index 0000000..c6da9ee --- /dev/null +++ b/src/ltc/mac/blake2/blake2smac_file.c @@ -0,0 +1,79 @@ +/* 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. + */ + +#include "tomcrypt.h" + +#ifdef LTC_BLAKE2SMAC + +/** + BLAKE2S MAC a file + @param fname The name of the file you wish to BLAKE2S MAC + @param key The secret key + @param keylen The length of the secret key + @param mac [out] The BLAKE2S MAC authentication tag + @param maclen [in/out] The max size and resulting size of the authentication tag + @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled +*/ +int blake2smac_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen) +{ +#ifdef LTC_NO_FILE + return CRYPT_NOP; +#else + blake2smac_state st; + FILE *in; + unsigned char *buf; + size_t x; + int err; + + LTC_ARGCHK(fname != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(mac != NULL); + LTC_ARGCHK(maclen != NULL); + + if ((buf = XMALLOC(LTC_FILE_READ_BUFSIZE)) == NULL) { + return CRYPT_MEM; + } + + if ((err = blake2smac_init(&st, *maclen, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + + in = fopen(fname, "rb"); + if (in == NULL) { + err = CRYPT_FILE_NOTFOUND; + goto LBL_ERR; + } + + do { + x = fread(buf, 1, LTC_FILE_READ_BUFSIZE, in); + if ((err = blake2smac_process(&st, buf, (unsigned long)x)) != CRYPT_OK) { + fclose(in); + goto LBL_CLEANBUF; + } + } while (x == LTC_FILE_READ_BUFSIZE); + + if (fclose(in) != 0) { + err = CRYPT_ERROR; + goto LBL_CLEANBUF; + } + + err = blake2smac_done(&st, mac, maclen); + +LBL_CLEANBUF: + zeromem(buf, LTC_FILE_READ_BUFSIZE); +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(&st, sizeof(blake2smac_state)); +#endif + XFREE(buf); + return err; +#endif +} + +#endif diff --git a/src/ltc/mac/blake2/blake2smac_memory.c b/src/ltc/mac/blake2/blake2smac_memory.c new file mode 100644 index 0000000..0376554 --- /dev/null +++ b/src/ltc/mac/blake2/blake2smac_memory.c @@ -0,0 +1,44 @@ +/* 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. + */ + +#include "tomcrypt.h" + +#ifdef LTC_BLAKE2SMAC + +/** + BLAKE2S MAC a block of memory to produce the authentication tag + @param key The secret key + @param keylen The length of the secret key (octets) + @param in The data to BLAKE2S MAC + @param inlen The length of the data to BLAKE2S MAC (octets) + @param mac [out] Destination of the authentication tag + @param maclen [in/out] Max size and resulting size of authentication tag + @return CRYPT_OK if successful +*/ +int blake2smac_memory(const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *mac, unsigned long *maclen) +{ + blake2smac_state st; + int err; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(mac != NULL); + LTC_ARGCHK(maclen != NULL); + + if ((err = blake2smac_init(&st, *maclen, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = blake2smac_process(&st, in, inlen)) != CRYPT_OK) { goto LBL_ERR; } + err = blake2smac_done(&st, mac, maclen); +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(&st, sizeof(blake2smac_state)); +#endif + return err; +} + +#endif diff --git a/src/ltc/mac/blake2/blake2smac_memory_multi.c b/src/ltc/mac/blake2/blake2smac_memory_multi.c new file mode 100644 index 0000000..27889c2 --- /dev/null +++ b/src/ltc/mac/blake2/blake2smac_memory_multi.c @@ -0,0 +1,58 @@ +/* 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. + */ + +#include "tomcrypt.h" +#include + +#ifdef LTC_BLAKE2SMAC + +/** + BLAKE2S MAC multiple blocks of memory to produce the authentication tag + @param key The secret key + @param keylen The length of the secret key (octets) + @param out [out] Destination of the authentication tag + @param outlen [in/out] Max size and resulting size of authentication tag + @param in The data to BLAKE2S MAC + @param inlen The length of the data to BLAKE2S MAC (octets) + @param ... tuples of (data,len) pairs to BLAKE2S MAC, terminated with a (NULL,x) (x=don't care) + @return CRYPT_OK if successful +*/ +int blake2smac_memory_multi(const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen, const unsigned char *in, unsigned long inlen, ...) +{ + blake2smac_state st; + int err; + va_list args; + const unsigned char *curptr; + unsigned long curlen; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(mac != NULL); + LTC_ARGCHK(maclen != NULL); + + va_start(args, inlen); + curptr = in; + curlen = inlen; + if ((err = blake2smac_init(&st, *maclen, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } + for (;;) { + if ((err = blake2smac_process(&st, curptr, curlen)) != CRYPT_OK) { goto LBL_ERR; } + curptr = va_arg(args, const unsigned char*); + if (curptr == NULL) break; + curlen = va_arg(args, unsigned long); + } + err = blake2smac_done(&st, mac, maclen); +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(&st, sizeof(blake2smac_state)); +#endif + va_end(args); + return err; +} + +#endif diff --git a/src/ltc/mac/f9/f9_done.c b/src/ltc/mac/f9/f9_done.c new file mode 100644 index 0000000..9bcf1b5 --- /dev/null +++ b/src/ltc/mac/f9/f9_done.c @@ -0,0 +1,77 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file f9_done.c + f9 Support, terminate the state +*/ + +#ifdef LTC_F9_MODE + +/** Terminate the f9-MAC state + @param f9 f9 state to terminate + @param out [out] Destination for the MAC tag + @param outlen [in/out] Destination size and final tag size + Return CRYPT_OK on success +*/ +int f9_done(f9_state *f9, unsigned char *out, unsigned long *outlen) +{ + int err, x; + LTC_ARGCHK(f9 != NULL); + LTC_ARGCHK(out != NULL); + + /* check structure */ + if ((err = cipher_is_valid(f9->cipher)) != CRYPT_OK) { + return err; + } + + if ((f9->blocksize > cipher_descriptor[f9->cipher].block_length) || (f9->blocksize < 0) || + (f9->buflen > f9->blocksize) || (f9->buflen < 0)) { + return CRYPT_INVALID_ARG; + } + + if (f9->buflen != 0) { + /* encrypt */ + cipher_descriptor[f9->cipher].ecb_encrypt(f9->IV, f9->IV, &f9->key); + f9->buflen = 0; + for (x = 0; x < f9->blocksize; x++) { + f9->ACC[x] ^= f9->IV[x]; + } + } + + /* schedule modified key */ + if ((err = cipher_descriptor[f9->cipher].setup(f9->akey, f9->keylen, 0, &f9->key)) != CRYPT_OK) { + return err; + } + + /* encrypt the ACC */ + cipher_descriptor[f9->cipher].ecb_encrypt(f9->ACC, f9->ACC, &f9->key); + cipher_descriptor[f9->cipher].done(&f9->key); + + /* extract tag */ + for (x = 0; x < f9->blocksize && (unsigned long)x < *outlen; x++) { + out[x] = f9->ACC[x]; + } + *outlen = x; + +#ifdef LTC_CLEAN_STACK + zeromem(f9, sizeof(*f9)); +#endif + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ + diff --git a/src/ltc/mac/f9/f9_file.c b/src/ltc/mac/f9/f9_file.c new file mode 100644 index 0000000..c99d7a3 --- /dev/null +++ b/src/ltc/mac/f9/f9_file.c @@ -0,0 +1,93 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file f9_file.c + f9 support, process a file, Tom St Denis +*/ + +#ifdef LTC_F9_MODE + +/** + f9 a file + @param cipher The index of the cipher desired + @param key The secret key + @param keylen The length of the secret key (octets) + @param fname The name of the file you wish to f9 + @param out [out] Where the authentication tag is to be stored + @param outlen [in/out] The max size and resulting size of the authentication tag + @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled +*/ +int f9_file(int cipher, + const unsigned char *key, unsigned long keylen, + const char *fname, + unsigned char *out, unsigned long *outlen) +{ +#ifdef LTC_NO_FILE + return CRYPT_NOP; +#else + size_t x; + int err; + f9_state f9; + FILE *in; + unsigned char *buf; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(fname != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + if ((buf = XMALLOC(LTC_FILE_READ_BUFSIZE)) == NULL) { + return CRYPT_MEM; + } + + if ((err = f9_init(&f9, cipher, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + + in = fopen(fname, "rb"); + if (in == NULL) { + err = CRYPT_FILE_NOTFOUND; + goto LBL_ERR; + } + + do { + x = fread(buf, 1, LTC_FILE_READ_BUFSIZE, in); + if ((err = f9_process(&f9, buf, (unsigned long)x)) != CRYPT_OK) { + fclose(in); + goto LBL_CLEANBUF; + } + } while (x == LTC_FILE_READ_BUFSIZE); + + if (fclose(in) != 0) { + err = CRYPT_ERROR; + goto LBL_CLEANBUF; + } + + err = f9_done(&f9, out, outlen); + +LBL_CLEANBUF: + zeromem(buf, LTC_FILE_READ_BUFSIZE); +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(&f9, sizeof(f9_state)); +#endif + XFREE(buf); + return err; +#endif +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/mac/f9/f9_init.c b/src/ltc/mac/f9/f9_init.c new file mode 100644 index 0000000..ec026b9 --- /dev/null +++ b/src/ltc/mac/f9/f9_init.c @@ -0,0 +1,70 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file f9_init.c + F9 Support, start an F9 state +*/ + +#ifdef LTC_F9_MODE + +/** Initialize F9-MAC state + @param f9 [out] f9 state to initialize + @param cipher Index of cipher to use + @param key [in] Secret key + @param keylen Length of secret key in octets + Return CRYPT_OK on success +*/ +int f9_init(f9_state *f9, int cipher, const unsigned char *key, unsigned long keylen) +{ + int x, err; + + LTC_ARGCHK(f9 != NULL); + LTC_ARGCHK(key != NULL); + + /* schedule the key */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + +#ifdef LTC_FAST + if (cipher_descriptor[cipher].block_length % sizeof(LTC_FAST_TYPE)) { + return CRYPT_INVALID_ARG; + } +#endif + + if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &f9->key)) != CRYPT_OK) { + goto done; + } + + /* make the second key */ + for (x = 0; (unsigned)x < keylen; x++) { + f9->akey[x] = key[x] ^ 0xAA; + } + + /* setup struct */ + zeromem(f9->IV, cipher_descriptor[cipher].block_length); + zeromem(f9->ACC, cipher_descriptor[cipher].block_length); + f9->blocksize = cipher_descriptor[cipher].block_length; + f9->cipher = cipher; + f9->buflen = 0; + f9->keylen = keylen; +done: + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ + diff --git a/src/ltc/mac/f9/f9_memory.c b/src/ltc/mac/f9/f9_memory.c new file mode 100644 index 0000000..e07a05c --- /dev/null +++ b/src/ltc/mac/f9/f9_memory.c @@ -0,0 +1,71 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file f9_process.c + f9 Support, Process a block through F9-MAC +*/ + +#ifdef LTC_F9_MODE + +/** f9-MAC a block of memory + @param cipher Index of cipher to use + @param key [in] Secret key + @param keylen Length of key in octets + @param in [in] Message to MAC + @param inlen Length of input in octets + @param out [out] Destination for the MAC tag + @param outlen [in/out] Output size and final tag size + Return CRYPT_OK on success. +*/ +int f9_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + f9_state *f9; + int err; + + /* is the cipher valid? */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + /* Use accelerator if found */ + if (cipher_descriptor[cipher].f9_memory != NULL) { + return cipher_descriptor[cipher].f9_memory(key, keylen, in, inlen, out, outlen); + } + + f9 = XCALLOC(1, sizeof(*f9)); + if (f9 == NULL) { + return CRYPT_MEM; + } + + if ((err = f9_init(f9, cipher, key, keylen)) != CRYPT_OK) { + goto done; + } + + if ((err = f9_process(f9, in, inlen)) != CRYPT_OK) { + goto done; + } + + err = f9_done(f9, out, outlen); +done: + XFREE(f9); + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/mac/f9/f9_memory_multi.c b/src/ltc/mac/f9/f9_memory_multi.c new file mode 100644 index 0000000..6c8f2dc --- /dev/null +++ b/src/ltc/mac/f9/f9_memory_multi.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://libtom.org + */ +#include "tomcrypt.h" +#include + +/** + @file f9_memory_multi.c + f9 support, process multiple blocks of memory, Tom St Denis +*/ + +#ifdef LTC_F9_MODE + +/** + f9 multiple blocks of memory + @param cipher The index of the desired cipher + @param key The secret key + @param keylen The length of the secret key (octets) + @param out [out] The destination of the authentication tag + @param outlen [in/out] The max size and resulting size of the authentication tag (octets) + @param in The data to send through f9 + @param inlen The length of the data to send through f9 (octets) + @param ... tuples of (data,len) pairs to f9, terminated with a (NULL,x) (x=don't care) + @return CRYPT_OK if successful +*/ +int f9_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 err; + f9_state *f9; + va_list args; + const unsigned char *curptr; + unsigned long curlen; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* allocate ram for f9 state */ + f9 = XMALLOC(sizeof(f9_state)); + if (f9 == NULL) { + return CRYPT_MEM; + } + + /* f9 process the message */ + if ((err = f9_init(f9, cipher, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + va_start(args, inlen); + curptr = in; + curlen = inlen; + for (;;) { + /* process buf */ + if ((err = f9_process(f9, curptr, curlen)) != CRYPT_OK) { + goto LBL_ERR; + } + /* step to next */ + curptr = va_arg(args, const unsigned char*); + if (curptr == NULL) { + break; + } + curlen = va_arg(args, unsigned long); + } + if ((err = f9_done(f9, out, outlen)) != CRYPT_OK) { + goto LBL_ERR; + } +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(f9, sizeof(f9_state)); +#endif + XFREE(f9); + va_end(args); + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/mac/f9/f9_process.c b/src/ltc/mac/f9/f9_process.c new file mode 100644 index 0000000..42027fd --- /dev/null +++ b/src/ltc/mac/f9/f9_process.c @@ -0,0 +1,78 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file f9_process.c + f9 Support, process blocks with f9 +*/ + +#ifdef LTC_F9_MODE + +/** Process data through f9-MAC + @param f9 The f9-MAC state + @param in Input data to process + @param inlen Length of input in octets + Return CRYPT_OK on success +*/ +int f9_process(f9_state *f9, const unsigned char *in, unsigned long inlen) +{ + int err, x; + + LTC_ARGCHK(f9 != NULL); + LTC_ARGCHK(in != NULL); + + /* check structure */ + if ((err = cipher_is_valid(f9->cipher)) != CRYPT_OK) { + return err; + } + + if ((f9->blocksize > cipher_descriptor[f9->cipher].block_length) || (f9->blocksize < 0) || + (f9->buflen > f9->blocksize) || (f9->buflen < 0)) { + return CRYPT_INVALID_ARG; + } + +#ifdef LTC_FAST + if (f9->buflen == 0) { + while (inlen >= (unsigned long)f9->blocksize) { + for (x = 0; x < f9->blocksize; x += sizeof(LTC_FAST_TYPE)) { + *(LTC_FAST_TYPE_PTR_CAST(&(f9->IV[x]))) ^= *(LTC_FAST_TYPE_PTR_CAST(&(in[x]))); + } + cipher_descriptor[f9->cipher].ecb_encrypt(f9->IV, f9->IV, &f9->key); + for (x = 0; x < f9->blocksize; x += sizeof(LTC_FAST_TYPE)) { + *(LTC_FAST_TYPE_PTR_CAST(&(f9->ACC[x]))) ^= *(LTC_FAST_TYPE_PTR_CAST(&(f9->IV[x]))); + } + in += f9->blocksize; + inlen -= f9->blocksize; + } + } +#endif + + while (inlen) { + if (f9->buflen == f9->blocksize) { + cipher_descriptor[f9->cipher].ecb_encrypt(f9->IV, f9->IV, &f9->key); + for (x = 0; x < f9->blocksize; x++) { + f9->ACC[x] ^= f9->IV[x]; + } + f9->buflen = 0; + } + f9->IV[f9->buflen++] ^= *in++; + --inlen; + } + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ + diff --git a/src/ltc/mac/hmac/hmac_done.c b/src/ltc/mac/hmac/hmac_done.c new file mode 100644 index 0000000..15baa0c --- /dev/null +++ b/src/ltc/mac/hmac/hmac_done.c @@ -0,0 +1,109 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file hmac_done.c + HMAC support, terminate stream, Tom St Denis/Dobes Vandermeer +*/ + +#ifdef LTC_HMAC + +#define LTC_HMAC_BLOCKSIZE hash_descriptor[hash].blocksize + +/** + Terminate an HMAC session + @param hmac The HMAC state + @param out [out] The destination of the HMAC authentication tag + @param outlen [in/out] The max size and resulting size of the HMAC authentication tag + @return CRYPT_OK if successful +*/ +int hmac_done(hmac_state *hmac, unsigned char *out, unsigned long *outlen) +{ + unsigned char *buf, *isha; + unsigned long hashsize, i; + int hash, err; + + LTC_ARGCHK(hmac != NULL); + LTC_ARGCHK(out != NULL); + + /* test hash */ + hash = hmac->hash; + if((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + /* get the hash message digest size */ + hashsize = hash_descriptor[hash].hashsize; + + /* allocate buffers */ + buf = XMALLOC(LTC_HMAC_BLOCKSIZE); + isha = XMALLOC(hashsize); + if (buf == NULL || isha == NULL) { + if (buf != NULL) { + XFREE(buf); + } + if (isha != NULL) { + XFREE(isha); + } + return CRYPT_MEM; + } + + /* Get the hash of the first HMAC vector plus the data */ + if ((err = hash_descriptor[hash].done(&hmac->md, isha)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* Create the second HMAC vector vector for step (3) */ + for(i=0; i < LTC_HMAC_BLOCKSIZE; i++) { + buf[i] = hmac->key[i] ^ 0x5C; + } + + /* Now calculate the "outer" hash for step (5), (6), and (7) */ + if ((err = hash_descriptor[hash].init(&hmac->md)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash].process(&hmac->md, buf, LTC_HMAC_BLOCKSIZE)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash].process(&hmac->md, isha, hashsize)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash].done(&hmac->md, buf)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* copy to output */ + for (i = 0; i < hashsize && i < *outlen; i++) { + out[i] = buf[i]; + } + *outlen = i; + + err = CRYPT_OK; +LBL_ERR: + XFREE(hmac->key); +#ifdef LTC_CLEAN_STACK + zeromem(isha, hashsize); + zeromem(buf, hashsize); + zeromem(hmac, sizeof(*hmac)); +#endif + + XFREE(isha); + XFREE(buf); + + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/mac/hmac/hmac_file.c b/src/ltc/mac/hmac/hmac_file.c new file mode 100644 index 0000000..f74505c --- /dev/null +++ b/src/ltc/mac/hmac/hmac_file.c @@ -0,0 +1,96 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file hmac_file.c + HMAC support, process a file, Tom St Denis/Dobes Vandermeer +*/ + +#ifdef LTC_HMAC + +/** + HMAC a file + @param hash The index of the hash you wish to use + @param fname The name of the file you wish to HMAC + @param key The secret key + @param keylen The length of the secret key + @param out [out] The HMAC authentication tag + @param outlen [in/out] The max size and resulting size of the authentication tag + @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled +*/ +int hmac_file(int hash, const char *fname, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen) +{ +#ifdef LTC_NO_FILE + return CRYPT_NOP; +#else + hmac_state hmac; + FILE *in; + unsigned char *buf; + size_t x; + int err; + + LTC_ARGCHK(fname != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + if ((buf = XMALLOC(LTC_FILE_READ_BUFSIZE)) == NULL) { + return CRYPT_MEM; + } + + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + goto LBL_ERR; + } + + if ((err = hmac_init(&hmac, hash, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + + in = fopen(fname, "rb"); + if (in == NULL) { + err = CRYPT_FILE_NOTFOUND; + goto LBL_ERR; + } + + do { + x = fread(buf, 1, LTC_FILE_READ_BUFSIZE, in); + if ((err = hmac_process(&hmac, buf, (unsigned long)x)) != CRYPT_OK) { + fclose(in); /* we don't trap this error since we're already returning an error! */ + goto LBL_CLEANBUF; + } + } while (x == LTC_FILE_READ_BUFSIZE); + + if (fclose(in) != 0) { + err = CRYPT_ERROR; + goto LBL_CLEANBUF; + } + + err = hmac_done(&hmac, out, outlen); + +LBL_CLEANBUF: + zeromem(buf, LTC_FILE_READ_BUFSIZE); +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(&hmac, sizeof(hmac_state)); +#endif + XFREE(buf); + return err; +#endif +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/mac/hmac/hmac_init.c b/src/ltc/mac/hmac/hmac_init.c new file mode 100644 index 0000000..2c887db --- /dev/null +++ b/src/ltc/mac/hmac/hmac_init.c @@ -0,0 +1,110 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file hmac_init.c + HMAC support, initialize state, Tom St Denis/Dobes Vandermeer +*/ + +#ifdef LTC_HMAC + +#define LTC_HMAC_BLOCKSIZE hash_descriptor[hash].blocksize + +/** + Initialize an HMAC context. + @param hmac The HMAC state + @param hash The index of the hash you want to use + @param key The secret key + @param keylen The length of the secret key (octets) + @return CRYPT_OK if successful +*/ +int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen) +{ + unsigned char *buf; + unsigned long hashsize; + unsigned long i, z; + int err; + + LTC_ARGCHK(hmac != NULL); + LTC_ARGCHK(key != NULL); + + /* valid hash? */ + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + hmac->hash = hash; + hashsize = hash_descriptor[hash].hashsize; + + /* valid key length? */ + if (keylen == 0) { + return CRYPT_INVALID_KEYSIZE; + } + + /* allocate ram for buf */ + buf = XMALLOC(LTC_HMAC_BLOCKSIZE); + if (buf == NULL) { + return CRYPT_MEM; + } + + /* allocate memory for key */ + hmac->key = XMALLOC(LTC_HMAC_BLOCKSIZE); + if (hmac->key == NULL) { + XFREE(buf); + return CRYPT_MEM; + } + + /* (1) make sure we have a large enough key */ + if(keylen > LTC_HMAC_BLOCKSIZE) { + z = LTC_HMAC_BLOCKSIZE; + if ((err = hash_memory(hash, key, keylen, hmac->key, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + keylen = hashsize; + } else { + XMEMCPY(hmac->key, key, (size_t)keylen); + } + + if(keylen < LTC_HMAC_BLOCKSIZE) { + zeromem((hmac->key) + keylen, (size_t)(LTC_HMAC_BLOCKSIZE - keylen)); + } + + /* Create the initial vector for step (3) */ + for(i=0; i < LTC_HMAC_BLOCKSIZE; i++) { + buf[i] = hmac->key[i] ^ 0x36; + } + + /* Pre-pend that to the hash data */ + if ((err = hash_descriptor[hash].init(&hmac->md)) != CRYPT_OK) { + goto LBL_ERR; + } + + if ((err = hash_descriptor[hash].process(&hmac->md, buf, LTC_HMAC_BLOCKSIZE)) != CRYPT_OK) { + goto LBL_ERR; + } + goto done; +LBL_ERR: + /* free the key since we failed */ + XFREE(hmac->key); +done: +#ifdef LTC_CLEAN_STACK + zeromem(buf, LTC_HMAC_BLOCKSIZE); +#endif + + XFREE(buf); + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/mac/hmac/hmac_memory.c b/src/ltc/mac/hmac/hmac_memory.c new file mode 100644 index 0000000..c32f13a --- /dev/null +++ b/src/ltc/mac/hmac/hmac_memory.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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file hmac_memory.c + HMAC support, process a block of memory, Tom St Denis/Dobes Vandermeer +*/ + +#ifdef LTC_HMAC + +/** + HMAC a block of memory to produce the authentication tag + @param hash The index of the hash to use + @param key The secret key + @param keylen The length of the secret key (octets) + @param in The data to HMAC + @param inlen The length of the data to HMAC (octets) + @param out [out] Destination of the authentication tag + @param outlen [in/out] Max size and resulting size of authentication tag + @return CRYPT_OK if successful +*/ +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) +{ + hmac_state *hmac; + int err; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* make sure hash descriptor is valid */ + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + /* is there a descriptor? */ + if (hash_descriptor[hash].hmac_block != NULL) { + return hash_descriptor[hash].hmac_block(key, keylen, in, inlen, out, outlen); + } + + /* nope, so call the hmac functions */ + /* allocate ram for hmac state */ + hmac = XMALLOC(sizeof(hmac_state)); + if (hmac == NULL) { + return CRYPT_MEM; + } + + if ((err = hmac_init(hmac, hash, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + + if ((err = hmac_process(hmac, in, inlen)) != CRYPT_OK) { + goto LBL_ERR; + } + + if ((err = hmac_done(hmac, out, outlen)) != CRYPT_OK) { + goto LBL_ERR; + } + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(hmac, sizeof(hmac_state)); +#endif + + XFREE(hmac); + return err; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/mac/hmac/hmac_memory_multi.c b/src/ltc/mac/hmac/hmac_memory_multi.c new file mode 100644 index 0000000..f9d8587 --- /dev/null +++ b/src/ltc/mac/hmac/hmac_memory_multi.c @@ -0,0 +1,92 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" +#include + +/** + @file hmac_memory_multi.c + HMAC support, process multiple blocks of memory, Tom St Denis/Dobes Vandermeer +*/ + +#ifdef LTC_HMAC + +/** + HMAC multiple blocks of memory to produce the authentication tag + @param hash The index of the hash to use + @param key The secret key + @param keylen The length of the secret key (octets) + @param out [out] Destination of the authentication tag + @param outlen [in/out] Max size and resulting size of authentication tag + @param in The data to HMAC + @param inlen The length of the data to HMAC (octets) + @param ... tuples of (data,len) pairs to HMAC, terminated with a (NULL,x) (x=don't care) + @return CRYPT_OK if successful +*/ +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, ...) + +{ + hmac_state *hmac; + int err; + va_list args; + const unsigned char *curptr; + unsigned long curlen; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* allocate ram for hmac state */ + hmac = XMALLOC(sizeof(hmac_state)); + if (hmac == NULL) { + return CRYPT_MEM; + } + + if ((err = hmac_init(hmac, hash, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + + va_start(args, inlen); + curptr = in; + curlen = inlen; + for (;;) { + /* process buf */ + if ((err = hmac_process(hmac, curptr, curlen)) != CRYPT_OK) { + goto LBL_ERR; + } + /* step to next */ + curptr = va_arg(args, const unsigned char*); + if (curptr == NULL) { + break; + } + curlen = va_arg(args, unsigned long); + } + if ((err = hmac_done(hmac, out, outlen)) != CRYPT_OK) { + goto LBL_ERR; + } +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(hmac, sizeof(hmac_state)); +#endif + XFREE(hmac); + va_end(args); + return err; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/mac/hmac/hmac_process.c b/src/ltc/mac/hmac/hmac_process.c new file mode 100644 index 0000000..f1931c8 --- /dev/null +++ b/src/ltc/mac/hmac/hmac_process.c @@ -0,0 +1,43 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file hmac_process.c + HMAC support, process data, Tom St Denis/Dobes Vandermeer +*/ + +#ifdef LTC_HMAC + +/** + Process data through HMAC + @param hmac The hmac state + @param in The data to send through HMAC + @param inlen The length of the data to HMAC (octets) + @return CRYPT_OK if successful +*/ +int hmac_process(hmac_state *hmac, const unsigned char *in, unsigned long inlen) +{ + int err; + LTC_ARGCHK(hmac != NULL); + LTC_ARGCHK(in != NULL); + if ((err = hash_is_valid(hmac->hash)) != CRYPT_OK) { + return err; + } + return hash_descriptor[hmac->hash].process(&hmac->md, in, inlen); +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/mac/omac/omac_done.c b/src/ltc/mac/omac/omac_done.c new file mode 100644 index 0000000..18fa25c --- /dev/null +++ b/src/ltc/mac/omac/omac_done.c @@ -0,0 +1,86 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file omac_done.c + OMAC1 support, terminate a stream, Tom St Denis +*/ + +#ifdef LTC_OMAC + +/** + Terminate an OMAC stream + @param omac The OMAC state + @param out [out] Destination for the authentication tag + @param outlen [in/out] The max size and resulting size of the authentication tag + @return CRYPT_OK if successful +*/ +int omac_done(omac_state *omac, unsigned char *out, unsigned long *outlen) +{ + int err, mode; + unsigned x; + + LTC_ARGCHK(omac != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + if ((err = cipher_is_valid(omac->cipher_idx)) != CRYPT_OK) { + return err; + } + + if ((omac->buflen > (int)sizeof(omac->block)) || (omac->buflen < 0) || + (omac->blklen > (int)sizeof(omac->block)) || (omac->buflen > omac->blklen)) { + return CRYPT_INVALID_ARG; + } + + /* figure out mode */ + if (omac->buflen != omac->blklen) { + /* add the 0x80 byte */ + omac->block[omac->buflen++] = 0x80; + + /* pad with 0x00 */ + while (omac->buflen < omac->blklen) { + omac->block[omac->buflen++] = 0x00; + } + mode = 1; + } else { + mode = 0; + } + + /* now xor prev + Lu[mode] */ + for (x = 0; x < (unsigned)omac->blklen; x++) { + omac->block[x] ^= omac->prev[x] ^ omac->Lu[mode][x]; + } + + /* encrypt it */ + if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->block, &omac->key)) != CRYPT_OK) { + return err; + } + cipher_descriptor[omac->cipher_idx].done(&omac->key); + + /* output it */ + for (x = 0; x < (unsigned)omac->blklen && x < *outlen; x++) { + out[x] = omac->block[x]; + } + *outlen = x; + +#ifdef LTC_CLEAN_STACK + zeromem(omac, sizeof(*omac)); +#endif + return CRYPT_OK; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/mac/omac/omac_file.c b/src/ltc/mac/omac/omac_file.c new file mode 100644 index 0000000..51c67b7 --- /dev/null +++ b/src/ltc/mac/omac/omac_file.c @@ -0,0 +1,93 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file omac_file.c + OMAC1 support, process a file, Tom St Denis +*/ + +#ifdef LTC_OMAC + +/** + OMAC a file + @param cipher The index of the cipher desired + @param key The secret key + @param keylen The length of the secret key (octets) + @param filename The name of the file you wish to OMAC + @param out [out] Where the authentication tag is to be stored + @param outlen [in/out] The max size and resulting size of the authentication tag + @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled +*/ +int omac_file(int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen) +{ +#ifdef LTC_NO_FILE + return CRYPT_NOP; +#else + size_t x; + int err; + omac_state omac; + FILE *in; + unsigned char *buf; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(filename != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + if ((buf = XMALLOC(LTC_FILE_READ_BUFSIZE)) == NULL) { + return CRYPT_MEM; + } + + if ((err = omac_init(&omac, cipher, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + + in = fopen(filename, "rb"); + if (in == NULL) { + err = CRYPT_FILE_NOTFOUND; + goto LBL_ERR; + } + + do { + x = fread(buf, 1, LTC_FILE_READ_BUFSIZE, in); + if ((err = omac_process(&omac, buf, (unsigned long)x)) != CRYPT_OK) { + fclose(in); + goto LBL_CLEANBUF; + } + } while (x == LTC_FILE_READ_BUFSIZE); + + if (fclose(in) != 0) { + err = CRYPT_ERROR; + goto LBL_CLEANBUF; + } + + err = omac_done(&omac, out, outlen); + +LBL_CLEANBUF: + zeromem(buf, LTC_FILE_READ_BUFSIZE); +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(&omac, sizeof(omac_state)); +#endif + XFREE(buf); + return err; +#endif +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/mac/omac/omac_init.c b/src/ltc/mac/omac/omac_init.c new file mode 100644 index 0000000..3bee70f --- /dev/null +++ b/src/ltc/mac/omac/omac_init.c @@ -0,0 +1,101 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file omac_init.c + OMAC1 support, initialize state, by Tom St Denis +*/ + + +#ifdef LTC_OMAC + +/** + Initialize an OMAC state + @param omac The OMAC state to initialize + @param cipher The index of the desired cipher + @param key The secret key + @param keylen The length of the secret key (octets) + @return CRYPT_OK if successful +*/ +int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned long keylen) +{ + int err, x, y, mask, msb, len; + + LTC_ARGCHK(omac != NULL); + LTC_ARGCHK(key != NULL); + + /* schedule the key */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + +#ifdef LTC_FAST + if (cipher_descriptor[cipher].block_length % sizeof(LTC_FAST_TYPE)) { + return CRYPT_INVALID_ARG; + } +#endif + + /* now setup the system */ + switch (cipher_descriptor[cipher].block_length) { + case 8: mask = 0x1B; + len = 8; + break; + case 16: mask = 0x87; + len = 16; + break; + default: return CRYPT_INVALID_ARG; + } + + if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &omac->key)) != CRYPT_OK) { + return err; + } + + /* ok now we need Lu and Lu^2 [calc one from the other] */ + + /* first calc L which is Ek(0) */ + zeromem(omac->Lu[0], cipher_descriptor[cipher].block_length); + if ((err = cipher_descriptor[cipher].ecb_encrypt(omac->Lu[0], omac->Lu[0], &omac->key)) != CRYPT_OK) { + return err; + } + + /* now do the mults, whoopy! */ + for (x = 0; x < 2; x++) { + /* if msb(L * u^(x+1)) = 0 then just shift, otherwise shift and xor constant mask */ + msb = omac->Lu[x][0] >> 7; + + /* shift left */ + for (y = 0; y < (len - 1); y++) { + omac->Lu[x][y] = ((omac->Lu[x][y] << 1) | (omac->Lu[x][y+1] >> 7)) & 255; + } + omac->Lu[x][len - 1] = ((omac->Lu[x][len - 1] << 1) ^ (msb ? mask : 0)) & 255; + + /* copy up as require */ + if (x == 0) { + XMEMCPY(omac->Lu[1], omac->Lu[0], sizeof(omac->Lu[0])); + } + } + + /* setup state */ + omac->cipher_idx = cipher; + omac->buflen = 0; + omac->blklen = len; + zeromem(omac->prev, sizeof(omac->prev)); + zeromem(omac->block, sizeof(omac->block)); + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/mac/omac/omac_memory.c b/src/ltc/mac/omac/omac_memory.c new file mode 100644 index 0000000..dde7e76 --- /dev/null +++ b/src/ltc/mac/omac/omac_memory.c @@ -0,0 +1,85 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file omac_memory.c + OMAC1 support, process a block of memory, Tom St Denis +*/ + +#ifdef LTC_OMAC + +/** + OMAC a block of memory + @param cipher The index of the desired cipher + @param key The secret key + @param keylen The length of the secret key (octets) + @param in The data to send through OMAC + @param inlen The length of the data to send through OMAC (octets) + @param out [out] The destination of the authentication tag + @param outlen [in/out] The max size and resulting size of the authentication tag (octets) + @return CRYPT_OK if successful +*/ +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 err; + omac_state *omac; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* is the cipher valid? */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + /* Use accelerator if found */ + if (cipher_descriptor[cipher].omac_memory != NULL) { + return cipher_descriptor[cipher].omac_memory(key, keylen, in, inlen, out, outlen); + } + + /* allocate ram for omac state */ + omac = XMALLOC(sizeof(omac_state)); + if (omac == NULL) { + return CRYPT_MEM; + } + + /* omac process the message */ + if ((err = omac_init(omac, cipher, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = omac_process(omac, in, inlen)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = omac_done(omac, out, outlen)) != CRYPT_OK) { + goto LBL_ERR; + } + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(omac, sizeof(omac_state)); +#endif + + XFREE(omac); + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/mac/omac/omac_memory_multi.c b/src/ltc/mac/omac/omac_memory_multi.c new file mode 100644 index 0000000..afaf8cb --- /dev/null +++ b/src/ltc/mac/omac/omac_memory_multi.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://libtom.org + */ +#include "tomcrypt.h" +#include + +/** + @file omac_memory_multi.c + OMAC1 support, process multiple blocks of memory, Tom St Denis +*/ + +#ifdef LTC_OMAC + +/** + OMAC multiple blocks of memory + @param cipher The index of the desired cipher + @param key The secret key + @param keylen The length of the secret key (octets) + @param out [out] The destination of the authentication tag + @param outlen [in/out] The max size and resulting size of the authentication tag (octets) + @param in The data to send through OMAC + @param inlen The length of the data to send through OMAC (octets) + @param ... tuples of (data,len) pairs to OMAC, terminated with a (NULL,x) (x=don't care) + @return CRYPT_OK if successful +*/ +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 err; + omac_state *omac; + va_list args; + const unsigned char *curptr; + unsigned long curlen; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* allocate ram for omac state */ + omac = XMALLOC(sizeof(omac_state)); + if (omac == NULL) { + return CRYPT_MEM; + } + + /* omac process the message */ + if ((err = omac_init(omac, cipher, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + va_start(args, inlen); + curptr = in; + curlen = inlen; + for (;;) { + /* process buf */ + if ((err = omac_process(omac, curptr, curlen)) != CRYPT_OK) { + goto LBL_ERR; + } + /* step to next */ + curptr = va_arg(args, const unsigned char*); + if (curptr == NULL) { + break; + } + curlen = va_arg(args, unsigned long); + } + if ((err = omac_done(omac, out, outlen)) != CRYPT_OK) { + goto LBL_ERR; + } +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(omac, sizeof(omac_state)); +#endif + XFREE(omac); + va_end(args); + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/mac/omac/omac_process.c b/src/ltc/mac/omac/omac_process.c new file mode 100644 index 0000000..df94208 --- /dev/null +++ b/src/ltc/mac/omac/omac_process.c @@ -0,0 +1,92 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file omac_process.c + OMAC1 support, process data, Tom St Denis +*/ + + +#ifdef LTC_OMAC + +/** + Process data through OMAC + @param omac The OMAC state + @param in The input data to send through OMAC + @param inlen The length of the input (octets) + @return CRYPT_OK if successful +*/ +int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen) +{ + unsigned long n, x; + int err; + + LTC_ARGCHK(omac != NULL); + LTC_ARGCHK(in != NULL); + if ((err = cipher_is_valid(omac->cipher_idx)) != CRYPT_OK) { + return err; + } + + if ((omac->buflen > (int)sizeof(omac->block)) || (omac->buflen < 0) || + (omac->blklen > (int)sizeof(omac->block)) || (omac->buflen > omac->blklen)) { + return CRYPT_INVALID_ARG; + } + +#ifdef LTC_FAST + { + unsigned long blklen = cipher_descriptor[omac->cipher_idx].block_length; + + if (omac->buflen == 0 && inlen > blklen) { + unsigned long y; + for (x = 0; x < (inlen - blklen); x += blklen) { + for (y = 0; y < blklen; y += sizeof(LTC_FAST_TYPE)) { + *(LTC_FAST_TYPE_PTR_CAST(&omac->prev[y])) ^= *(LTC_FAST_TYPE_PTR_CAST(&in[y])); + } + in += blklen; + if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->prev, omac->prev, &omac->key)) != CRYPT_OK) { + return err; + } + } + 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) { + for (x = 0; x < (unsigned long)omac->blklen; x++) { + omac->block[x] ^= omac->prev[x]; + } + if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->prev, &omac->key)) != CRYPT_OK) { + return err; + } + omac->buflen = 0; + } + + /* add bytes */ + n = MIN(inlen, (unsigned long)(omac->blklen - omac->buflen)); + XMEMCPY(omac->block + omac->buflen, in, n); + omac->buflen += n; + inlen -= n; + in += n; + } + + return CRYPT_OK; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/mac/pelican/pelican.c b/src/ltc/mac/pelican/pelican.c new file mode 100644 index 0000000..95af87e --- /dev/null +++ b/src/ltc/mac/pelican/pelican.c @@ -0,0 +1,166 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pelican.c + Pelican MAC, initialize state, by Tom St Denis +*/ + +#ifdef LTC_PELICAN + +#define __LTC_AES_TAB_C__ +#define ENCRYPT_ONLY +#define PELI_TAB +#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); + + /* check range */ + if (pelmac->buflen < 0 || pelmac->buflen > 15) { + return CRYPT_INVALID_ARG; + } + +#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_PTR_CAST((unsigned char *)pelmac->state + x)) ^= *(LTC_FAST_TYPE_PTR_CAST((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); + + /* check range */ + if (pelmac->buflen < 0 || pelmac->buflen > 16) { + return CRYPT_INVALID_ARG; + } + + 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 + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/mac/pelican/pelican_memory.c b/src/ltc/mac/pelican/pelican_memory.c new file mode 100644 index 0000000..f5e7b4a --- /dev/null +++ b/src/ltc/mac/pelican/pelican_memory.c @@ -0,0 +1,59 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pelican_memory.c + Pelican MAC, MAC a block of memory, by Tom St Denis +*/ + +#ifdef LTC_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 + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/mac/pmac/pmac_done.c b/src/ltc/mac/pmac/pmac_done.c new file mode 100644 index 0000000..6ad5646 --- /dev/null +++ b/src/ltc/mac/pmac/pmac_done.c @@ -0,0 +1,74 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pmac_done.c + PMAC implementation, terminate a session, by Tom St Denis +*/ + +#ifdef LTC_PMAC + +int pmac_done(pmac_state *state, unsigned char *out, unsigned long *outlen) +{ + int err, x; + + LTC_ARGCHK(state != NULL); + LTC_ARGCHK(out != NULL); + if ((err = cipher_is_valid(state->cipher_idx)) != CRYPT_OK) { + return err; + } + + if ((state->buflen > (int)sizeof(state->block)) || (state->buflen < 0) || + (state->block_len > (int)sizeof(state->block)) || (state->buflen > state->block_len)) { + return CRYPT_INVALID_ARG; + } + + + /* handle padding. If multiple xor in L/x */ + + if (state->buflen == state->block_len) { + /* xor Lr against the checksum */ + for (x = 0; x < state->block_len; x++) { + state->checksum[x] ^= state->block[x] ^ state->Lr[x]; + } + } else { + /* otherwise xor message bytes then the 0x80 byte */ + for (x = 0; x < state->buflen; x++) { + state->checksum[x] ^= state->block[x]; + } + state->checksum[x] ^= 0x80; + } + + /* encrypt it */ + if ((err = cipher_descriptor[state->cipher_idx].ecb_encrypt(state->checksum, state->checksum, &state->key)) != CRYPT_OK) { + return err; + } + cipher_descriptor[state->cipher_idx].done(&state->key); + + /* store it */ + for (x = 0; x < state->block_len && x < (int)*outlen; x++) { + out[x] = state->checksum[x]; + } + *outlen = x; + +#ifdef LTC_CLEAN_STACK + zeromem(state, sizeof(*state)); +#endif + return CRYPT_OK; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/mac/pmac/pmac_file.c b/src/ltc/mac/pmac/pmac_file.c new file mode 100644 index 0000000..c7d9877 --- /dev/null +++ b/src/ltc/mac/pmac/pmac_file.c @@ -0,0 +1,94 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pmac_file.c + PMAC implementation, process a file, by Tom St Denis +*/ + +#ifdef LTC_PMAC + +/** + PMAC a file + @param cipher The index of the cipher desired + @param key The secret key + @param keylen The length of the secret key (octets) + @param filename The name of the file to send through PMAC + @param out [out] Destination for the authentication tag + @param outlen [in/out] Max size and resulting size of the authentication tag + @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled +*/ +int pmac_file(int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen) +{ +#ifdef LTC_NO_FILE + return CRYPT_NOP; +#else + size_t x; + int err; + pmac_state pmac; + FILE *in; + unsigned char *buf; + + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(filename != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + if ((buf = XMALLOC(LTC_FILE_READ_BUFSIZE)) == NULL) { + return CRYPT_MEM; + } + + if ((err = pmac_init(&pmac, cipher, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + + in = fopen(filename, "rb"); + if (in == NULL) { + err = CRYPT_FILE_NOTFOUND; + goto LBL_ERR; + } + + do { + x = fread(buf, 1, LTC_FILE_READ_BUFSIZE, in); + if ((err = pmac_process(&pmac, buf, (unsigned long)x)) != CRYPT_OK) { + fclose(in); + goto LBL_CLEANBUF; + } + } while (x == LTC_FILE_READ_BUFSIZE); + + if (fclose(in) != 0) { + err = CRYPT_ERROR; + goto LBL_CLEANBUF; + } + + err = pmac_done(&pmac, out, outlen); + +LBL_CLEANBUF: + zeromem(buf, LTC_FILE_READ_BUFSIZE); +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(&pmac, sizeof(pmac_state)); +#endif + XFREE(buf); + return err; +#endif +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/mac/pmac/pmac_init.c b/src/ltc/mac/pmac/pmac_init.c new file mode 100644 index 0000000..9a7192c --- /dev/null +++ b/src/ltc/mac/pmac/pmac_init.c @@ -0,0 +1,150 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pmac_init.c + PMAC implementation, initialize state, by Tom St Denis +*/ + +#ifdef LTC_PMAC + +static const struct { + int len; + unsigned char poly_div[MAXBLOCKSIZE], + poly_mul[MAXBLOCKSIZE]; +} polys[] = { +{ + 8, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B } +}, { + 16, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 } +} +}; + +/** + Initialize a PMAC state + @param pmac The PMAC state to initialize + @param cipher The index of the desired cipher + @param key The secret key + @param keylen The length of the secret key (octets) + @return CRYPT_OK if successful +*/ +int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned long keylen) +{ + int poly, x, y, m, err; + unsigned char *L; + + LTC_ARGCHK(pmac != NULL); + LTC_ARGCHK(key != NULL); + + /* valid cipher? */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + /* determine which polys to use */ + pmac->block_len = cipher_descriptor[cipher].block_length; + for (poly = 0; poly < (int)(sizeof(polys)/sizeof(polys[0])); poly++) { + if (polys[poly].len == pmac->block_len) { + break; + } + } + if (poly >= (int)(sizeof(polys)/sizeof(polys[0]))) { + return CRYPT_INVALID_ARG; + } + 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) { + return err; + } + + /* allocate L */ + L = XMALLOC(pmac->block_len); + if (L == NULL) { + return CRYPT_MEM; + } + + /* find L = E[0] */ + zeromem(L, pmac->block_len); + if ((err = cipher_descriptor[cipher].ecb_encrypt(L, L, &pmac->key)) != CRYPT_OK) { + goto error; + } + + /* find Ls[i] = L << i for i == 0..31 */ + XMEMCPY(pmac->Ls[0], L, pmac->block_len); + for (x = 1; x < 32; x++) { + m = pmac->Ls[x-1][0] >> 7; + for (y = 0; y < pmac->block_len-1; y++) { + pmac->Ls[x][y] = ((pmac->Ls[x-1][y] << 1) | (pmac->Ls[x-1][y+1] >> 7)) & 255; + } + pmac->Ls[x][pmac->block_len-1] = (pmac->Ls[x-1][pmac->block_len-1] << 1) & 255; + + if (m == 1) { + for (y = 0; y < pmac->block_len; y++) { + pmac->Ls[x][y] ^= polys[poly].poly_mul[y]; + } + } + } + + /* find Lr = L / x */ + m = L[pmac->block_len-1] & 1; + + /* shift right */ + for (x = pmac->block_len - 1; x > 0; x--) { + pmac->Lr[x] = ((L[x] >> 1) | (L[x-1] << 7)) & 255; + } + pmac->Lr[0] = L[0] >> 1; + + if (m == 1) { + for (x = 0; x < pmac->block_len; x++) { + pmac->Lr[x] ^= polys[poly].poly_div[x]; + } + } + + /* zero buffer, counters, etc... */ + pmac->block_index = 1; + pmac->cipher_idx = cipher; + pmac->buflen = 0; + zeromem(pmac->block, sizeof(pmac->block)); + zeromem(pmac->Li, sizeof(pmac->Li)); + zeromem(pmac->checksum, sizeof(pmac->checksum)); + err = CRYPT_OK; +error: +#ifdef LTC_CLEAN_STACK + zeromem(L, pmac->block_len); +#endif + + XFREE(L); + + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/mac/pmac/pmac_memory.c b/src/ltc/mac/pmac/pmac_memory.c new file mode 100644 index 0000000..f73244a --- /dev/null +++ b/src/ltc/mac/pmac/pmac_memory.c @@ -0,0 +1,74 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pmac_memory.c + PMAC implementation, process a block of memory, by Tom St Denis +*/ + +#ifdef LTC_PMAC + +/** + PMAC a block of memory + @param cipher The index of the cipher desired + @param key The secret key + @param keylen The length of the secret key (octets) + @param in The data you wish to send through PMAC + @param inlen The length of data you wish to send through PMAC (octets) + @param out [out] Destination for the authentication tag + @param outlen [in/out] The max size and resulting size of the authentication tag + @return CRYPT_OK if successful +*/ +int pmac_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + int err; + pmac_state *pmac; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* allocate ram for pmac state */ + pmac = XMALLOC(sizeof(pmac_state)); + if (pmac == NULL) { + return CRYPT_MEM; + } + + if ((err = pmac_init(pmac, cipher, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = pmac_process(pmac, in, inlen)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = pmac_done(pmac, out, outlen)) != CRYPT_OK) { + goto LBL_ERR; + } + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(pmac, sizeof(pmac_state)); +#endif + + XFREE(pmac); + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/mac/pmac/pmac_memory_multi.c b/src/ltc/mac/pmac/pmac_memory_multi.c new file mode 100644 index 0000000..913840a --- /dev/null +++ b/src/ltc/mac/pmac/pmac_memory_multi.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://libtom.org + */ +#include "tomcrypt.h" +#include + +/** + @file pmac_memory_multi.c + PMAC implementation, process multiple blocks of memory, by Tom St Denis +*/ + +#ifdef LTC_PMAC + +/** + PMAC multiple blocks of memory + @param cipher The index of the cipher desired + @param key The secret key + @param keylen The length of the secret key (octets) + @param out [out] Destination for the authentication tag + @param outlen [in/out] The max size and resulting size of the authentication tag + @param in The data you wish to send through PMAC + @param inlen The length of data you wish to send through PMAC (octets) + @param ... tuples of (data,len) pairs to PMAC, terminated with a (NULL,x) (x=don't care) + @return CRYPT_OK if successful +*/ +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 err; + pmac_state *pmac; + va_list args; + const unsigned char *curptr; + unsigned long curlen; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* allocate ram for pmac state */ + pmac = XMALLOC(sizeof(pmac_state)); + if (pmac == NULL) { + return CRYPT_MEM; + } + + if ((err = pmac_init(pmac, cipher, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + va_start(args, inlen); + curptr = in; + curlen = inlen; + for (;;) { + /* process buf */ + if ((err = pmac_process(pmac, curptr, curlen)) != CRYPT_OK) { + goto LBL_ERR; + } + /* step to next */ + curptr = va_arg(args, const unsigned char*); + if (curptr == NULL) { + break; + } + curlen = va_arg(args, unsigned long); + } + if ((err = pmac_done(pmac, out, outlen)) != CRYPT_OK) { + goto LBL_ERR; + } +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(pmac, sizeof(pmac_state)); +#endif + XFREE(pmac); + va_end(args); + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/mac/pmac/pmac_ntz.c b/src/ltc/mac/pmac/pmac_ntz.c new file mode 100644 index 0000000..2e649f9 --- /dev/null +++ b/src/ltc/mac/pmac/pmac_ntz.c @@ -0,0 +1,39 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pmac_ntz.c + PMAC implementation, internal function, by Tom St Denis +*/ + +#ifdef LTC_PMAC + +/** + Internal PMAC function +*/ +int pmac_ntz(unsigned long x) +{ + int c; + x &= 0xFFFFFFFFUL; + c = 0; + while ((x & 1) == 0) { + ++c; + x >>= 1; + } + return c; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/mac/pmac/pmac_process.c b/src/ltc/mac/pmac/pmac_process.c new file mode 100644 index 0000000..9c26783 --- /dev/null +++ b/src/ltc/mac/pmac/pmac_process.c @@ -0,0 +1,100 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pmac_process.c + PMAC implementation, process data, by Tom St Denis +*/ + + +#ifdef LTC_PMAC + +/** + Process data in a PMAC stream + @param pmac The PMAC state + @param in The data to send through PMAC + @param inlen The length of the data to send through PMAC + @return CRYPT_OK if successful +*/ +int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen) +{ + int err, n; + unsigned long x; + unsigned char Z[MAXBLOCKSIZE]; + + LTC_ARGCHK(pmac != NULL); + LTC_ARGCHK(in != NULL); + if ((err = cipher_is_valid(pmac->cipher_idx)) != CRYPT_OK) { + return err; + } + + if ((pmac->buflen > (int)sizeof(pmac->block)) || (pmac->buflen < 0) || + (pmac->block_len > (int)sizeof(pmac->block)) || (pmac->buflen > pmac->block_len)) { + 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_PTR_CAST(&Z[y])) = *(LTC_FAST_TYPE_PTR_CAST(&in[y])) ^ *(LTC_FAST_TYPE_PTR_CAST(&pmac->Li[y])); + } + if ((err = cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key)) != CRYPT_OK) { + return err; + } + for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { + *(LTC_FAST_TYPE_PTR_CAST(&pmac->checksum[y])) ^= *(LTC_FAST_TYPE_PTR_CAST(&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 < (unsigned long)pmac->block_len; x++) { + Z[x] = pmac->Li[x] ^ pmac->block[x]; + } + if ((err = cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key)) != CRYPT_OK) { + return err; + } + for (x = 0; x < (unsigned long)pmac->block_len; x++) { + pmac->checksum[x] ^= Z[x]; + } + pmac->buflen = 0; + } + + /* add bytes */ + n = MIN(inlen, (unsigned long)(pmac->block_len - pmac->buflen)); + XMEMCPY(pmac->block + pmac->buflen, in, n); + pmac->buflen += n; + inlen -= n; + in += n; + } + +#ifdef LTC_CLEAN_STACK + zeromem(Z, sizeof(Z)); +#endif + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/mac/pmac/pmac_shift_xor.c b/src/ltc/mac/pmac/pmac_shift_xor.c new file mode 100644 index 0000000..ac3c12f --- /dev/null +++ b/src/ltc/mac/pmac/pmac_shift_xor.c @@ -0,0 +1,44 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pmac_shift_xor.c + PMAC implementation, internal function, by Tom St Denis +*/ + +#ifdef LTC_PMAC + +/** + Internal function. Performs the state update (adding correct multiple) + @param pmac The PMAC state. +*/ +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_PTR_CAST((unsigned char *)pmac->Li + x)) ^= + *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pmac->Ls[y] + x)); + } +#else + for (x = 0; x < pmac->block_len; x++) { + pmac->Li[x] ^= pmac->Ls[y][x]; + } +#endif +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/mac/poly1305/poly1305.c b/src/ltc/mac/poly1305/poly1305.c new file mode 100644 index 0000000..369341b --- /dev/null +++ b/src/ltc/mac/poly1305/poly1305.c @@ -0,0 +1,264 @@ +/* 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. + */ + +/* The implementation is based on: + * Public Domain poly1305 from Andrew Moon + * https://github.com/floodyberry/poly1305-donna + */ + +#include "tomcrypt.h" + +#ifdef LTC_POLY1305 + +/* internal only */ +static void _poly1305_block(poly1305_state *st, const unsigned char *in, unsigned long inlen) +{ + const unsigned long hibit = (st->final) ? 0 : (1UL << 24); /* 1 << 128 */ + ulong32 r0,r1,r2,r3,r4; + ulong32 s1,s2,s3,s4; + ulong32 h0,h1,h2,h3,h4; + ulong32 tmp; + ulong64 d0,d1,d2,d3,d4; + ulong32 c; + + r0 = st->r[0]; + r1 = st->r[1]; + r2 = st->r[2]; + r3 = st->r[3]; + r4 = st->r[4]; + + s1 = r1 * 5; + s2 = r2 * 5; + s3 = r3 * 5; + s4 = r4 * 5; + + h0 = st->h[0]; + h1 = st->h[1]; + h2 = st->h[2]; + h3 = st->h[3]; + h4 = st->h[4]; + + while (inlen >= 16) { + /* h += in[i] */ + LOAD32L(tmp, in+ 0); h0 += (tmp ) & 0x3ffffff; + LOAD32L(tmp, in+ 3); h1 += (tmp >> 2) & 0x3ffffff; + LOAD32L(tmp, in+ 6); h2 += (tmp >> 4) & 0x3ffffff; + LOAD32L(tmp, in+ 9); h3 += (tmp >> 6) & 0x3ffffff; + LOAD32L(tmp, in+12); h4 += (tmp >> 8) | hibit; + + /* h *= r */ + d0 = ((ulong64)h0 * r0) + ((ulong64)h1 * s4) + ((ulong64)h2 * s3) + ((ulong64)h3 * s2) + ((ulong64)h4 * s1); + d1 = ((ulong64)h0 * r1) + ((ulong64)h1 * r0) + ((ulong64)h2 * s4) + ((ulong64)h3 * s3) + ((ulong64)h4 * s2); + d2 = ((ulong64)h0 * r2) + ((ulong64)h1 * r1) + ((ulong64)h2 * r0) + ((ulong64)h3 * s4) + ((ulong64)h4 * s3); + d3 = ((ulong64)h0 * r3) + ((ulong64)h1 * r2) + ((ulong64)h2 * r1) + ((ulong64)h3 * r0) + ((ulong64)h4 * s4); + d4 = ((ulong64)h0 * r4) + ((ulong64)h1 * r3) + ((ulong64)h2 * r2) + ((ulong64)h3 * r1) + ((ulong64)h4 * r0); + + /* (partial) h %= p */ + c = (ulong32)(d0 >> 26); h0 = (ulong32)d0 & 0x3ffffff; + d1 += c; c = (ulong32)(d1 >> 26); h1 = (ulong32)d1 & 0x3ffffff; + d2 += c; c = (ulong32)(d2 >> 26); h2 = (ulong32)d2 & 0x3ffffff; + d3 += c; c = (ulong32)(d3 >> 26); h3 = (ulong32)d3 & 0x3ffffff; + d4 += c; c = (ulong32)(d4 >> 26); h4 = (ulong32)d4 & 0x3ffffff; + h0 += c * 5; c = (h0 >> 26); h0 = h0 & 0x3ffffff; + h1 += c; + + in += 16; + inlen -= 16; + } + + st->h[0] = h0; + st->h[1] = h1; + st->h[2] = h2; + st->h[3] = h3; + st->h[4] = h4; +} + +/** + Initialize an POLY1305 context. + @param st The POLY1305 state + @param key The secret key + @param keylen The length of the secret key (octets) + @return CRYPT_OK if successful +*/ +int poly1305_init(poly1305_state *st, const unsigned char *key, unsigned long keylen) +{ + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(keylen == 32); + + /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */ + LOAD32L(st->r[0], key + 0); st->r[0] = (st->r[0] ) & 0x3ffffff; + LOAD32L(st->r[1], key + 3); st->r[1] = (st->r[1] >> 2) & 0x3ffff03; + LOAD32L(st->r[2], key + 6); st->r[2] = (st->r[2] >> 4) & 0x3ffc0ff; + LOAD32L(st->r[3], key + 9); st->r[3] = (st->r[3] >> 6) & 0x3f03fff; + LOAD32L(st->r[4], key + 12); st->r[4] = (st->r[4] >> 8) & 0x00fffff; + + /* h = 0 */ + st->h[0] = 0; + st->h[1] = 0; + st->h[2] = 0; + st->h[3] = 0; + st->h[4] = 0; + + /* save pad for later */ + LOAD32L(st->pad[0], key + 16); + LOAD32L(st->pad[1], key + 20); + LOAD32L(st->pad[2], key + 24); + LOAD32L(st->pad[3], key + 28); + + st->leftover = 0; + st->final = 0; + return CRYPT_OK; +} + +/** + Process data through POLY1305 + @param st The POLY1305 state + @param in The data to send through HMAC + @param inlen The length of the data to HMAC (octets) + @return CRYPT_OK if successful +*/ +int poly1305_process(poly1305_state *st, const unsigned char *in, unsigned long inlen) +{ + unsigned long i; + + if (inlen == 0) return CRYPT_OK; /* nothing to do */ + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(in != NULL); + + /* handle leftover */ + if (st->leftover) { + unsigned long want = (16 - st->leftover); + if (want > inlen) want = inlen; + for (i = 0; i < want; i++) st->buffer[st->leftover + i] = in[i]; + inlen -= want; + in += want; + st->leftover += want; + if (st->leftover < 16) return CRYPT_OK; + _poly1305_block(st, st->buffer, 16); + st->leftover = 0; + } + + /* process full blocks */ + if (inlen >= 16) { + unsigned long want = (inlen & ~(16 - 1)); + _poly1305_block(st, in, want); + in += want; + inlen -= want; + } + + /* store leftover */ + if (inlen) { + for (i = 0; i < inlen; i++) st->buffer[st->leftover + i] = in[i]; + st->leftover += inlen; + } + return CRYPT_OK; +} + +/** + Terminate a POLY1305 session + @param st The POLY1305 state + @param out [out] The destination of the POLY1305 authentication tag + @param outlen [in/out] The max size and resulting size of the POLY1305 authentication tag + @return CRYPT_OK if successful +*/ +int poly1305_done(poly1305_state *st, unsigned char *mac, unsigned long *maclen) +{ + ulong32 h0,h1,h2,h3,h4,c; + ulong32 g0,g1,g2,g3,g4; + ulong64 f; + ulong32 mask; + + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(mac != NULL); + LTC_ARGCHK(maclen != NULL); + LTC_ARGCHK(*maclen >= 16); + + /* process the remaining block */ + if (st->leftover) { + unsigned long i = st->leftover; + st->buffer[i++] = 1; + for (; i < 16; i++) st->buffer[i] = 0; + st->final = 1; + _poly1305_block(st, st->buffer, 16); + } + + /* fully carry h */ + h0 = st->h[0]; + h1 = st->h[1]; + h2 = st->h[2]; + h3 = st->h[3]; + h4 = st->h[4]; + + c = h1 >> 26; h1 = h1 & 0x3ffffff; + h2 += c; c = h2 >> 26; h2 = h2 & 0x3ffffff; + h3 += c; c = h3 >> 26; h3 = h3 & 0x3ffffff; + h4 += c; c = h4 >> 26; h4 = h4 & 0x3ffffff; + h0 += c * 5; c = h0 >> 26; h0 = h0 & 0x3ffffff; + h1 += c; + + /* compute h + -p */ + g0 = h0 + 5; c = g0 >> 26; g0 &= 0x3ffffff; + g1 = h1 + c; c = g1 >> 26; g1 &= 0x3ffffff; + g2 = h2 + c; c = g2 >> 26; g2 &= 0x3ffffff; + g3 = h3 + c; c = g3 >> 26; g3 &= 0x3ffffff; + g4 = h4 + c - (1UL << 26); + + /* select h if h < p, or h + -p if h >= p */ + mask = (g4 >> 31) - 1; + g0 &= mask; + g1 &= mask; + g2 &= mask; + g3 &= mask; + g4 &= mask; + mask = ~mask; + h0 = (h0 & mask) | g0; + h1 = (h1 & mask) | g1; + h2 = (h2 & mask) | g2; + h3 = (h3 & mask) | g3; + h4 = (h4 & mask) | g4; + + /* h = h % (2^128) */ + h0 = ((h0 ) | (h1 << 26)) & 0xffffffff; + h1 = ((h1 >> 6) | (h2 << 20)) & 0xffffffff; + h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff; + h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff; + + /* mac = (h + pad) % (2^128) */ + f = (ulong64)h0 + st->pad[0] ; h0 = (ulong32)f; + f = (ulong64)h1 + st->pad[1] + (f >> 32); h1 = (ulong32)f; + f = (ulong64)h2 + st->pad[2] + (f >> 32); h2 = (ulong32)f; + f = (ulong64)h3 + st->pad[3] + (f >> 32); h3 = (ulong32)f; + + STORE32L(h0, mac + 0); + STORE32L(h1, mac + 4); + STORE32L(h2, mac + 8); + STORE32L(h3, mac + 12); + + /* zero out the state */ + st->h[0] = 0; + st->h[1] = 0; + st->h[2] = 0; + st->h[3] = 0; + st->h[4] = 0; + st->r[0] = 0; + st->r[1] = 0; + st->r[2] = 0; + st->r[3] = 0; + st->r[4] = 0; + st->pad[0] = 0; + st->pad[1] = 0; + st->pad[2] = 0; + st->pad[3] = 0; + + *maclen = 16; + return CRYPT_OK; +} + +#endif diff --git a/src/ltc/mac/poly1305/poly1305_file.c b/src/ltc/mac/poly1305/poly1305_file.c new file mode 100644 index 0000000..42afdc3 --- /dev/null +++ b/src/ltc/mac/poly1305/poly1305_file.c @@ -0,0 +1,84 @@ +/* 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. + */ + +/* The implementation is based on: + * Public Domain poly1305 from Andrew Moon + * https://github.com/floodyberry/poly1305-donna + */ + +#include "tomcrypt.h" + +#ifdef LTC_POLY1305 + +/** + POLY1305 a file + @param fname The name of the file you wish to POLY1305 + @param key The secret key + @param keylen The length of the secret key + @param mac [out] The POLY1305 authentication tag + @param maclen [in/out] The max size and resulting size of the authentication tag + @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled +*/ +int poly1305_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen) +{ +#ifdef LTC_NO_FILE + return CRYPT_NOP; +#else + poly1305_state st; + FILE *in; + unsigned char *buf; + size_t x; + int err; + + LTC_ARGCHK(fname != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(mac != NULL); + LTC_ARGCHK(maclen != NULL); + + if ((buf = XMALLOC(LTC_FILE_READ_BUFSIZE)) == NULL) { + return CRYPT_MEM; + } + + if ((err = poly1305_init(&st, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + + in = fopen(fname, "rb"); + if (in == NULL) { + err = CRYPT_FILE_NOTFOUND; + goto LBL_ERR; + } + + do { + x = fread(buf, 1, LTC_FILE_READ_BUFSIZE, in); + if ((err = poly1305_process(&st, buf, (unsigned long)x)) != CRYPT_OK) { + fclose(in); + goto LBL_CLEANBUF; + } + } while (x == LTC_FILE_READ_BUFSIZE); + + if (fclose(in) != 0) { + err = CRYPT_ERROR; + goto LBL_CLEANBUF; + } + + err = poly1305_done(&st, mac, maclen); + +LBL_CLEANBUF: + zeromem(buf, LTC_FILE_READ_BUFSIZE); +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(&st, sizeof(poly1305_state)); +#endif + XFREE(buf); + return err; +#endif +} + +#endif diff --git a/src/ltc/mac/poly1305/poly1305_memory.c b/src/ltc/mac/poly1305/poly1305_memory.c new file mode 100644 index 0000000..b948efb --- /dev/null +++ b/src/ltc/mac/poly1305/poly1305_memory.c @@ -0,0 +1,49 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ + +/* The implementation is based on: + * Public Domain poly1305 from Andrew Moon + * https://github.com/floodyberry/poly1305-donna + */ + +#include "tomcrypt.h" + +#ifdef LTC_POLY1305 + +/** + POLY1305 a block of memory to produce the authentication tag + @param key The secret key + @param keylen The length of the secret key (octets) + @param in The data to POLY1305 + @param inlen The length of the data to POLY1305 (octets) + @param mac [out] Destination of the authentication tag + @param maclen [in/out] Max size and resulting size of authentication tag + @return CRYPT_OK if successful +*/ +int poly1305_memory(const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *mac, unsigned long *maclen) +{ + poly1305_state st; + int err; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(mac != NULL); + LTC_ARGCHK(maclen != NULL); + + if ((err = poly1305_init(&st, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = poly1305_process(&st, in, inlen)) != CRYPT_OK) { goto LBL_ERR; } + err = poly1305_done(&st, mac, maclen); +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(&st, sizeof(poly1305_state)); +#endif + return err; +} + +#endif diff --git a/src/ltc/mac/poly1305/poly1305_memory_multi.c b/src/ltc/mac/poly1305/poly1305_memory_multi.c new file mode 100644 index 0000000..0ac122e --- /dev/null +++ b/src/ltc/mac/poly1305/poly1305_memory_multi.c @@ -0,0 +1,63 @@ +/* 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. + */ + +/* The implementation is based on: + * Public Domain poly1305 from Andrew Moon + * https://github.com/floodyberry/poly1305-donna + */ + +#include "tomcrypt.h" +#include + +#ifdef LTC_POLY1305 + +/** + POLY1305 multiple blocks of memory to produce the authentication tag + @param key The secret key + @param keylen The length of the secret key (octets) + @param out [out] Destination of the authentication tag + @param outlen [in/out] Max size and resulting size of authentication tag + @param in The data to POLY1305 + @param inlen The length of the data to POLY1305 (octets) + @param ... tuples of (data,len) pairs to POLY1305, terminated with a (NULL,x) (x=don't care) + @return CRYPT_OK if successful +*/ +int poly1305_memory_multi(const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen, const unsigned char *in, unsigned long inlen, ...) +{ + poly1305_state st; + int err; + va_list args; + const unsigned char *curptr; + unsigned long curlen; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(mac != NULL); + LTC_ARGCHK(maclen != NULL); + + va_start(args, inlen); + curptr = in; + curlen = inlen; + if ((err = poly1305_init(&st, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } + for (;;) { + if ((err = poly1305_process(&st, curptr, curlen)) != CRYPT_OK) { goto LBL_ERR; } + curptr = va_arg(args, const unsigned char*); + if (curptr == NULL) break; + curlen = va_arg(args, unsigned long); + } + err = poly1305_done(&st, mac, maclen); +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(&st, sizeof(poly1305_state)); +#endif + va_end(args); + return err; +} + +#endif diff --git a/src/ltc/mac/xcbc/xcbc_done.c b/src/ltc/mac/xcbc/xcbc_done.c new file mode 100644 index 0000000..1573263 --- /dev/null +++ b/src/ltc/mac/xcbc/xcbc_done.c @@ -0,0 +1,77 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file xcbc_done.c + XCBC Support, terminate the state +*/ + +#ifdef LTC_XCBC + +/** Terminate the XCBC-MAC state + @param xcbc XCBC state to terminate + @param out [out] Destination for the MAC tag + @param outlen [in/out] Destination size and final tag size + Return CRYPT_OK on success +*/ +int xcbc_done(xcbc_state *xcbc, unsigned char *out, unsigned long *outlen) +{ + int err, x; + LTC_ARGCHK(xcbc != NULL); + LTC_ARGCHK(out != NULL); + + /* check structure */ + if ((err = cipher_is_valid(xcbc->cipher)) != CRYPT_OK) { + return err; + } + + if ((xcbc->blocksize > cipher_descriptor[xcbc->cipher].block_length) || (xcbc->blocksize < 0) || + (xcbc->buflen > xcbc->blocksize) || (xcbc->buflen < 0)) { + return CRYPT_INVALID_ARG; + } + + /* which key do we use? */ + if (xcbc->buflen == xcbc->blocksize) { + /* k2 */ + for (x = 0; x < xcbc->blocksize; x++) { + xcbc->IV[x] ^= xcbc->K[1][x]; + } + } else { + xcbc->IV[xcbc->buflen] ^= 0x80; + /* k3 */ + for (x = 0; x < xcbc->blocksize; x++) { + xcbc->IV[x] ^= xcbc->K[2][x]; + } + } + + /* encrypt */ + cipher_descriptor[xcbc->cipher].ecb_encrypt(xcbc->IV, xcbc->IV, &xcbc->key); + cipher_descriptor[xcbc->cipher].done(&xcbc->key); + + /* extract tag */ + for (x = 0; x < xcbc->blocksize && (unsigned long)x < *outlen; x++) { + out[x] = xcbc->IV[x]; + } + *outlen = x; + +#ifdef LTC_CLEAN_STACK + zeromem(xcbc, sizeof(*xcbc)); +#endif + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ + diff --git a/src/ltc/mac/xcbc/xcbc_file.c b/src/ltc/mac/xcbc/xcbc_file.c new file mode 100644 index 0000000..c8119f9 --- /dev/null +++ b/src/ltc/mac/xcbc/xcbc_file.c @@ -0,0 +1,93 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file xcbc_file.c + XCBC support, process a file, Tom St Denis +*/ + +#ifdef LTC_XCBC + +/** + XCBC a file + @param cipher The index of the cipher desired + @param key The secret key + @param keylen The length of the secret key (octets) + @param filename The name of the file you wish to XCBC + @param out [out] Where the authentication tag is to be stored + @param outlen [in/out] The max size and resulting size of the authentication tag + @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled +*/ +int xcbc_file(int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen) +{ +#ifdef LTC_NO_FILE + return CRYPT_NOP; +#else + size_t x; + int err; + xcbc_state xcbc; + FILE *in; + unsigned char *buf; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(filename != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + if ((buf = XMALLOC(LTC_FILE_READ_BUFSIZE)) == NULL) { + return CRYPT_MEM; + } + + if ((err = xcbc_init(&xcbc, cipher, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + + in = fopen(filename, "rb"); + if (in == NULL) { + err = CRYPT_FILE_NOTFOUND; + goto LBL_ERR; + } + + do { + x = fread(buf, 1, LTC_FILE_READ_BUFSIZE, in); + if ((err = xcbc_process(&xcbc, buf, (unsigned long)x)) != CRYPT_OK) { + fclose(in); + goto LBL_CLEANBUF; + } + } while (x == LTC_FILE_READ_BUFSIZE); + + if (fclose(in) != 0) { + err = CRYPT_ERROR; + goto LBL_CLEANBUF; + } + + err = xcbc_done(&xcbc, out, outlen); + +LBL_CLEANBUF: + zeromem(buf, LTC_FILE_READ_BUFSIZE); +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(&xcbc, sizeof(xcbc_state)); +#endif + XFREE(buf); + return err; +#endif +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/mac/xcbc/xcbc_init.c b/src/ltc/mac/xcbc/xcbc_init.c new file mode 100644 index 0000000..b4ad2e9 --- /dev/null +++ b/src/ltc/mac/xcbc/xcbc_init.c @@ -0,0 +1,108 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file xcbc_init.c + XCBC Support, start an XCBC state +*/ + +#ifdef LTC_XCBC + +/** Initialize XCBC-MAC state + @param xcbc [out] XCBC state to initialize + @param cipher Index of cipher to use + @param key [in] Secret key + @param keylen Length of secret key in octets + Return CRYPT_OK on success +*/ +int xcbc_init(xcbc_state *xcbc, int cipher, const unsigned char *key, unsigned long keylen) +{ + int x, y, err; + symmetric_key *skey; + unsigned long k1; + + LTC_ARGCHK(xcbc != NULL); + LTC_ARGCHK(key != NULL); + + /* schedule the key */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + +#ifdef LTC_FAST + if (cipher_descriptor[cipher].block_length % sizeof(LTC_FAST_TYPE)) { + return CRYPT_INVALID_ARG; + } +#endif + + skey = NULL; + + /* are we in pure XCBC mode with three keys? */ + if (keylen & LTC_XCBC_PURE) { + keylen &= ~LTC_XCBC_PURE; + + if (keylen < 2UL*cipher_descriptor[cipher].block_length) { + return CRYPT_INVALID_ARG; + } + + k1 = keylen - 2*cipher_descriptor[cipher].block_length; + XMEMCPY(xcbc->K[0], key, k1); + XMEMCPY(xcbc->K[1], key+k1, cipher_descriptor[cipher].block_length); + XMEMCPY(xcbc->K[2], key+k1 + cipher_descriptor[cipher].block_length, cipher_descriptor[cipher].block_length); + } else { + /* use the key expansion */ + k1 = cipher_descriptor[cipher].block_length; + + /* schedule the user key */ + skey = XCALLOC(1, sizeof(*skey)); + if (skey == NULL) { + return CRYPT_MEM; + } + + if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, skey)) != CRYPT_OK) { + goto done; + } + + /* make the three keys */ + for (y = 0; y < 3; y++) { + for (x = 0; x < cipher_descriptor[cipher].block_length; x++) { + xcbc->K[y][x] = y + 1; + } + cipher_descriptor[cipher].ecb_encrypt(xcbc->K[y], xcbc->K[y], skey); + } + } + + /* setup K1 */ + err = cipher_descriptor[cipher].setup(xcbc->K[0], k1, 0, &xcbc->key); + + /* setup struct */ + zeromem(xcbc->IV, cipher_descriptor[cipher].block_length); + xcbc->blocksize = cipher_descriptor[cipher].block_length; + xcbc->cipher = cipher; + xcbc->buflen = 0; +done: + cipher_descriptor[cipher].done(skey); + if (skey != NULL) { +#ifdef LTC_CLEAN_STACK + zeromem(skey, sizeof(*skey)); +#endif + XFREE(skey); + } + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ + diff --git a/src/ltc/mac/xcbc/xcbc_memory.c b/src/ltc/mac/xcbc/xcbc_memory.c new file mode 100644 index 0000000..aac9298 --- /dev/null +++ b/src/ltc/mac/xcbc/xcbc_memory.c @@ -0,0 +1,71 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file xcbc_process.c + XCBC Support, XCBC-MAC a block of memory +*/ + +#ifdef LTC_XCBC + +/** XCBC-MAC a block of memory + @param cipher Index of cipher to use + @param key [in] Secret key + @param keylen Length of key in octets + @param in [in] Message to MAC + @param inlen Length of input in octets + @param out [out] Destination for the MAC tag + @param outlen [in/out] Output size and final tag size + Return CRYPT_OK on success. +*/ +int xcbc_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + xcbc_state *xcbc; + int err; + + /* is the cipher valid? */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + /* Use accelerator if found */ + if (cipher_descriptor[cipher].xcbc_memory != NULL) { + return cipher_descriptor[cipher].xcbc_memory(key, keylen, in, inlen, out, outlen); + } + + xcbc = XCALLOC(1, sizeof(*xcbc)); + if (xcbc == NULL) { + return CRYPT_MEM; + } + + if ((err = xcbc_init(xcbc, cipher, key, keylen)) != CRYPT_OK) { + goto done; + } + + if ((err = xcbc_process(xcbc, in, inlen)) != CRYPT_OK) { + goto done; + } + + err = xcbc_done(xcbc, out, outlen); +done: + XFREE(xcbc); + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/mac/xcbc/xcbc_memory_multi.c b/src/ltc/mac/xcbc/xcbc_memory_multi.c new file mode 100644 index 0000000..994bdce --- /dev/null +++ b/src/ltc/mac/xcbc/xcbc_memory_multi.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://libtom.org + */ +#include "tomcrypt.h" +#include + +/** + @file xcbc_memory_multi.c + XCBC support, process multiple blocks of memory, Tom St Denis +*/ + +#ifdef LTC_XCBC + +/** + XCBC multiple blocks of memory + @param cipher The index of the desired cipher + @param key The secret key + @param keylen The length of the secret key (octets) + @param out [out] The destination of the authentication tag + @param outlen [in/out] The max size and resulting size of the authentication tag (octets) + @param in The data to send through XCBC + @param inlen The length of the data to send through XCBC (octets) + @param ... tuples of (data,len) pairs to XCBC, terminated with a (NULL,x) (x=don't care) + @return CRYPT_OK if successful +*/ +int xcbc_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 err; + xcbc_state *xcbc; + va_list args; + const unsigned char *curptr; + unsigned long curlen; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* allocate ram for xcbc state */ + xcbc = XMALLOC(sizeof(xcbc_state)); + if (xcbc == NULL) { + return CRYPT_MEM; + } + + /* xcbc process the message */ + if ((err = xcbc_init(xcbc, cipher, key, keylen)) != CRYPT_OK) { + goto LBL_ERR; + } + va_start(args, inlen); + curptr = in; + curlen = inlen; + for (;;) { + /* process buf */ + if ((err = xcbc_process(xcbc, curptr, curlen)) != CRYPT_OK) { + goto LBL_ERR; + } + /* step to next */ + curptr = va_arg(args, const unsigned char*); + if (curptr == NULL) { + break; + } + curlen = va_arg(args, unsigned long); + } + if ((err = xcbc_done(xcbc, out, outlen)) != CRYPT_OK) { + goto LBL_ERR; + } +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(xcbc, sizeof(xcbc_state)); +#endif + XFREE(xcbc); + va_end(args); + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/mac/xcbc/xcbc_process.c b/src/ltc/mac/xcbc/xcbc_process.c new file mode 100644 index 0000000..dca321a --- /dev/null +++ b/src/ltc/mac/xcbc/xcbc_process.c @@ -0,0 +1,75 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file xcbc_process.c + XCBC Support, process blocks with XCBC +*/ + +#ifdef LTC_XCBC + +/** Process data through XCBC-MAC + @param xcbc The XCBC-MAC state + @param in Input data to process + @param inlen Length of input in octets + Return CRYPT_OK on success +*/ +int xcbc_process(xcbc_state *xcbc, const unsigned char *in, unsigned long inlen) +{ + int err; +#ifdef LTC_FAST + int x; +#endif + + LTC_ARGCHK(xcbc != NULL); + LTC_ARGCHK(in != NULL); + + /* check structure */ + if ((err = cipher_is_valid(xcbc->cipher)) != CRYPT_OK) { + return err; + } + + if ((xcbc->blocksize > cipher_descriptor[xcbc->cipher].block_length) || (xcbc->blocksize < 0) || + (xcbc->buflen > xcbc->blocksize) || (xcbc->buflen < 0)) { + return CRYPT_INVALID_ARG; + } + +#ifdef LTC_FAST + if (xcbc->buflen == 0) { + while (inlen > (unsigned long)xcbc->blocksize) { + for (x = 0; x < xcbc->blocksize; x += sizeof(LTC_FAST_TYPE)) { + *(LTC_FAST_TYPE_PTR_CAST(&(xcbc->IV[x]))) ^= *(LTC_FAST_TYPE_PTR_CAST(&(in[x]))); + } + cipher_descriptor[xcbc->cipher].ecb_encrypt(xcbc->IV, xcbc->IV, &xcbc->key); + in += xcbc->blocksize; + inlen -= xcbc->blocksize; + } + } +#endif + + while (inlen) { + if (xcbc->buflen == xcbc->blocksize) { + cipher_descriptor[xcbc->cipher].ecb_encrypt(xcbc->IV, xcbc->IV, &xcbc->key); + xcbc->buflen = 0; + } + xcbc->IV[xcbc->buflen++] ^= *in++; + --inlen; + } + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ + diff --git a/src/ltc/math/fp/ltc_ecc_fp_mulmod.c b/src/ltc/math/fp/ltc_ecc_fp_mulmod.c new file mode 100644 index 0000000..df9aef6 --- /dev/null +++ b/src/ltc/math/fp/ltc_ecc_fp_mulmod.c @@ -0,0 +1,1590 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ltc_ecc_fp_mulmod.c + ECC Crypto, Tom St Denis +*/ + +#if defined(LTC_MECC) && defined(LTC_MECC_FP) +#include + +/* number of entries in the cache */ +#ifndef FP_ENTRIES +#define FP_ENTRIES 16 +#endif + +/* number of bits in LUT */ +#ifndef FP_LUT +#define FP_LUT 8U +#endif + +#if (FP_LUT > 12) || (FP_LUT < 2) + #error FP_LUT must be between 2 and 12 inclusively +#endif + +/** Our FP cache */ +static struct { + ecc_point *g, /* cached COPY of base point */ + *LUT[1U< 6 + { 1, 0, 0 }, { 2, 1, 64 }, { 2, 2, 64 }, { 3, 3, 64 }, { 2, 4, 64 }, { 3, 5, 64 }, { 3, 6, 64 }, { 4, 7, 64 }, + { 2, 8, 64 }, { 3, 9, 64 }, { 3, 10, 64 }, { 4, 11, 64 }, { 3, 12, 64 }, { 4, 13, 64 }, { 4, 14, 64 }, { 5, 15, 64 }, + { 2, 16, 64 }, { 3, 17, 64 }, { 3, 18, 64 }, { 4, 19, 64 }, { 3, 20, 64 }, { 4, 21, 64 }, { 4, 22, 64 }, { 5, 23, 64 }, + { 3, 24, 64 }, { 4, 25, 64 }, { 4, 26, 64 }, { 5, 27, 64 }, { 4, 28, 64 }, { 5, 29, 64 }, { 5, 30, 64 }, { 6, 31, 64 }, + { 2, 32, 64 }, { 3, 33, 64 }, { 3, 34, 64 }, { 4, 35, 64 }, { 3, 36, 64 }, { 4, 37, 64 }, { 4, 38, 64 }, { 5, 39, 64 }, + { 3, 40, 64 }, { 4, 41, 64 }, { 4, 42, 64 }, { 5, 43, 64 }, { 4, 44, 64 }, { 5, 45, 64 }, { 5, 46, 64 }, { 6, 47, 64 }, + { 3, 48, 64 }, { 4, 49, 64 }, { 4, 50, 64 }, { 5, 51, 64 }, { 4, 52, 64 }, { 5, 53, 64 }, { 5, 54, 64 }, { 6, 55, 64 }, + { 4, 56, 64 }, { 5, 57, 64 }, { 5, 58, 64 }, { 6, 59, 64 }, { 5, 60, 64 }, { 6, 61, 64 }, { 6, 62, 64 }, { 7, 63, 64 }, +#if FP_LUT > 7 + { 1, 0, 0 }, { 2, 1, 128 }, { 2, 2, 128 }, { 3, 3, 128 }, { 2, 4, 128 }, { 3, 5, 128 }, { 3, 6, 128 }, { 4, 7, 128 }, + { 2, 8, 128 }, { 3, 9, 128 }, { 3, 10, 128 }, { 4, 11, 128 }, { 3, 12, 128 }, { 4, 13, 128 }, { 4, 14, 128 }, { 5, 15, 128 }, + { 2, 16, 128 }, { 3, 17, 128 }, { 3, 18, 128 }, { 4, 19, 128 }, { 3, 20, 128 }, { 4, 21, 128 }, { 4, 22, 128 }, { 5, 23, 128 }, + { 3, 24, 128 }, { 4, 25, 128 }, { 4, 26, 128 }, { 5, 27, 128 }, { 4, 28, 128 }, { 5, 29, 128 }, { 5, 30, 128 }, { 6, 31, 128 }, + { 2, 32, 128 }, { 3, 33, 128 }, { 3, 34, 128 }, { 4, 35, 128 }, { 3, 36, 128 }, { 4, 37, 128 }, { 4, 38, 128 }, { 5, 39, 128 }, + { 3, 40, 128 }, { 4, 41, 128 }, { 4, 42, 128 }, { 5, 43, 128 }, { 4, 44, 128 }, { 5, 45, 128 }, { 5, 46, 128 }, { 6, 47, 128 }, + { 3, 48, 128 }, { 4, 49, 128 }, { 4, 50, 128 }, { 5, 51, 128 }, { 4, 52, 128 }, { 5, 53, 128 }, { 5, 54, 128 }, { 6, 55, 128 }, + { 4, 56, 128 }, { 5, 57, 128 }, { 5, 58, 128 }, { 6, 59, 128 }, { 5, 60, 128 }, { 6, 61, 128 }, { 6, 62, 128 }, { 7, 63, 128 }, + { 2, 64, 128 }, { 3, 65, 128 }, { 3, 66, 128 }, { 4, 67, 128 }, { 3, 68, 128 }, { 4, 69, 128 }, { 4, 70, 128 }, { 5, 71, 128 }, + { 3, 72, 128 }, { 4, 73, 128 }, { 4, 74, 128 }, { 5, 75, 128 }, { 4, 76, 128 }, { 5, 77, 128 }, { 5, 78, 128 }, { 6, 79, 128 }, + { 3, 80, 128 }, { 4, 81, 128 }, { 4, 82, 128 }, { 5, 83, 128 }, { 4, 84, 128 }, { 5, 85, 128 }, { 5, 86, 128 }, { 6, 87, 128 }, + { 4, 88, 128 }, { 5, 89, 128 }, { 5, 90, 128 }, { 6, 91, 128 }, { 5, 92, 128 }, { 6, 93, 128 }, { 6, 94, 128 }, { 7, 95, 128 }, + { 3, 96, 128 }, { 4, 97, 128 }, { 4, 98, 128 }, { 5, 99, 128 }, { 4, 100, 128 }, { 5, 101, 128 }, { 5, 102, 128 }, { 6, 103, 128 }, + { 4, 104, 128 }, { 5, 105, 128 }, { 5, 106, 128 }, { 6, 107, 128 }, { 5, 108, 128 }, { 6, 109, 128 }, { 6, 110, 128 }, { 7, 111, 128 }, + { 4, 112, 128 }, { 5, 113, 128 }, { 5, 114, 128 }, { 6, 115, 128 }, { 5, 116, 128 }, { 6, 117, 128 }, { 6, 118, 128 }, { 7, 119, 128 }, + { 5, 120, 128 }, { 6, 121, 128 }, { 6, 122, 128 }, { 7, 123, 128 }, { 6, 124, 128 }, { 7, 125, 128 }, { 7, 126, 128 }, { 8, 127, 128 }, +#if FP_LUT > 8 + { 1, 0, 0 }, { 2, 1, 256 }, { 2, 2, 256 }, { 3, 3, 256 }, { 2, 4, 256 }, { 3, 5, 256 }, { 3, 6, 256 }, { 4, 7, 256 }, + { 2, 8, 256 }, { 3, 9, 256 }, { 3, 10, 256 }, { 4, 11, 256 }, { 3, 12, 256 }, { 4, 13, 256 }, { 4, 14, 256 }, { 5, 15, 256 }, + { 2, 16, 256 }, { 3, 17, 256 }, { 3, 18, 256 }, { 4, 19, 256 }, { 3, 20, 256 }, { 4, 21, 256 }, { 4, 22, 256 }, { 5, 23, 256 }, + { 3, 24, 256 }, { 4, 25, 256 }, { 4, 26, 256 }, { 5, 27, 256 }, { 4, 28, 256 }, { 5, 29, 256 }, { 5, 30, 256 }, { 6, 31, 256 }, + { 2, 32, 256 }, { 3, 33, 256 }, { 3, 34, 256 }, { 4, 35, 256 }, { 3, 36, 256 }, { 4, 37, 256 }, { 4, 38, 256 }, { 5, 39, 256 }, + { 3, 40, 256 }, { 4, 41, 256 }, { 4, 42, 256 }, { 5, 43, 256 }, { 4, 44, 256 }, { 5, 45, 256 }, { 5, 46, 256 }, { 6, 47, 256 }, + { 3, 48, 256 }, { 4, 49, 256 }, { 4, 50, 256 }, { 5, 51, 256 }, { 4, 52, 256 }, { 5, 53, 256 }, { 5, 54, 256 }, { 6, 55, 256 }, + { 4, 56, 256 }, { 5, 57, 256 }, { 5, 58, 256 }, { 6, 59, 256 }, { 5, 60, 256 }, { 6, 61, 256 }, { 6, 62, 256 }, { 7, 63, 256 }, + { 2, 64, 256 }, { 3, 65, 256 }, { 3, 66, 256 }, { 4, 67, 256 }, { 3, 68, 256 }, { 4, 69, 256 }, { 4, 70, 256 }, { 5, 71, 256 }, + { 3, 72, 256 }, { 4, 73, 256 }, { 4, 74, 256 }, { 5, 75, 256 }, { 4, 76, 256 }, { 5, 77, 256 }, { 5, 78, 256 }, { 6, 79, 256 }, + { 3, 80, 256 }, { 4, 81, 256 }, { 4, 82, 256 }, { 5, 83, 256 }, { 4, 84, 256 }, { 5, 85, 256 }, { 5, 86, 256 }, { 6, 87, 256 }, + { 4, 88, 256 }, { 5, 89, 256 }, { 5, 90, 256 }, { 6, 91, 256 }, { 5, 92, 256 }, { 6, 93, 256 }, { 6, 94, 256 }, { 7, 95, 256 }, + { 3, 96, 256 }, { 4, 97, 256 }, { 4, 98, 256 }, { 5, 99, 256 }, { 4, 100, 256 }, { 5, 101, 256 }, { 5, 102, 256 }, { 6, 103, 256 }, + { 4, 104, 256 }, { 5, 105, 256 }, { 5, 106, 256 }, { 6, 107, 256 }, { 5, 108, 256 }, { 6, 109, 256 }, { 6, 110, 256 }, { 7, 111, 256 }, + { 4, 112, 256 }, { 5, 113, 256 }, { 5, 114, 256 }, { 6, 115, 256 }, { 5, 116, 256 }, { 6, 117, 256 }, { 6, 118, 256 }, { 7, 119, 256 }, + { 5, 120, 256 }, { 6, 121, 256 }, { 6, 122, 256 }, { 7, 123, 256 }, { 6, 124, 256 }, { 7, 125, 256 }, { 7, 126, 256 }, { 8, 127, 256 }, + { 2, 128, 256 }, { 3, 129, 256 }, { 3, 130, 256 }, { 4, 131, 256 }, { 3, 132, 256 }, { 4, 133, 256 }, { 4, 134, 256 }, { 5, 135, 256 }, + { 3, 136, 256 }, { 4, 137, 256 }, { 4, 138, 256 }, { 5, 139, 256 }, { 4, 140, 256 }, { 5, 141, 256 }, { 5, 142, 256 }, { 6, 143, 256 }, + { 3, 144, 256 }, { 4, 145, 256 }, { 4, 146, 256 }, { 5, 147, 256 }, { 4, 148, 256 }, { 5, 149, 256 }, { 5, 150, 256 }, { 6, 151, 256 }, + { 4, 152, 256 }, { 5, 153, 256 }, { 5, 154, 256 }, { 6, 155, 256 }, { 5, 156, 256 }, { 6, 157, 256 }, { 6, 158, 256 }, { 7, 159, 256 }, + { 3, 160, 256 }, { 4, 161, 256 }, { 4, 162, 256 }, { 5, 163, 256 }, { 4, 164, 256 }, { 5, 165, 256 }, { 5, 166, 256 }, { 6, 167, 256 }, + { 4, 168, 256 }, { 5, 169, 256 }, { 5, 170, 256 }, { 6, 171, 256 }, { 5, 172, 256 }, { 6, 173, 256 }, { 6, 174, 256 }, { 7, 175, 256 }, + { 4, 176, 256 }, { 5, 177, 256 }, { 5, 178, 256 }, { 6, 179, 256 }, { 5, 180, 256 }, { 6, 181, 256 }, { 6, 182, 256 }, { 7, 183, 256 }, + { 5, 184, 256 }, { 6, 185, 256 }, { 6, 186, 256 }, { 7, 187, 256 }, { 6, 188, 256 }, { 7, 189, 256 }, { 7, 190, 256 }, { 8, 191, 256 }, + { 3, 192, 256 }, { 4, 193, 256 }, { 4, 194, 256 }, { 5, 195, 256 }, { 4, 196, 256 }, { 5, 197, 256 }, { 5, 198, 256 }, { 6, 199, 256 }, + { 4, 200, 256 }, { 5, 201, 256 }, { 5, 202, 256 }, { 6, 203, 256 }, { 5, 204, 256 }, { 6, 205, 256 }, { 6, 206, 256 }, { 7, 207, 256 }, + { 4, 208, 256 }, { 5, 209, 256 }, { 5, 210, 256 }, { 6, 211, 256 }, { 5, 212, 256 }, { 6, 213, 256 }, { 6, 214, 256 }, { 7, 215, 256 }, + { 5, 216, 256 }, { 6, 217, 256 }, { 6, 218, 256 }, { 7, 219, 256 }, { 6, 220, 256 }, { 7, 221, 256 }, { 7, 222, 256 }, { 8, 223, 256 }, + { 4, 224, 256 }, { 5, 225, 256 }, { 5, 226, 256 }, { 6, 227, 256 }, { 5, 228, 256 }, { 6, 229, 256 }, { 6, 230, 256 }, { 7, 231, 256 }, + { 5, 232, 256 }, { 6, 233, 256 }, { 6, 234, 256 }, { 7, 235, 256 }, { 6, 236, 256 }, { 7, 237, 256 }, { 7, 238, 256 }, { 8, 239, 256 }, + { 5, 240, 256 }, { 6, 241, 256 }, { 6, 242, 256 }, { 7, 243, 256 }, { 6, 244, 256 }, { 7, 245, 256 }, { 7, 246, 256 }, { 8, 247, 256 }, + { 6, 248, 256 }, { 7, 249, 256 }, { 7, 250, 256 }, { 8, 251, 256 }, { 7, 252, 256 }, { 8, 253, 256 }, { 8, 254, 256 }, { 9, 255, 256 }, +#if FP_LUT > 9 + { 1, 0, 0 }, { 2, 1, 512 }, { 2, 2, 512 }, { 3, 3, 512 }, { 2, 4, 512 }, { 3, 5, 512 }, { 3, 6, 512 }, { 4, 7, 512 }, + { 2, 8, 512 }, { 3, 9, 512 }, { 3, 10, 512 }, { 4, 11, 512 }, { 3, 12, 512 }, { 4, 13, 512 }, { 4, 14, 512 }, { 5, 15, 512 }, + { 2, 16, 512 }, { 3, 17, 512 }, { 3, 18, 512 }, { 4, 19, 512 }, { 3, 20, 512 }, { 4, 21, 512 }, { 4, 22, 512 }, { 5, 23, 512 }, + { 3, 24, 512 }, { 4, 25, 512 }, { 4, 26, 512 }, { 5, 27, 512 }, { 4, 28, 512 }, { 5, 29, 512 }, { 5, 30, 512 }, { 6, 31, 512 }, + { 2, 32, 512 }, { 3, 33, 512 }, { 3, 34, 512 }, { 4, 35, 512 }, { 3, 36, 512 }, { 4, 37, 512 }, { 4, 38, 512 }, { 5, 39, 512 }, + { 3, 40, 512 }, { 4, 41, 512 }, { 4, 42, 512 }, { 5, 43, 512 }, { 4, 44, 512 }, { 5, 45, 512 }, { 5, 46, 512 }, { 6, 47, 512 }, + { 3, 48, 512 }, { 4, 49, 512 }, { 4, 50, 512 }, { 5, 51, 512 }, { 4, 52, 512 }, { 5, 53, 512 }, { 5, 54, 512 }, { 6, 55, 512 }, + { 4, 56, 512 }, { 5, 57, 512 }, { 5, 58, 512 }, { 6, 59, 512 }, { 5, 60, 512 }, { 6, 61, 512 }, { 6, 62, 512 }, { 7, 63, 512 }, + { 2, 64, 512 }, { 3, 65, 512 }, { 3, 66, 512 }, { 4, 67, 512 }, { 3, 68, 512 }, { 4, 69, 512 }, { 4, 70, 512 }, { 5, 71, 512 }, + { 3, 72, 512 }, { 4, 73, 512 }, { 4, 74, 512 }, { 5, 75, 512 }, { 4, 76, 512 }, { 5, 77, 512 }, { 5, 78, 512 }, { 6, 79, 512 }, + { 3, 80, 512 }, { 4, 81, 512 }, { 4, 82, 512 }, { 5, 83, 512 }, { 4, 84, 512 }, { 5, 85, 512 }, { 5, 86, 512 }, { 6, 87, 512 }, + { 4, 88, 512 }, { 5, 89, 512 }, { 5, 90, 512 }, { 6, 91, 512 }, { 5, 92, 512 }, { 6, 93, 512 }, { 6, 94, 512 }, { 7, 95, 512 }, + { 3, 96, 512 }, { 4, 97, 512 }, { 4, 98, 512 }, { 5, 99, 512 }, { 4, 100, 512 }, { 5, 101, 512 }, { 5, 102, 512 }, { 6, 103, 512 }, + { 4, 104, 512 }, { 5, 105, 512 }, { 5, 106, 512 }, { 6, 107, 512 }, { 5, 108, 512 }, { 6, 109, 512 }, { 6, 110, 512 }, { 7, 111, 512 }, + { 4, 112, 512 }, { 5, 113, 512 }, { 5, 114, 512 }, { 6, 115, 512 }, { 5, 116, 512 }, { 6, 117, 512 }, { 6, 118, 512 }, { 7, 119, 512 }, + { 5, 120, 512 }, { 6, 121, 512 }, { 6, 122, 512 }, { 7, 123, 512 }, { 6, 124, 512 }, { 7, 125, 512 }, { 7, 126, 512 }, { 8, 127, 512 }, + { 2, 128, 512 }, { 3, 129, 512 }, { 3, 130, 512 }, { 4, 131, 512 }, { 3, 132, 512 }, { 4, 133, 512 }, { 4, 134, 512 }, { 5, 135, 512 }, + { 3, 136, 512 }, { 4, 137, 512 }, { 4, 138, 512 }, { 5, 139, 512 }, { 4, 140, 512 }, { 5, 141, 512 }, { 5, 142, 512 }, { 6, 143, 512 }, + { 3, 144, 512 }, { 4, 145, 512 }, { 4, 146, 512 }, { 5, 147, 512 }, { 4, 148, 512 }, { 5, 149, 512 }, { 5, 150, 512 }, { 6, 151, 512 }, + { 4, 152, 512 }, { 5, 153, 512 }, { 5, 154, 512 }, { 6, 155, 512 }, { 5, 156, 512 }, { 6, 157, 512 }, { 6, 158, 512 }, { 7, 159, 512 }, + { 3, 160, 512 }, { 4, 161, 512 }, { 4, 162, 512 }, { 5, 163, 512 }, { 4, 164, 512 }, { 5, 165, 512 }, { 5, 166, 512 }, { 6, 167, 512 }, + { 4, 168, 512 }, { 5, 169, 512 }, { 5, 170, 512 }, { 6, 171, 512 }, { 5, 172, 512 }, { 6, 173, 512 }, { 6, 174, 512 }, { 7, 175, 512 }, + { 4, 176, 512 }, { 5, 177, 512 }, { 5, 178, 512 }, { 6, 179, 512 }, { 5, 180, 512 }, { 6, 181, 512 }, { 6, 182, 512 }, { 7, 183, 512 }, + { 5, 184, 512 }, { 6, 185, 512 }, { 6, 186, 512 }, { 7, 187, 512 }, { 6, 188, 512 }, { 7, 189, 512 }, { 7, 190, 512 }, { 8, 191, 512 }, + { 3, 192, 512 }, { 4, 193, 512 }, { 4, 194, 512 }, { 5, 195, 512 }, { 4, 196, 512 }, { 5, 197, 512 }, { 5, 198, 512 }, { 6, 199, 512 }, + { 4, 200, 512 }, { 5, 201, 512 }, { 5, 202, 512 }, { 6, 203, 512 }, { 5, 204, 512 }, { 6, 205, 512 }, { 6, 206, 512 }, { 7, 207, 512 }, + { 4, 208, 512 }, { 5, 209, 512 }, { 5, 210, 512 }, { 6, 211, 512 }, { 5, 212, 512 }, { 6, 213, 512 }, { 6, 214, 512 }, { 7, 215, 512 }, + { 5, 216, 512 }, { 6, 217, 512 }, { 6, 218, 512 }, { 7, 219, 512 }, { 6, 220, 512 }, { 7, 221, 512 }, { 7, 222, 512 }, { 8, 223, 512 }, + { 4, 224, 512 }, { 5, 225, 512 }, { 5, 226, 512 }, { 6, 227, 512 }, { 5, 228, 512 }, { 6, 229, 512 }, { 6, 230, 512 }, { 7, 231, 512 }, + { 5, 232, 512 }, { 6, 233, 512 }, { 6, 234, 512 }, { 7, 235, 512 }, { 6, 236, 512 }, { 7, 237, 512 }, { 7, 238, 512 }, { 8, 239, 512 }, + { 5, 240, 512 }, { 6, 241, 512 }, { 6, 242, 512 }, { 7, 243, 512 }, { 6, 244, 512 }, { 7, 245, 512 }, { 7, 246, 512 }, { 8, 247, 512 }, + { 6, 248, 512 }, { 7, 249, 512 }, { 7, 250, 512 }, { 8, 251, 512 }, { 7, 252, 512 }, { 8, 253, 512 }, { 8, 254, 512 }, { 9, 255, 512 }, + { 2, 256, 512 }, { 3, 257, 512 }, { 3, 258, 512 }, { 4, 259, 512 }, { 3, 260, 512 }, { 4, 261, 512 }, { 4, 262, 512 }, { 5, 263, 512 }, + { 3, 264, 512 }, { 4, 265, 512 }, { 4, 266, 512 }, { 5, 267, 512 }, { 4, 268, 512 }, { 5, 269, 512 }, { 5, 270, 512 }, { 6, 271, 512 }, + { 3, 272, 512 }, { 4, 273, 512 }, { 4, 274, 512 }, { 5, 275, 512 }, { 4, 276, 512 }, { 5, 277, 512 }, { 5, 278, 512 }, { 6, 279, 512 }, + { 4, 280, 512 }, { 5, 281, 512 }, { 5, 282, 512 }, { 6, 283, 512 }, { 5, 284, 512 }, { 6, 285, 512 }, { 6, 286, 512 }, { 7, 287, 512 }, + { 3, 288, 512 }, { 4, 289, 512 }, { 4, 290, 512 }, { 5, 291, 512 }, { 4, 292, 512 }, { 5, 293, 512 }, { 5, 294, 512 }, { 6, 295, 512 }, + { 4, 296, 512 }, { 5, 297, 512 }, { 5, 298, 512 }, { 6, 299, 512 }, { 5, 300, 512 }, { 6, 301, 512 }, { 6, 302, 512 }, { 7, 303, 512 }, + { 4, 304, 512 }, { 5, 305, 512 }, { 5, 306, 512 }, { 6, 307, 512 }, { 5, 308, 512 }, { 6, 309, 512 }, { 6, 310, 512 }, { 7, 311, 512 }, + { 5, 312, 512 }, { 6, 313, 512 }, { 6, 314, 512 }, { 7, 315, 512 }, { 6, 316, 512 }, { 7, 317, 512 }, { 7, 318, 512 }, { 8, 319, 512 }, + { 3, 320, 512 }, { 4, 321, 512 }, { 4, 322, 512 }, { 5, 323, 512 }, { 4, 324, 512 }, { 5, 325, 512 }, { 5, 326, 512 }, { 6, 327, 512 }, + { 4, 328, 512 }, { 5, 329, 512 }, { 5, 330, 512 }, { 6, 331, 512 }, { 5, 332, 512 }, { 6, 333, 512 }, { 6, 334, 512 }, { 7, 335, 512 }, + { 4, 336, 512 }, { 5, 337, 512 }, { 5, 338, 512 }, { 6, 339, 512 }, { 5, 340, 512 }, { 6, 341, 512 }, { 6, 342, 512 }, { 7, 343, 512 }, + { 5, 344, 512 }, { 6, 345, 512 }, { 6, 346, 512 }, { 7, 347, 512 }, { 6, 348, 512 }, { 7, 349, 512 }, { 7, 350, 512 }, { 8, 351, 512 }, + { 4, 352, 512 }, { 5, 353, 512 }, { 5, 354, 512 }, { 6, 355, 512 }, { 5, 356, 512 }, { 6, 357, 512 }, { 6, 358, 512 }, { 7, 359, 512 }, + { 5, 360, 512 }, { 6, 361, 512 }, { 6, 362, 512 }, { 7, 363, 512 }, { 6, 364, 512 }, { 7, 365, 512 }, { 7, 366, 512 }, { 8, 367, 512 }, + { 5, 368, 512 }, { 6, 369, 512 }, { 6, 370, 512 }, { 7, 371, 512 }, { 6, 372, 512 }, { 7, 373, 512 }, { 7, 374, 512 }, { 8, 375, 512 }, + { 6, 376, 512 }, { 7, 377, 512 }, { 7, 378, 512 }, { 8, 379, 512 }, { 7, 380, 512 }, { 8, 381, 512 }, { 8, 382, 512 }, { 9, 383, 512 }, + { 3, 384, 512 }, { 4, 385, 512 }, { 4, 386, 512 }, { 5, 387, 512 }, { 4, 388, 512 }, { 5, 389, 512 }, { 5, 390, 512 }, { 6, 391, 512 }, + { 4, 392, 512 }, { 5, 393, 512 }, { 5, 394, 512 }, { 6, 395, 512 }, { 5, 396, 512 }, { 6, 397, 512 }, { 6, 398, 512 }, { 7, 399, 512 }, + { 4, 400, 512 }, { 5, 401, 512 }, { 5, 402, 512 }, { 6, 403, 512 }, { 5, 404, 512 }, { 6, 405, 512 }, { 6, 406, 512 }, { 7, 407, 512 }, + { 5, 408, 512 }, { 6, 409, 512 }, { 6, 410, 512 }, { 7, 411, 512 }, { 6, 412, 512 }, { 7, 413, 512 }, { 7, 414, 512 }, { 8, 415, 512 }, + { 4, 416, 512 }, { 5, 417, 512 }, { 5, 418, 512 }, { 6, 419, 512 }, { 5, 420, 512 }, { 6, 421, 512 }, { 6, 422, 512 }, { 7, 423, 512 }, + { 5, 424, 512 }, { 6, 425, 512 }, { 6, 426, 512 }, { 7, 427, 512 }, { 6, 428, 512 }, { 7, 429, 512 }, { 7, 430, 512 }, { 8, 431, 512 }, + { 5, 432, 512 }, { 6, 433, 512 }, { 6, 434, 512 }, { 7, 435, 512 }, { 6, 436, 512 }, { 7, 437, 512 }, { 7, 438, 512 }, { 8, 439, 512 }, + { 6, 440, 512 }, { 7, 441, 512 }, { 7, 442, 512 }, { 8, 443, 512 }, { 7, 444, 512 }, { 8, 445, 512 }, { 8, 446, 512 }, { 9, 447, 512 }, + { 4, 448, 512 }, { 5, 449, 512 }, { 5, 450, 512 }, { 6, 451, 512 }, { 5, 452, 512 }, { 6, 453, 512 }, { 6, 454, 512 }, { 7, 455, 512 }, + { 5, 456, 512 }, { 6, 457, 512 }, { 6, 458, 512 }, { 7, 459, 512 }, { 6, 460, 512 }, { 7, 461, 512 }, { 7, 462, 512 }, { 8, 463, 512 }, + { 5, 464, 512 }, { 6, 465, 512 }, { 6, 466, 512 }, { 7, 467, 512 }, { 6, 468, 512 }, { 7, 469, 512 }, { 7, 470, 512 }, { 8, 471, 512 }, + { 6, 472, 512 }, { 7, 473, 512 }, { 7, 474, 512 }, { 8, 475, 512 }, { 7, 476, 512 }, { 8, 477, 512 }, { 8, 478, 512 }, { 9, 479, 512 }, + { 5, 480, 512 }, { 6, 481, 512 }, { 6, 482, 512 }, { 7, 483, 512 }, { 6, 484, 512 }, { 7, 485, 512 }, { 7, 486, 512 }, { 8, 487, 512 }, + { 6, 488, 512 }, { 7, 489, 512 }, { 7, 490, 512 }, { 8, 491, 512 }, { 7, 492, 512 }, { 8, 493, 512 }, { 8, 494, 512 }, { 9, 495, 512 }, + { 6, 496, 512 }, { 7, 497, 512 }, { 7, 498, 512 }, { 8, 499, 512 }, { 7, 500, 512 }, { 8, 501, 512 }, { 8, 502, 512 }, { 9, 503, 512 }, + { 7, 504, 512 }, { 8, 505, 512 }, { 8, 506, 512 }, { 9, 507, 512 }, { 8, 508, 512 }, { 9, 509, 512 }, { 9, 510, 512 }, { 10, 511, 512 }, +#if FP_LUT > 10 + { 1, 0, 0 }, { 2, 1, 1024 }, { 2, 2, 1024 }, { 3, 3, 1024 }, { 2, 4, 1024 }, { 3, 5, 1024 }, { 3, 6, 1024 }, { 4, 7, 1024 }, + { 2, 8, 1024 }, { 3, 9, 1024 }, { 3, 10, 1024 }, { 4, 11, 1024 }, { 3, 12, 1024 }, { 4, 13, 1024 }, { 4, 14, 1024 }, { 5, 15, 1024 }, + { 2, 16, 1024 }, { 3, 17, 1024 }, { 3, 18, 1024 }, { 4, 19, 1024 }, { 3, 20, 1024 }, { 4, 21, 1024 }, { 4, 22, 1024 }, { 5, 23, 1024 }, + { 3, 24, 1024 }, { 4, 25, 1024 }, { 4, 26, 1024 }, { 5, 27, 1024 }, { 4, 28, 1024 }, { 5, 29, 1024 }, { 5, 30, 1024 }, { 6, 31, 1024 }, + { 2, 32, 1024 }, { 3, 33, 1024 }, { 3, 34, 1024 }, { 4, 35, 1024 }, { 3, 36, 1024 }, { 4, 37, 1024 }, { 4, 38, 1024 }, { 5, 39, 1024 }, + { 3, 40, 1024 }, { 4, 41, 1024 }, { 4, 42, 1024 }, { 5, 43, 1024 }, { 4, 44, 1024 }, { 5, 45, 1024 }, { 5, 46, 1024 }, { 6, 47, 1024 }, + { 3, 48, 1024 }, { 4, 49, 1024 }, { 4, 50, 1024 }, { 5, 51, 1024 }, { 4, 52, 1024 }, { 5, 53, 1024 }, { 5, 54, 1024 }, { 6, 55, 1024 }, + { 4, 56, 1024 }, { 5, 57, 1024 }, { 5, 58, 1024 }, { 6, 59, 1024 }, { 5, 60, 1024 }, { 6, 61, 1024 }, { 6, 62, 1024 }, { 7, 63, 1024 }, + { 2, 64, 1024 }, { 3, 65, 1024 }, { 3, 66, 1024 }, { 4, 67, 1024 }, { 3, 68, 1024 }, { 4, 69, 1024 }, { 4, 70, 1024 }, { 5, 71, 1024 }, + { 3, 72, 1024 }, { 4, 73, 1024 }, { 4, 74, 1024 }, { 5, 75, 1024 }, { 4, 76, 1024 }, { 5, 77, 1024 }, { 5, 78, 1024 }, { 6, 79, 1024 }, + { 3, 80, 1024 }, { 4, 81, 1024 }, { 4, 82, 1024 }, { 5, 83, 1024 }, { 4, 84, 1024 }, { 5, 85, 1024 }, { 5, 86, 1024 }, { 6, 87, 1024 }, + { 4, 88, 1024 }, { 5, 89, 1024 }, { 5, 90, 1024 }, { 6, 91, 1024 }, { 5, 92, 1024 }, { 6, 93, 1024 }, { 6, 94, 1024 }, { 7, 95, 1024 }, + { 3, 96, 1024 }, { 4, 97, 1024 }, { 4, 98, 1024 }, { 5, 99, 1024 }, { 4, 100, 1024 }, { 5, 101, 1024 }, { 5, 102, 1024 }, { 6, 103, 1024 }, + { 4, 104, 1024 }, { 5, 105, 1024 }, { 5, 106, 1024 }, { 6, 107, 1024 }, { 5, 108, 1024 }, { 6, 109, 1024 }, { 6, 110, 1024 }, { 7, 111, 1024 }, + { 4, 112, 1024 }, { 5, 113, 1024 }, { 5, 114, 1024 }, { 6, 115, 1024 }, { 5, 116, 1024 }, { 6, 117, 1024 }, { 6, 118, 1024 }, { 7, 119, 1024 }, + { 5, 120, 1024 }, { 6, 121, 1024 }, { 6, 122, 1024 }, { 7, 123, 1024 }, { 6, 124, 1024 }, { 7, 125, 1024 }, { 7, 126, 1024 }, { 8, 127, 1024 }, + { 2, 128, 1024 }, { 3, 129, 1024 }, { 3, 130, 1024 }, { 4, 131, 1024 }, { 3, 132, 1024 }, { 4, 133, 1024 }, { 4, 134, 1024 }, { 5, 135, 1024 }, + { 3, 136, 1024 }, { 4, 137, 1024 }, { 4, 138, 1024 }, { 5, 139, 1024 }, { 4, 140, 1024 }, { 5, 141, 1024 }, { 5, 142, 1024 }, { 6, 143, 1024 }, + { 3, 144, 1024 }, { 4, 145, 1024 }, { 4, 146, 1024 }, { 5, 147, 1024 }, { 4, 148, 1024 }, { 5, 149, 1024 }, { 5, 150, 1024 }, { 6, 151, 1024 }, + { 4, 152, 1024 }, { 5, 153, 1024 }, { 5, 154, 1024 }, { 6, 155, 1024 }, { 5, 156, 1024 }, { 6, 157, 1024 }, { 6, 158, 1024 }, { 7, 159, 1024 }, + { 3, 160, 1024 }, { 4, 161, 1024 }, { 4, 162, 1024 }, { 5, 163, 1024 }, { 4, 164, 1024 }, { 5, 165, 1024 }, { 5, 166, 1024 }, { 6, 167, 1024 }, + { 4, 168, 1024 }, { 5, 169, 1024 }, { 5, 170, 1024 }, { 6, 171, 1024 }, { 5, 172, 1024 }, { 6, 173, 1024 }, { 6, 174, 1024 }, { 7, 175, 1024 }, + { 4, 176, 1024 }, { 5, 177, 1024 }, { 5, 178, 1024 }, { 6, 179, 1024 }, { 5, 180, 1024 }, { 6, 181, 1024 }, { 6, 182, 1024 }, { 7, 183, 1024 }, + { 5, 184, 1024 }, { 6, 185, 1024 }, { 6, 186, 1024 }, { 7, 187, 1024 }, { 6, 188, 1024 }, { 7, 189, 1024 }, { 7, 190, 1024 }, { 8, 191, 1024 }, + { 3, 192, 1024 }, { 4, 193, 1024 }, { 4, 194, 1024 }, { 5, 195, 1024 }, { 4, 196, 1024 }, { 5, 197, 1024 }, { 5, 198, 1024 }, { 6, 199, 1024 }, + { 4, 200, 1024 }, { 5, 201, 1024 }, { 5, 202, 1024 }, { 6, 203, 1024 }, { 5, 204, 1024 }, { 6, 205, 1024 }, { 6, 206, 1024 }, { 7, 207, 1024 }, + { 4, 208, 1024 }, { 5, 209, 1024 }, { 5, 210, 1024 }, { 6, 211, 1024 }, { 5, 212, 1024 }, { 6, 213, 1024 }, { 6, 214, 1024 }, { 7, 215, 1024 }, + { 5, 216, 1024 }, { 6, 217, 1024 }, { 6, 218, 1024 }, { 7, 219, 1024 }, { 6, 220, 1024 }, { 7, 221, 1024 }, { 7, 222, 1024 }, { 8, 223, 1024 }, + { 4, 224, 1024 }, { 5, 225, 1024 }, { 5, 226, 1024 }, { 6, 227, 1024 }, { 5, 228, 1024 }, { 6, 229, 1024 }, { 6, 230, 1024 }, { 7, 231, 1024 }, + { 5, 232, 1024 }, { 6, 233, 1024 }, { 6, 234, 1024 }, { 7, 235, 1024 }, { 6, 236, 1024 }, { 7, 237, 1024 }, { 7, 238, 1024 }, { 8, 239, 1024 }, + { 5, 240, 1024 }, { 6, 241, 1024 }, { 6, 242, 1024 }, { 7, 243, 1024 }, { 6, 244, 1024 }, { 7, 245, 1024 }, { 7, 246, 1024 }, { 8, 247, 1024 }, + { 6, 248, 1024 }, { 7, 249, 1024 }, { 7, 250, 1024 }, { 8, 251, 1024 }, { 7, 252, 1024 }, { 8, 253, 1024 }, { 8, 254, 1024 }, { 9, 255, 1024 }, + { 2, 256, 1024 }, { 3, 257, 1024 }, { 3, 258, 1024 }, { 4, 259, 1024 }, { 3, 260, 1024 }, { 4, 261, 1024 }, { 4, 262, 1024 }, { 5, 263, 1024 }, + { 3, 264, 1024 }, { 4, 265, 1024 }, { 4, 266, 1024 }, { 5, 267, 1024 }, { 4, 268, 1024 }, { 5, 269, 1024 }, { 5, 270, 1024 }, { 6, 271, 1024 }, + { 3, 272, 1024 }, { 4, 273, 1024 }, { 4, 274, 1024 }, { 5, 275, 1024 }, { 4, 276, 1024 }, { 5, 277, 1024 }, { 5, 278, 1024 }, { 6, 279, 1024 }, + { 4, 280, 1024 }, { 5, 281, 1024 }, { 5, 282, 1024 }, { 6, 283, 1024 }, { 5, 284, 1024 }, { 6, 285, 1024 }, { 6, 286, 1024 }, { 7, 287, 1024 }, + { 3, 288, 1024 }, { 4, 289, 1024 }, { 4, 290, 1024 }, { 5, 291, 1024 }, { 4, 292, 1024 }, { 5, 293, 1024 }, { 5, 294, 1024 }, { 6, 295, 1024 }, + { 4, 296, 1024 }, { 5, 297, 1024 }, { 5, 298, 1024 }, { 6, 299, 1024 }, { 5, 300, 1024 }, { 6, 301, 1024 }, { 6, 302, 1024 }, { 7, 303, 1024 }, + { 4, 304, 1024 }, { 5, 305, 1024 }, { 5, 306, 1024 }, { 6, 307, 1024 }, { 5, 308, 1024 }, { 6, 309, 1024 }, { 6, 310, 1024 }, { 7, 311, 1024 }, + { 5, 312, 1024 }, { 6, 313, 1024 }, { 6, 314, 1024 }, { 7, 315, 1024 }, { 6, 316, 1024 }, { 7, 317, 1024 }, { 7, 318, 1024 }, { 8, 319, 1024 }, + { 3, 320, 1024 }, { 4, 321, 1024 }, { 4, 322, 1024 }, { 5, 323, 1024 }, { 4, 324, 1024 }, { 5, 325, 1024 }, { 5, 326, 1024 }, { 6, 327, 1024 }, + { 4, 328, 1024 }, { 5, 329, 1024 }, { 5, 330, 1024 }, { 6, 331, 1024 }, { 5, 332, 1024 }, { 6, 333, 1024 }, { 6, 334, 1024 }, { 7, 335, 1024 }, + { 4, 336, 1024 }, { 5, 337, 1024 }, { 5, 338, 1024 }, { 6, 339, 1024 }, { 5, 340, 1024 }, { 6, 341, 1024 }, { 6, 342, 1024 }, { 7, 343, 1024 }, + { 5, 344, 1024 }, { 6, 345, 1024 }, { 6, 346, 1024 }, { 7, 347, 1024 }, { 6, 348, 1024 }, { 7, 349, 1024 }, { 7, 350, 1024 }, { 8, 351, 1024 }, + { 4, 352, 1024 }, { 5, 353, 1024 }, { 5, 354, 1024 }, { 6, 355, 1024 }, { 5, 356, 1024 }, { 6, 357, 1024 }, { 6, 358, 1024 }, { 7, 359, 1024 }, + { 5, 360, 1024 }, { 6, 361, 1024 }, { 6, 362, 1024 }, { 7, 363, 1024 }, { 6, 364, 1024 }, { 7, 365, 1024 }, { 7, 366, 1024 }, { 8, 367, 1024 }, + { 5, 368, 1024 }, { 6, 369, 1024 }, { 6, 370, 1024 }, { 7, 371, 1024 }, { 6, 372, 1024 }, { 7, 373, 1024 }, { 7, 374, 1024 }, { 8, 375, 1024 }, + { 6, 376, 1024 }, { 7, 377, 1024 }, { 7, 378, 1024 }, { 8, 379, 1024 }, { 7, 380, 1024 }, { 8, 381, 1024 }, { 8, 382, 1024 }, { 9, 383, 1024 }, + { 3, 384, 1024 }, { 4, 385, 1024 }, { 4, 386, 1024 }, { 5, 387, 1024 }, { 4, 388, 1024 }, { 5, 389, 1024 }, { 5, 390, 1024 }, { 6, 391, 1024 }, + { 4, 392, 1024 }, { 5, 393, 1024 }, { 5, 394, 1024 }, { 6, 395, 1024 }, { 5, 396, 1024 }, { 6, 397, 1024 }, { 6, 398, 1024 }, { 7, 399, 1024 }, + { 4, 400, 1024 }, { 5, 401, 1024 }, { 5, 402, 1024 }, { 6, 403, 1024 }, { 5, 404, 1024 }, { 6, 405, 1024 }, { 6, 406, 1024 }, { 7, 407, 1024 }, + { 5, 408, 1024 }, { 6, 409, 1024 }, { 6, 410, 1024 }, { 7, 411, 1024 }, { 6, 412, 1024 }, { 7, 413, 1024 }, { 7, 414, 1024 }, { 8, 415, 1024 }, + { 4, 416, 1024 }, { 5, 417, 1024 }, { 5, 418, 1024 }, { 6, 419, 1024 }, { 5, 420, 1024 }, { 6, 421, 1024 }, { 6, 422, 1024 }, { 7, 423, 1024 }, + { 5, 424, 1024 }, { 6, 425, 1024 }, { 6, 426, 1024 }, { 7, 427, 1024 }, { 6, 428, 1024 }, { 7, 429, 1024 }, { 7, 430, 1024 }, { 8, 431, 1024 }, + { 5, 432, 1024 }, { 6, 433, 1024 }, { 6, 434, 1024 }, { 7, 435, 1024 }, { 6, 436, 1024 }, { 7, 437, 1024 }, { 7, 438, 1024 }, { 8, 439, 1024 }, + { 6, 440, 1024 }, { 7, 441, 1024 }, { 7, 442, 1024 }, { 8, 443, 1024 }, { 7, 444, 1024 }, { 8, 445, 1024 }, { 8, 446, 1024 }, { 9, 447, 1024 }, + { 4, 448, 1024 }, { 5, 449, 1024 }, { 5, 450, 1024 }, { 6, 451, 1024 }, { 5, 452, 1024 }, { 6, 453, 1024 }, { 6, 454, 1024 }, { 7, 455, 1024 }, + { 5, 456, 1024 }, { 6, 457, 1024 }, { 6, 458, 1024 }, { 7, 459, 1024 }, { 6, 460, 1024 }, { 7, 461, 1024 }, { 7, 462, 1024 }, { 8, 463, 1024 }, + { 5, 464, 1024 }, { 6, 465, 1024 }, { 6, 466, 1024 }, { 7, 467, 1024 }, { 6, 468, 1024 }, { 7, 469, 1024 }, { 7, 470, 1024 }, { 8, 471, 1024 }, + { 6, 472, 1024 }, { 7, 473, 1024 }, { 7, 474, 1024 }, { 8, 475, 1024 }, { 7, 476, 1024 }, { 8, 477, 1024 }, { 8, 478, 1024 }, { 9, 479, 1024 }, + { 5, 480, 1024 }, { 6, 481, 1024 }, { 6, 482, 1024 }, { 7, 483, 1024 }, { 6, 484, 1024 }, { 7, 485, 1024 }, { 7, 486, 1024 }, { 8, 487, 1024 }, + { 6, 488, 1024 }, { 7, 489, 1024 }, { 7, 490, 1024 }, { 8, 491, 1024 }, { 7, 492, 1024 }, { 8, 493, 1024 }, { 8, 494, 1024 }, { 9, 495, 1024 }, + { 6, 496, 1024 }, { 7, 497, 1024 }, { 7, 498, 1024 }, { 8, 499, 1024 }, { 7, 500, 1024 }, { 8, 501, 1024 }, { 8, 502, 1024 }, { 9, 503, 1024 }, + { 7, 504, 1024 }, { 8, 505, 1024 }, { 8, 506, 1024 }, { 9, 507, 1024 }, { 8, 508, 1024 }, { 9, 509, 1024 }, { 9, 510, 1024 }, { 10, 511, 1024 }, + { 2, 512, 1024 }, { 3, 513, 1024 }, { 3, 514, 1024 }, { 4, 515, 1024 }, { 3, 516, 1024 }, { 4, 517, 1024 }, { 4, 518, 1024 }, { 5, 519, 1024 }, + { 3, 520, 1024 }, { 4, 521, 1024 }, { 4, 522, 1024 }, { 5, 523, 1024 }, { 4, 524, 1024 }, { 5, 525, 1024 }, { 5, 526, 1024 }, { 6, 527, 1024 }, + { 3, 528, 1024 }, { 4, 529, 1024 }, { 4, 530, 1024 }, { 5, 531, 1024 }, { 4, 532, 1024 }, { 5, 533, 1024 }, { 5, 534, 1024 }, { 6, 535, 1024 }, + { 4, 536, 1024 }, { 5, 537, 1024 }, { 5, 538, 1024 }, { 6, 539, 1024 }, { 5, 540, 1024 }, { 6, 541, 1024 }, { 6, 542, 1024 }, { 7, 543, 1024 }, + { 3, 544, 1024 }, { 4, 545, 1024 }, { 4, 546, 1024 }, { 5, 547, 1024 }, { 4, 548, 1024 }, { 5, 549, 1024 }, { 5, 550, 1024 }, { 6, 551, 1024 }, + { 4, 552, 1024 }, { 5, 553, 1024 }, { 5, 554, 1024 }, { 6, 555, 1024 }, { 5, 556, 1024 }, { 6, 557, 1024 }, { 6, 558, 1024 }, { 7, 559, 1024 }, + { 4, 560, 1024 }, { 5, 561, 1024 }, { 5, 562, 1024 }, { 6, 563, 1024 }, { 5, 564, 1024 }, { 6, 565, 1024 }, { 6, 566, 1024 }, { 7, 567, 1024 }, + { 5, 568, 1024 }, { 6, 569, 1024 }, { 6, 570, 1024 }, { 7, 571, 1024 }, { 6, 572, 1024 }, { 7, 573, 1024 }, { 7, 574, 1024 }, { 8, 575, 1024 }, + { 3, 576, 1024 }, { 4, 577, 1024 }, { 4, 578, 1024 }, { 5, 579, 1024 }, { 4, 580, 1024 }, { 5, 581, 1024 }, { 5, 582, 1024 }, { 6, 583, 1024 }, + { 4, 584, 1024 }, { 5, 585, 1024 }, { 5, 586, 1024 }, { 6, 587, 1024 }, { 5, 588, 1024 }, { 6, 589, 1024 }, { 6, 590, 1024 }, { 7, 591, 1024 }, + { 4, 592, 1024 }, { 5, 593, 1024 }, { 5, 594, 1024 }, { 6, 595, 1024 }, { 5, 596, 1024 }, { 6, 597, 1024 }, { 6, 598, 1024 }, { 7, 599, 1024 }, + { 5, 600, 1024 }, { 6, 601, 1024 }, { 6, 602, 1024 }, { 7, 603, 1024 }, { 6, 604, 1024 }, { 7, 605, 1024 }, { 7, 606, 1024 }, { 8, 607, 1024 }, + { 4, 608, 1024 }, { 5, 609, 1024 }, { 5, 610, 1024 }, { 6, 611, 1024 }, { 5, 612, 1024 }, { 6, 613, 1024 }, { 6, 614, 1024 }, { 7, 615, 1024 }, + { 5, 616, 1024 }, { 6, 617, 1024 }, { 6, 618, 1024 }, { 7, 619, 1024 }, { 6, 620, 1024 }, { 7, 621, 1024 }, { 7, 622, 1024 }, { 8, 623, 1024 }, + { 5, 624, 1024 }, { 6, 625, 1024 }, { 6, 626, 1024 }, { 7, 627, 1024 }, { 6, 628, 1024 }, { 7, 629, 1024 }, { 7, 630, 1024 }, { 8, 631, 1024 }, + { 6, 632, 1024 }, { 7, 633, 1024 }, { 7, 634, 1024 }, { 8, 635, 1024 }, { 7, 636, 1024 }, { 8, 637, 1024 }, { 8, 638, 1024 }, { 9, 639, 1024 }, + { 3, 640, 1024 }, { 4, 641, 1024 }, { 4, 642, 1024 }, { 5, 643, 1024 }, { 4, 644, 1024 }, { 5, 645, 1024 }, { 5, 646, 1024 }, { 6, 647, 1024 }, + { 4, 648, 1024 }, { 5, 649, 1024 }, { 5, 650, 1024 }, { 6, 651, 1024 }, { 5, 652, 1024 }, { 6, 653, 1024 }, { 6, 654, 1024 }, { 7, 655, 1024 }, + { 4, 656, 1024 }, { 5, 657, 1024 }, { 5, 658, 1024 }, { 6, 659, 1024 }, { 5, 660, 1024 }, { 6, 661, 1024 }, { 6, 662, 1024 }, { 7, 663, 1024 }, + { 5, 664, 1024 }, { 6, 665, 1024 }, { 6, 666, 1024 }, { 7, 667, 1024 }, { 6, 668, 1024 }, { 7, 669, 1024 }, { 7, 670, 1024 }, { 8, 671, 1024 }, + { 4, 672, 1024 }, { 5, 673, 1024 }, { 5, 674, 1024 }, { 6, 675, 1024 }, { 5, 676, 1024 }, { 6, 677, 1024 }, { 6, 678, 1024 }, { 7, 679, 1024 }, + { 5, 680, 1024 }, { 6, 681, 1024 }, { 6, 682, 1024 }, { 7, 683, 1024 }, { 6, 684, 1024 }, { 7, 685, 1024 }, { 7, 686, 1024 }, { 8, 687, 1024 }, + { 5, 688, 1024 }, { 6, 689, 1024 }, { 6, 690, 1024 }, { 7, 691, 1024 }, { 6, 692, 1024 }, { 7, 693, 1024 }, { 7, 694, 1024 }, { 8, 695, 1024 }, + { 6, 696, 1024 }, { 7, 697, 1024 }, { 7, 698, 1024 }, { 8, 699, 1024 }, { 7, 700, 1024 }, { 8, 701, 1024 }, { 8, 702, 1024 }, { 9, 703, 1024 }, + { 4, 704, 1024 }, { 5, 705, 1024 }, { 5, 706, 1024 }, { 6, 707, 1024 }, { 5, 708, 1024 }, { 6, 709, 1024 }, { 6, 710, 1024 }, { 7, 711, 1024 }, + { 5, 712, 1024 }, { 6, 713, 1024 }, { 6, 714, 1024 }, { 7, 715, 1024 }, { 6, 716, 1024 }, { 7, 717, 1024 }, { 7, 718, 1024 }, { 8, 719, 1024 }, + { 5, 720, 1024 }, { 6, 721, 1024 }, { 6, 722, 1024 }, { 7, 723, 1024 }, { 6, 724, 1024 }, { 7, 725, 1024 }, { 7, 726, 1024 }, { 8, 727, 1024 }, + { 6, 728, 1024 }, { 7, 729, 1024 }, { 7, 730, 1024 }, { 8, 731, 1024 }, { 7, 732, 1024 }, { 8, 733, 1024 }, { 8, 734, 1024 }, { 9, 735, 1024 }, + { 5, 736, 1024 }, { 6, 737, 1024 }, { 6, 738, 1024 }, { 7, 739, 1024 }, { 6, 740, 1024 }, { 7, 741, 1024 }, { 7, 742, 1024 }, { 8, 743, 1024 }, + { 6, 744, 1024 }, { 7, 745, 1024 }, { 7, 746, 1024 }, { 8, 747, 1024 }, { 7, 748, 1024 }, { 8, 749, 1024 }, { 8, 750, 1024 }, { 9, 751, 1024 }, + { 6, 752, 1024 }, { 7, 753, 1024 }, { 7, 754, 1024 }, { 8, 755, 1024 }, { 7, 756, 1024 }, { 8, 757, 1024 }, { 8, 758, 1024 }, { 9, 759, 1024 }, + { 7, 760, 1024 }, { 8, 761, 1024 }, { 8, 762, 1024 }, { 9, 763, 1024 }, { 8, 764, 1024 }, { 9, 765, 1024 }, { 9, 766, 1024 }, { 10, 767, 1024 }, + { 3, 768, 1024 }, { 4, 769, 1024 }, { 4, 770, 1024 }, { 5, 771, 1024 }, { 4, 772, 1024 }, { 5, 773, 1024 }, { 5, 774, 1024 }, { 6, 775, 1024 }, + { 4, 776, 1024 }, { 5, 777, 1024 }, { 5, 778, 1024 }, { 6, 779, 1024 }, { 5, 780, 1024 }, { 6, 781, 1024 }, { 6, 782, 1024 }, { 7, 783, 1024 }, + { 4, 784, 1024 }, { 5, 785, 1024 }, { 5, 786, 1024 }, { 6, 787, 1024 }, { 5, 788, 1024 }, { 6, 789, 1024 }, { 6, 790, 1024 }, { 7, 791, 1024 }, + { 5, 792, 1024 }, { 6, 793, 1024 }, { 6, 794, 1024 }, { 7, 795, 1024 }, { 6, 796, 1024 }, { 7, 797, 1024 }, { 7, 798, 1024 }, { 8, 799, 1024 }, + { 4, 800, 1024 }, { 5, 801, 1024 }, { 5, 802, 1024 }, { 6, 803, 1024 }, { 5, 804, 1024 }, { 6, 805, 1024 }, { 6, 806, 1024 }, { 7, 807, 1024 }, + { 5, 808, 1024 }, { 6, 809, 1024 }, { 6, 810, 1024 }, { 7, 811, 1024 }, { 6, 812, 1024 }, { 7, 813, 1024 }, { 7, 814, 1024 }, { 8, 815, 1024 }, + { 5, 816, 1024 }, { 6, 817, 1024 }, { 6, 818, 1024 }, { 7, 819, 1024 }, { 6, 820, 1024 }, { 7, 821, 1024 }, { 7, 822, 1024 }, { 8, 823, 1024 }, + { 6, 824, 1024 }, { 7, 825, 1024 }, { 7, 826, 1024 }, { 8, 827, 1024 }, { 7, 828, 1024 }, { 8, 829, 1024 }, { 8, 830, 1024 }, { 9, 831, 1024 }, + { 4, 832, 1024 }, { 5, 833, 1024 }, { 5, 834, 1024 }, { 6, 835, 1024 }, { 5, 836, 1024 }, { 6, 837, 1024 }, { 6, 838, 1024 }, { 7, 839, 1024 }, + { 5, 840, 1024 }, { 6, 841, 1024 }, { 6, 842, 1024 }, { 7, 843, 1024 }, { 6, 844, 1024 }, { 7, 845, 1024 }, { 7, 846, 1024 }, { 8, 847, 1024 }, + { 5, 848, 1024 }, { 6, 849, 1024 }, { 6, 850, 1024 }, { 7, 851, 1024 }, { 6, 852, 1024 }, { 7, 853, 1024 }, { 7, 854, 1024 }, { 8, 855, 1024 }, + { 6, 856, 1024 }, { 7, 857, 1024 }, { 7, 858, 1024 }, { 8, 859, 1024 }, { 7, 860, 1024 }, { 8, 861, 1024 }, { 8, 862, 1024 }, { 9, 863, 1024 }, + { 5, 864, 1024 }, { 6, 865, 1024 }, { 6, 866, 1024 }, { 7, 867, 1024 }, { 6, 868, 1024 }, { 7, 869, 1024 }, { 7, 870, 1024 }, { 8, 871, 1024 }, + { 6, 872, 1024 }, { 7, 873, 1024 }, { 7, 874, 1024 }, { 8, 875, 1024 }, { 7, 876, 1024 }, { 8, 877, 1024 }, { 8, 878, 1024 }, { 9, 879, 1024 }, + { 6, 880, 1024 }, { 7, 881, 1024 }, { 7, 882, 1024 }, { 8, 883, 1024 }, { 7, 884, 1024 }, { 8, 885, 1024 }, { 8, 886, 1024 }, { 9, 887, 1024 }, + { 7, 888, 1024 }, { 8, 889, 1024 }, { 8, 890, 1024 }, { 9, 891, 1024 }, { 8, 892, 1024 }, { 9, 893, 1024 }, { 9, 894, 1024 }, { 10, 895, 1024 }, + { 4, 896, 1024 }, { 5, 897, 1024 }, { 5, 898, 1024 }, { 6, 899, 1024 }, { 5, 900, 1024 }, { 6, 901, 1024 }, { 6, 902, 1024 }, { 7, 903, 1024 }, + { 5, 904, 1024 }, { 6, 905, 1024 }, { 6, 906, 1024 }, { 7, 907, 1024 }, { 6, 908, 1024 }, { 7, 909, 1024 }, { 7, 910, 1024 }, { 8, 911, 1024 }, + { 5, 912, 1024 }, { 6, 913, 1024 }, { 6, 914, 1024 }, { 7, 915, 1024 }, { 6, 916, 1024 }, { 7, 917, 1024 }, { 7, 918, 1024 }, { 8, 919, 1024 }, + { 6, 920, 1024 }, { 7, 921, 1024 }, { 7, 922, 1024 }, { 8, 923, 1024 }, { 7, 924, 1024 }, { 8, 925, 1024 }, { 8, 926, 1024 }, { 9, 927, 1024 }, + { 5, 928, 1024 }, { 6, 929, 1024 }, { 6, 930, 1024 }, { 7, 931, 1024 }, { 6, 932, 1024 }, { 7, 933, 1024 }, { 7, 934, 1024 }, { 8, 935, 1024 }, + { 6, 936, 1024 }, { 7, 937, 1024 }, { 7, 938, 1024 }, { 8, 939, 1024 }, { 7, 940, 1024 }, { 8, 941, 1024 }, { 8, 942, 1024 }, { 9, 943, 1024 }, + { 6, 944, 1024 }, { 7, 945, 1024 }, { 7, 946, 1024 }, { 8, 947, 1024 }, { 7, 948, 1024 }, { 8, 949, 1024 }, { 8, 950, 1024 }, { 9, 951, 1024 }, + { 7, 952, 1024 }, { 8, 953, 1024 }, { 8, 954, 1024 }, { 9, 955, 1024 }, { 8, 956, 1024 }, { 9, 957, 1024 }, { 9, 958, 1024 }, { 10, 959, 1024 }, + { 5, 960, 1024 }, { 6, 961, 1024 }, { 6, 962, 1024 }, { 7, 963, 1024 }, { 6, 964, 1024 }, { 7, 965, 1024 }, { 7, 966, 1024 }, { 8, 967, 1024 }, + { 6, 968, 1024 }, { 7, 969, 1024 }, { 7, 970, 1024 }, { 8, 971, 1024 }, { 7, 972, 1024 }, { 8, 973, 1024 }, { 8, 974, 1024 }, { 9, 975, 1024 }, + { 6, 976, 1024 }, { 7, 977, 1024 }, { 7, 978, 1024 }, { 8, 979, 1024 }, { 7, 980, 1024 }, { 8, 981, 1024 }, { 8, 982, 1024 }, { 9, 983, 1024 }, + { 7, 984, 1024 }, { 8, 985, 1024 }, { 8, 986, 1024 }, { 9, 987, 1024 }, { 8, 988, 1024 }, { 9, 989, 1024 }, { 9, 990, 1024 }, { 10, 991, 1024 }, + { 6, 992, 1024 }, { 7, 993, 1024 }, { 7, 994, 1024 }, { 8, 995, 1024 }, { 7, 996, 1024 }, { 8, 997, 1024 }, { 8, 998, 1024 }, { 9, 999, 1024 }, + { 7, 1000, 1024 }, { 8, 1001, 1024 }, { 8, 1002, 1024 }, { 9, 1003, 1024 }, { 8, 1004, 1024 }, { 9, 1005, 1024 }, { 9, 1006, 1024 }, { 10, 1007, 1024 }, + { 7, 1008, 1024 }, { 8, 1009, 1024 }, { 8, 1010, 1024 }, { 9, 1011, 1024 }, { 8, 1012, 1024 }, { 9, 1013, 1024 }, { 9, 1014, 1024 }, { 10, 1015, 1024 }, + { 8, 1016, 1024 }, { 9, 1017, 1024 }, { 9, 1018, 1024 }, { 10, 1019, 1024 }, { 9, 1020, 1024 }, { 10, 1021, 1024 }, { 10, 1022, 1024 }, { 11, 1023, 1024 }, +#if FP_LUT > 11 + { 1, 0, 0 }, { 2, 1, 2048 }, { 2, 2, 2048 }, { 3, 3, 2048 }, { 2, 4, 2048 }, { 3, 5, 2048 }, { 3, 6, 2048 }, { 4, 7, 2048 }, + { 2, 8, 2048 }, { 3, 9, 2048 }, { 3, 10, 2048 }, { 4, 11, 2048 }, { 3, 12, 2048 }, { 4, 13, 2048 }, { 4, 14, 2048 }, { 5, 15, 2048 }, + { 2, 16, 2048 }, { 3, 17, 2048 }, { 3, 18, 2048 }, { 4, 19, 2048 }, { 3, 20, 2048 }, { 4, 21, 2048 }, { 4, 22, 2048 }, { 5, 23, 2048 }, + { 3, 24, 2048 }, { 4, 25, 2048 }, { 4, 26, 2048 }, { 5, 27, 2048 }, { 4, 28, 2048 }, { 5, 29, 2048 }, { 5, 30, 2048 }, { 6, 31, 2048 }, + { 2, 32, 2048 }, { 3, 33, 2048 }, { 3, 34, 2048 }, { 4, 35, 2048 }, { 3, 36, 2048 }, { 4, 37, 2048 }, { 4, 38, 2048 }, { 5, 39, 2048 }, + { 3, 40, 2048 }, { 4, 41, 2048 }, { 4, 42, 2048 }, { 5, 43, 2048 }, { 4, 44, 2048 }, { 5, 45, 2048 }, { 5, 46, 2048 }, { 6, 47, 2048 }, + { 3, 48, 2048 }, { 4, 49, 2048 }, { 4, 50, 2048 }, { 5, 51, 2048 }, { 4, 52, 2048 }, { 5, 53, 2048 }, { 5, 54, 2048 }, { 6, 55, 2048 }, + { 4, 56, 2048 }, { 5, 57, 2048 }, { 5, 58, 2048 }, { 6, 59, 2048 }, { 5, 60, 2048 }, { 6, 61, 2048 }, { 6, 62, 2048 }, { 7, 63, 2048 }, + { 2, 64, 2048 }, { 3, 65, 2048 }, { 3, 66, 2048 }, { 4, 67, 2048 }, { 3, 68, 2048 }, { 4, 69, 2048 }, { 4, 70, 2048 }, { 5, 71, 2048 }, + { 3, 72, 2048 }, { 4, 73, 2048 }, { 4, 74, 2048 }, { 5, 75, 2048 }, { 4, 76, 2048 }, { 5, 77, 2048 }, { 5, 78, 2048 }, { 6, 79, 2048 }, + { 3, 80, 2048 }, { 4, 81, 2048 }, { 4, 82, 2048 }, { 5, 83, 2048 }, { 4, 84, 2048 }, { 5, 85, 2048 }, { 5, 86, 2048 }, { 6, 87, 2048 }, + { 4, 88, 2048 }, { 5, 89, 2048 }, { 5, 90, 2048 }, { 6, 91, 2048 }, { 5, 92, 2048 }, { 6, 93, 2048 }, { 6, 94, 2048 }, { 7, 95, 2048 }, + { 3, 96, 2048 }, { 4, 97, 2048 }, { 4, 98, 2048 }, { 5, 99, 2048 }, { 4, 100, 2048 }, { 5, 101, 2048 }, { 5, 102, 2048 }, { 6, 103, 2048 }, + { 4, 104, 2048 }, { 5, 105, 2048 }, { 5, 106, 2048 }, { 6, 107, 2048 }, { 5, 108, 2048 }, { 6, 109, 2048 }, { 6, 110, 2048 }, { 7, 111, 2048 }, + { 4, 112, 2048 }, { 5, 113, 2048 }, { 5, 114, 2048 }, { 6, 115, 2048 }, { 5, 116, 2048 }, { 6, 117, 2048 }, { 6, 118, 2048 }, { 7, 119, 2048 }, + { 5, 120, 2048 }, { 6, 121, 2048 }, { 6, 122, 2048 }, { 7, 123, 2048 }, { 6, 124, 2048 }, { 7, 125, 2048 }, { 7, 126, 2048 }, { 8, 127, 2048 }, + { 2, 128, 2048 }, { 3, 129, 2048 }, { 3, 130, 2048 }, { 4, 131, 2048 }, { 3, 132, 2048 }, { 4, 133, 2048 }, { 4, 134, 2048 }, { 5, 135, 2048 }, + { 3, 136, 2048 }, { 4, 137, 2048 }, { 4, 138, 2048 }, { 5, 139, 2048 }, { 4, 140, 2048 }, { 5, 141, 2048 }, { 5, 142, 2048 }, { 6, 143, 2048 }, + { 3, 144, 2048 }, { 4, 145, 2048 }, { 4, 146, 2048 }, { 5, 147, 2048 }, { 4, 148, 2048 }, { 5, 149, 2048 }, { 5, 150, 2048 }, { 6, 151, 2048 }, + { 4, 152, 2048 }, { 5, 153, 2048 }, { 5, 154, 2048 }, { 6, 155, 2048 }, { 5, 156, 2048 }, { 6, 157, 2048 }, { 6, 158, 2048 }, { 7, 159, 2048 }, + { 3, 160, 2048 }, { 4, 161, 2048 }, { 4, 162, 2048 }, { 5, 163, 2048 }, { 4, 164, 2048 }, { 5, 165, 2048 }, { 5, 166, 2048 }, { 6, 167, 2048 }, + { 4, 168, 2048 }, { 5, 169, 2048 }, { 5, 170, 2048 }, { 6, 171, 2048 }, { 5, 172, 2048 }, { 6, 173, 2048 }, { 6, 174, 2048 }, { 7, 175, 2048 }, + { 4, 176, 2048 }, { 5, 177, 2048 }, { 5, 178, 2048 }, { 6, 179, 2048 }, { 5, 180, 2048 }, { 6, 181, 2048 }, { 6, 182, 2048 }, { 7, 183, 2048 }, + { 5, 184, 2048 }, { 6, 185, 2048 }, { 6, 186, 2048 }, { 7, 187, 2048 }, { 6, 188, 2048 }, { 7, 189, 2048 }, { 7, 190, 2048 }, { 8, 191, 2048 }, + { 3, 192, 2048 }, { 4, 193, 2048 }, { 4, 194, 2048 }, { 5, 195, 2048 }, { 4, 196, 2048 }, { 5, 197, 2048 }, { 5, 198, 2048 }, { 6, 199, 2048 }, + { 4, 200, 2048 }, { 5, 201, 2048 }, { 5, 202, 2048 }, { 6, 203, 2048 }, { 5, 204, 2048 }, { 6, 205, 2048 }, { 6, 206, 2048 }, { 7, 207, 2048 }, + { 4, 208, 2048 }, { 5, 209, 2048 }, { 5, 210, 2048 }, { 6, 211, 2048 }, { 5, 212, 2048 }, { 6, 213, 2048 }, { 6, 214, 2048 }, { 7, 215, 2048 }, + { 5, 216, 2048 }, { 6, 217, 2048 }, { 6, 218, 2048 }, { 7, 219, 2048 }, { 6, 220, 2048 }, { 7, 221, 2048 }, { 7, 222, 2048 }, { 8, 223, 2048 }, + { 4, 224, 2048 }, { 5, 225, 2048 }, { 5, 226, 2048 }, { 6, 227, 2048 }, { 5, 228, 2048 }, { 6, 229, 2048 }, { 6, 230, 2048 }, { 7, 231, 2048 }, + { 5, 232, 2048 }, { 6, 233, 2048 }, { 6, 234, 2048 }, { 7, 235, 2048 }, { 6, 236, 2048 }, { 7, 237, 2048 }, { 7, 238, 2048 }, { 8, 239, 2048 }, + { 5, 240, 2048 }, { 6, 241, 2048 }, { 6, 242, 2048 }, { 7, 243, 2048 }, { 6, 244, 2048 }, { 7, 245, 2048 }, { 7, 246, 2048 }, { 8, 247, 2048 }, + { 6, 248, 2048 }, { 7, 249, 2048 }, { 7, 250, 2048 }, { 8, 251, 2048 }, { 7, 252, 2048 }, { 8, 253, 2048 }, { 8, 254, 2048 }, { 9, 255, 2048 }, + { 2, 256, 2048 }, { 3, 257, 2048 }, { 3, 258, 2048 }, { 4, 259, 2048 }, { 3, 260, 2048 }, { 4, 261, 2048 }, { 4, 262, 2048 }, { 5, 263, 2048 }, + { 3, 264, 2048 }, { 4, 265, 2048 }, { 4, 266, 2048 }, { 5, 267, 2048 }, { 4, 268, 2048 }, { 5, 269, 2048 }, { 5, 270, 2048 }, { 6, 271, 2048 }, + { 3, 272, 2048 }, { 4, 273, 2048 }, { 4, 274, 2048 }, { 5, 275, 2048 }, { 4, 276, 2048 }, { 5, 277, 2048 }, { 5, 278, 2048 }, { 6, 279, 2048 }, + { 4, 280, 2048 }, { 5, 281, 2048 }, { 5, 282, 2048 }, { 6, 283, 2048 }, { 5, 284, 2048 }, { 6, 285, 2048 }, { 6, 286, 2048 }, { 7, 287, 2048 }, + { 3, 288, 2048 }, { 4, 289, 2048 }, { 4, 290, 2048 }, { 5, 291, 2048 }, { 4, 292, 2048 }, { 5, 293, 2048 }, { 5, 294, 2048 }, { 6, 295, 2048 }, + { 4, 296, 2048 }, { 5, 297, 2048 }, { 5, 298, 2048 }, { 6, 299, 2048 }, { 5, 300, 2048 }, { 6, 301, 2048 }, { 6, 302, 2048 }, { 7, 303, 2048 }, + { 4, 304, 2048 }, { 5, 305, 2048 }, { 5, 306, 2048 }, { 6, 307, 2048 }, { 5, 308, 2048 }, { 6, 309, 2048 }, { 6, 310, 2048 }, { 7, 311, 2048 }, + { 5, 312, 2048 }, { 6, 313, 2048 }, { 6, 314, 2048 }, { 7, 315, 2048 }, { 6, 316, 2048 }, { 7, 317, 2048 }, { 7, 318, 2048 }, { 8, 319, 2048 }, + { 3, 320, 2048 }, { 4, 321, 2048 }, { 4, 322, 2048 }, { 5, 323, 2048 }, { 4, 324, 2048 }, { 5, 325, 2048 }, { 5, 326, 2048 }, { 6, 327, 2048 }, + { 4, 328, 2048 }, { 5, 329, 2048 }, { 5, 330, 2048 }, { 6, 331, 2048 }, { 5, 332, 2048 }, { 6, 333, 2048 }, { 6, 334, 2048 }, { 7, 335, 2048 }, + { 4, 336, 2048 }, { 5, 337, 2048 }, { 5, 338, 2048 }, { 6, 339, 2048 }, { 5, 340, 2048 }, { 6, 341, 2048 }, { 6, 342, 2048 }, { 7, 343, 2048 }, + { 5, 344, 2048 }, { 6, 345, 2048 }, { 6, 346, 2048 }, { 7, 347, 2048 }, { 6, 348, 2048 }, { 7, 349, 2048 }, { 7, 350, 2048 }, { 8, 351, 2048 }, + { 4, 352, 2048 }, { 5, 353, 2048 }, { 5, 354, 2048 }, { 6, 355, 2048 }, { 5, 356, 2048 }, { 6, 357, 2048 }, { 6, 358, 2048 }, { 7, 359, 2048 }, + { 5, 360, 2048 }, { 6, 361, 2048 }, { 6, 362, 2048 }, { 7, 363, 2048 }, { 6, 364, 2048 }, { 7, 365, 2048 }, { 7, 366, 2048 }, { 8, 367, 2048 }, + { 5, 368, 2048 }, { 6, 369, 2048 }, { 6, 370, 2048 }, { 7, 371, 2048 }, { 6, 372, 2048 }, { 7, 373, 2048 }, { 7, 374, 2048 }, { 8, 375, 2048 }, + { 6, 376, 2048 }, { 7, 377, 2048 }, { 7, 378, 2048 }, { 8, 379, 2048 }, { 7, 380, 2048 }, { 8, 381, 2048 }, { 8, 382, 2048 }, { 9, 383, 2048 }, + { 3, 384, 2048 }, { 4, 385, 2048 }, { 4, 386, 2048 }, { 5, 387, 2048 }, { 4, 388, 2048 }, { 5, 389, 2048 }, { 5, 390, 2048 }, { 6, 391, 2048 }, + { 4, 392, 2048 }, { 5, 393, 2048 }, { 5, 394, 2048 }, { 6, 395, 2048 }, { 5, 396, 2048 }, { 6, 397, 2048 }, { 6, 398, 2048 }, { 7, 399, 2048 }, + { 4, 400, 2048 }, { 5, 401, 2048 }, { 5, 402, 2048 }, { 6, 403, 2048 }, { 5, 404, 2048 }, { 6, 405, 2048 }, { 6, 406, 2048 }, { 7, 407, 2048 }, + { 5, 408, 2048 }, { 6, 409, 2048 }, { 6, 410, 2048 }, { 7, 411, 2048 }, { 6, 412, 2048 }, { 7, 413, 2048 }, { 7, 414, 2048 }, { 8, 415, 2048 }, + { 4, 416, 2048 }, { 5, 417, 2048 }, { 5, 418, 2048 }, { 6, 419, 2048 }, { 5, 420, 2048 }, { 6, 421, 2048 }, { 6, 422, 2048 }, { 7, 423, 2048 }, + { 5, 424, 2048 }, { 6, 425, 2048 }, { 6, 426, 2048 }, { 7, 427, 2048 }, { 6, 428, 2048 }, { 7, 429, 2048 }, { 7, 430, 2048 }, { 8, 431, 2048 }, + { 5, 432, 2048 }, { 6, 433, 2048 }, { 6, 434, 2048 }, { 7, 435, 2048 }, { 6, 436, 2048 }, { 7, 437, 2048 }, { 7, 438, 2048 }, { 8, 439, 2048 }, + { 6, 440, 2048 }, { 7, 441, 2048 }, { 7, 442, 2048 }, { 8, 443, 2048 }, { 7, 444, 2048 }, { 8, 445, 2048 }, { 8, 446, 2048 }, { 9, 447, 2048 }, + { 4, 448, 2048 }, { 5, 449, 2048 }, { 5, 450, 2048 }, { 6, 451, 2048 }, { 5, 452, 2048 }, { 6, 453, 2048 }, { 6, 454, 2048 }, { 7, 455, 2048 }, + { 5, 456, 2048 }, { 6, 457, 2048 }, { 6, 458, 2048 }, { 7, 459, 2048 }, { 6, 460, 2048 }, { 7, 461, 2048 }, { 7, 462, 2048 }, { 8, 463, 2048 }, + { 5, 464, 2048 }, { 6, 465, 2048 }, { 6, 466, 2048 }, { 7, 467, 2048 }, { 6, 468, 2048 }, { 7, 469, 2048 }, { 7, 470, 2048 }, { 8, 471, 2048 }, + { 6, 472, 2048 }, { 7, 473, 2048 }, { 7, 474, 2048 }, { 8, 475, 2048 }, { 7, 476, 2048 }, { 8, 477, 2048 }, { 8, 478, 2048 }, { 9, 479, 2048 }, + { 5, 480, 2048 }, { 6, 481, 2048 }, { 6, 482, 2048 }, { 7, 483, 2048 }, { 6, 484, 2048 }, { 7, 485, 2048 }, { 7, 486, 2048 }, { 8, 487, 2048 }, + { 6, 488, 2048 }, { 7, 489, 2048 }, { 7, 490, 2048 }, { 8, 491, 2048 }, { 7, 492, 2048 }, { 8, 493, 2048 }, { 8, 494, 2048 }, { 9, 495, 2048 }, + { 6, 496, 2048 }, { 7, 497, 2048 }, { 7, 498, 2048 }, { 8, 499, 2048 }, { 7, 500, 2048 }, { 8, 501, 2048 }, { 8, 502, 2048 }, { 9, 503, 2048 }, + { 7, 504, 2048 }, { 8, 505, 2048 }, { 8, 506, 2048 }, { 9, 507, 2048 }, { 8, 508, 2048 }, { 9, 509, 2048 }, { 9, 510, 2048 }, { 10, 511, 2048 }, + { 2, 512, 2048 }, { 3, 513, 2048 }, { 3, 514, 2048 }, { 4, 515, 2048 }, { 3, 516, 2048 }, { 4, 517, 2048 }, { 4, 518, 2048 }, { 5, 519, 2048 }, + { 3, 520, 2048 }, { 4, 521, 2048 }, { 4, 522, 2048 }, { 5, 523, 2048 }, { 4, 524, 2048 }, { 5, 525, 2048 }, { 5, 526, 2048 }, { 6, 527, 2048 }, + { 3, 528, 2048 }, { 4, 529, 2048 }, { 4, 530, 2048 }, { 5, 531, 2048 }, { 4, 532, 2048 }, { 5, 533, 2048 }, { 5, 534, 2048 }, { 6, 535, 2048 }, + { 4, 536, 2048 }, { 5, 537, 2048 }, { 5, 538, 2048 }, { 6, 539, 2048 }, { 5, 540, 2048 }, { 6, 541, 2048 }, { 6, 542, 2048 }, { 7, 543, 2048 }, + { 3, 544, 2048 }, { 4, 545, 2048 }, { 4, 546, 2048 }, { 5, 547, 2048 }, { 4, 548, 2048 }, { 5, 549, 2048 }, { 5, 550, 2048 }, { 6, 551, 2048 }, + { 4, 552, 2048 }, { 5, 553, 2048 }, { 5, 554, 2048 }, { 6, 555, 2048 }, { 5, 556, 2048 }, { 6, 557, 2048 }, { 6, 558, 2048 }, { 7, 559, 2048 }, + { 4, 560, 2048 }, { 5, 561, 2048 }, { 5, 562, 2048 }, { 6, 563, 2048 }, { 5, 564, 2048 }, { 6, 565, 2048 }, { 6, 566, 2048 }, { 7, 567, 2048 }, + { 5, 568, 2048 }, { 6, 569, 2048 }, { 6, 570, 2048 }, { 7, 571, 2048 }, { 6, 572, 2048 }, { 7, 573, 2048 }, { 7, 574, 2048 }, { 8, 575, 2048 }, + { 3, 576, 2048 }, { 4, 577, 2048 }, { 4, 578, 2048 }, { 5, 579, 2048 }, { 4, 580, 2048 }, { 5, 581, 2048 }, { 5, 582, 2048 }, { 6, 583, 2048 }, + { 4, 584, 2048 }, { 5, 585, 2048 }, { 5, 586, 2048 }, { 6, 587, 2048 }, { 5, 588, 2048 }, { 6, 589, 2048 }, { 6, 590, 2048 }, { 7, 591, 2048 }, + { 4, 592, 2048 }, { 5, 593, 2048 }, { 5, 594, 2048 }, { 6, 595, 2048 }, { 5, 596, 2048 }, { 6, 597, 2048 }, { 6, 598, 2048 }, { 7, 599, 2048 }, + { 5, 600, 2048 }, { 6, 601, 2048 }, { 6, 602, 2048 }, { 7, 603, 2048 }, { 6, 604, 2048 }, { 7, 605, 2048 }, { 7, 606, 2048 }, { 8, 607, 2048 }, + { 4, 608, 2048 }, { 5, 609, 2048 }, { 5, 610, 2048 }, { 6, 611, 2048 }, { 5, 612, 2048 }, { 6, 613, 2048 }, { 6, 614, 2048 }, { 7, 615, 2048 }, + { 5, 616, 2048 }, { 6, 617, 2048 }, { 6, 618, 2048 }, { 7, 619, 2048 }, { 6, 620, 2048 }, { 7, 621, 2048 }, { 7, 622, 2048 }, { 8, 623, 2048 }, + { 5, 624, 2048 }, { 6, 625, 2048 }, { 6, 626, 2048 }, { 7, 627, 2048 }, { 6, 628, 2048 }, { 7, 629, 2048 }, { 7, 630, 2048 }, { 8, 631, 2048 }, + { 6, 632, 2048 }, { 7, 633, 2048 }, { 7, 634, 2048 }, { 8, 635, 2048 }, { 7, 636, 2048 }, { 8, 637, 2048 }, { 8, 638, 2048 }, { 9, 639, 2048 }, + { 3, 640, 2048 }, { 4, 641, 2048 }, { 4, 642, 2048 }, { 5, 643, 2048 }, { 4, 644, 2048 }, { 5, 645, 2048 }, { 5, 646, 2048 }, { 6, 647, 2048 }, + { 4, 648, 2048 }, { 5, 649, 2048 }, { 5, 650, 2048 }, { 6, 651, 2048 }, { 5, 652, 2048 }, { 6, 653, 2048 }, { 6, 654, 2048 }, { 7, 655, 2048 }, + { 4, 656, 2048 }, { 5, 657, 2048 }, { 5, 658, 2048 }, { 6, 659, 2048 }, { 5, 660, 2048 }, { 6, 661, 2048 }, { 6, 662, 2048 }, { 7, 663, 2048 }, + { 5, 664, 2048 }, { 6, 665, 2048 }, { 6, 666, 2048 }, { 7, 667, 2048 }, { 6, 668, 2048 }, { 7, 669, 2048 }, { 7, 670, 2048 }, { 8, 671, 2048 }, + { 4, 672, 2048 }, { 5, 673, 2048 }, { 5, 674, 2048 }, { 6, 675, 2048 }, { 5, 676, 2048 }, { 6, 677, 2048 }, { 6, 678, 2048 }, { 7, 679, 2048 }, + { 5, 680, 2048 }, { 6, 681, 2048 }, { 6, 682, 2048 }, { 7, 683, 2048 }, { 6, 684, 2048 }, { 7, 685, 2048 }, { 7, 686, 2048 }, { 8, 687, 2048 }, + { 5, 688, 2048 }, { 6, 689, 2048 }, { 6, 690, 2048 }, { 7, 691, 2048 }, { 6, 692, 2048 }, { 7, 693, 2048 }, { 7, 694, 2048 }, { 8, 695, 2048 }, + { 6, 696, 2048 }, { 7, 697, 2048 }, { 7, 698, 2048 }, { 8, 699, 2048 }, { 7, 700, 2048 }, { 8, 701, 2048 }, { 8, 702, 2048 }, { 9, 703, 2048 }, + { 4, 704, 2048 }, { 5, 705, 2048 }, { 5, 706, 2048 }, { 6, 707, 2048 }, { 5, 708, 2048 }, { 6, 709, 2048 }, { 6, 710, 2048 }, { 7, 711, 2048 }, + { 5, 712, 2048 }, { 6, 713, 2048 }, { 6, 714, 2048 }, { 7, 715, 2048 }, { 6, 716, 2048 }, { 7, 717, 2048 }, { 7, 718, 2048 }, { 8, 719, 2048 }, + { 5, 720, 2048 }, { 6, 721, 2048 }, { 6, 722, 2048 }, { 7, 723, 2048 }, { 6, 724, 2048 }, { 7, 725, 2048 }, { 7, 726, 2048 }, { 8, 727, 2048 }, + { 6, 728, 2048 }, { 7, 729, 2048 }, { 7, 730, 2048 }, { 8, 731, 2048 }, { 7, 732, 2048 }, { 8, 733, 2048 }, { 8, 734, 2048 }, { 9, 735, 2048 }, + { 5, 736, 2048 }, { 6, 737, 2048 }, { 6, 738, 2048 }, { 7, 739, 2048 }, { 6, 740, 2048 }, { 7, 741, 2048 }, { 7, 742, 2048 }, { 8, 743, 2048 }, + { 6, 744, 2048 }, { 7, 745, 2048 }, { 7, 746, 2048 }, { 8, 747, 2048 }, { 7, 748, 2048 }, { 8, 749, 2048 }, { 8, 750, 2048 }, { 9, 751, 2048 }, + { 6, 752, 2048 }, { 7, 753, 2048 }, { 7, 754, 2048 }, { 8, 755, 2048 }, { 7, 756, 2048 }, { 8, 757, 2048 }, { 8, 758, 2048 }, { 9, 759, 2048 }, + { 7, 760, 2048 }, { 8, 761, 2048 }, { 8, 762, 2048 }, { 9, 763, 2048 }, { 8, 764, 2048 }, { 9, 765, 2048 }, { 9, 766, 2048 }, { 10, 767, 2048 }, + { 3, 768, 2048 }, { 4, 769, 2048 }, { 4, 770, 2048 }, { 5, 771, 2048 }, { 4, 772, 2048 }, { 5, 773, 2048 }, { 5, 774, 2048 }, { 6, 775, 2048 }, + { 4, 776, 2048 }, { 5, 777, 2048 }, { 5, 778, 2048 }, { 6, 779, 2048 }, { 5, 780, 2048 }, { 6, 781, 2048 }, { 6, 782, 2048 }, { 7, 783, 2048 }, + { 4, 784, 2048 }, { 5, 785, 2048 }, { 5, 786, 2048 }, { 6, 787, 2048 }, { 5, 788, 2048 }, { 6, 789, 2048 }, { 6, 790, 2048 }, { 7, 791, 2048 }, + { 5, 792, 2048 }, { 6, 793, 2048 }, { 6, 794, 2048 }, { 7, 795, 2048 }, { 6, 796, 2048 }, { 7, 797, 2048 }, { 7, 798, 2048 }, { 8, 799, 2048 }, + { 4, 800, 2048 }, { 5, 801, 2048 }, { 5, 802, 2048 }, { 6, 803, 2048 }, { 5, 804, 2048 }, { 6, 805, 2048 }, { 6, 806, 2048 }, { 7, 807, 2048 }, + { 5, 808, 2048 }, { 6, 809, 2048 }, { 6, 810, 2048 }, { 7, 811, 2048 }, { 6, 812, 2048 }, { 7, 813, 2048 }, { 7, 814, 2048 }, { 8, 815, 2048 }, + { 5, 816, 2048 }, { 6, 817, 2048 }, { 6, 818, 2048 }, { 7, 819, 2048 }, { 6, 820, 2048 }, { 7, 821, 2048 }, { 7, 822, 2048 }, { 8, 823, 2048 }, + { 6, 824, 2048 }, { 7, 825, 2048 }, { 7, 826, 2048 }, { 8, 827, 2048 }, { 7, 828, 2048 }, { 8, 829, 2048 }, { 8, 830, 2048 }, { 9, 831, 2048 }, + { 4, 832, 2048 }, { 5, 833, 2048 }, { 5, 834, 2048 }, { 6, 835, 2048 }, { 5, 836, 2048 }, { 6, 837, 2048 }, { 6, 838, 2048 }, { 7, 839, 2048 }, + { 5, 840, 2048 }, { 6, 841, 2048 }, { 6, 842, 2048 }, { 7, 843, 2048 }, { 6, 844, 2048 }, { 7, 845, 2048 }, { 7, 846, 2048 }, { 8, 847, 2048 }, + { 5, 848, 2048 }, { 6, 849, 2048 }, { 6, 850, 2048 }, { 7, 851, 2048 }, { 6, 852, 2048 }, { 7, 853, 2048 }, { 7, 854, 2048 }, { 8, 855, 2048 }, + { 6, 856, 2048 }, { 7, 857, 2048 }, { 7, 858, 2048 }, { 8, 859, 2048 }, { 7, 860, 2048 }, { 8, 861, 2048 }, { 8, 862, 2048 }, { 9, 863, 2048 }, + { 5, 864, 2048 }, { 6, 865, 2048 }, { 6, 866, 2048 }, { 7, 867, 2048 }, { 6, 868, 2048 }, { 7, 869, 2048 }, { 7, 870, 2048 }, { 8, 871, 2048 }, + { 6, 872, 2048 }, { 7, 873, 2048 }, { 7, 874, 2048 }, { 8, 875, 2048 }, { 7, 876, 2048 }, { 8, 877, 2048 }, { 8, 878, 2048 }, { 9, 879, 2048 }, + { 6, 880, 2048 }, { 7, 881, 2048 }, { 7, 882, 2048 }, { 8, 883, 2048 }, { 7, 884, 2048 }, { 8, 885, 2048 }, { 8, 886, 2048 }, { 9, 887, 2048 }, + { 7, 888, 2048 }, { 8, 889, 2048 }, { 8, 890, 2048 }, { 9, 891, 2048 }, { 8, 892, 2048 }, { 9, 893, 2048 }, { 9, 894, 2048 }, { 10, 895, 2048 }, + { 4, 896, 2048 }, { 5, 897, 2048 }, { 5, 898, 2048 }, { 6, 899, 2048 }, { 5, 900, 2048 }, { 6, 901, 2048 }, { 6, 902, 2048 }, { 7, 903, 2048 }, + { 5, 904, 2048 }, { 6, 905, 2048 }, { 6, 906, 2048 }, { 7, 907, 2048 }, { 6, 908, 2048 }, { 7, 909, 2048 }, { 7, 910, 2048 }, { 8, 911, 2048 }, + { 5, 912, 2048 }, { 6, 913, 2048 }, { 6, 914, 2048 }, { 7, 915, 2048 }, { 6, 916, 2048 }, { 7, 917, 2048 }, { 7, 918, 2048 }, { 8, 919, 2048 }, + { 6, 920, 2048 }, { 7, 921, 2048 }, { 7, 922, 2048 }, { 8, 923, 2048 }, { 7, 924, 2048 }, { 8, 925, 2048 }, { 8, 926, 2048 }, { 9, 927, 2048 }, + { 5, 928, 2048 }, { 6, 929, 2048 }, { 6, 930, 2048 }, { 7, 931, 2048 }, { 6, 932, 2048 }, { 7, 933, 2048 }, { 7, 934, 2048 }, { 8, 935, 2048 }, + { 6, 936, 2048 }, { 7, 937, 2048 }, { 7, 938, 2048 }, { 8, 939, 2048 }, { 7, 940, 2048 }, { 8, 941, 2048 }, { 8, 942, 2048 }, { 9, 943, 2048 }, + { 6, 944, 2048 }, { 7, 945, 2048 }, { 7, 946, 2048 }, { 8, 947, 2048 }, { 7, 948, 2048 }, { 8, 949, 2048 }, { 8, 950, 2048 }, { 9, 951, 2048 }, + { 7, 952, 2048 }, { 8, 953, 2048 }, { 8, 954, 2048 }, { 9, 955, 2048 }, { 8, 956, 2048 }, { 9, 957, 2048 }, { 9, 958, 2048 }, { 10, 959, 2048 }, + { 5, 960, 2048 }, { 6, 961, 2048 }, { 6, 962, 2048 }, { 7, 963, 2048 }, { 6, 964, 2048 }, { 7, 965, 2048 }, { 7, 966, 2048 }, { 8, 967, 2048 }, + { 6, 968, 2048 }, { 7, 969, 2048 }, { 7, 970, 2048 }, { 8, 971, 2048 }, { 7, 972, 2048 }, { 8, 973, 2048 }, { 8, 974, 2048 }, { 9, 975, 2048 }, + { 6, 976, 2048 }, { 7, 977, 2048 }, { 7, 978, 2048 }, { 8, 979, 2048 }, { 7, 980, 2048 }, { 8, 981, 2048 }, { 8, 982, 2048 }, { 9, 983, 2048 }, + { 7, 984, 2048 }, { 8, 985, 2048 }, { 8, 986, 2048 }, { 9, 987, 2048 }, { 8, 988, 2048 }, { 9, 989, 2048 }, { 9, 990, 2048 }, { 10, 991, 2048 }, + { 6, 992, 2048 }, { 7, 993, 2048 }, { 7, 994, 2048 }, { 8, 995, 2048 }, { 7, 996, 2048 }, { 8, 997, 2048 }, { 8, 998, 2048 }, { 9, 999, 2048 }, + { 7, 1000, 2048 }, { 8, 1001, 2048 }, { 8, 1002, 2048 }, { 9, 1003, 2048 }, { 8, 1004, 2048 }, { 9, 1005, 2048 }, { 9, 1006, 2048 }, { 10, 1007, 2048 }, + { 7, 1008, 2048 }, { 8, 1009, 2048 }, { 8, 1010, 2048 }, { 9, 1011, 2048 }, { 8, 1012, 2048 }, { 9, 1013, 2048 }, { 9, 1014, 2048 }, { 10, 1015, 2048 }, + { 8, 1016, 2048 }, { 9, 1017, 2048 }, { 9, 1018, 2048 }, { 10, 1019, 2048 }, { 9, 1020, 2048 }, { 10, 1021, 2048 }, { 10, 1022, 2048 }, { 11, 1023, 2048 }, + { 2, 1024, 2048 }, { 3, 1025, 2048 }, { 3, 1026, 2048 }, { 4, 1027, 2048 }, { 3, 1028, 2048 }, { 4, 1029, 2048 }, { 4, 1030, 2048 }, { 5, 1031, 2048 }, + { 3, 1032, 2048 }, { 4, 1033, 2048 }, { 4, 1034, 2048 }, { 5, 1035, 2048 }, { 4, 1036, 2048 }, { 5, 1037, 2048 }, { 5, 1038, 2048 }, { 6, 1039, 2048 }, + { 3, 1040, 2048 }, { 4, 1041, 2048 }, { 4, 1042, 2048 }, { 5, 1043, 2048 }, { 4, 1044, 2048 }, { 5, 1045, 2048 }, { 5, 1046, 2048 }, { 6, 1047, 2048 }, + { 4, 1048, 2048 }, { 5, 1049, 2048 }, { 5, 1050, 2048 }, { 6, 1051, 2048 }, { 5, 1052, 2048 }, { 6, 1053, 2048 }, { 6, 1054, 2048 }, { 7, 1055, 2048 }, + { 3, 1056, 2048 }, { 4, 1057, 2048 }, { 4, 1058, 2048 }, { 5, 1059, 2048 }, { 4, 1060, 2048 }, { 5, 1061, 2048 }, { 5, 1062, 2048 }, { 6, 1063, 2048 }, + { 4, 1064, 2048 }, { 5, 1065, 2048 }, { 5, 1066, 2048 }, { 6, 1067, 2048 }, { 5, 1068, 2048 }, { 6, 1069, 2048 }, { 6, 1070, 2048 }, { 7, 1071, 2048 }, + { 4, 1072, 2048 }, { 5, 1073, 2048 }, { 5, 1074, 2048 }, { 6, 1075, 2048 }, { 5, 1076, 2048 }, { 6, 1077, 2048 }, { 6, 1078, 2048 }, { 7, 1079, 2048 }, + { 5, 1080, 2048 }, { 6, 1081, 2048 }, { 6, 1082, 2048 }, { 7, 1083, 2048 }, { 6, 1084, 2048 }, { 7, 1085, 2048 }, { 7, 1086, 2048 }, { 8, 1087, 2048 }, + { 3, 1088, 2048 }, { 4, 1089, 2048 }, { 4, 1090, 2048 }, { 5, 1091, 2048 }, { 4, 1092, 2048 }, { 5, 1093, 2048 }, { 5, 1094, 2048 }, { 6, 1095, 2048 }, + { 4, 1096, 2048 }, { 5, 1097, 2048 }, { 5, 1098, 2048 }, { 6, 1099, 2048 }, { 5, 1100, 2048 }, { 6, 1101, 2048 }, { 6, 1102, 2048 }, { 7, 1103, 2048 }, + { 4, 1104, 2048 }, { 5, 1105, 2048 }, { 5, 1106, 2048 }, { 6, 1107, 2048 }, { 5, 1108, 2048 }, { 6, 1109, 2048 }, { 6, 1110, 2048 }, { 7, 1111, 2048 }, + { 5, 1112, 2048 }, { 6, 1113, 2048 }, { 6, 1114, 2048 }, { 7, 1115, 2048 }, { 6, 1116, 2048 }, { 7, 1117, 2048 }, { 7, 1118, 2048 }, { 8, 1119, 2048 }, + { 4, 1120, 2048 }, { 5, 1121, 2048 }, { 5, 1122, 2048 }, { 6, 1123, 2048 }, { 5, 1124, 2048 }, { 6, 1125, 2048 }, { 6, 1126, 2048 }, { 7, 1127, 2048 }, + { 5, 1128, 2048 }, { 6, 1129, 2048 }, { 6, 1130, 2048 }, { 7, 1131, 2048 }, { 6, 1132, 2048 }, { 7, 1133, 2048 }, { 7, 1134, 2048 }, { 8, 1135, 2048 }, + { 5, 1136, 2048 }, { 6, 1137, 2048 }, { 6, 1138, 2048 }, { 7, 1139, 2048 }, { 6, 1140, 2048 }, { 7, 1141, 2048 }, { 7, 1142, 2048 }, { 8, 1143, 2048 }, + { 6, 1144, 2048 }, { 7, 1145, 2048 }, { 7, 1146, 2048 }, { 8, 1147, 2048 }, { 7, 1148, 2048 }, { 8, 1149, 2048 }, { 8, 1150, 2048 }, { 9, 1151, 2048 }, + { 3, 1152, 2048 }, { 4, 1153, 2048 }, { 4, 1154, 2048 }, { 5, 1155, 2048 }, { 4, 1156, 2048 }, { 5, 1157, 2048 }, { 5, 1158, 2048 }, { 6, 1159, 2048 }, + { 4, 1160, 2048 }, { 5, 1161, 2048 }, { 5, 1162, 2048 }, { 6, 1163, 2048 }, { 5, 1164, 2048 }, { 6, 1165, 2048 }, { 6, 1166, 2048 }, { 7, 1167, 2048 }, + { 4, 1168, 2048 }, { 5, 1169, 2048 }, { 5, 1170, 2048 }, { 6, 1171, 2048 }, { 5, 1172, 2048 }, { 6, 1173, 2048 }, { 6, 1174, 2048 }, { 7, 1175, 2048 }, + { 5, 1176, 2048 }, { 6, 1177, 2048 }, { 6, 1178, 2048 }, { 7, 1179, 2048 }, { 6, 1180, 2048 }, { 7, 1181, 2048 }, { 7, 1182, 2048 }, { 8, 1183, 2048 }, + { 4, 1184, 2048 }, { 5, 1185, 2048 }, { 5, 1186, 2048 }, { 6, 1187, 2048 }, { 5, 1188, 2048 }, { 6, 1189, 2048 }, { 6, 1190, 2048 }, { 7, 1191, 2048 }, + { 5, 1192, 2048 }, { 6, 1193, 2048 }, { 6, 1194, 2048 }, { 7, 1195, 2048 }, { 6, 1196, 2048 }, { 7, 1197, 2048 }, { 7, 1198, 2048 }, { 8, 1199, 2048 }, + { 5, 1200, 2048 }, { 6, 1201, 2048 }, { 6, 1202, 2048 }, { 7, 1203, 2048 }, { 6, 1204, 2048 }, { 7, 1205, 2048 }, { 7, 1206, 2048 }, { 8, 1207, 2048 }, + { 6, 1208, 2048 }, { 7, 1209, 2048 }, { 7, 1210, 2048 }, { 8, 1211, 2048 }, { 7, 1212, 2048 }, { 8, 1213, 2048 }, { 8, 1214, 2048 }, { 9, 1215, 2048 }, + { 4, 1216, 2048 }, { 5, 1217, 2048 }, { 5, 1218, 2048 }, { 6, 1219, 2048 }, { 5, 1220, 2048 }, { 6, 1221, 2048 }, { 6, 1222, 2048 }, { 7, 1223, 2048 }, + { 5, 1224, 2048 }, { 6, 1225, 2048 }, { 6, 1226, 2048 }, { 7, 1227, 2048 }, { 6, 1228, 2048 }, { 7, 1229, 2048 }, { 7, 1230, 2048 }, { 8, 1231, 2048 }, + { 5, 1232, 2048 }, { 6, 1233, 2048 }, { 6, 1234, 2048 }, { 7, 1235, 2048 }, { 6, 1236, 2048 }, { 7, 1237, 2048 }, { 7, 1238, 2048 }, { 8, 1239, 2048 }, + { 6, 1240, 2048 }, { 7, 1241, 2048 }, { 7, 1242, 2048 }, { 8, 1243, 2048 }, { 7, 1244, 2048 }, { 8, 1245, 2048 }, { 8, 1246, 2048 }, { 9, 1247, 2048 }, + { 5, 1248, 2048 }, { 6, 1249, 2048 }, { 6, 1250, 2048 }, { 7, 1251, 2048 }, { 6, 1252, 2048 }, { 7, 1253, 2048 }, { 7, 1254, 2048 }, { 8, 1255, 2048 }, + { 6, 1256, 2048 }, { 7, 1257, 2048 }, { 7, 1258, 2048 }, { 8, 1259, 2048 }, { 7, 1260, 2048 }, { 8, 1261, 2048 }, { 8, 1262, 2048 }, { 9, 1263, 2048 }, + { 6, 1264, 2048 }, { 7, 1265, 2048 }, { 7, 1266, 2048 }, { 8, 1267, 2048 }, { 7, 1268, 2048 }, { 8, 1269, 2048 }, { 8, 1270, 2048 }, { 9, 1271, 2048 }, + { 7, 1272, 2048 }, { 8, 1273, 2048 }, { 8, 1274, 2048 }, { 9, 1275, 2048 }, { 8, 1276, 2048 }, { 9, 1277, 2048 }, { 9, 1278, 2048 }, { 10, 1279, 2048 }, + { 3, 1280, 2048 }, { 4, 1281, 2048 }, { 4, 1282, 2048 }, { 5, 1283, 2048 }, { 4, 1284, 2048 }, { 5, 1285, 2048 }, { 5, 1286, 2048 }, { 6, 1287, 2048 }, + { 4, 1288, 2048 }, { 5, 1289, 2048 }, { 5, 1290, 2048 }, { 6, 1291, 2048 }, { 5, 1292, 2048 }, { 6, 1293, 2048 }, { 6, 1294, 2048 }, { 7, 1295, 2048 }, + { 4, 1296, 2048 }, { 5, 1297, 2048 }, { 5, 1298, 2048 }, { 6, 1299, 2048 }, { 5, 1300, 2048 }, { 6, 1301, 2048 }, { 6, 1302, 2048 }, { 7, 1303, 2048 }, + { 5, 1304, 2048 }, { 6, 1305, 2048 }, { 6, 1306, 2048 }, { 7, 1307, 2048 }, { 6, 1308, 2048 }, { 7, 1309, 2048 }, { 7, 1310, 2048 }, { 8, 1311, 2048 }, + { 4, 1312, 2048 }, { 5, 1313, 2048 }, { 5, 1314, 2048 }, { 6, 1315, 2048 }, { 5, 1316, 2048 }, { 6, 1317, 2048 }, { 6, 1318, 2048 }, { 7, 1319, 2048 }, + { 5, 1320, 2048 }, { 6, 1321, 2048 }, { 6, 1322, 2048 }, { 7, 1323, 2048 }, { 6, 1324, 2048 }, { 7, 1325, 2048 }, { 7, 1326, 2048 }, { 8, 1327, 2048 }, + { 5, 1328, 2048 }, { 6, 1329, 2048 }, { 6, 1330, 2048 }, { 7, 1331, 2048 }, { 6, 1332, 2048 }, { 7, 1333, 2048 }, { 7, 1334, 2048 }, { 8, 1335, 2048 }, + { 6, 1336, 2048 }, { 7, 1337, 2048 }, { 7, 1338, 2048 }, { 8, 1339, 2048 }, { 7, 1340, 2048 }, { 8, 1341, 2048 }, { 8, 1342, 2048 }, { 9, 1343, 2048 }, + { 4, 1344, 2048 }, { 5, 1345, 2048 }, { 5, 1346, 2048 }, { 6, 1347, 2048 }, { 5, 1348, 2048 }, { 6, 1349, 2048 }, { 6, 1350, 2048 }, { 7, 1351, 2048 }, + { 5, 1352, 2048 }, { 6, 1353, 2048 }, { 6, 1354, 2048 }, { 7, 1355, 2048 }, { 6, 1356, 2048 }, { 7, 1357, 2048 }, { 7, 1358, 2048 }, { 8, 1359, 2048 }, + { 5, 1360, 2048 }, { 6, 1361, 2048 }, { 6, 1362, 2048 }, { 7, 1363, 2048 }, { 6, 1364, 2048 }, { 7, 1365, 2048 }, { 7, 1366, 2048 }, { 8, 1367, 2048 }, + { 6, 1368, 2048 }, { 7, 1369, 2048 }, { 7, 1370, 2048 }, { 8, 1371, 2048 }, { 7, 1372, 2048 }, { 8, 1373, 2048 }, { 8, 1374, 2048 }, { 9, 1375, 2048 }, + { 5, 1376, 2048 }, { 6, 1377, 2048 }, { 6, 1378, 2048 }, { 7, 1379, 2048 }, { 6, 1380, 2048 }, { 7, 1381, 2048 }, { 7, 1382, 2048 }, { 8, 1383, 2048 }, + { 6, 1384, 2048 }, { 7, 1385, 2048 }, { 7, 1386, 2048 }, { 8, 1387, 2048 }, { 7, 1388, 2048 }, { 8, 1389, 2048 }, { 8, 1390, 2048 }, { 9, 1391, 2048 }, + { 6, 1392, 2048 }, { 7, 1393, 2048 }, { 7, 1394, 2048 }, { 8, 1395, 2048 }, { 7, 1396, 2048 }, { 8, 1397, 2048 }, { 8, 1398, 2048 }, { 9, 1399, 2048 }, + { 7, 1400, 2048 }, { 8, 1401, 2048 }, { 8, 1402, 2048 }, { 9, 1403, 2048 }, { 8, 1404, 2048 }, { 9, 1405, 2048 }, { 9, 1406, 2048 }, { 10, 1407, 2048 }, + { 4, 1408, 2048 }, { 5, 1409, 2048 }, { 5, 1410, 2048 }, { 6, 1411, 2048 }, { 5, 1412, 2048 }, { 6, 1413, 2048 }, { 6, 1414, 2048 }, { 7, 1415, 2048 }, + { 5, 1416, 2048 }, { 6, 1417, 2048 }, { 6, 1418, 2048 }, { 7, 1419, 2048 }, { 6, 1420, 2048 }, { 7, 1421, 2048 }, { 7, 1422, 2048 }, { 8, 1423, 2048 }, + { 5, 1424, 2048 }, { 6, 1425, 2048 }, { 6, 1426, 2048 }, { 7, 1427, 2048 }, { 6, 1428, 2048 }, { 7, 1429, 2048 }, { 7, 1430, 2048 }, { 8, 1431, 2048 }, + { 6, 1432, 2048 }, { 7, 1433, 2048 }, { 7, 1434, 2048 }, { 8, 1435, 2048 }, { 7, 1436, 2048 }, { 8, 1437, 2048 }, { 8, 1438, 2048 }, { 9, 1439, 2048 }, + { 5, 1440, 2048 }, { 6, 1441, 2048 }, { 6, 1442, 2048 }, { 7, 1443, 2048 }, { 6, 1444, 2048 }, { 7, 1445, 2048 }, { 7, 1446, 2048 }, { 8, 1447, 2048 }, + { 6, 1448, 2048 }, { 7, 1449, 2048 }, { 7, 1450, 2048 }, { 8, 1451, 2048 }, { 7, 1452, 2048 }, { 8, 1453, 2048 }, { 8, 1454, 2048 }, { 9, 1455, 2048 }, + { 6, 1456, 2048 }, { 7, 1457, 2048 }, { 7, 1458, 2048 }, { 8, 1459, 2048 }, { 7, 1460, 2048 }, { 8, 1461, 2048 }, { 8, 1462, 2048 }, { 9, 1463, 2048 }, + { 7, 1464, 2048 }, { 8, 1465, 2048 }, { 8, 1466, 2048 }, { 9, 1467, 2048 }, { 8, 1468, 2048 }, { 9, 1469, 2048 }, { 9, 1470, 2048 }, { 10, 1471, 2048 }, + { 5, 1472, 2048 }, { 6, 1473, 2048 }, { 6, 1474, 2048 }, { 7, 1475, 2048 }, { 6, 1476, 2048 }, { 7, 1477, 2048 }, { 7, 1478, 2048 }, { 8, 1479, 2048 }, + { 6, 1480, 2048 }, { 7, 1481, 2048 }, { 7, 1482, 2048 }, { 8, 1483, 2048 }, { 7, 1484, 2048 }, { 8, 1485, 2048 }, { 8, 1486, 2048 }, { 9, 1487, 2048 }, + { 6, 1488, 2048 }, { 7, 1489, 2048 }, { 7, 1490, 2048 }, { 8, 1491, 2048 }, { 7, 1492, 2048 }, { 8, 1493, 2048 }, { 8, 1494, 2048 }, { 9, 1495, 2048 }, + { 7, 1496, 2048 }, { 8, 1497, 2048 }, { 8, 1498, 2048 }, { 9, 1499, 2048 }, { 8, 1500, 2048 }, { 9, 1501, 2048 }, { 9, 1502, 2048 }, { 10, 1503, 2048 }, + { 6, 1504, 2048 }, { 7, 1505, 2048 }, { 7, 1506, 2048 }, { 8, 1507, 2048 }, { 7, 1508, 2048 }, { 8, 1509, 2048 }, { 8, 1510, 2048 }, { 9, 1511, 2048 }, + { 7, 1512, 2048 }, { 8, 1513, 2048 }, { 8, 1514, 2048 }, { 9, 1515, 2048 }, { 8, 1516, 2048 }, { 9, 1517, 2048 }, { 9, 1518, 2048 }, { 10, 1519, 2048 }, + { 7, 1520, 2048 }, { 8, 1521, 2048 }, { 8, 1522, 2048 }, { 9, 1523, 2048 }, { 8, 1524, 2048 }, { 9, 1525, 2048 }, { 9, 1526, 2048 }, { 10, 1527, 2048 }, + { 8, 1528, 2048 }, { 9, 1529, 2048 }, { 9, 1530, 2048 }, { 10, 1531, 2048 }, { 9, 1532, 2048 }, { 10, 1533, 2048 }, { 10, 1534, 2048 }, { 11, 1535, 2048 }, + { 3, 1536, 2048 }, { 4, 1537, 2048 }, { 4, 1538, 2048 }, { 5, 1539, 2048 }, { 4, 1540, 2048 }, { 5, 1541, 2048 }, { 5, 1542, 2048 }, { 6, 1543, 2048 }, + { 4, 1544, 2048 }, { 5, 1545, 2048 }, { 5, 1546, 2048 }, { 6, 1547, 2048 }, { 5, 1548, 2048 }, { 6, 1549, 2048 }, { 6, 1550, 2048 }, { 7, 1551, 2048 }, + { 4, 1552, 2048 }, { 5, 1553, 2048 }, { 5, 1554, 2048 }, { 6, 1555, 2048 }, { 5, 1556, 2048 }, { 6, 1557, 2048 }, { 6, 1558, 2048 }, { 7, 1559, 2048 }, + { 5, 1560, 2048 }, { 6, 1561, 2048 }, { 6, 1562, 2048 }, { 7, 1563, 2048 }, { 6, 1564, 2048 }, { 7, 1565, 2048 }, { 7, 1566, 2048 }, { 8, 1567, 2048 }, + { 4, 1568, 2048 }, { 5, 1569, 2048 }, { 5, 1570, 2048 }, { 6, 1571, 2048 }, { 5, 1572, 2048 }, { 6, 1573, 2048 }, { 6, 1574, 2048 }, { 7, 1575, 2048 }, + { 5, 1576, 2048 }, { 6, 1577, 2048 }, { 6, 1578, 2048 }, { 7, 1579, 2048 }, { 6, 1580, 2048 }, { 7, 1581, 2048 }, { 7, 1582, 2048 }, { 8, 1583, 2048 }, + { 5, 1584, 2048 }, { 6, 1585, 2048 }, { 6, 1586, 2048 }, { 7, 1587, 2048 }, { 6, 1588, 2048 }, { 7, 1589, 2048 }, { 7, 1590, 2048 }, { 8, 1591, 2048 }, + { 6, 1592, 2048 }, { 7, 1593, 2048 }, { 7, 1594, 2048 }, { 8, 1595, 2048 }, { 7, 1596, 2048 }, { 8, 1597, 2048 }, { 8, 1598, 2048 }, { 9, 1599, 2048 }, + { 4, 1600, 2048 }, { 5, 1601, 2048 }, { 5, 1602, 2048 }, { 6, 1603, 2048 }, { 5, 1604, 2048 }, { 6, 1605, 2048 }, { 6, 1606, 2048 }, { 7, 1607, 2048 }, + { 5, 1608, 2048 }, { 6, 1609, 2048 }, { 6, 1610, 2048 }, { 7, 1611, 2048 }, { 6, 1612, 2048 }, { 7, 1613, 2048 }, { 7, 1614, 2048 }, { 8, 1615, 2048 }, + { 5, 1616, 2048 }, { 6, 1617, 2048 }, { 6, 1618, 2048 }, { 7, 1619, 2048 }, { 6, 1620, 2048 }, { 7, 1621, 2048 }, { 7, 1622, 2048 }, { 8, 1623, 2048 }, + { 6, 1624, 2048 }, { 7, 1625, 2048 }, { 7, 1626, 2048 }, { 8, 1627, 2048 }, { 7, 1628, 2048 }, { 8, 1629, 2048 }, { 8, 1630, 2048 }, { 9, 1631, 2048 }, + { 5, 1632, 2048 }, { 6, 1633, 2048 }, { 6, 1634, 2048 }, { 7, 1635, 2048 }, { 6, 1636, 2048 }, { 7, 1637, 2048 }, { 7, 1638, 2048 }, { 8, 1639, 2048 }, + { 6, 1640, 2048 }, { 7, 1641, 2048 }, { 7, 1642, 2048 }, { 8, 1643, 2048 }, { 7, 1644, 2048 }, { 8, 1645, 2048 }, { 8, 1646, 2048 }, { 9, 1647, 2048 }, + { 6, 1648, 2048 }, { 7, 1649, 2048 }, { 7, 1650, 2048 }, { 8, 1651, 2048 }, { 7, 1652, 2048 }, { 8, 1653, 2048 }, { 8, 1654, 2048 }, { 9, 1655, 2048 }, + { 7, 1656, 2048 }, { 8, 1657, 2048 }, { 8, 1658, 2048 }, { 9, 1659, 2048 }, { 8, 1660, 2048 }, { 9, 1661, 2048 }, { 9, 1662, 2048 }, { 10, 1663, 2048 }, + { 4, 1664, 2048 }, { 5, 1665, 2048 }, { 5, 1666, 2048 }, { 6, 1667, 2048 }, { 5, 1668, 2048 }, { 6, 1669, 2048 }, { 6, 1670, 2048 }, { 7, 1671, 2048 }, + { 5, 1672, 2048 }, { 6, 1673, 2048 }, { 6, 1674, 2048 }, { 7, 1675, 2048 }, { 6, 1676, 2048 }, { 7, 1677, 2048 }, { 7, 1678, 2048 }, { 8, 1679, 2048 }, + { 5, 1680, 2048 }, { 6, 1681, 2048 }, { 6, 1682, 2048 }, { 7, 1683, 2048 }, { 6, 1684, 2048 }, { 7, 1685, 2048 }, { 7, 1686, 2048 }, { 8, 1687, 2048 }, + { 6, 1688, 2048 }, { 7, 1689, 2048 }, { 7, 1690, 2048 }, { 8, 1691, 2048 }, { 7, 1692, 2048 }, { 8, 1693, 2048 }, { 8, 1694, 2048 }, { 9, 1695, 2048 }, + { 5, 1696, 2048 }, { 6, 1697, 2048 }, { 6, 1698, 2048 }, { 7, 1699, 2048 }, { 6, 1700, 2048 }, { 7, 1701, 2048 }, { 7, 1702, 2048 }, { 8, 1703, 2048 }, + { 6, 1704, 2048 }, { 7, 1705, 2048 }, { 7, 1706, 2048 }, { 8, 1707, 2048 }, { 7, 1708, 2048 }, { 8, 1709, 2048 }, { 8, 1710, 2048 }, { 9, 1711, 2048 }, + { 6, 1712, 2048 }, { 7, 1713, 2048 }, { 7, 1714, 2048 }, { 8, 1715, 2048 }, { 7, 1716, 2048 }, { 8, 1717, 2048 }, { 8, 1718, 2048 }, { 9, 1719, 2048 }, + { 7, 1720, 2048 }, { 8, 1721, 2048 }, { 8, 1722, 2048 }, { 9, 1723, 2048 }, { 8, 1724, 2048 }, { 9, 1725, 2048 }, { 9, 1726, 2048 }, { 10, 1727, 2048 }, + { 5, 1728, 2048 }, { 6, 1729, 2048 }, { 6, 1730, 2048 }, { 7, 1731, 2048 }, { 6, 1732, 2048 }, { 7, 1733, 2048 }, { 7, 1734, 2048 }, { 8, 1735, 2048 }, + { 6, 1736, 2048 }, { 7, 1737, 2048 }, { 7, 1738, 2048 }, { 8, 1739, 2048 }, { 7, 1740, 2048 }, { 8, 1741, 2048 }, { 8, 1742, 2048 }, { 9, 1743, 2048 }, + { 6, 1744, 2048 }, { 7, 1745, 2048 }, { 7, 1746, 2048 }, { 8, 1747, 2048 }, { 7, 1748, 2048 }, { 8, 1749, 2048 }, { 8, 1750, 2048 }, { 9, 1751, 2048 }, + { 7, 1752, 2048 }, { 8, 1753, 2048 }, { 8, 1754, 2048 }, { 9, 1755, 2048 }, { 8, 1756, 2048 }, { 9, 1757, 2048 }, { 9, 1758, 2048 }, { 10, 1759, 2048 }, + { 6, 1760, 2048 }, { 7, 1761, 2048 }, { 7, 1762, 2048 }, { 8, 1763, 2048 }, { 7, 1764, 2048 }, { 8, 1765, 2048 }, { 8, 1766, 2048 }, { 9, 1767, 2048 }, + { 7, 1768, 2048 }, { 8, 1769, 2048 }, { 8, 1770, 2048 }, { 9, 1771, 2048 }, { 8, 1772, 2048 }, { 9, 1773, 2048 }, { 9, 1774, 2048 }, { 10, 1775, 2048 }, + { 7, 1776, 2048 }, { 8, 1777, 2048 }, { 8, 1778, 2048 }, { 9, 1779, 2048 }, { 8, 1780, 2048 }, { 9, 1781, 2048 }, { 9, 1782, 2048 }, { 10, 1783, 2048 }, + { 8, 1784, 2048 }, { 9, 1785, 2048 }, { 9, 1786, 2048 }, { 10, 1787, 2048 }, { 9, 1788, 2048 }, { 10, 1789, 2048 }, { 10, 1790, 2048 }, { 11, 1791, 2048 }, + { 4, 1792, 2048 }, { 5, 1793, 2048 }, { 5, 1794, 2048 }, { 6, 1795, 2048 }, { 5, 1796, 2048 }, { 6, 1797, 2048 }, { 6, 1798, 2048 }, { 7, 1799, 2048 }, + { 5, 1800, 2048 }, { 6, 1801, 2048 }, { 6, 1802, 2048 }, { 7, 1803, 2048 }, { 6, 1804, 2048 }, { 7, 1805, 2048 }, { 7, 1806, 2048 }, { 8, 1807, 2048 }, + { 5, 1808, 2048 }, { 6, 1809, 2048 }, { 6, 1810, 2048 }, { 7, 1811, 2048 }, { 6, 1812, 2048 }, { 7, 1813, 2048 }, { 7, 1814, 2048 }, { 8, 1815, 2048 }, + { 6, 1816, 2048 }, { 7, 1817, 2048 }, { 7, 1818, 2048 }, { 8, 1819, 2048 }, { 7, 1820, 2048 }, { 8, 1821, 2048 }, { 8, 1822, 2048 }, { 9, 1823, 2048 }, + { 5, 1824, 2048 }, { 6, 1825, 2048 }, { 6, 1826, 2048 }, { 7, 1827, 2048 }, { 6, 1828, 2048 }, { 7, 1829, 2048 }, { 7, 1830, 2048 }, { 8, 1831, 2048 }, + { 6, 1832, 2048 }, { 7, 1833, 2048 }, { 7, 1834, 2048 }, { 8, 1835, 2048 }, { 7, 1836, 2048 }, { 8, 1837, 2048 }, { 8, 1838, 2048 }, { 9, 1839, 2048 }, + { 6, 1840, 2048 }, { 7, 1841, 2048 }, { 7, 1842, 2048 }, { 8, 1843, 2048 }, { 7, 1844, 2048 }, { 8, 1845, 2048 }, { 8, 1846, 2048 }, { 9, 1847, 2048 }, + { 7, 1848, 2048 }, { 8, 1849, 2048 }, { 8, 1850, 2048 }, { 9, 1851, 2048 }, { 8, 1852, 2048 }, { 9, 1853, 2048 }, { 9, 1854, 2048 }, { 10, 1855, 2048 }, + { 5, 1856, 2048 }, { 6, 1857, 2048 }, { 6, 1858, 2048 }, { 7, 1859, 2048 }, { 6, 1860, 2048 }, { 7, 1861, 2048 }, { 7, 1862, 2048 }, { 8, 1863, 2048 }, + { 6, 1864, 2048 }, { 7, 1865, 2048 }, { 7, 1866, 2048 }, { 8, 1867, 2048 }, { 7, 1868, 2048 }, { 8, 1869, 2048 }, { 8, 1870, 2048 }, { 9, 1871, 2048 }, + { 6, 1872, 2048 }, { 7, 1873, 2048 }, { 7, 1874, 2048 }, { 8, 1875, 2048 }, { 7, 1876, 2048 }, { 8, 1877, 2048 }, { 8, 1878, 2048 }, { 9, 1879, 2048 }, + { 7, 1880, 2048 }, { 8, 1881, 2048 }, { 8, 1882, 2048 }, { 9, 1883, 2048 }, { 8, 1884, 2048 }, { 9, 1885, 2048 }, { 9, 1886, 2048 }, { 10, 1887, 2048 }, + { 6, 1888, 2048 }, { 7, 1889, 2048 }, { 7, 1890, 2048 }, { 8, 1891, 2048 }, { 7, 1892, 2048 }, { 8, 1893, 2048 }, { 8, 1894, 2048 }, { 9, 1895, 2048 }, + { 7, 1896, 2048 }, { 8, 1897, 2048 }, { 8, 1898, 2048 }, { 9, 1899, 2048 }, { 8, 1900, 2048 }, { 9, 1901, 2048 }, { 9, 1902, 2048 }, { 10, 1903, 2048 }, + { 7, 1904, 2048 }, { 8, 1905, 2048 }, { 8, 1906, 2048 }, { 9, 1907, 2048 }, { 8, 1908, 2048 }, { 9, 1909, 2048 }, { 9, 1910, 2048 }, { 10, 1911, 2048 }, + { 8, 1912, 2048 }, { 9, 1913, 2048 }, { 9, 1914, 2048 }, { 10, 1915, 2048 }, { 9, 1916, 2048 }, { 10, 1917, 2048 }, { 10, 1918, 2048 }, { 11, 1919, 2048 }, + { 5, 1920, 2048 }, { 6, 1921, 2048 }, { 6, 1922, 2048 }, { 7, 1923, 2048 }, { 6, 1924, 2048 }, { 7, 1925, 2048 }, { 7, 1926, 2048 }, { 8, 1927, 2048 }, + { 6, 1928, 2048 }, { 7, 1929, 2048 }, { 7, 1930, 2048 }, { 8, 1931, 2048 }, { 7, 1932, 2048 }, { 8, 1933, 2048 }, { 8, 1934, 2048 }, { 9, 1935, 2048 }, + { 6, 1936, 2048 }, { 7, 1937, 2048 }, { 7, 1938, 2048 }, { 8, 1939, 2048 }, { 7, 1940, 2048 }, { 8, 1941, 2048 }, { 8, 1942, 2048 }, { 9, 1943, 2048 }, + { 7, 1944, 2048 }, { 8, 1945, 2048 }, { 8, 1946, 2048 }, { 9, 1947, 2048 }, { 8, 1948, 2048 }, { 9, 1949, 2048 }, { 9, 1950, 2048 }, { 10, 1951, 2048 }, + { 6, 1952, 2048 }, { 7, 1953, 2048 }, { 7, 1954, 2048 }, { 8, 1955, 2048 }, { 7, 1956, 2048 }, { 8, 1957, 2048 }, { 8, 1958, 2048 }, { 9, 1959, 2048 }, + { 7, 1960, 2048 }, { 8, 1961, 2048 }, { 8, 1962, 2048 }, { 9, 1963, 2048 }, { 8, 1964, 2048 }, { 9, 1965, 2048 }, { 9, 1966, 2048 }, { 10, 1967, 2048 }, + { 7, 1968, 2048 }, { 8, 1969, 2048 }, { 8, 1970, 2048 }, { 9, 1971, 2048 }, { 8, 1972, 2048 }, { 9, 1973, 2048 }, { 9, 1974, 2048 }, { 10, 1975, 2048 }, + { 8, 1976, 2048 }, { 9, 1977, 2048 }, { 9, 1978, 2048 }, { 10, 1979, 2048 }, { 9, 1980, 2048 }, { 10, 1981, 2048 }, { 10, 1982, 2048 }, { 11, 1983, 2048 }, + { 6, 1984, 2048 }, { 7, 1985, 2048 }, { 7, 1986, 2048 }, { 8, 1987, 2048 }, { 7, 1988, 2048 }, { 8, 1989, 2048 }, { 8, 1990, 2048 }, { 9, 1991, 2048 }, + { 7, 1992, 2048 }, { 8, 1993, 2048 }, { 8, 1994, 2048 }, { 9, 1995, 2048 }, { 8, 1996, 2048 }, { 9, 1997, 2048 }, { 9, 1998, 2048 }, { 10, 1999, 2048 }, + { 7, 2000, 2048 }, { 8, 2001, 2048 }, { 8, 2002, 2048 }, { 9, 2003, 2048 }, { 8, 2004, 2048 }, { 9, 2005, 2048 }, { 9, 2006, 2048 }, { 10, 2007, 2048 }, + { 8, 2008, 2048 }, { 9, 2009, 2048 }, { 9, 2010, 2048 }, { 10, 2011, 2048 }, { 9, 2012, 2048 }, { 10, 2013, 2048 }, { 10, 2014, 2048 }, { 11, 2015, 2048 }, + { 7, 2016, 2048 }, { 8, 2017, 2048 }, { 8, 2018, 2048 }, { 9, 2019, 2048 }, { 8, 2020, 2048 }, { 9, 2021, 2048 }, { 9, 2022, 2048 }, { 10, 2023, 2048 }, + { 8, 2024, 2048 }, { 9, 2025, 2048 }, { 9, 2026, 2048 }, { 10, 2027, 2048 }, { 9, 2028, 2048 }, { 10, 2029, 2048 }, { 10, 2030, 2048 }, { 11, 2031, 2048 }, + { 8, 2032, 2048 }, { 9, 2033, 2048 }, { 9, 2034, 2048 }, { 10, 2035, 2048 }, { 9, 2036, 2048 }, { 10, 2037, 2048 }, { 10, 2038, 2048 }, { 11, 2039, 2048 }, + { 9, 2040, 2048 }, { 10, 2041, 2048 }, { 10, 2042, 2048 }, { 11, 2043, 2048 }, { 10, 2044, 2048 }, { 11, 2045, 2048 }, { 11, 2046, 2048 }, { 12, 2047, 2048 }, +#endif +#endif +#endif +#endif +#endif +#endif +}; + +/* find a hole and free as required, return -1 if no hole found */ +static int find_hole(void) +{ + unsigned x; + int y, z; + for (z = -1, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) { + if (fp_cache[x].lru_count < y && fp_cache[x].lock == 0) { + z = x; + y = fp_cache[x].lru_count; + } + } + + /* decrease all */ + for (x = 0; x < FP_ENTRIES; x++) { + if (fp_cache[x].lru_count > 3) { + --(fp_cache[x].lru_count); + } + } + + /* free entry z */ + if (z >= 0 && fp_cache[z].g) { + if (fp_cache[z].mu != NULL) { + mp_clear(fp_cache[z].mu); + fp_cache[z].mu = NULL; + } + ltc_ecc_del_point(fp_cache[z].g); + fp_cache[z].g = NULL; + for (x = 0; x < (1U<x, g->x) == LTC_MP_EQ && + mp_cmp(fp_cache[x].g->y, g->y) == LTC_MP_EQ && + mp_cmp(fp_cache[x].g->z, g->z) == LTC_MP_EQ) { + break; + } + } + if (x == FP_ENTRIES) { + x = -1; + } + return x; +} + +/* add a new base to the cache */ +static int add_entry(int idx, ecc_point *g) +{ + unsigned x, y; + + /* allocate base and LUT */ + fp_cache[idx].g = ltc_ecc_new_point(); + if (fp_cache[idx].g == NULL) { + return CRYPT_MEM; + } + + /* copy x and y */ + if ((mp_copy(g->x, fp_cache[idx].g->x) != CRYPT_OK) || + (mp_copy(g->y, fp_cache[idx].g->y) != CRYPT_OK) || + (mp_copy(g->z, fp_cache[idx].g->z) != CRYPT_OK)) { + ltc_ecc_del_point(fp_cache[idx].g); + fp_cache[idx].g = NULL; + return CRYPT_MEM; + } + + for (x = 0; x < (1U<x, mu, modulus, fp_cache[idx].LUT[1]->x) != CRYPT_OK) || + (mp_mulmod(fp_cache[idx].g->y, mu, modulus, fp_cache[idx].LUT[1]->y) != CRYPT_OK) || + (mp_mulmod(fp_cache[idx].g->z, mu, modulus, fp_cache[idx].LUT[1]->z) != CRYPT_OK)) { goto ERR; } + + /* make all single bit entries */ + for (x = 1; x < FP_LUT; x++) { + if ((mp_copy(fp_cache[idx].LUT[1<<(x-1)]->x, fp_cache[idx].LUT[1<x) != CRYPT_OK) || + (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->y, fp_cache[idx].LUT[1<y) != CRYPT_OK) || + (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->z, fp_cache[idx].LUT[1<z) != CRYPT_OK)) { goto ERR; } + + /* now double it bitlen/FP_LUT times */ + for (y = 0; y < lut_gap; y++) { + if ((err = ltc_mp.ecc_ptdbl(fp_cache[idx].LUT[1<z, modulus, mp)) != CRYPT_OK) { goto ERR; } + + /* invert it */ + if ((err = mp_invmod(fp_cache[idx].LUT[x]->z, modulus, fp_cache[idx].LUT[x]->z)) != CRYPT_OK) { goto ERR; } + + /* now square it */ + if ((err = mp_sqrmod(fp_cache[idx].LUT[x]->z, modulus, tmp)) != CRYPT_OK) { goto ERR; } + + /* fix x */ + if ((err = mp_mulmod(fp_cache[idx].LUT[x]->x, tmp, modulus, fp_cache[idx].LUT[x]->x)) != CRYPT_OK) { goto ERR; } + + /* get 1/z^3 */ + if ((err = mp_mulmod(tmp, fp_cache[idx].LUT[x]->z, modulus, tmp)) != CRYPT_OK) { goto ERR; } + + /* fix y */ + if ((err = mp_mulmod(fp_cache[idx].LUT[x]->y, tmp, modulus, fp_cache[idx].LUT[x]->y)) != CRYPT_OK) { goto ERR; } + + /* free z */ + mp_clear(fp_cache[idx].LUT[x]->z); + fp_cache[idx].LUT[x]->z = NULL; + } + mp_clear(tmp); + + return CRYPT_OK; +ERR: + err = CRYPT_MEM; +DONE: + for (y = 0; y < (1U< mp_unsigned_bin_size(modulus)) { + /* find order */ + y = mp_unsigned_bin_size(modulus); + for (x = 0; ltc_ecc_sets[x].size; x++) { + if (y <= (unsigned)ltc_ecc_sets[x].size) break; + } + + /* back off if we are on the 521 bit curve */ + if (y == 66) --x; + + if ((err = mp_init(&order)) != CRYPT_OK) { + return err; + } + if ((err = mp_read_radix(order, ltc_ecc_sets[x].order, 16)) != CRYPT_OK) { + mp_clear(&order); + return err; + } + + /* k must be less than modulus */ + if (mp_cmp(k, order) != LTC_MP_LT) { + if ((err = mp_init(&tk)) != CRYPT_OK) { + mp_clear(order); + return err; + } + if ((err = mp_mod(k, order, tk)) != CRYPT_OK) { + mp_clear(tk); + mp_clear(order); + return err; + } + } else { + tk = k; + } + mp_clear(order); + } else { + tk = k; + } + + /* get bitlen and round up to next multiple of FP_LUT */ + bitlen = mp_unsigned_bin_size(modulus) << 3; + x = bitlen % FP_LUT; + if (x) { + bitlen += FP_LUT - x; + } + lut_gap = bitlen / FP_LUT; + + /* get the k value */ + if (mp_unsigned_bin_size(tk) > (sizeof(kb) - 2)) { + if (tk != k) { + mp_clear(tk); + } + return CRYPT_BUFFER_OVERFLOW; + } + + /* store k */ + zeromem(kb, sizeof(kb)); + if ((err = mp_to_unsigned_bin(tk, kb)) != CRYPT_OK) { + if (tk != k) { + mp_clear(tk); + } + return err; + } + + /* let's reverse kb so it's little endian */ + x = 0; + y = mp_unsigned_bin_size(tk) - 1; + if (tk != k) { + mp_clear(tk); + } + while ((unsigned)x < y) { + z = kb[x]; kb[x] = kb[y]; kb[y] = z; + ++x; --y; + } + + /* at this point we can start, yipee */ + first = 1; + for (x = lut_gap-1; x >= 0; x--) { + /* extract FP_LUT bits from kb spread out by lut_gap bits and offset by x bits from the start */ + bitpos = x; + for (y = z = 0; y < FP_LUT; y++) { + z |= ((kb[bitpos>>3] >> (bitpos&7)) & 1) << y; + bitpos += lut_gap; /* it's y*lut_gap + x, but here we can avoid the mult in each loop */ + } + + /* double if not first */ + if (!first) { + if ((err = ltc_mp.ecc_ptdbl(R, R, a, modulus, mp)) != CRYPT_OK) { + return err; + } + } + + /* add if not first, otherwise copy */ + if (!first && z) { + if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx].LUT[z], R, a, modulus, mp)) != CRYPT_OK) { + return err; + } + } else if (z) { + if ((mp_copy(fp_cache[idx].LUT[z]->x, R->x) != CRYPT_OK) || + (mp_copy(fp_cache[idx].LUT[z]->y, R->y) != CRYPT_OK) || + (mp_copy(fp_cache[idx].mu, R->z) != CRYPT_OK)) { return CRYPT_MEM; } + first = 0; + } + } + z = 0; + zeromem(kb, sizeof(kb)); + /* map R back from projective space */ + if (map) { + err = ltc_ecc_map(R, modulus, mp); + } else { + err = CRYPT_OK; + } + return err; +} + +#ifdef LTC_ECC_SHAMIR +/* perform a fixed point ECC mulmod */ +static int accel_fp_mul2add(int idx1, int idx2, + void *kA, void *kB, + ecc_point *R, void *a, void *modulus, void *mp) +{ + unsigned char kb[2][128]; + int x; + unsigned y, z, err, bitlen, bitpos, lut_gap, first, zA, zB; + void *tka, *tkb, *order; + + /* if it's smaller than modulus we fine */ + if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) { + /* find order */ + y = mp_unsigned_bin_size(modulus); + for (x = 0; ltc_ecc_sets[x].size; x++) { + if (y <= (unsigned)ltc_ecc_sets[x].size) break; + } + + /* back off if we are on the 521 bit curve */ + if (y == 66) --x; + + if ((err = mp_init(&order)) != CRYPT_OK) { + return err; + } + if ((err = mp_read_radix(order, ltc_ecc_sets[x].order, 16)) != CRYPT_OK) { + mp_clear(&order); + return err; + } + + /* kA must be less than modulus */ + if (mp_cmp(kA, order) != LTC_MP_LT) { + if ((err = mp_init(&tka)) != CRYPT_OK) { + mp_clear(order); + return err; + } + if ((err = mp_mod(kA, order, tka)) != CRYPT_OK) { + mp_clear(tka); + mp_clear(order); + return err; + } + } else { + tka = kA; + } + mp_clear(order); + } else { + tka = kA; + } + + /* if it's smaller than modulus we fine */ + if (mp_unsigned_bin_size(kB) > mp_unsigned_bin_size(modulus)) { + /* find order */ + y = mp_unsigned_bin_size(modulus); + for (x = 0; ltc_ecc_sets[x].size; x++) { + if (y <= (unsigned)ltc_ecc_sets[x].size) break; + } + + /* back off if we are on the 521 bit curve */ + if (y == 66) --x; + + if ((err = mp_init(&order)) != CRYPT_OK) { + return err; + } + if ((err = mp_read_radix(order, ltc_ecc_sets[x].order, 16)) != CRYPT_OK) { + mp_clear(&order); + return err; + } + + /* kB must be less than modulus */ + if (mp_cmp(kB, order) != LTC_MP_LT) { + if ((err = mp_init(&tkb)) != CRYPT_OK) { + mp_clear(order); + return err; + } + if ((err = mp_mod(kB, order, tkb)) != CRYPT_OK) { + mp_clear(tkb); + mp_clear(order); + return err; + } + } else { + tkb = kB; + } + mp_clear(order); + } else { + tkb = kB; + } + + /* get bitlen and round up to next multiple of FP_LUT */ + bitlen = mp_unsigned_bin_size(modulus) << 3; + x = bitlen % FP_LUT; + if (x) { + bitlen += FP_LUT - x; + } + lut_gap = bitlen / FP_LUT; + + /* get the k value */ + if ((mp_unsigned_bin_size(tka) > (sizeof(kb[0]) - 2)) || (mp_unsigned_bin_size(tkb) > (sizeof(kb[0]) - 2)) ) { + if (tka != kA) { + mp_clear(tka); + } + if (tkb != kB) { + mp_clear(tkb); + } + return CRYPT_BUFFER_OVERFLOW; + } + + /* store k */ + zeromem(kb, sizeof(kb)); + if ((err = mp_to_unsigned_bin(tka, kb[0])) != CRYPT_OK) { + if (tka != kA) { + mp_clear(tka); + } + if (tkb != kB) { + mp_clear(tkb); + } + return err; + } + + /* let's reverse kb so it's little endian */ + x = 0; + y = mp_unsigned_bin_size(tka) - 1; + if (tka != kA) { + mp_clear(tka); + } + while ((unsigned)x < y) { + z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = z; + ++x; --y; + } + + /* store b */ + if ((err = mp_to_unsigned_bin(tkb, kb[1])) != CRYPT_OK) { + if (tkb != kB) { + mp_clear(tkb); + } + return err; + } + + x = 0; + y = mp_unsigned_bin_size(tkb) - 1; + if (tkb != kB) { + mp_clear(tkb); + } + while ((unsigned)x < y) { + z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = z; + ++x; --y; + } + + /* at this point we can start, yipee */ + first = 1; + for (x = lut_gap-1; x >= 0; x--) { + /* extract FP_LUT bits from kb spread out by lut_gap bits and offset by x bits from the start */ + bitpos = x; + for (y = zA = zB = 0; y < FP_LUT; y++) { + zA |= ((kb[0][bitpos>>3] >> (bitpos&7)) & 1) << y; + zB |= ((kb[1][bitpos>>3] >> (bitpos&7)) & 1) << y; + bitpos += lut_gap; /* it's y*lut_gap + x, but here we can avoid the mult in each loop */ + } + + /* double if not first */ + if (!first) { + if ((err = ltc_mp.ecc_ptdbl(R, R, a, modulus, mp)) != CRYPT_OK) { + return err; + } + } + + /* add if not first, otherwise copy */ + if (!first) { + if (zA) { + if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx1].LUT[zA], R, a, modulus, mp)) != CRYPT_OK) { + return err; + } + } + if (zB) { + if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx2].LUT[zB], R, a, modulus, mp)) != CRYPT_OK) { + return err; + } + } + } else { + if (zA) { + if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != CRYPT_OK) || + (mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != CRYPT_OK) || + (mp_copy(fp_cache[idx1].mu, R->z) != CRYPT_OK)) { return CRYPT_MEM; } + first = 0; + } + if (zB && first == 0) { + if (zB) { + if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx2].LUT[zB], R, a, modulus, mp)) != CRYPT_OK) { + return err; + } + } + } else if (zB && first == 1) { + if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != CRYPT_OK) || + (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != CRYPT_OK) || + (mp_copy(fp_cache[idx2].mu, R->z) != CRYPT_OK)) { return CRYPT_MEM; } + first = 0; + } + } + } + zeromem(kb, sizeof(kb)); + return ltc_ecc_map(R, modulus, mp); +} + +/** ECC Fixed Point mulmod global + Computes kA*A + kB*B = C using Shamir's Trick + @param A First point to multiply + @param kA What to multiple A by + @param B Second point to multiply + @param kB What to multiple B by + @param C [out] Destination point (can overlap with A or B) + @param modulus Modulus for curve + @return CRYPT_OK on success +*/ +int ltc_ecc_fp_mul2add(ecc_point *A, void *kA, + ecc_point *B, void *kB, + ecc_point *C, + void *a, + void *modulus) +{ + int idx1, idx2, err; + void *mp, *mu; + + mp = NULL; + mu = NULL; + LTC_MUTEX_LOCK(<c_ecc_fp_lock); + /* find point */ + idx1 = find_base(A); + + /* no entry? */ + if (idx1 == -1) { + /* find hole and add it */ + if ((idx1 = find_hole()) >= 0) { + if ((err = add_entry(idx1, A)) != CRYPT_OK) { + goto LBL_ERR; + } + } + } + if (idx1 != -1) { + /* increment LRU */ + ++(fp_cache[idx1].lru_count); + } + + /* find point */ + idx2 = find_base(B); + + /* no entry? */ + if (idx2 == -1) { + /* find hole and add it */ + if ((idx2 = find_hole()) >= 0) { + if ((err = add_entry(idx2, B)) != CRYPT_OK) { + goto LBL_ERR; + } + } + } + if (idx2 != -1) { + /* increment LRU */ + ++(fp_cache[idx2].lru_count); + } + + /* if it's 2 build the LUT, if it's higher just use the LUT */ + if (idx1 >= 0 && fp_cache[idx1].lru_count == 2) { + /* compute mp */ + if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } + + /* compute mu */ + if ((err = mp_init(&mu)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* build the LUT */ + if ((err = build_lut(idx1, a, modulus, mp, mu)) != CRYPT_OK) { + goto LBL_ERR;; + } + } + + /* if it's 2 build the LUT, if it's higher just use the LUT */ + if (idx2 >= 0 && fp_cache[idx2].lru_count == 2) { + if (mp == NULL) { + /* compute mp */ + if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } + + /* compute mu */ + if ((err = mp_init(&mu)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { + goto LBL_ERR; + } + } + + /* build the LUT */ + if ((err = build_lut(idx2, a, modulus, mp, mu)) != CRYPT_OK) { + goto LBL_ERR;; + } + } + + + if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].lru_count >= 2 && fp_cache[idx2].lru_count >= 2) { + if (mp == NULL) { + /* compute mp */ + if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } + } + err = accel_fp_mul2add(idx1, idx2, kA, kB, C, a, modulus, mp); + } else { + err = ltc_ecc_mul2add(A, kA, B, kB, C, a, modulus); + } +LBL_ERR: + LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); + if (mp != NULL) { + mp_montgomery_free(mp); + } + if (mu != NULL) { + mp_clear(mu); + } + return err; +} +#endif + +/** ECC Fixed Point mulmod global + @param k The multiplicand + @param G Base point to multiply + @param R [out] Destination of product + @param a ECC curve parameter a + @param modulus The modulus for the curve + @param map [boolean] If non-zero maps the point back to affine co-ordinates, otherwise it's left in jacobian-montgomery form + @return CRYPT_OK if successful +*/ +int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map) +{ + int idx, err; + void *mp, *mu; + + mp = NULL; + mu = NULL; + LTC_MUTEX_LOCK(<c_ecc_fp_lock); + /* find point */ + idx = find_base(G); + + /* no entry? */ + if (idx == -1) { + /* find hole and add it */ + idx = find_hole(); + + if (idx >= 0) { + if ((err = add_entry(idx, G)) != CRYPT_OK) { + goto LBL_ERR; + } + } + } + if (idx != -1) { + /* increment LRU */ + ++(fp_cache[idx].lru_count); + } + + + /* if it's 2 build the LUT, if it's higher just use the LUT */ + if (idx >= 0 && fp_cache[idx].lru_count == 2) { + /* compute mp */ + if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } + + /* compute mu */ + if ((err = mp_init(&mu)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* build the LUT */ + if ((err = build_lut(idx, a, modulus, mp, mu)) != CRYPT_OK) { + goto LBL_ERR;; + } + } + + if (idx >= 0 && fp_cache[idx].lru_count >= 2) { + if (mp == NULL) { + /* compute mp */ + if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } + } + err = accel_fp_mul(idx, k, R, a, modulus, mp, map); + } else { + err = ltc_ecc_mulmod(k, G, R, a, modulus, map); + } +LBL_ERR: + LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); + if (mp != NULL) { + mp_montgomery_free(mp); + } + if (mu != NULL) { + mp_clear(mu); + } + return err; +} + +/* helper function for freeing the cache ... must be called with the cache mutex locked */ +static void ltc_ecc_fp_free_cache(void) +{ + unsigned x, y; + for (x = 0; x < FP_ENTRIES; x++) { + if (fp_cache[x].g != NULL) { + for (y = 0; y < (1U<= 0) { + /* it is already in the cache ... just check that the LUT is initialized */ + if(fp_cache[idx].lru_count >= 2) { + LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); + return CRYPT_OK; + } + } + + if(idx == -1 && (idx = find_hole()) == -1) { + err = CRYPT_BUFFER_OVERFLOW; + goto LBL_ERR; + } + if ((err = add_entry(idx, g)) != CRYPT_OK) { + goto LBL_ERR; + } + /* compute mp */ + if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* compute mu */ + if ((err = mp_init(&mu)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* build the LUT */ + if ((err = build_lut(idx, a, modulus, mp, mu)) != CRYPT_OK) { + goto LBL_ERR; + } + fp_cache[idx].lru_count = 2; + fp_cache[idx].lock = lock; +LBL_ERR: + LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); + if (mp != NULL) { + mp_montgomery_free(mp); + } + if (mu != NULL) { + mp_clear(mu); + } + return err; +} + +/** Prevent/permit the FP cache from being updated + @param flag If flag is 0, remove cache lock (unlock), otherwise lock it +*/ +void ltc_ecc_fp_tablelock(int lock) +{ + int i; + + LTC_MUTEX_LOCK(<c_ecc_fp_lock); + for (i = 0; i < FP_ENTRIES; i++) { + fp_cache[i].lock = lock; + } + LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); +} + +/** Export the current cache as a binary packet + @param out [out] pointer to malloc'ed space containing the packet + @param outlen [out] size of exported packet + @return CRYPT_OK if successful +*/ +int ltc_ecc_fp_save_state(unsigned char **out, unsigned long *outlen) +{ + ltc_asn1_list *cache_entry; + unsigned int i, j, k; + unsigned long fp_entries, fp_lut, num_entries; + int err; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + fp_entries = FP_ENTRIES; + fp_lut = FP_LUT; + num_entries = 0; + + LTC_MUTEX_LOCK(<c_ecc_fp_lock); + /* + * build the list; + Cache DEFINITIONS ::= + BEGIN + CacheDump ::= SEQUENCE { + numEntries SHORTINTEGER, + maxEntries SHORTINTEGER, + numLUT SHORTINTEGER, + cache SEQUENCE OF INTEGER + } + END + * + */ + /* + * The cache itself is a point (3 INTEGERS), + * the LUT as pairs of INTEGERS (2 * 1<x, 1); + LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].g->y, 1); + LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].g->z, 1); + for (k = 0; k < (1U<x, 1); + LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].LUT[k]->y, 1); + } + LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].mu, 1); + } + LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_EOL, 0, 0); + + LTC_SET_ASN1(cache_entry, 0, LTC_ASN1_SHORT_INTEGER, &num_entries, 1); + + if ((err = der_length_sequence(cache_entry, j, outlen)) != CRYPT_OK) { + goto save_err; + } + if ((*out = XMALLOC(*outlen)) == NULL) { + err = CRYPT_MEM; + goto save_err; + } + err = der_encode_sequence(cache_entry, j, *out, outlen); +save_err: + XFREE(cache_entry); + LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); + return err; +} + +/** Import a binary packet into the current cache + @param in [in] pointer to packet + @param inlen [in] size of packet (bytes) + @return CRYPT_OK if successful +*/ +int ltc_ecc_fp_restore_state(unsigned char *in, unsigned long inlen) +{ + int err; + ltc_asn1_list *asn1_list; + unsigned long num_entries, fp_entries, fp_lut; + unsigned long i, j; + unsigned int x; + + LTC_ARGCHK(in != NULL); + if (inlen == 0) { + return CRYPT_INVALID_ARG; + } + + /* zero indecies */ + i = 0; + j = 0; + asn1_list = NULL; + + LTC_MUTEX_LOCK(<c_ecc_fp_lock); + /* + * start with an empty cache + */ + ltc_ecc_fp_free_cache(); + + /* + * decode the input packet: It consists of a sequence with a few + * integers (including the FP_ENTRIES and FP_LUT sizes), followed by a + * SEQUENCE which is the cache itself. + * + * use standard decoding for the first part, then flexible for the second + */ + if((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_SHORT_INTEGER, 1, &num_entries, + LTC_ASN1_SHORT_INTEGER, 1, &fp_entries, + LTC_ASN1_SHORT_INTEGER, 1, &fp_lut, + LTC_ASN1_EOL, 0, 0)) != CRYPT_OK) { + goto ERR_OUT; + } + if (fp_entries != FP_ENTRIES || fp_lut != FP_LUT || num_entries > fp_entries) { + err = CRYPT_INVALID_PACKET; + goto ERR_OUT; + } + if ((asn1_list = XCALLOC(3+num_entries*(4+2*(1<x, 1); + LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, fp_cache[i].g->y, 1); + LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, fp_cache[i].g->z, 1); + for (x = 0; x < (1U<x, &p->y, NULL)) != CRYPT_OK) { + goto ERR_OUT; + } + p->z = NULL; + LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, p->x, 1); + LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, p->y, 1); + } + if((err = mp_init(&fp_cache[i].mu)) != CRYPT_OK) { + goto ERR_OUT; + } + LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, fp_cache[i].mu, 1); + fp_cache[i].lru_count = 3; + fp_cache[i].lock = 1; + } + + if ((err = der_decode_sequence(in, inlen, asn1_list, j)) != CRYPT_OK) { + goto ERR_OUT; + } + XFREE(asn1_list); + LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); + return CRYPT_OK; +ERR_OUT: + if(asn1_list) + XFREE(asn1_list); + ltc_ecc_fp_free_cache(); + LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); + return err; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ + diff --git a/src/ltc/math/ltm_desc.c b/src/ltc/math/ltm_desc.c new file mode 100644 index 0000000..a7577c1 --- /dev/null +++ b/src/ltc/math/ltm_desc.c @@ -0,0 +1,525 @@ +/* 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://libtom.org + */ + +#define DESC_DEF_ONLY +#include "tomcrypt.h" + +#ifdef LTM_DESC + +#include + +static const struct { + int mpi_code, ltc_code; +} mpi_to_ltc_codes[] = { + { MP_OKAY , CRYPT_OK}, + { MP_MEM , CRYPT_MEM}, + { MP_VAL , CRYPT_INVALID_ARG}, +}; + +/** + Convert a MPI error to a LTC error (Possibly the most powerful function ever! Oh wait... no) + @param err The error to convert + @return The equivalent LTC error code or CRYPT_ERROR if none found +*/ +static int mpi_to_ltc_error(int err) +{ + int x; + + for (x = 0; x < (int)(sizeof(mpi_to_ltc_codes)/sizeof(mpi_to_ltc_codes[0])); x++) { + if (err == mpi_to_ltc_codes[x].mpi_code) { + return mpi_to_ltc_codes[x].ltc_code; + } + } + return CRYPT_ERROR; +} + +static int init(void **a) +{ + int err; + + LTC_ARGCHK(a != NULL); + + *a = XCALLOC(1, sizeof(mp_int)); + if (*a == NULL) { + return CRYPT_MEM; + } + + if ((err = mpi_to_ltc_error(mp_init(*a))) != CRYPT_OK) { + XFREE(*a); + } + return err; +} + +static void deinit(void *a) +{ + LTC_ARGCHKVD(a != NULL); + mp_clear(a); + XFREE(a); +} + +static int neg(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_neg(a, b)); +} + +static int copy(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_copy(a, b)); +} + +static int init_copy(void **a, void *b) +{ + if (init(a) != CRYPT_OK) { + return CRYPT_MEM; + } + return copy(b, *a); +} + +/* ---- trivial ---- */ +static int set_int(void *a, unsigned long b) +{ + LTC_ARGCHK(a != NULL); + return mpi_to_ltc_error(mp_set_int(a, b)); +} + +static unsigned long get_int(void *a) +{ + LTC_ARGCHK(a != NULL); + return mp_get_int(a); +} + +static ltc_mp_digit get_digit(void *a, int n) +{ + mp_int *A; + LTC_ARGCHK(a != NULL); + A = a; + return (n >= A->used || n < 0) ? 0 : A->dp[n]; +} + +static int get_digit_count(void *a) +{ + mp_int *A; + LTC_ARGCHK(a != NULL); + A = a; + return A->used; +} + +static int compare(void *a, void *b) +{ + int ret; + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + ret = mp_cmp(a, b); + switch (ret) { + case MP_LT: return LTC_MP_LT; + case MP_EQ: return LTC_MP_EQ; + case MP_GT: return LTC_MP_GT; + default: return 0; + } +} + +static int compare_d(void *a, unsigned long b) +{ + int ret; + LTC_ARGCHK(a != NULL); + ret = mp_cmp_d(a, b); + switch (ret) { + case MP_LT: return LTC_MP_LT; + case MP_EQ: return LTC_MP_EQ; + case MP_GT: return LTC_MP_GT; + default: return 0; + } +} + +static int count_bits(void *a) +{ + LTC_ARGCHK(a != NULL); + return mp_count_bits(a); +} + +static int count_lsb_bits(void *a) +{ + LTC_ARGCHK(a != NULL); + return mp_cnt_lsb(a); +} + + +static int twoexpt(void *a, int n) +{ + LTC_ARGCHK(a != NULL); + return mpi_to_ltc_error(mp_2expt(a, n)); +} + +/* ---- conversions ---- */ + +/* read ascii string */ +static int read_radix(void *a, const char *b, int radix) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_read_radix(a, b, radix)); +} + +/* write one */ +static int write_radix(void *a, char *b, int radix) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_toradix(a, b, radix)); +} + +/* get size as unsigned char string */ +static unsigned long unsigned_size(void *a) +{ + LTC_ARGCHK(a != NULL); + return mp_unsigned_bin_size(a); +} + +/* store */ +static int unsigned_write(void *a, unsigned char *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_to_unsigned_bin(a, b)); +} + +/* read */ +static int unsigned_read(void *a, unsigned char *b, unsigned long len) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_read_unsigned_bin(a, b, len)); +} + +/* add */ +static int add(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_add(a, b, c)); +} + +static int addi(void *a, unsigned long b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_add_d(a, b, c)); +} + +/* sub */ +static int sub(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_sub(a, b, c)); +} + +static int subi(void *a, unsigned long b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_sub_d(a, b, c)); +} + +/* mul */ +static int mul(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_mul(a, b, c)); +} + +static int muli(void *a, unsigned long b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_mul_d(a, b, c)); +} + +/* sqr */ +static int sqr(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_sqr(a, b)); +} + +/* sqrtmod_prime */ +static int sqrtmod_prime(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_sqrtmod_prime(a, b, c)); +} + +/* div */ +static int divide(void *a, void *b, void *c, void *d) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_div(a, b, c, d)); +} + +static int div_2(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_div_2(a, b)); +} + +/* modi */ +static int modi(void *a, unsigned long b, unsigned long *c) +{ + mp_digit tmp; + int err; + + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(c != NULL); + + if ((err = mpi_to_ltc_error(mp_mod_d(a, b, &tmp))) != CRYPT_OK) { + return err; + } + *c = tmp; + return CRYPT_OK; +} + +/* gcd */ +static int gcd(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_gcd(a, b, c)); +} + +/* lcm */ +static int lcm(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_lcm(a, b, c)); +} + +static int addmod(void *a, void *b, void *c, void *d) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + LTC_ARGCHK(d != NULL); + return mpi_to_ltc_error(mp_addmod(a,b,c,d)); +} + +static int submod(void *a, void *b, void *c, void *d) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + LTC_ARGCHK(d != NULL); + return mpi_to_ltc_error(mp_submod(a,b,c,d)); +} + +static int mulmod(void *a, void *b, void *c, void *d) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + LTC_ARGCHK(d != NULL); + return mpi_to_ltc_error(mp_mulmod(a,b,c,d)); +} + +static int sqrmod(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_sqrmod(a,b,c)); +} + +/* invmod */ +static int invmod(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_invmod(a, b, c)); +} + +/* setup */ +static int montgomery_setup(void *a, void **b) +{ + int err; + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + *b = XCALLOC(1, sizeof(mp_digit)); + if (*b == NULL) { + return CRYPT_MEM; + } + if ((err = mpi_to_ltc_error(mp_montgomery_setup(a, (mp_digit *)*b))) != CRYPT_OK) { + XFREE(*b); + } + return err; +} + +/* get normalization value */ +static int montgomery_normalization(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_montgomery_calc_normalization(a, b)); +} + +/* reduce */ +static int montgomery_reduce(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_montgomery_reduce(a, b, *((mp_digit *)c))); +} + +/* clean up */ +static void montgomery_deinit(void *a) +{ + XFREE(a); +} + +static int exptmod(void *a, void *b, void *c, void *d) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + LTC_ARGCHK(d != NULL); + return mpi_to_ltc_error(mp_exptmod(a,b,c,d)); +} + +static int isprime(void *a, int b, int *c) +{ + int err; + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(c != NULL); + if (b == 0) { + b = 8; + } /* if */ + err = mpi_to_ltc_error(mp_prime_is_prime(a, b, c)); + *c = (*c == MP_YES) ? LTC_MP_YES : LTC_MP_NO; + return err; +} + +static int set_rand(void *a, int size) +{ + LTC_ARGCHK(a != NULL); + return mpi_to_ltc_error(mp_rand(a, size)); +} + +const ltc_math_descriptor ltm_desc = { + + "LibTomMath", + (int)DIGIT_BIT, + + &init, + &init_copy, + &deinit, + + &neg, + ©, + + &set_int, + &get_int, + &get_digit, + &get_digit_count, + &compare, + &compare_d, + &count_bits, + &count_lsb_bits, + &twoexpt, + + &read_radix, + &write_radix, + &unsigned_size, + &unsigned_write, + &unsigned_read, + + &add, + &addi, + &sub, + &subi, + &mul, + &muli, + &sqr, + &sqrtmod_prime, + ÷, + &div_2, + &modi, + &gcd, + &lcm, + + &mulmod, + &sqrmod, + &invmod, + + &montgomery_setup, + &montgomery_normalization, + &montgomery_reduce, + &montgomery_deinit, + + &exptmod, + &isprime, + +#ifdef LTC_MECC +#ifdef LTC_MECC_FP + <c_ecc_fp_mulmod, +#else + <c_ecc_mulmod, +#endif + <c_ecc_projective_add_point, + <c_ecc_projective_dbl_point, + <c_ecc_map, +#ifdef LTC_ECC_SHAMIR +#ifdef LTC_MECC_FP + <c_ecc_fp_mul2add, +#else + <c_ecc_mul2add, +#endif /* LTC_MECC_FP */ +#else + NULL, +#endif /* LTC_ECC_SHAMIR */ +#else + NULL, NULL, NULL, NULL, NULL, +#endif /* LTC_MECC */ + +#ifdef LTC_MRSA + &rsa_make_key, + &rsa_exptmod, +#else + NULL, NULL, +#endif + &addmod, + &submod, + + &set_rand, + +}; + + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/math/multi.c b/src/ltc/math/multi.c new file mode 100644 index 0000000..f85e900 --- /dev/null +++ b/src/ltc/math/multi.c @@ -0,0 +1,62 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +#ifdef LTC_MPI +#include + +int ltc_init_multi(void **a, ...) +{ + void **cur = a; + int np = 0; + va_list args; + + va_start(args, a); + while (cur != NULL) { + if (mp_init(cur) != CRYPT_OK) { + /* failed */ + va_list clean_list; + + va_start(clean_list, a); + cur = a; + while (np--) { + mp_clear(*cur); + cur = va_arg(clean_list, void**); + } + va_end(clean_list); + va_end(args); + return CRYPT_MEM; + } + ++np; + cur = va_arg(args, void**); + } + va_end(args); + return CRYPT_OK; +} + +void ltc_deinit_multi(void *a, ...) +{ + void *cur = a; + va_list args; + + va_start(args, a); + while (cur != NULL) { + mp_clear(cur); + cur = va_arg(args, void *); + } + va_end(args); +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/math/rand_bn.c b/src/ltc/math/rand_bn.c new file mode 100644 index 0000000..bdfb3d7 --- /dev/null +++ b/src/ltc/math/rand_bn.c @@ -0,0 +1,71 @@ +/* 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. + * + */ +#include "tomcrypt.h" + +#if defined(LTC_MDSA) || defined(LTC_MECC) +/** + Generate a random number N with given bitlength (note: MSB can be 0) +*/ + +int rand_bn_bits(void *N, int bits, prng_state *prng, int wprng) +{ + int res, bytes; + unsigned char *buf, mask; + + LTC_ARGCHK(N != NULL); + LTC_ARGCHK(bits > 1); + + /* check PRNG */ + if ((res = prng_is_valid(wprng)) != CRYPT_OK) return res; + + bytes = (bits+7) >> 3; + mask = 0xff << (8 - bits % 8); + + /* allocate buffer */ + if ((buf = XCALLOC(1, bytes)) == NULL) return CRYPT_MEM; + + /* generate random bytes */ + if (prng_descriptor[wprng].read(buf, bytes, prng) != (unsigned long)bytes) { + res = CRYPT_ERROR_READPRNG; + goto cleanup; + } + /* mask bits */ + buf[0] &= ~mask; + /* load value */ + if ((res = mp_read_unsigned_bin(N, buf, bytes)) != CRYPT_OK) goto cleanup; + + res = CRYPT_OK; + +cleanup: +#ifdef LTC_CLEAN_STACK + zeromem(buf, bytes); +#endif + XFREE(buf); + return res; +} + +/** + Generate a random number N in a range: 0 <= N < limit +*/ +int rand_bn_range(void *N, void *limit, prng_state *prng, int wprng) +{ + int res; + + LTC_ARGCHK(N != NULL); + LTC_ARGCHK(limit != NULL); + + do { + res = rand_bn_bits(N, mp_count_bits(limit), prng, wprng); + if (res != CRYPT_OK) return res; + } while (mp_cmp(N, limit) != LTC_MP_LT); + + return CRYPT_OK; +} +#endif diff --git a/src/ltc/math/rand_prime.c b/src/ltc/math/rand_prime.c new file mode 100644 index 0000000..9dd737b --- /dev/null +++ b/src/ltc/math/rand_prime.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://libtom.org + */ +#include "tomcrypt.h" + +#if defined(LTC_MRSA) || (!defined(LTC_NO_MATH) && !defined(LTC_NO_PRNGS)) + +/** + @file rand_prime.c + Generate a random prime, Tom St Denis +*/ + +#define USE_BBS 1 + +int rand_prime(void *N, long len, prng_state *prng, int wprng) +{ + int err, res, type; + unsigned char *buf; + + LTC_ARGCHK(N != NULL); + + /* get type */ + if (len < 0) { + type = USE_BBS; + len = -len; + } else { + type = 0; + } + + /* allow sizes between 2 and 512 bytes for a prime size */ + if (len < 2 || len > 512) { + return CRYPT_INVALID_PRIME_SIZE; + } + + /* valid PRNG? Better be! */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + /* allocate buffer to work with */ + buf = XCALLOC(1, len); + if (buf == NULL) { + return CRYPT_MEM; + } + + do { + /* generate value */ + if (prng_descriptor[wprng].read(buf, len, prng) != (unsigned long)len) { + XFREE(buf); + return CRYPT_ERROR_READPRNG; + } + + /* munge bits */ + buf[0] |= 0x80 | 0x40; + buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00); + + /* load value */ + if ((err = mp_read_unsigned_bin(N, buf, len)) != CRYPT_OK) { + XFREE(buf); + return err; + } + + /* test */ + if ((err = mp_prime_is_prime(N, 8, &res)) != CRYPT_OK) { + XFREE(buf); + return err; + } + } while (res == LTC_MP_NO); + +#ifdef LTC_CLEAN_STACK + zeromem(buf, len); +#endif + + XFREE(buf); + return CRYPT_OK; +} + +#endif /* LTC_NO_MATH */ + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/math/tfm_desc.c b/src/ltc/math/tfm_desc.c new file mode 100644 index 0000000..a30a8de --- /dev/null +++ b/src/ltc/math/tfm_desc.c @@ -0,0 +1,811 @@ +/* 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://libtom.org + */ + +#define DESC_DEF_ONLY +#include "tomcrypt.h" + +#ifdef TFM_DESC + +#include + +static const struct { + int tfm_code, ltc_code; +} tfm_to_ltc_codes[] = { + { FP_OKAY , CRYPT_OK}, + { FP_MEM , CRYPT_MEM}, + { FP_VAL , CRYPT_INVALID_ARG}, +}; + +/** + Convert a tfm error to a LTC error (Possibly the most powerful function ever! Oh wait... no) + @param err The error to convert + @return The equivalent LTC error code or CRYPT_ERROR if none found +*/ +static int tfm_to_ltc_error(int err) +{ + int x; + + for (x = 0; x < (int)(sizeof(tfm_to_ltc_codes)/sizeof(tfm_to_ltc_codes[0])); x++) { + if (err == tfm_to_ltc_codes[x].tfm_code) { + return tfm_to_ltc_codes[x].ltc_code; + } + } + return CRYPT_ERROR; +} + +static int init(void **a) +{ + LTC_ARGCHK(a != NULL); + + *a = XCALLOC(1, sizeof(fp_int)); + if (*a == NULL) { + return CRYPT_MEM; + } + fp_init(*a); + return CRYPT_OK; +} + +static void deinit(void *a) +{ + LTC_ARGCHKVD(a != NULL); + XFREE(a); +} + +static int neg(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + fp_neg(((fp_int*)a), ((fp_int*)b)); + return CRYPT_OK; +} + +static int copy(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + fp_copy(a, b); + return CRYPT_OK; +} + +static int init_copy(void **a, void *b) +{ + if (init(a) != CRYPT_OK) { + return CRYPT_MEM; + } + return copy(b, *a); +} + +/* ---- trivial ---- */ +static int set_int(void *a, unsigned long b) +{ + LTC_ARGCHK(a != NULL); + fp_set(a, b); + return CRYPT_OK; +} + +static unsigned long get_int(void *a) +{ + fp_int *A; + LTC_ARGCHK(a != NULL); + A = a; + return A->used > 0 ? A->dp[0] : 0; +} + +static ltc_mp_digit get_digit(void *a, int n) +{ + fp_int *A; + LTC_ARGCHK(a != NULL); + A = a; + return (n >= A->used || n < 0) ? 0 : A->dp[n]; +} + +static int get_digit_count(void *a) +{ + fp_int *A; + LTC_ARGCHK(a != NULL); + A = a; + return A->used; +} + +static int compare(void *a, void *b) +{ + int ret; + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + ret = fp_cmp(a, b); + switch (ret) { + case FP_LT: return LTC_MP_LT; + case FP_EQ: return LTC_MP_EQ; + case FP_GT: return LTC_MP_GT; + } + return 0; +} + +static int compare_d(void *a, unsigned long b) +{ + int ret; + LTC_ARGCHK(a != NULL); + ret = fp_cmp_d(a, b); + switch (ret) { + case FP_LT: return LTC_MP_LT; + case FP_EQ: return LTC_MP_EQ; + case FP_GT: return LTC_MP_GT; + } + return 0; +} + +static int count_bits(void *a) +{ + LTC_ARGCHK(a != NULL); + return fp_count_bits(a); +} + +static int count_lsb_bits(void *a) +{ + LTC_ARGCHK(a != NULL); + return fp_cnt_lsb(a); +} + +static int twoexpt(void *a, int n) +{ + LTC_ARGCHK(a != NULL); + fp_2expt(a, n); + return CRYPT_OK; +} + +/* ---- conversions ---- */ + +/* read ascii string */ +static int read_radix(void *a, const char *b, int radix) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return tfm_to_ltc_error(fp_read_radix(a, (char *)b, radix)); +} + +/* write one */ +static int write_radix(void *a, char *b, int radix) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return tfm_to_ltc_error(fp_toradix(a, b, radix)); +} + +/* get size as unsigned char string */ +static unsigned long unsigned_size(void *a) +{ + LTC_ARGCHK(a != NULL); + return fp_unsigned_bin_size(a); +} + +/* store */ +static int unsigned_write(void *a, unsigned char *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + fp_to_unsigned_bin(a, b); + return CRYPT_OK; +} + +/* read */ +static int unsigned_read(void *a, unsigned char *b, unsigned long len) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + fp_read_unsigned_bin(a, b, len); + return CRYPT_OK; +} + +/* add */ +static int add(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + fp_add(a, b, c); + return CRYPT_OK; +} + +static int addi(void *a, unsigned long b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(c != NULL); + fp_add_d(a, b, c); + return CRYPT_OK; +} + +/* sub */ +static int sub(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + fp_sub(a, b, c); + return CRYPT_OK; +} + +static int subi(void *a, unsigned long b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(c != NULL); + fp_sub_d(a, b, c); + return CRYPT_OK; +} + +/* mul */ +static int mul(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + fp_mul(a, b, c); + return CRYPT_OK; +} + +static int muli(void *a, unsigned long b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(c != NULL); + fp_mul_d(a, b, c); + return CRYPT_OK; +} + +/* sqr */ +static int sqr(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + fp_sqr(a, b); + return CRYPT_OK; +} + +/* sqrtmod_prime */ +static int sqrtmod_prime(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + fprintf(stderr, "TFM does not support sqrtmod_prime\n"); /* XXX-FIXME */ + return CRYPT_ERROR; +} + +/* div */ +static int divide(void *a, void *b, void *c, void *d) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return tfm_to_ltc_error(fp_div(a, b, c, d)); +} + +static int div_2(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + fp_div_2(a, b); + return CRYPT_OK; +} + +/* modi */ +static int modi(void *a, unsigned long b, unsigned long *c) +{ + fp_digit tmp; + int err; + + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(c != NULL); + + if ((err = tfm_to_ltc_error(fp_mod_d(a, b, &tmp))) != CRYPT_OK) { + return err; + } + *c = tmp; + return CRYPT_OK; +} + +/* gcd */ +static int gcd(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + fp_gcd(a, b, c); + return CRYPT_OK; +} + +/* lcm */ +static int lcm(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + fp_lcm(a, b, c); + return CRYPT_OK; +} + +static int addmod(void *a, void *b, void *c, void *d) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + LTC_ARGCHK(d != NULL); + return tfm_to_ltc_error(fp_addmod(a,b,c,d)); +} + +static int submod(void *a, void *b, void *c, void *d) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + LTC_ARGCHK(d != NULL); + return tfm_to_ltc_error(fp_submod(a,b,c,d)); +} + +static int mulmod(void *a, void *b, void *c, void *d) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + LTC_ARGCHK(d != NULL); + return tfm_to_ltc_error(fp_mulmod(a,b,c,d)); +} + +static int sqrmod(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + return tfm_to_ltc_error(fp_sqrmod(a,b,c)); +} + +/* invmod */ +static int invmod(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + return tfm_to_ltc_error(fp_invmod(a, b, c)); +} + +/* setup */ +static int montgomery_setup(void *a, void **b) +{ + int err; + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + *b = XCALLOC(1, sizeof(fp_digit)); + if (*b == NULL) { + return CRYPT_MEM; + } + if ((err = tfm_to_ltc_error(fp_montgomery_setup(a, (fp_digit *)*b))) != CRYPT_OK) { + XFREE(*b); + } + return err; +} + +/* get normalization value */ +static int montgomery_normalization(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + fp_montgomery_calc_normalization(a, b); + return CRYPT_OK; +} + +/* reduce */ +static int montgomery_reduce(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + fp_montgomery_reduce(a, b, *((fp_digit *)c)); + return CRYPT_OK; +} + +/* clean up */ +static void montgomery_deinit(void *a) +{ + XFREE(a); +} + +static int exptmod(void *a, void *b, void *c, void *d) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + LTC_ARGCHK(d != NULL); + return tfm_to_ltc_error(fp_exptmod(a,b,c,d)); +} + +static int isprime(void *a, int b, int *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(c != NULL); + (void)b; + *c = (fp_isprime(a) == FP_YES) ? LTC_MP_YES : LTC_MP_NO; + return CRYPT_OK; +} + +#if defined(LTC_MECC) && defined(LTC_MECC_ACCEL) + +static int tfm_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *Mp) +{ + fp_int t1, t2; + fp_digit mp; + + LTC_ARGCHK(P != NULL); + LTC_ARGCHK(R != NULL); + LTC_ARGCHK(modulus != NULL); + LTC_ARGCHK(Mp != NULL); + + mp = *((fp_digit*)Mp); + + fp_init(&t1); + fp_init(&t2); + + if (P != R) { + fp_copy(P->x, R->x); + fp_copy(P->y, R->y); + fp_copy(P->z, R->z); + } + + /* t1 = Z * Z */ + fp_sqr(R->z, &t1); + fp_montgomery_reduce(&t1, modulus, mp); + /* Z = Y * Z */ + fp_mul(R->z, R->y, R->z); + fp_montgomery_reduce(R->z, modulus, mp); + /* Z = 2Z */ + fp_add(R->z, R->z, R->z); + if (fp_cmp(R->z, modulus) != FP_LT) { + fp_sub(R->z, modulus, R->z); + } + + /* &t2 = X - T1 */ + fp_sub(R->x, &t1, &t2); + if (fp_cmp_d(&t2, 0) == FP_LT) { + fp_add(&t2, modulus, &t2); + } + /* T1 = X + T1 */ + fp_add(&t1, R->x, &t1); + if (fp_cmp(&t1, modulus) != FP_LT) { + fp_sub(&t1, modulus, &t1); + } + /* T2 = T1 * T2 */ + fp_mul(&t1, &t2, &t2); + fp_montgomery_reduce(&t2, modulus, mp); + /* T1 = 2T2 */ + fp_add(&t2, &t2, &t1); + if (fp_cmp(&t1, modulus) != FP_LT) { + fp_sub(&t1, modulus, &t1); + } + /* T1 = T1 + T2 */ + fp_add(&t1, &t2, &t1); + if (fp_cmp(&t1, modulus) != FP_LT) { + fp_sub(&t1, modulus, &t1); + } + + /* Y = 2Y */ + fp_add(R->y, R->y, R->y); + if (fp_cmp(R->y, modulus) != FP_LT) { + fp_sub(R->y, modulus, R->y); + } + /* Y = Y * Y */ + fp_sqr(R->y, R->y); + fp_montgomery_reduce(R->y, modulus, mp); + /* T2 = Y * Y */ + fp_sqr(R->y, &t2); + fp_montgomery_reduce(&t2, modulus, mp); + /* T2 = T2/2 */ + if (fp_isodd(&t2)) { + fp_add(&t2, modulus, &t2); + } + fp_div_2(&t2, &t2); + /* Y = Y * X */ + fp_mul(R->y, R->x, R->y); + fp_montgomery_reduce(R->y, modulus, mp); + + /* X = T1 * T1 */ + fp_sqr(&t1, R->x); + fp_montgomery_reduce(R->x, modulus, mp); + /* X = X - Y */ + fp_sub(R->x, R->y, R->x); + if (fp_cmp_d(R->x, 0) == FP_LT) { + fp_add(R->x, modulus, R->x); + } + /* X = X - Y */ + fp_sub(R->x, R->y, R->x); + if (fp_cmp_d(R->x, 0) == FP_LT) { + fp_add(R->x, modulus, R->x); + } + + /* Y = Y - X */ + fp_sub(R->y, R->x, R->y); + if (fp_cmp_d(R->y, 0) == FP_LT) { + fp_add(R->y, modulus, R->y); + } + /* Y = Y * T1 */ + fp_mul(R->y, &t1, R->y); + fp_montgomery_reduce(R->y, modulus, mp); + /* Y = Y - T2 */ + fp_sub(R->y, &t2, R->y); + if (fp_cmp_d(R->y, 0) == FP_LT) { + fp_add(R->y, modulus, R->y); + } + + return CRYPT_OK; +} + +/** + Add two ECC points + @param P The point to add + @param Q The point to add + @param R [out] The destination of the double + @param modulus The modulus of the field the ECC curve is in + @param mp The "b" value from montgomery_setup() + @return CRYPT_OK on success +*/ +static int tfm_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *Mp) +{ + fp_int t1, t2, x, y, z; + fp_digit mp; + + LTC_ARGCHK(P != NULL); + LTC_ARGCHK(Q != NULL); + LTC_ARGCHK(R != NULL); + LTC_ARGCHK(modulus != NULL); + LTC_ARGCHK(Mp != NULL); + + mp = *((fp_digit*)Mp); + + fp_init(&t1); + fp_init(&t2); + fp_init(&x); + fp_init(&y); + fp_init(&z); + + /* should we dbl instead? */ + fp_sub(modulus, Q->y, &t1); + if ( (fp_cmp(P->x, Q->x) == FP_EQ) && + (Q->z != NULL && fp_cmp(P->z, Q->z) == FP_EQ) && + (fp_cmp(P->y, Q->y) == FP_EQ || fp_cmp(P->y, &t1) == FP_EQ)) { + return tfm_ecc_projective_dbl_point(P, R, modulus, Mp); + } + + fp_copy(P->x, &x); + fp_copy(P->y, &y); + fp_copy(P->z, &z); + + /* if Z is one then these are no-operations */ + if (Q->z != NULL) { + /* T1 = Z' * Z' */ + fp_sqr(Q->z, &t1); + fp_montgomery_reduce(&t1, modulus, mp); + /* X = X * T1 */ + fp_mul(&t1, &x, &x); + fp_montgomery_reduce(&x, modulus, mp); + /* T1 = Z' * T1 */ + fp_mul(Q->z, &t1, &t1); + fp_montgomery_reduce(&t1, modulus, mp); + /* Y = Y * T1 */ + fp_mul(&t1, &y, &y); + fp_montgomery_reduce(&y, modulus, mp); + } + + /* T1 = Z*Z */ + fp_sqr(&z, &t1); + fp_montgomery_reduce(&t1, modulus, mp); + /* T2 = X' * T1 */ + fp_mul(Q->x, &t1, &t2); + fp_montgomery_reduce(&t2, modulus, mp); + /* T1 = Z * T1 */ + fp_mul(&z, &t1, &t1); + fp_montgomery_reduce(&t1, modulus, mp); + /* T1 = Y' * T1 */ + fp_mul(Q->y, &t1, &t1); + fp_montgomery_reduce(&t1, modulus, mp); + + /* Y = Y - T1 */ + fp_sub(&y, &t1, &y); + if (fp_cmp_d(&y, 0) == FP_LT) { + fp_add(&y, modulus, &y); + } + /* T1 = 2T1 */ + fp_add(&t1, &t1, &t1); + if (fp_cmp(&t1, modulus) != FP_LT) { + fp_sub(&t1, modulus, &t1); + } + /* T1 = Y + T1 */ + fp_add(&t1, &y, &t1); + if (fp_cmp(&t1, modulus) != FP_LT) { + fp_sub(&t1, modulus, &t1); + } + /* X = X - T2 */ + fp_sub(&x, &t2, &x); + if (fp_cmp_d(&x, 0) == FP_LT) { + fp_add(&x, modulus, &x); + } + /* T2 = 2T2 */ + fp_add(&t2, &t2, &t2); + if (fp_cmp(&t2, modulus) != FP_LT) { + fp_sub(&t2, modulus, &t2); + } + /* T2 = X + T2 */ + fp_add(&t2, &x, &t2); + if (fp_cmp(&t2, modulus) != FP_LT) { + fp_sub(&t2, modulus, &t2); + } + + /* if Z' != 1 */ + if (Q->z != NULL) { + /* Z = Z * Z' */ + fp_mul(&z, Q->z, &z); + fp_montgomery_reduce(&z, modulus, mp); + } + + /* Z = Z * X */ + fp_mul(&z, &x, &z); + fp_montgomery_reduce(&z, modulus, mp); + + /* T1 = T1 * X */ + fp_mul(&t1, &x, &t1); + fp_montgomery_reduce(&t1, modulus, mp); + /* X = X * X */ + fp_sqr(&x, &x); + fp_montgomery_reduce(&x, modulus, mp); + /* T2 = T2 * x */ + fp_mul(&t2, &x, &t2); + fp_montgomery_reduce(&t2, modulus, mp); + /* T1 = T1 * X */ + fp_mul(&t1, &x, &t1); + fp_montgomery_reduce(&t1, modulus, mp); + + /* X = Y*Y */ + fp_sqr(&y, &x); + fp_montgomery_reduce(&x, modulus, mp); + /* X = X - T2 */ + fp_sub(&x, &t2, &x); + if (fp_cmp_d(&x, 0) == FP_LT) { + fp_add(&x, modulus, &x); + } + + /* T2 = T2 - X */ + fp_sub(&t2, &x, &t2); + if (fp_cmp_d(&t2, 0) == FP_LT) { + fp_add(&t2, modulus, &t2); + } + /* T2 = T2 - X */ + fp_sub(&t2, &x, &t2); + if (fp_cmp_d(&t2, 0) == FP_LT) { + fp_add(&t2, modulus, &t2); + } + /* T2 = T2 * Y */ + fp_mul(&t2, &y, &t2); + fp_montgomery_reduce(&t2, modulus, mp); + /* Y = T2 - T1 */ + fp_sub(&t2, &t1, &y); + if (fp_cmp_d(&y, 0) == FP_LT) { + fp_add(&y, modulus, &y); + } + /* Y = Y/2 */ + if (fp_isodd(&y)) { + fp_add(&y, modulus, &y); + } + fp_div_2(&y, &y); + + fp_copy(&x, R->x); + fp_copy(&y, R->y); + fp_copy(&z, R->z); + + return CRYPT_OK; +} + + +#endif + +const ltc_math_descriptor tfm_desc = { + + "TomsFastMath", + (int)DIGIT_BIT, + + &init, + &init_copy, + &deinit, + + &neg, + ©, + + &set_int, + &get_int, + &get_digit, + &get_digit_count, + &compare, + &compare_d, + &count_bits, + &count_lsb_bits, + &twoexpt, + + &read_radix, + &write_radix, + &unsigned_size, + &unsigned_write, + &unsigned_read, + + &add, + &addi, + &sub, + &subi, + &mul, + &muli, + &sqr, + &sqrtmod_prime, + ÷, + &div_2, + &modi, + &gcd, + &lcm, + + &mulmod, + &sqrmod, + &invmod, + + &montgomery_setup, + &montgomery_normalization, + &montgomery_reduce, + &montgomery_deinit, + + &exptmod, + &isprime, + +#ifdef LTC_MECC +#ifdef LTC_MECC_FP + <c_ecc_fp_mulmod, +#else + <c_ecc_mulmod, +#endif /* LTC_MECC_FP */ +#ifdef LTC_MECC_ACCEL + &tfm_ecc_projective_add_point, + &tfm_ecc_projective_dbl_point, +#else + <c_ecc_projective_add_point, + <c_ecc_projective_dbl_point, +#endif /* LTC_MECC_ACCEL */ + <c_ecc_map, +#ifdef LTC_ECC_SHAMIR +#ifdef LTC_MECC_FP + <c_ecc_fp_mul2add, +#else + <c_ecc_mul2add, +#endif /* LTC_MECC_FP */ +#else + NULL, +#endif /* LTC_ECC_SHAMIR */ +#else + NULL, NULL, NULL, NULL, NULL, +#endif /* LTC_MECC */ + +#ifdef LTC_MRSA + &rsa_make_key, + &rsa_exptmod, +#else + NULL, NULL, +#endif + &addmod, + &submod, + + NULL, + +}; + + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/adler32.c b/src/ltc/misc/adler32.c new file mode 100644 index 0000000..987931b --- /dev/null +++ b/src/ltc/misc/adler32.c @@ -0,0 +1,139 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file adler32.c + Adler-32 checksum algorithm + Written and placed in the public domain by Wei Dai + Adapted for libtomcrypt by Steffen Jaeckel +*/ +#ifdef LTC_ADLER32 + +static const unsigned long _adler32_base = 65521; + +void adler32_init(adler32_state *ctx) +{ + LTC_ARGCHKVD(ctx != NULL); + ctx->s[0] = 1; + ctx->s[1] = 0; +} + +void adler32_update(adler32_state *ctx, const unsigned char *input, unsigned long length) +{ + unsigned long s1, s2; + + LTC_ARGCHKVD(ctx != NULL); + LTC_ARGCHKVD(input != NULL); + s1 = ctx->s[0]; + s2 = ctx->s[1]; + + if (length % 8 != 0) { + do { + s1 += *input++; + s2 += s1; + length--; + } while (length % 8 != 0); + + if (s1 >= _adler32_base) + s1 -= _adler32_base; + s2 %= _adler32_base; + } + + while (length > 0) { + s1 += input[0]; + s2 += s1; + s1 += input[1]; + s2 += s1; + s1 += input[2]; + s2 += s1; + s1 += input[3]; + s2 += s1; + s1 += input[4]; + s2 += s1; + s1 += input[5]; + s2 += s1; + s1 += input[6]; + s2 += s1; + s1 += input[7]; + s2 += s1; + + length -= 8; + input += 8; + + if (s1 >= _adler32_base) + s1 -= _adler32_base; + s2 %= _adler32_base; + } + + LTC_ARGCHKVD(s1 < _adler32_base); + LTC_ARGCHKVD(s2 < _adler32_base); + + ctx->s[0] = (unsigned short)s1; + ctx->s[1] = (unsigned short)s2; +} + +void adler32_finish(adler32_state *ctx, void *hash, unsigned long size) +{ + unsigned char* h; + + LTC_ARGCHKVD(ctx != NULL); + LTC_ARGCHKVD(hash != NULL); + + h = hash; + + switch (size) { + default: + h[3] = ctx->s[0] & 0x0ff; + /* FALLTHROUGH */ + case 3: + h[2] = (ctx->s[0] >> 8) & 0x0ff; + /* FALLTHROUGH */ + case 2: + h[1] = ctx->s[1] & 0x0ff; + /* FALLTHROUGH */ + case 1: + h[0] = (ctx->s[1] >> 8) & 0x0ff; + /* FALLTHROUGH */ + case 0: + ; + } +} + +int adler32_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + const void* in = "libtomcrypt"; + const unsigned char adler32[] = { 0x1b, 0xe8, 0x04, 0xba }; + unsigned char out[4]; + adler32_state ctx; + adler32_init(&ctx); + adler32_update(&ctx, in, strlen(in)); + adler32_finish(&ctx, out, 4); + if (XMEMCMP(adler32, out, 4)) { +#ifdef LTC_TEST_DBG + ulong32 _out, _adler32; + LOAD32H(_out, out); + LOAD32H(_adler32, adler32); + printf("adler32 fail! Is: 0x%x Should: 0x%x\n", _out, _adler32); +#endif + return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; +#endif +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/base64/base64_decode.c b/src/ltc/misc/base64/base64_decode.c new file mode 100644 index 0000000..d3b89b1 --- /dev/null +++ b/src/ltc/misc/base64/base64_decode.c @@ -0,0 +1,198 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file base64_decode.c + Compliant base64 code donated by Wayne Scott (wscott@bitmover.com) + base64 URL Safe variant (RFC 4648 section 5) by Karel Miko +*/ + + +#if defined(LTC_BASE64) || defined (LTC_BASE64_URL) + +#if defined(LTC_BASE64) +static const unsigned char map_base64[256] = { +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, +255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, +255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255 }; +#endif /* LTC_BASE64 */ + +static const unsigned char map_base64url[] = { +#if defined(LTC_BASE64_URL) +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, +255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 63, +255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255 +#endif /* LTC_BASE64_URL */ +}; + +enum { + relaxed = 0, + strict = 1 +}; + +static int _base64_decode_internal(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const unsigned char *map, int is_strict) +{ + unsigned long t, x, y, z; + unsigned char c; + int g; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + g = 0; /* '=' counter */ + for (x = y = z = t = 0; x < inlen; x++) { + c = map[in[x]&0xFF]; + if (c == 254) { + g++; + continue; + } + else if (is_strict && g > 0) { + /* we only allow '=' to be at the end */ + return CRYPT_INVALID_PACKET; + } + if (c == 255) { + if (is_strict) + return CRYPT_INVALID_PACKET; + else + continue; + } + + t = (t<<6)|c; + + if (++y == 4) { + if (z + 3 > *outlen) return CRYPT_BUFFER_OVERFLOW; + out[z++] = (unsigned char)((t>>16)&255); + out[z++] = (unsigned char)((t>>8)&255); + out[z++] = (unsigned char)(t&255); + y = t = 0; + } + } + + if (y != 0) { + if (y == 1) return CRYPT_INVALID_PACKET; + if ((y + g) != 4 && is_strict && map != map_base64url) return CRYPT_INVALID_PACKET; + t = t << (6 * (4 - y)); + if (z + y - 1 > *outlen) return CRYPT_BUFFER_OVERFLOW; + if (y >= 2) out[z++] = (unsigned char) ((t >> 16) & 255); + if (y == 3) out[z++] = (unsigned char) ((t >> 8) & 255); + } + *outlen = z; + return CRYPT_OK; +} + +#if defined(LTC_BASE64) +/** + Relaxed base64 decode a block of memory + @param in The base64 data to decode + @param inlen The length of the base64 data + @param out [out] The destination of the binary decoded data + @param outlen [in/out] The max size and resulting size of the decoded data + @return CRYPT_OK if successful +*/ +int base64_decode(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + return _base64_decode_internal(in, inlen, out, outlen, map_base64, relaxed); +} + +/** + Strict base64 decode a block of memory + @param in The base64 data to decode + @param inlen The length of the base64 data + @param out [out] The destination of the binary decoded data + @param outlen [in/out] The max size and resulting size of the decoded data + @return CRYPT_OK if successful +*/ +int base64_strict_decode(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + return _base64_decode_internal(in, inlen, out, outlen, map_base64, strict); +} +#endif /* LTC_BASE64 */ + +#if defined(LTC_BASE64_URL) +/** + Relaxed base64 (URL Safe, RFC 4648 section 5) decode a block of memory + @param in The base64 data to decode + @param inlen The length of the base64 data + @param out [out] The destination of the binary decoded data + @param outlen [in/out] The max size and resulting size of the decoded data + @return CRYPT_OK if successful +*/ +int base64url_decode(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + return _base64_decode_internal(in, inlen, out, outlen, map_base64url, relaxed); +} + +/** + Strict base64 (URL Safe, RFC 4648 section 5) decode a block of memory + @param in The base64 data to decode + @param inlen The length of the base64 data + @param out [out] The destination of the binary decoded data + @param outlen [in/out] The max size and resulting size of the decoded data + @return CRYPT_OK if successful +*/ +int base64url_strict_decode(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + return _base64_decode_internal(in, inlen, out, outlen, map_base64url, strict); +} +#endif /* LTC_BASE64_URL */ + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/base64/base64_encode.c b/src/ltc/misc/base64/base64_encode.c new file mode 100644 index 0000000..ea3eadd --- /dev/null +++ b/src/ltc/misc/base64/base64_encode.c @@ -0,0 +1,126 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file base64_encode.c + Compliant base64 encoder donated by Wayne Scott (wscott@bitmover.com) + base64 URL Safe variant (RFC 4648 section 5) by Karel Miko +*/ + + +#if defined(LTC_BASE64) || defined (LTC_BASE64_URL) + +#if defined(LTC_BASE64) +static const char * const codes_base64 = +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +#endif /* LTC_BASE64 */ + +#if defined(LTC_BASE64_URL) +static const char * const codes_base64url = +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; +#endif /* LTC_BASE64_URL */ + +static int _base64_encode_internal(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const char *codes, int pad) +{ + unsigned long i, len2, leven; + unsigned char *p; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* valid output size ? */ + len2 = 4 * ((inlen + 2) / 3); + if (*outlen < len2 + 1) { + *outlen = len2 + 1; + return CRYPT_BUFFER_OVERFLOW; + } + p = out; + leven = 3*(inlen / 3); + for (i = 0; i < leven; i += 3) { + *p++ = codes[(in[0] >> 2) & 0x3F]; + *p++ = codes[(((in[0] & 3) << 4) + (in[1] >> 4)) & 0x3F]; + *p++ = codes[(((in[1] & 0xf) << 2) + (in[2] >> 6)) & 0x3F]; + *p++ = codes[in[2] & 0x3F]; + in += 3; + } + /* Pad it if necessary... */ + if (i < inlen) { + unsigned a = in[0]; + unsigned b = (i+1 < inlen) ? in[1] : 0; + + *p++ = codes[(a >> 2) & 0x3F]; + *p++ = codes[(((a & 3) << 4) + (b >> 4)) & 0x3F]; + if (pad) { + *p++ = (i+1 < inlen) ? codes[(((b & 0xf) << 2)) & 0x3F] : '='; + *p++ = '='; + } + else { + if (i+1 < inlen) *p++ = codes[(((b & 0xf) << 2)) & 0x3F]; + } + } + + /* append a NULL byte */ + *p = '\0'; + + /* return ok */ + *outlen = (unsigned long)(p - out); + return CRYPT_OK; +} + +#if defined(LTC_BASE64) +/** + base64 Encode a buffer (NUL terminated) + @param in The input buffer to encode + @param inlen The length of the input buffer + @param out [out] The destination of the base64 encoded data + @param outlen [in/out] The max size and resulting size + @return CRYPT_OK if successful +*/ +int base64_encode(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + return _base64_encode_internal(in, inlen, out, outlen, codes_base64, 1); +} +#endif /* LTC_BASE64 */ + + +#if defined(LTC_BASE64_URL) +/** + base64 (URL Safe, RFC 4648 section 5) Encode a buffer (NUL terminated) + @param in The input buffer to encode + @param inlen The length of the input buffer + @param out [out] The destination of the base64 encoded data + @param outlen [in/out] The max size and resulting size + @return CRYPT_OK if successful +*/ +int base64url_encode(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + return _base64_encode_internal(in, inlen, out, outlen, codes_base64url, 0); +} + +int base64url_strict_encode(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + return _base64_encode_internal(in, inlen, out, outlen, codes_base64url, 1); +} +#endif /* LTC_BASE64_URL */ + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/burn_stack.c b/src/ltc/misc/burn_stack.c new file mode 100644 index 0000000..2610c06 --- /dev/null +++ b/src/ltc/misc/burn_stack.c @@ -0,0 +1,34 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file burn_stack.c + Burn stack, Tom St Denis +*/ + +/** + Burn some stack memory + @param len amount of stack to burn in bytes +*/ +void burn_stack(unsigned long len) +{ + unsigned char buf[32]; + zeromem(buf, sizeof(buf)); + if (len > (unsigned long)sizeof(buf)) + burn_stack(len - sizeof(buf)); +} + + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/crc32.c b/src/ltc/misc/crc32.c new file mode 100644 index 0000000..8228c29 --- /dev/null +++ b/src/ltc/misc/crc32.c @@ -0,0 +1,210 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crc32.c + CRC-32 checksum algorithm + Written and placed in the public domain by Wei Dai + Adapted for libtomcrypt by Steffen Jaeckel +*/ +#ifdef LTC_CRC32 + +static const ulong32 _CRC32_NEGL = 0xffffffffUL; + +#if defined(ENDIAN_LITTLE) +#define CRC32_INDEX(c) (c & 0xff) +#define CRC32_SHIFTED(c) (c >> 8) +#elif defined(ENDIAN_BIG) +#define CRC32_INDEX(c) (c >> 24) +#define CRC32_SHIFTED(c) (c << 8) +#else +#error The existing CRC32 implementation only works properly when the endianness of the target platform is known. +#endif + +/* Table of CRC-32's of all single byte values (made by makecrc.c) */ +static const ulong32 crc32_m_tab[] = +{ +#if defined(ENDIAN_LITTLE) + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +#else + 0x00000000L, 0x96300777L, 0x2c610eeeL, 0xba510999L, 0x19c46d07L, + 0x8ff46a70L, 0x35a563e9L, 0xa395649eL, 0x3288db0eL, 0xa4b8dc79L, + 0x1ee9d5e0L, 0x88d9d297L, 0x2b4cb609L, 0xbd7cb17eL, 0x072db8e7L, + 0x911dbf90L, 0x6410b71dL, 0xf220b06aL, 0x4871b9f3L, 0xde41be84L, + 0x7dd4da1aL, 0xebe4dd6dL, 0x51b5d4f4L, 0xc785d383L, 0x56986c13L, + 0xc0a86b64L, 0x7af962fdL, 0xecc9658aL, 0x4f5c0114L, 0xd96c0663L, + 0x633d0ffaL, 0xf50d088dL, 0xc8206e3bL, 0x5e10694cL, 0xe44160d5L, + 0x727167a2L, 0xd1e4033cL, 0x47d4044bL, 0xfd850dd2L, 0x6bb50aa5L, + 0xfaa8b535L, 0x6c98b242L, 0xd6c9bbdbL, 0x40f9bcacL, 0xe36cd832L, + 0x755cdf45L, 0xcf0dd6dcL, 0x593dd1abL, 0xac30d926L, 0x3a00de51L, + 0x8051d7c8L, 0x1661d0bfL, 0xb5f4b421L, 0x23c4b356L, 0x9995bacfL, + 0x0fa5bdb8L, 0x9eb80228L, 0x0888055fL, 0xb2d90cc6L, 0x24e90bb1L, + 0x877c6f2fL, 0x114c6858L, 0xab1d61c1L, 0x3d2d66b6L, 0x9041dc76L, + 0x0671db01L, 0xbc20d298L, 0x2a10d5efL, 0x8985b171L, 0x1fb5b606L, + 0xa5e4bf9fL, 0x33d4b8e8L, 0xa2c90778L, 0x34f9000fL, 0x8ea80996L, + 0x18980ee1L, 0xbb0d6a7fL, 0x2d3d6d08L, 0x976c6491L, 0x015c63e6L, + 0xf4516b6bL, 0x62616c1cL, 0xd8306585L, 0x4e0062f2L, 0xed95066cL, + 0x7ba5011bL, 0xc1f40882L, 0x57c40ff5L, 0xc6d9b065L, 0x50e9b712L, + 0xeab8be8bL, 0x7c88b9fcL, 0xdf1ddd62L, 0x492dda15L, 0xf37cd38cL, + 0x654cd4fbL, 0x5861b24dL, 0xce51b53aL, 0x7400bca3L, 0xe230bbd4L, + 0x41a5df4aL, 0xd795d83dL, 0x6dc4d1a4L, 0xfbf4d6d3L, 0x6ae96943L, + 0xfcd96e34L, 0x468867adL, 0xd0b860daL, 0x732d0444L, 0xe51d0333L, + 0x5f4c0aaaL, 0xc97c0dddL, 0x3c710550L, 0xaa410227L, 0x10100bbeL, + 0x86200cc9L, 0x25b56857L, 0xb3856f20L, 0x09d466b9L, 0x9fe461ceL, + 0x0ef9de5eL, 0x98c9d929L, 0x2298d0b0L, 0xb4a8d7c7L, 0x173db359L, + 0x810db42eL, 0x3b5cbdb7L, 0xad6cbac0L, 0x2083b8edL, 0xb6b3bf9aL, + 0x0ce2b603L, 0x9ad2b174L, 0x3947d5eaL, 0xaf77d29dL, 0x1526db04L, + 0x8316dc73L, 0x120b63e3L, 0x843b6494L, 0x3e6a6d0dL, 0xa85a6a7aL, + 0x0bcf0ee4L, 0x9dff0993L, 0x27ae000aL, 0xb19e077dL, 0x44930ff0L, + 0xd2a30887L, 0x68f2011eL, 0xfec20669L, 0x5d5762f7L, 0xcb676580L, + 0x71366c19L, 0xe7066b6eL, 0x761bd4feL, 0xe02bd389L, 0x5a7ada10L, + 0xcc4add67L, 0x6fdfb9f9L, 0xf9efbe8eL, 0x43beb717L, 0xd58eb060L, + 0xe8a3d6d6L, 0x7e93d1a1L, 0xc4c2d838L, 0x52f2df4fL, 0xf167bbd1L, + 0x6757bca6L, 0xdd06b53fL, 0x4b36b248L, 0xda2b0dd8L, 0x4c1b0aafL, + 0xf64a0336L, 0x607a0441L, 0xc3ef60dfL, 0x55df67a8L, 0xef8e6e31L, + 0x79be6946L, 0x8cb361cbL, 0x1a8366bcL, 0xa0d26f25L, 0x36e26852L, + 0x95770cccL, 0x03470bbbL, 0xb9160222L, 0x2f260555L, 0xbe3bbac5L, + 0x280bbdb2L, 0x925ab42bL, 0x046ab35cL, 0xa7ffd7c2L, 0x31cfd0b5L, + 0x8b9ed92cL, 0x1daede5bL, 0xb0c2649bL, 0x26f263ecL, 0x9ca36a75L, + 0x0a936d02L, 0xa906099cL, 0x3f360eebL, 0x85670772L, 0x13570005L, + 0x824abf95L, 0x147ab8e2L, 0xae2bb17bL, 0x381bb60cL, 0x9b8ed292L, + 0x0dbed5e5L, 0xb7efdc7cL, 0x21dfdb0bL, 0xd4d2d386L, 0x42e2d4f1L, + 0xf8b3dd68L, 0x6e83da1fL, 0xcd16be81L, 0x5b26b9f6L, 0xe177b06fL, + 0x7747b718L, 0xe65a0888L, 0x706a0fffL, 0xca3b0666L, 0x5c0b0111L, + 0xff9e658fL, 0x69ae62f8L, 0xd3ff6b61L, 0x45cf6c16L, 0x78e20aa0L, + 0xeed20dd7L, 0x5483044eL, 0xc2b30339L, 0x612667a7L, 0xf71660d0L, + 0x4d476949L, 0xdb776e3eL, 0x4a6ad1aeL, 0xdc5ad6d9L, 0x660bdf40L, + 0xf03bd837L, 0x53aebca9L, 0xc59ebbdeL, 0x7fcfb247L, 0xe9ffb530L, + 0x1cf2bdbdL, 0x8ac2bacaL, 0x3093b353L, 0xa6a3b424L, 0x0536d0baL, + 0x9306d7cdL, 0x2957de54L, 0xbf67d923L, 0x2e7a66b3L, 0xb84a61c4L, + 0x021b685dL, 0x942b6f2aL, 0x37be0bb4L, 0xa18e0cc3L, 0x1bdf055aL, + 0x8def022dL +#endif +}; + +void crc32_init(crc32_state *ctx) +{ + LTC_ARGCHKVD(ctx != NULL); + ctx->crc = _CRC32_NEGL; +} + +void crc32_update(crc32_state *ctx, const unsigned char *input, unsigned long length) +{ + ulong32 crc; + LTC_ARGCHKVD(ctx != NULL); + LTC_ARGCHKVD(input != NULL); + crc = ctx->crc; + + while (length--) + crc = crc32_m_tab[CRC32_INDEX(crc) ^ *input++] ^ CRC32_SHIFTED(crc); + + ctx->crc = crc; +} + +void crc32_finish(crc32_state *ctx, void *hash, unsigned long size) +{ + unsigned long i; + unsigned char* h; + ulong32 crc; + LTC_ARGCHKVD(ctx != NULL); + LTC_ARGCHKVD(hash != NULL); + + h = hash; + crc = ctx->crc; + crc ^= _CRC32_NEGL; + + if (size > 4) size = 4; + for (i = 0; i < size; i++) { + h[i] = ((unsigned char*)&(crc))[size-i-1]; + } +} + +int crc32_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + const void* in = "libtomcrypt"; + const unsigned char crc32[] = { 0xb3, 0x73, 0x76, 0xef }; + unsigned char out[4]; + crc32_state ctx; + crc32_init(&ctx); + crc32_update(&ctx, in, strlen(in)); + crc32_finish(&ctx, out, 4); + if (XMEMCMP(crc32, out, 4)) { +#ifdef LTC_TEST_DBG + ulong32 _out, _crc32; + LOAD32H(_out, out); + LOAD32H(_crc32, crc32); + printf("crc32 fail! Is: 0x%x Should: 0x%x\n", _out, _crc32); +#endif + return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; +#endif +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/crypt/crypt.c b/src/ltc/misc/crypt/crypt.c new file mode 100644 index 0000000..cfe2606 --- /dev/null +++ b/src/ltc/misc/crypt/crypt.c @@ -0,0 +1,486 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt.c + Build strings, Tom St Denis +*/ +#define NAME_VALUE(s) #s"="NAME(s) +#define NAME(s) #s + +const char *crypt_build_settings = + "LibTomCrypt " SCRYPT " (Tom St Denis, tomstdenis@gmail.com)\n" + "LibTomCrypt is public domain software.\n" +#if defined(INCLUDE_BUILD_DATE) + "Built on " __DATE__ " at " __TIME__ "\n" +#endif + "\n\nEndianness: " +#if defined(ENDIAN_NEUTRAL) + "neutral/" +#endif +#if defined(ENDIAN_LITTLE) + "little" +#elif defined(ENDIAN_BIG) + "big" +#endif + #if defined(ENDIAN_32BITWORD) + " (32-bit words)\n" + #elif defined(ENDIAN_64BITWORD) + " (64-bit words)\n" + #else + " (no wordsize defined)\n" + #endif + "Clean stack: " +#if defined(LTC_CLEAN_STACK) + "enabled\n" +#else + "disabled\n" +#endif + "Ciphers built-in:\n" +#if defined(LTC_BLOWFISH) + " Blowfish\n" +#endif +#if defined(LTC_RC2) + " RC2\n" +#endif +#if defined(LTC_RC5) + " RC5\n" +#endif +#if defined(LTC_RC6) + " RC6\n" +#endif +#if defined(LTC_SAFERP) + " Safer+\n" +#endif +#if defined(LTC_SAFER) + " Safer\n" +#endif +#if defined(LTC_RIJNDAEL) + " Rijndael\n" +#endif +#if defined(LTC_XTEA) + " XTEA\n" +#endif +#if defined(LTC_TWOFISH) + " Twofish " + #if defined(LTC_TWOFISH_SMALL) && defined(LTC_TWOFISH_TABLES) && defined(LTC_TWOFISH_ALL_TABLES) + "(small, tables, all_tables)\n" + #elif defined(LTC_TWOFISH_SMALL) && defined(LTC_TWOFISH_TABLES) + "(small, tables)\n" + #elif defined(LTC_TWOFISH_SMALL) && defined(LTC_TWOFISH_ALL_TABLES) + "(small, all_tables)\n" + #elif defined(LTC_TWOFISH_TABLES) && defined(LTC_TWOFISH_ALL_TABLES) + "(tables, all_tables)\n" + #elif defined(LTC_TWOFISH_SMALL) + "(small)\n" + #elif defined(LTC_TWOFISH_TABLES) + "(tables)\n" + #elif defined(LTC_TWOFISH_ALL_TABLES) + "(all_tables)\n" + #else + "\n" + #endif +#endif +#if defined(LTC_DES) + " DES\n" +#endif +#if defined(LTC_CAST5) + " CAST5\n" +#endif +#if defined(LTC_NOEKEON) + " Noekeon\n" +#endif +#if defined(LTC_SKIPJACK) + " Skipjack\n" +#endif +#if defined(LTC_KHAZAD) + " Khazad\n" +#endif +#if defined(LTC_ANUBIS) + " Anubis " +#endif +#if defined(LTC_ANUBIS_TWEAK) + " (tweaked)" +#endif + "\n" +#if defined(LTC_KSEED) + " KSEED\n" +#endif +#if defined(LTC_KASUMI) + " KASUMI\n" +#endif +#if defined(LTC_MULTI2) + " MULTI2\n" +#endif +#if defined(LTC_CAMELLIA) + " Camellia\n" +#endif + "Stream ciphers built-in:\n" +#if defined(LTC_CHACHA) + " ChaCha\n" +#endif +#if defined(LTC_RC4_STREAM) + " RC4\n" +#endif +#if defined(LTC_SOBER128_STREAM) + " SOBER128\n" +#endif + + "\nHashes built-in:\n" +#if defined(LTC_SHA3) + " SHA3\n" +#endif +#if defined(LTC_SHA512) + " SHA-512\n" +#endif +#if defined(LTC_SHA384) + " SHA-384\n" +#endif +#if defined(LTC_SHA512_256) + " SHA-512/256\n" +#endif +#if defined(LTC_SHA256) + " SHA-256\n" +#endif +#if defined(LTC_SHA512_224) + " SHA-512/224\n" +#endif +#if defined(LTC_SHA224) + " SHA-224\n" +#endif +#if defined(LTC_TIGER) + " TIGER\n" +#endif +#if defined(LTC_SHA1) + " SHA1\n" +#endif +#if defined(LTC_MD5) + " MD5\n" +#endif +#if defined(LTC_MD4) + " MD4\n" +#endif +#if defined(LTC_MD2) + " MD2\n" +#endif +#if defined(LTC_RIPEMD128) + " RIPEMD128\n" +#endif +#if defined(LTC_RIPEMD160) + " RIPEMD160\n" +#endif +#if defined(LTC_RIPEMD256) + " RIPEMD256\n" +#endif +#if defined(LTC_RIPEMD320) + " RIPEMD320\n" +#endif +#if defined(LTC_WHIRLPOOL) + " WHIRLPOOL\n" +#endif +#if defined(LTC_BLAKE2S) + " BLAKE2S\n" +#endif +#if defined(LTC_BLAKE2B) + " BLAKE2B\n" +#endif +#if defined(LTC_CHC_HASH) + " CHC_HASH\n" +#endif + + "\nBlock Chaining Modes:\n" +#if defined(LTC_CFB_MODE) + " CFB\n" +#endif +#if defined(LTC_OFB_MODE) + " OFB\n" +#endif +#if defined(LTC_ECB_MODE) + " ECB\n" +#endif +#if defined(LTC_CBC_MODE) + " CBC\n" +#endif +#if defined(LTC_CTR_MODE) + " CTR\n" +#endif +#if defined(LTC_LRW_MODE) + " LRW" +#if defined(LTC_LRW_TABLES) + " (tables) " +#endif + "\n" +#endif +#if defined(LTC_F8_MODE) + " F8\n" +#endif +#if defined(LTC_XTS_MODE) + " XTS\n" +#endif + + "\nMACs:\n" +#if defined(LTC_HMAC) + " HMAC\n" +#endif +#if defined(LTC_OMAC) + " OMAC\n" +#endif +#if defined(LTC_PMAC) + " PMAC\n" +#endif +#if defined(LTC_PELICAN) + " PELICAN\n" +#endif +#if defined(LTC_XCBC) + " XCBC\n" +#endif +#if defined(LTC_F9_MODE) + " F9\n" +#endif +#if defined(LTC_POLY1305) + " POLY1305\n" +#endif +#if defined(LTC_BLAKE2SMAC) + " BLAKE2S MAC\n" +#endif +#if defined(LTC_BLAKE2BMAC) + " BLAKE2B MAC\n" +#endif + + "\nENC + AUTH modes:\n" +#if defined(LTC_EAX_MODE) + " EAX\n" +#endif +#if defined(LTC_OCB_MODE) + " OCB\n" +#endif +#if defined(LTC_OCB3_MODE) + " OCB3\n" +#endif +#if defined(LTC_CCM_MODE) + " CCM\n" +#endif +#if defined(LTC_GCM_MODE) + " GCM" +#if defined(LTC_GCM_TABLES) + " (tables) " +#endif +#if defined(LTC_GCM_TABLES_SSE2) + " (SSE2) " +#endif + "\n" +#endif +#if defined(LTC_CHACHA20POLY1305_MODE) + " CHACHA20POLY1305\n" +#endif + + "\nPRNG:\n" +#if defined(LTC_YARROW) + " Yarrow ("NAME_VALUE(LTC_YARROW_AES)")\n" +#endif +#if defined(LTC_SPRNG) + " SPRNG\n" +#endif +#if defined(LTC_RC4) + " RC4\n" +#endif +#if defined(LTC_CHACHA20_PRNG) + " ChaCha20\n" +#endif +#if defined(LTC_FORTUNA) + " Fortuna (" NAME_VALUE(LTC_FORTUNA_POOLS) ", " NAME_VALUE(LTC_FORTUNA_WD) ")\n" +#endif +#if defined(LTC_SOBER128) + " SOBER128\n" +#endif + + "\nPK Algs:\n" +#if defined(LTC_MRSA) + " RSA" +#if defined(LTC_RSA_BLINDING) && defined(LTC_RSA_CRT_HARDENING) + " (with blinding and CRT hardening)" +#elif defined(LTC_RSA_BLINDING) + " (with blinding)" +#elif defined(LTC_RSA_CRT_HARDENING) + " (with CRT hardening)" +#endif + "\n" +#endif +#if defined(LTC_MDH) + " DH\n" +#endif +#if defined(LTC_MECC) + " ECC" +#if defined(LTC_ECC_TIMING_RESISTANT) + " (with blinding)" +#endif + "\n" +#endif +#if defined(LTC_MDSA) + " DSA\n" +#endif +#if defined(LTC_MKAT) + " Katja\n" +#endif + + "\nCompiler:\n" +#if defined(_WIN64) + " WIN64 platform detected.\n" +#elif defined(_WIN32) + " WIN32 platform detected.\n" +#endif +#if defined(__CYGWIN__) + " CYGWIN Detected.\n" +#endif +#if defined(__DJGPP__) + " DJGPP Detected.\n" +#endif +#if defined(_MSC_VER) + " MSVC compiler detected.\n" +#endif +#if defined(__clang_version__) + " Clang compiler " __clang_version__ ".\n" +#elif defined(INTEL_CC) + " Intel C Compiler " __VERSION__ ".\n" +#elif defined(__GNUC__) /* clang and icc also define __GNUC__ */ + " GCC compiler " __VERSION__ ".\n" +#endif + +#if defined(__x86_64__) + " x86-64 detected.\n" +#endif +#if defined(LTC_PPC32) + " PPC32 detected.\n" +#endif + + "\nVarious others: " +#if defined(LTC_ADLER32) + " ADLER32 " +#endif +#if defined(LTC_BASE64) + " BASE64 " +#endif +#if defined(LTC_BASE64_URL) + " BASE64-URL-SAFE " +#endif +#if defined(LTC_CRC32) + " CRC32 " +#endif +#if defined(LTC_DER) + " DER " +#endif +#if defined(LTC_DER_MAX_PUBKEY_SIZE) + " " NAME_VALUE(LTC_DER_MAX_PUBKEY_SIZE) " " +#endif +#if defined(LTC_PKCS_1) + " PKCS#1 " +#endif +#if defined(LTC_PKCS_5) + " PKCS#5 " +#endif +#if defined(LTC_HKDF) + " HKDF " +#endif +#if defined(MPI) + " MPI " +#endif +#if defined(LTC_DEVRANDOM) + " LTC_DEVRANDOM " +#endif +#if defined(LTC_TRY_URANDOM_FIRST) + " LTC_TRY_URANDOM_FIRST " +#endif +#if defined(LTC_RNG_GET_BYTES) + " LTC_RNG_GET_BYTES " +#endif +#if defined(LTC_RNG_MAKE_PRNG) + " LTC_RNG_MAKE_PRNG " +#endif +#if defined(LTC_PRNG_ENABLE_LTC_RNG) + " LTC_PRNG_ENABLE_LTC_RNG " +#endif +#if defined(LTC_HASH_HELPERS) + " LTC_HASH_HELPERS " +#endif +#if defined(LTC_VALGRIND) + " LTC_VALGRIND " +#endif +#if defined(LTC_TEST) + " LTC_TEST " +#endif +#if defined(LTC_TEST_EXT) + " LTC_TEST_EXT " +#endif +#if defined(LTC_SMALL_CODE) + " LTC_SMALL_CODE " +#endif +#if defined(LTC_NO_FILE) + " LTC_NO_FILE " +#endif +#if defined(LTC_FILE_READ_BUFSIZE) + " " NAME_VALUE(LTC_FILE_READ_BUFSIZE) " " +#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 +#if defined(LTC_ROx_ASM) + " LTC_ROx_ASM " +#if defined(LTC_NO_ROLC) + " LTC_NO_ROLC " +#endif +#endif +#if defined(LTC_NO_TEST) + " LTC_NO_TEST " +#endif +#if defined(LTC_NO_TABLES) + " LTC_NO_TABLES " +#endif +#if defined(LTC_PTHREAD) + " LTC_PTHREAD " +#endif +#if defined(LTM_DESC) + " LTM_DESC " +#endif +#if defined(TFM_DESC) + " TFM_DESC " +#endif +#if defined(GMP_DESC) + " GMP_DESC " +#endif +#if defined(LTC_EASY) + " LTC_EASY " +#endif +#if defined(LTC_MECC_ACCEL) + " LTC_MECC_ACCEL " +#endif +#if defined(LTC_MECC_FP) + " LTC_MECC_FP " +#endif +#if defined(LTC_ECC_SHAMIR) + " LTC_ECC_SHAMIR " +#endif + "\n" + ; + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/crypt/crypt_argchk.c b/src/ltc/misc/crypt/crypt_argchk.c new file mode 100644 index 0000000..8588896 --- /dev/null +++ b/src/ltc/misc/crypt/crypt_argchk.c @@ -0,0 +1,29 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_argchk.c + Perform argument checking, Tom St Denis +*/ + +#if (ARGTYPE == 0) +void crypt_argchk(char *v, char *s, int d) +{ + fprintf(stderr, "LTC_ARGCHK '%s' failure on line %d of file %s\n", + v, d, s); + abort(); +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/crypt/crypt_cipher_descriptor.c b/src/ltc/misc/crypt/crypt_cipher_descriptor.c new file mode 100644 index 0000000..2e35787 --- /dev/null +++ b/src/ltc/misc/crypt/crypt_cipher_descriptor.c @@ -0,0 +1,27 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_cipher_descriptor.c + Stores the cipher descriptor table, Tom St Denis +*/ + +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, NULL, NULL, NULL, NULL, NULL, NULL, NULL } + }; + +LTC_MUTEX_GLOBAL(ltc_cipher_mutex) + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/crypt/crypt_cipher_is_valid.c b/src/ltc/misc/crypt/crypt_cipher_is_valid.c new file mode 100644 index 0000000..35f1ace --- /dev/null +++ b/src/ltc/misc/crypt/crypt_cipher_is_valid.c @@ -0,0 +1,36 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_cipher_is_valid.c + Determine if cipher is valid, Tom St Denis +*/ + +/* + Test if a cipher index is valid + @param idx The index of the cipher to search for + @return CRYPT_OK if valid +*/ +int cipher_is_valid(int idx) +{ + LTC_MUTEX_LOCK(<c_cipher_mutex); + if (idx < 0 || idx >= TAB_SIZE || cipher_descriptor[idx].name == NULL) { + LTC_MUTEX_UNLOCK(<c_cipher_mutex); + return CRYPT_INVALID_CIPHER; + } + LTC_MUTEX_UNLOCK(<c_cipher_mutex); + return CRYPT_OK; +} + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/crypt/crypt_find_cipher.c b/src/ltc/misc/crypt/crypt_find_cipher.c new file mode 100644 index 0000000..0c563b0 --- /dev/null +++ b/src/ltc/misc/crypt/crypt_find_cipher.c @@ -0,0 +1,41 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_find_cipher.c + Find a cipher in the descriptor tables, Tom St Denis +*/ + +/** + Find a registered cipher by name + @param name The name of the cipher to look for + @return >= 0 if found, -1 if not present +*/ +int find_cipher(const char *name) +{ + int x; + LTC_ARGCHK(name != NULL); + LTC_MUTEX_LOCK(<c_cipher_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if (cipher_descriptor[x].name != NULL && !XSTRCMP(cipher_descriptor[x].name, name)) { + LTC_MUTEX_UNLOCK(<c_cipher_mutex); + return x; + } + } + LTC_MUTEX_UNLOCK(<c_cipher_mutex); + return -1; +} + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/crypt/crypt_find_cipher_any.c b/src/ltc/misc/crypt/crypt_find_cipher_any.c new file mode 100644 index 0000000..34cd8f0 --- /dev/null +++ b/src/ltc/misc/crypt/crypt_find_cipher_any.c @@ -0,0 +1,50 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_find_cipher_any.c + Find a cipher in the descriptor tables, Tom St Denis +*/ + +/** + Find a cipher flexibly. First by name then if not present by block and key size + @param name The name of the cipher desired + @param blocklen The minimum length of the block cipher desired (octets) + @param keylen The minimum length of the key size desired (octets) + @return >= 0 if found, -1 if not present +*/ +int find_cipher_any(const char *name, int blocklen, int keylen) +{ + int x; + + LTC_ARGCHK(name != NULL); + + x = find_cipher(name); + if (x != -1) return x; + + LTC_MUTEX_LOCK(<c_cipher_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if (cipher_descriptor[x].name == NULL) { + continue; + } + if (blocklen <= (int)cipher_descriptor[x].block_length && keylen <= (int)cipher_descriptor[x].max_key_length) { + LTC_MUTEX_UNLOCK(<c_cipher_mutex); + return x; + } + } + LTC_MUTEX_UNLOCK(<c_cipher_mutex); + return -1; +} + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/crypt/crypt_find_cipher_id.c b/src/ltc/misc/crypt/crypt_find_cipher_id.c new file mode 100644 index 0000000..be4e0fa --- /dev/null +++ b/src/ltc/misc/crypt/crypt_find_cipher_id.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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_find_cipher_id.c + Find cipher by ID, Tom St Denis +*/ + +/** + Find a cipher by ID number + @param ID The ID (not same as index) of the cipher to find + @return >= 0 if found, -1 if not present +*/ +int find_cipher_id(unsigned char ID) +{ + int x; + LTC_MUTEX_LOCK(<c_cipher_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if (cipher_descriptor[x].ID == ID) { + x = (cipher_descriptor[x].name == NULL) ? -1 : x; + LTC_MUTEX_UNLOCK(<c_cipher_mutex); + return x; + } + } + LTC_MUTEX_UNLOCK(<c_cipher_mutex); + return -1; +} + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/crypt/crypt_find_hash.c b/src/ltc/misc/crypt/crypt_find_hash.c new file mode 100644 index 0000000..12ef320 --- /dev/null +++ b/src/ltc/misc/crypt/crypt_find_hash.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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_find_hash.c + Find a hash, Tom St Denis +*/ + +/** + Find a registered hash by name + @param name The name of the hash to look for + @return >= 0 if found, -1 if not present +*/ +int find_hash(const char *name) +{ + int x; + LTC_ARGCHK(name != NULL); + LTC_MUTEX_LOCK(<c_hash_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if (hash_descriptor[x].name != NULL && XSTRCMP(hash_descriptor[x].name, name) == 0) { + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return x; + } + } + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return -1; +} + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/crypt/crypt_find_hash_any.c b/src/ltc/misc/crypt/crypt_find_hash_any.c new file mode 100644 index 0000000..777ce08 --- /dev/null +++ b/src/ltc/misc/crypt/crypt_find_hash_any.c @@ -0,0 +1,49 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_find_hash_any.c + Find a hash, Tom St Denis +*/ + +/** + Find a hash flexibly. First by name then if not present by digest size + @param name The name of the hash desired + @param digestlen The minimum length of the digest size (octets) + @return >= 0 if found, -1 if not present +*/int find_hash_any(const char *name, int digestlen) +{ + int x, y, z; + LTC_ARGCHK(name != NULL); + + x = find_hash(name); + if (x != -1) return x; + + LTC_MUTEX_LOCK(<c_hash_mutex); + y = MAXBLOCKSIZE+1; + z = -1; + for (x = 0; x < TAB_SIZE; x++) { + if (hash_descriptor[x].name == NULL) { + continue; + } + if ((int)hash_descriptor[x].hashsize >= digestlen && (int)hash_descriptor[x].hashsize < y) { + z = x; + y = hash_descriptor[x].hashsize; + } + } + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return z; +} + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/crypt/crypt_find_hash_id.c b/src/ltc/misc/crypt/crypt_find_hash_id.c new file mode 100644 index 0000000..f8e75fc --- /dev/null +++ b/src/ltc/misc/crypt/crypt_find_hash_id.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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_find_hash_id.c + Find hash by ID, Tom St Denis +*/ + +/** + Find a hash by ID number + @param ID The ID (not same as index) of the hash to find + @return >= 0 if found, -1 if not present +*/ +int find_hash_id(unsigned char ID) +{ + int x; + LTC_MUTEX_LOCK(<c_hash_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if (hash_descriptor[x].ID == ID) { + x = (hash_descriptor[x].name == NULL) ? -1 : x; + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return x; + } + } + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return -1; +} + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/crypt/crypt_find_hash_oid.c b/src/ltc/misc/crypt/crypt_find_hash_oid.c new file mode 100644 index 0000000..19aece7 --- /dev/null +++ b/src/ltc/misc/crypt/crypt_find_hash_oid.c @@ -0,0 +1,35 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_find_hash_oid.c + Find a hash, Tom St Denis +*/ + +int find_hash_oid(const unsigned long *ID, unsigned long IDlen) +{ + int x; + LTC_ARGCHK(ID != NULL); + LTC_MUTEX_LOCK(<c_hash_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if (hash_descriptor[x].name != NULL && hash_descriptor[x].OIDlen == IDlen && !XMEMCMP(hash_descriptor[x].OID, ID, sizeof(unsigned long) * IDlen)) { + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return x; + } + } + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return -1; +} + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/crypt/crypt_find_prng.c b/src/ltc/misc/crypt/crypt_find_prng.c new file mode 100644 index 0000000..af3f7b6 --- /dev/null +++ b/src/ltc/misc/crypt/crypt_find_prng.c @@ -0,0 +1,41 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_find_prng.c + Find a PRNG, Tom St Denis +*/ + +/** + Find a registered PRNG by name + @param name The name of the PRNG to look for + @return >= 0 if found, -1 if not present +*/ +int find_prng(const char *name) +{ + int x; + LTC_ARGCHK(name != NULL); + LTC_MUTEX_LOCK(<c_prng_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if ((prng_descriptor[x].name != NULL) && XSTRCMP(prng_descriptor[x].name, name) == 0) { + LTC_MUTEX_UNLOCK(<c_prng_mutex); + return x; + } + } + LTC_MUTEX_UNLOCK(<c_prng_mutex); + return -1; +} + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/crypt/crypt_fsa.c b/src/ltc/misc/crypt/crypt_fsa.c new file mode 100644 index 0000000..e177f9a --- /dev/null +++ b/src/ltc/misc/crypt/crypt_fsa.c @@ -0,0 +1,58 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" +#include + +/** + @file crypt_fsa.c + LibTomCrypt FULL SPEED AHEAD!, Tom St Denis +*/ + +/* format is ltc_mp, cipher_desc, [cipher_desc], NULL, hash_desc, [hash_desc], NULL, prng_desc, [prng_desc], NULL */ +int crypt_fsa(void *mp, ...) +{ + va_list args; + void *p; + + va_start(args, mp); + if (mp != NULL) { + XMEMCPY(<c_mp, mp, sizeof(ltc_mp)); + } + + while ((p = va_arg(args, void*)) != NULL) { + if (register_cipher(p) == -1) { + va_end(args); + return CRYPT_INVALID_CIPHER; + } + } + + while ((p = va_arg(args, void*)) != NULL) { + if (register_hash(p) == -1) { + va_end(args); + return CRYPT_INVALID_HASH; + } + } + + while ((p = va_arg(args, void*)) != NULL) { + if (register_prng(p) == -1) { + va_end(args); + return CRYPT_INVALID_PRNG; + } + } + + va_end(args); + return CRYPT_OK; +} + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/crypt/crypt_hash_descriptor.c b/src/ltc/misc/crypt/crypt_hash_descriptor.c new file mode 100644 index 0000000..4e8bce1 --- /dev/null +++ b/src/ltc/misc/crypt/crypt_hash_descriptor.c @@ -0,0 +1,27 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_hash_descriptor.c + Stores the hash descriptor table, Tom St Denis +*/ + +struct ltc_hash_descriptor hash_descriptor[TAB_SIZE] = { +{ NULL, 0, 0, 0, { 0 }, 0, NULL, NULL, NULL, NULL, NULL } +}; + +LTC_MUTEX_GLOBAL(ltc_hash_mutex) + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/crypt/crypt_hash_is_valid.c b/src/ltc/misc/crypt/crypt_hash_is_valid.c new file mode 100644 index 0000000..dbab714 --- /dev/null +++ b/src/ltc/misc/crypt/crypt_hash_is_valid.c @@ -0,0 +1,36 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_hash_is_valid.c + Determine if hash is valid, Tom St Denis +*/ + +/* + Test if a hash index is valid + @param idx The index of the hash to search for + @return CRYPT_OK if valid +*/ +int hash_is_valid(int idx) +{ + LTC_MUTEX_LOCK(<c_hash_mutex); + if (idx < 0 || idx >= TAB_SIZE || hash_descriptor[idx].name == NULL) { + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return CRYPT_INVALID_HASH; + } + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return CRYPT_OK; +} + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/crypt/crypt_inits.c b/src/ltc/misc/crypt/crypt_inits.c new file mode 100644 index 0000000..cc92f52 --- /dev/null +++ b/src/ltc/misc/crypt/crypt_inits.c @@ -0,0 +1,44 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_inits.c + + Provide math library functions for dynamic languages + like Python - Larry Bugbee, February 2013 +*/ + + +#ifdef LTM_DESC +void init_LTM(void) { + ltc_mp = ltm_desc; +} +#endif + +#ifdef TFM_DESC +void init_TFM(void) { + ltc_mp = tfm_desc; +} +#endif + +/* *** use of GMP is untested *** +#ifdef GMP_DESC +void init_GMP(void) { + ltc_mp = gmp_desc; +} +#endif +*/ + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/crypt/crypt_ltc_mp_descriptor.c b/src/ltc/misc/crypt/crypt_ltc_mp_descriptor.c new file mode 100644 index 0000000..0577d1d --- /dev/null +++ b/src/ltc/misc/crypt/crypt_ltc_mp_descriptor.c @@ -0,0 +1,13 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +ltc_math_descriptor ltc_mp; diff --git a/src/ltc/misc/crypt/crypt_prng_descriptor.c b/src/ltc/misc/crypt/crypt_prng_descriptor.c new file mode 100644 index 0000000..926f3bb --- /dev/null +++ b/src/ltc/misc/crypt/crypt_prng_descriptor.c @@ -0,0 +1,26 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_prng_descriptor.c + Stores the PRNG descriptors, Tom St Denis +*/ +struct ltc_prng_descriptor prng_descriptor[TAB_SIZE] = { +{ NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } +}; + +LTC_MUTEX_GLOBAL(ltc_prng_mutex) + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/crypt/crypt_prng_is_valid.c b/src/ltc/misc/crypt/crypt_prng_is_valid.c new file mode 100644 index 0000000..ccc6e04 --- /dev/null +++ b/src/ltc/misc/crypt/crypt_prng_is_valid.c @@ -0,0 +1,36 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_prng_is_valid.c + Determine if PRNG is valid, Tom St Denis +*/ + +/* + Test if a PRNG index is valid + @param idx The index of the PRNG to search for + @return CRYPT_OK if valid +*/ +int prng_is_valid(int idx) +{ + LTC_MUTEX_LOCK(<c_prng_mutex); + if (idx < 0 || idx >= TAB_SIZE || prng_descriptor[idx].name == NULL) { + LTC_MUTEX_UNLOCK(<c_prng_mutex); + return CRYPT_INVALID_PRNG; + } + LTC_MUTEX_UNLOCK(<c_prng_mutex); + return CRYPT_OK; +} + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/crypt/crypt_register_cipher.c b/src/ltc/misc/crypt/crypt_register_cipher.c new file mode 100644 index 0000000..d7feedf --- /dev/null +++ b/src/ltc/misc/crypt/crypt_register_cipher.c @@ -0,0 +1,54 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_register_cipher.c + Register a cipher, Tom St Denis +*/ + +/** + Register a cipher with the descriptor table + @param cipher The cipher you wish to register + @return value >= 0 if successfully added (or already present), -1 if unsuccessful +*/ +int register_cipher(const struct ltc_cipher_descriptor *cipher) +{ + int x; + + LTC_ARGCHK(cipher != NULL); + + /* is it already registered? */ + LTC_MUTEX_LOCK(<c_cipher_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if (cipher_descriptor[x].name != NULL && cipher_descriptor[x].ID == cipher->ID) { + LTC_MUTEX_UNLOCK(<c_cipher_mutex); + return x; + } + } + + /* find a blank spot */ + for (x = 0; x < TAB_SIZE; x++) { + if (cipher_descriptor[x].name == NULL) { + XMEMCPY(&cipher_descriptor[x], cipher, sizeof(struct ltc_cipher_descriptor)); + LTC_MUTEX_UNLOCK(<c_cipher_mutex); + return x; + } + } + + /* no spot */ + LTC_MUTEX_UNLOCK(<c_cipher_mutex); + return -1; +} + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/crypt/crypt_register_hash.c b/src/ltc/misc/crypt/crypt_register_hash.c new file mode 100644 index 0000000..10ccee4 --- /dev/null +++ b/src/ltc/misc/crypt/crypt_register_hash.c @@ -0,0 +1,54 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_register_hash.c + Register a HASH, Tom St Denis +*/ + +/** + Register a hash with the descriptor table + @param hash The hash you wish to register + @return value >= 0 if successfully added (or already present), -1 if unsuccessful +*/ +int register_hash(const struct ltc_hash_descriptor *hash) +{ + int x; + + LTC_ARGCHK(hash != NULL); + + /* is it already registered? */ + LTC_MUTEX_LOCK(<c_hash_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if (XMEMCMP(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)) == 0) { + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return x; + } + } + + /* find a blank spot */ + for (x = 0; x < TAB_SIZE; x++) { + if (hash_descriptor[x].name == NULL) { + XMEMCPY(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)); + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return x; + } + } + + /* no spot */ + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return -1; +} + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/crypt/crypt_register_prng.c b/src/ltc/misc/crypt/crypt_register_prng.c new file mode 100644 index 0000000..faebb18 --- /dev/null +++ b/src/ltc/misc/crypt/crypt_register_prng.c @@ -0,0 +1,54 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_register_prng.c + Register a PRNG, Tom St Denis +*/ + +/** + Register a PRNG with the descriptor table + @param prng The PRNG you wish to register + @return value >= 0 if successfully added (or already present), -1 if unsuccessful +*/ +int register_prng(const struct ltc_prng_descriptor *prng) +{ + int x; + + LTC_ARGCHK(prng != NULL); + + /* is it already registered? */ + LTC_MUTEX_LOCK(<c_prng_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if (XMEMCMP(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)) == 0) { + LTC_MUTEX_UNLOCK(<c_prng_mutex); + return x; + } + } + + /* find a blank spot */ + for (x = 0; x < TAB_SIZE; x++) { + if (prng_descriptor[x].name == NULL) { + XMEMCPY(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)); + LTC_MUTEX_UNLOCK(<c_prng_mutex); + return x; + } + } + + /* no spot */ + LTC_MUTEX_UNLOCK(<c_prng_mutex); + return -1; +} + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/crypt/crypt_unregister_cipher.c b/src/ltc/misc/crypt/crypt_unregister_cipher.c new file mode 100644 index 0000000..b75785f --- /dev/null +++ b/src/ltc/misc/crypt/crypt_unregister_cipher.c @@ -0,0 +1,45 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_unregister_cipher.c + Unregister a cipher, Tom St Denis +*/ + +/** + Unregister a cipher from the descriptor table + @param cipher The cipher descriptor to remove + @return CRYPT_OK on success +*/ +int unregister_cipher(const struct ltc_cipher_descriptor *cipher) +{ + int x; + + LTC_ARGCHK(cipher != NULL); + + /* is it already registered? */ + LTC_MUTEX_LOCK(<c_cipher_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if (XMEMCMP(&cipher_descriptor[x], cipher, sizeof(struct ltc_cipher_descriptor)) == 0) { + cipher_descriptor[x].name = NULL; + cipher_descriptor[x].ID = 255; + LTC_MUTEX_UNLOCK(<c_cipher_mutex); + return CRYPT_OK; + } + } + LTC_MUTEX_UNLOCK(<c_cipher_mutex); + return CRYPT_ERROR; +} + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/crypt/crypt_unregister_hash.c b/src/ltc/misc/crypt/crypt_unregister_hash.c new file mode 100644 index 0000000..ac95d2d --- /dev/null +++ b/src/ltc/misc/crypt/crypt_unregister_hash.c @@ -0,0 +1,44 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_unregister_hash.c + Unregister a hash, Tom St Denis +*/ + +/** + Unregister a hash from the descriptor table + @param hash The hash descriptor to remove + @return CRYPT_OK on success +*/ +int unregister_hash(const struct ltc_hash_descriptor *hash) +{ + int x; + + LTC_ARGCHK(hash != NULL); + + /* is it already registered? */ + LTC_MUTEX_LOCK(<c_hash_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if (XMEMCMP(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)) == 0) { + hash_descriptor[x].name = NULL; + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return CRYPT_OK; + } + } + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return CRYPT_ERROR; +} + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/crypt/crypt_unregister_prng.c b/src/ltc/misc/crypt/crypt_unregister_prng.c new file mode 100644 index 0000000..424131a --- /dev/null +++ b/src/ltc/misc/crypt/crypt_unregister_prng.c @@ -0,0 +1,44 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file crypt_unregister_prng.c + Unregister a PRNG, Tom St Denis +*/ + +/** + Unregister a PRNG from the descriptor table + @param prng The PRNG descriptor to remove + @return CRYPT_OK on success +*/ +int unregister_prng(const struct ltc_prng_descriptor *prng) +{ + int x; + + LTC_ARGCHK(prng != NULL); + + /* is it already registered? */ + LTC_MUTEX_LOCK(<c_prng_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if (XMEMCMP(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)) == 0) { + prng_descriptor[x].name = NULL; + LTC_MUTEX_UNLOCK(<c_prng_mutex); + return CRYPT_OK; + } + } + LTC_MUTEX_UNLOCK(<c_prng_mutex); + return CRYPT_ERROR; +} + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/error_to_string.c b/src/ltc/misc/error_to_string.c new file mode 100644 index 0000000..c3d0872 --- /dev/null +++ b/src/ltc/misc/error_to_string.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://libtom.org + */ + +#include "tomcrypt.h" + +/** + @file error_to_string.c + Convert error codes to ASCII strings, Tom St Denis +*/ + +static const char * const err_2_str[] = +{ + "CRYPT_OK", + "CRYPT_ERROR", + "Non-fatal 'no-operation' requested.", + + "Invalid keysize for block cipher.", + "Invalid number of rounds for block cipher.", + "Algorithm failed test vectors.", + + "Buffer overflow.", + "Invalid input packet.", + + "Invalid number of bits for a PRNG.", + "Error reading the PRNG.", + + "Invalid cipher specified.", + "Invalid hash specified.", + "Invalid PRNG specified.", + + "Out of memory.", + + "Invalid PK key or key type specified for function.", + "A private PK key is required.", + + "Invalid argument provided.", + "File Not Found", + + "Invalid PK type.", + + "An overflow of a value was detected/prevented.", + + "UNUSED1.", + "UNUSED2.", + + "Invalid sized parameter.", + + "Invalid size for prime.", + + "Invalid padding.", + + "Hash applied to too many bits.", +}; + +/** + Convert an LTC error code to ASCII + @param err The error code + @return A pointer to the ASCII NUL terminated string for the error or "Invalid error code." if the err code was not valid. +*/ +const char *error_to_string(int err) +{ + if (err < 0 || err >= (int)(sizeof(err_2_str)/sizeof(err_2_str[0]))) { + return "Invalid error code."; + } else { + return err_2_str[err]; + } +} + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/hkdf/hkdf.c b/src/ltc/misc/hkdf/hkdf.c new file mode 100644 index 0000000..c4d69d1 --- /dev/null +++ b/src/ltc/misc/hkdf/hkdf.c @@ -0,0 +1,142 @@ +#include +#include +#include + +#include + +#ifdef LTC_HKDF + +/* This is mostly just a wrapper around hmac_memory */ +int hkdf_extract(int hash_idx, const unsigned char *salt, unsigned long saltlen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + /* libtomcrypt chokes on a zero length HMAC key, so we need to check for + that. HMAC specifies that keys shorter than the hash's blocksize are + 0 padded to the block size. HKDF specifies that a NULL salt is to be + substituted with a salt comprised of hashLen 0 bytes. HMAC's padding + means that in either case the HMAC is actually using a blocksize long + zero filled key. Unless blocksize < hashLen (which wouldn't make any + sense), we can use a single 0 byte as the HMAC key and still generate + valid results for HKDF. */ + if (salt == NULL || saltlen == 0) { + return hmac_memory(hash_idx, (const unsigned char *)"", 1, in, inlen, out, outlen); + } else { + return hmac_memory(hash_idx, salt, saltlen, in, inlen, out, outlen); + } +} + +int hkdf_expand(int hash_idx, const unsigned char *info, unsigned long infolen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long outlen) +{ + unsigned long hashsize; + int err; + unsigned char N; + unsigned long Noutlen, outoff; + + unsigned char *T, *dat; + unsigned long Tlen, datlen; + + /* make sure hash descriptor is valid */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + + hashsize = hash_descriptor[hash_idx].hashsize; + + /* RFC5869 parameter restrictions */ + if (inlen < hashsize || outlen > hashsize * 255) + return CRYPT_INVALID_ARG; + if (info == NULL && infolen != 0) + return CRYPT_INVALID_ARG; + LTC_ARGCHK(out != NULL); + + Tlen = hashsize + infolen + 1; + T = XMALLOC(Tlen); /* Replace with static buffer? */ + if (T == NULL) { + return CRYPT_MEM; + } + if (info != NULL) { + XMEMCPY(T + hashsize, info, infolen); + } + + /* HMAC data T(1) doesn't include a previous hash value */ + dat = T + hashsize; + datlen = Tlen - hashsize; + + N = 0; + outoff = 0; /* offset in out to write to */ + while (1) { /* an exit condition breaks mid-loop */ + Noutlen = MIN(hashsize, outlen - outoff); + T[Tlen - 1] = ++N; + if ((err = hmac_memory(hash_idx, in, inlen, dat, datlen, + out + outoff, &Noutlen)) != CRYPT_OK) { + zeromem(T, Tlen); + XFREE(T); + return err; + } + outoff += Noutlen; + + if (outoff >= outlen) /* loop exit condition */ + break; + + /* All subsequent HMAC data T(N) DOES include the previous hash value */ + XMEMCPY(T, out + hashsize * (N-1), hashsize); + if (N == 1) { + dat = T; + datlen = Tlen; + } + } + zeromem(T, Tlen); + XFREE(T); + return CRYPT_OK; +} + +/* all in one step */ +int hkdf(int hash_idx, const unsigned char *salt, unsigned long saltlen, + const unsigned char *info, unsigned long infolen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long outlen) +{ + unsigned long hashsize; + int err; + unsigned char *extracted; + + /* make sure hash descriptor is valid */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + + hashsize = hash_descriptor[hash_idx].hashsize; + + extracted = XMALLOC(hashsize); /* replace with static buffer? */ + if (extracted == NULL) { + return CRYPT_MEM; + } + if ((err = hkdf_extract(hash_idx, salt, saltlen, in, inlen, extracted, &hashsize)) != 0) { + zeromem(extracted, hashsize); + XFREE(extracted); + return err; + } +#if 0 + { + int j; + printf("\nPRK: 0x"); + for(j=0; j < hashsize; j++) { + printf("%02x ", extracted[j]); + } + for(j=0; j < hashsize; j++) { + printf("%02x ", extracted[j]); + } + } +#endif + err = hkdf_expand(hash_idx, info, infolen, extracted, hashsize, out, outlen); + zeromem(extracted, hashsize); + XFREE(extracted); + return err; +} +#endif /* LTC_HKDF */ + + +/* vim: set ts=2 sw=2 et ai si: */ diff --git a/src/ltc/misc/mem_neq.c b/src/ltc/misc/mem_neq.c new file mode 100644 index 0000000..917b758 --- /dev/null +++ b/src/ltc/misc/mem_neq.c @@ -0,0 +1,60 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file mem_neq.c + Compare two blocks of memory for inequality. + Steffen Jaeckel +*/ + +/** + Compare two blocks of memory for inequality. + + The usage is similar to that of standard memcmp, but you can only test + if the memory is equal or not - you can not determine by how much the + first different byte differs. + + @param a The first memory region + @param b The second memory region + @param len The length of the area to compare (octets) + + @return 0 when a and b are equal for len bytes, else they are not equal. +*/ +int mem_neq(const void *a, const void *b, size_t len) +{ + unsigned char ret = 0; + const unsigned char* pa; + const unsigned char* pb; + + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + + pa = a; + pb = b; + + while (len-- > 0) { + ret |= *pa ^ *pb; + ++pa; + ++pb; + } + + ret |= ret >> 4; + ret |= ret >> 2; + ret |= ret >> 1; + ret &= 1; + + return ret; +} + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/pk_get_oid.c b/src/ltc/misc/pk_get_oid.c new file mode 100644 index 0000000..8c08380 --- /dev/null +++ b/src/ltc/misc/pk_get_oid.c @@ -0,0 +1,57 @@ +/* LibTomCrypt, modular cryptographic library + * + * 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. + * + */ +#include "tomcrypt.h" + +#ifdef LTC_DER +static const oid_st rsa_oid = { + { 1, 2, 840, 113549, 1, 1, 1 }, + 7, +}; + +static const oid_st dsa_oid = { + { 1, 2, 840, 10040, 4, 1 }, + 6, +}; + +static const oid_st ec_oid = { + { 1, 2, 840, 10045, 2, 1 }, + 6, +}; + +static const oid_st ec_primef = { + { 1, 2, 840, 10045, 1, 1 }, + 6, +}; + +/* + Returns the OID of the public key algorithm. + @return CRYPT_OK if valid +*/ +int pk_get_oid(int pk, oid_st *st) +{ + switch (pk) { + case PKA_RSA: + XMEMCPY(st, &rsa_oid, sizeof(*st)); + break; + case PKA_DSA: + XMEMCPY(st, &dsa_oid, sizeof(*st)); + break; + case PKA_EC: + XMEMCPY(st, &ec_oid, sizeof(*st)); + break; + case EC_PRIME_FIELD: + XMEMCPY(st, &ec_primef, sizeof(*st)); + break; + default: + return CRYPT_INVALID_ARG; + } + return CRYPT_OK; +} +#endif diff --git a/src/ltc/misc/pkcs5/pkcs_5_1.c b/src/ltc/misc/pkcs5/pkcs_5_1.c new file mode 100644 index 0000000..2ebdf2f --- /dev/null +++ b/src/ltc/misc/pkcs5/pkcs_5_1.c @@ -0,0 +1,189 @@ +/* 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://libtom.org + */ +#include + +/** + @file pkcs_5_1.c + PKCS #5, Algorithm #1, Tom St Denis +*/ +#ifdef LTC_PKCS_5 +/** + Execute PKCS #5 v1 in strict or OpenSSL EVP_BytesToKey()-compat mode. + + PKCS#5 v1 specifies that the output key length can be no larger than + the hash output length. OpenSSL unilaterally extended that by repeating + the hash process on a block-by-block basis for as long as needed to make + bigger keys. If you want to be compatible with KDF for e.g. "openssl enc", + you'll want that. + + If you want strict PKCS behavior, turn openssl_compat off. Or (more + likely), use one of the convenience functions below. + + @param password The password (or key) + @param password_len The length of the password (octet) + @param salt The salt (or nonce) which is 8 octets long + @param iteration_count The PKCS #5 v1 iteration count + @param hash_idx The index of the hash desired + @param out [out] The destination for this algorithm + @param outlen [in/out] The max size and resulting size of the algorithm output + @param openssl_compat [in] Whether or not to grow the key to the buffer size ala OpenSSL + @return CRYPT_OK if successful +*/ +static int _pkcs_5_alg1_common(const unsigned char *password, + unsigned long password_len, + const unsigned char *salt, + int iteration_count, int hash_idx, + unsigned char *out, unsigned long *outlen, + int openssl_compat) +{ + int err; + unsigned long x; + hash_state *md; + unsigned char *buf; + /* Storage vars in case we need to support > hashsize (OpenSSL compat) */ + unsigned long block = 0, iter; + /* How many bytes to put in the outbut buffer (convenience calc) */ + unsigned long outidx = 0, nb = 0; + + LTC_ARGCHK(password != NULL); + LTC_ARGCHK(salt != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* test hash IDX */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + + /* allocate memory */ + md = XMALLOC(sizeof(hash_state)); + buf = XMALLOC(MAXBLOCKSIZE); + if (md == NULL || buf == NULL) { + if (md != NULL) { + XFREE(md); + } + if (buf != NULL) { + XFREE(buf); + } + return CRYPT_MEM; + } + + while(block * hash_descriptor[hash_idx].hashsize < *outlen) { + + /* hash initial (maybe previous hash) + password + salt */ + if ((err = hash_descriptor[hash_idx].init(md)) != CRYPT_OK) { + goto LBL_ERR; + } + /* in OpenSSL mode, we first hash the previous result for blocks 2-n */ + if (openssl_compat && block) { + if ((err = hash_descriptor[hash_idx].process(md, buf, hash_descriptor[hash_idx].hashsize)) != CRYPT_OK) { + goto LBL_ERR; + } + } + if ((err = hash_descriptor[hash_idx].process(md, password, password_len)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].process(md, salt, 8)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].done(md, buf)) != CRYPT_OK) { + goto LBL_ERR; + } + + iter = iteration_count; + while (--iter) { + /* code goes here. */ + x = MAXBLOCKSIZE; + if ((err = hash_memory(hash_idx, buf, hash_descriptor[hash_idx].hashsize, buf, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + } + + /* limit the size of the copy to however many bytes we have left in + the output buffer (and how many bytes we have to copy) */ + outidx = block*hash_descriptor[hash_idx].hashsize; + nb = hash_descriptor[hash_idx].hashsize; + if(outidx+nb > *outlen) + nb = *outlen - outidx; + if(nb > 0) + XMEMCPY(out+outidx, buf, nb); + + block++; + if (!openssl_compat) + break; + } + /* In strict mode, we always return the hashsize, in compat we filled it + as much as was requested, so we leave it alone. */ + if(!openssl_compat) + *outlen = hash_descriptor[hash_idx].hashsize; + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(buf, MAXBLOCKSIZE); + zeromem(md, sizeof(hash_state)); +#endif + + XFREE(buf); + XFREE(md); + + return err; +} + +/** + Execute PKCS #5 v1 - Strict mode (no OpenSSL-compatible extension) + @param password The password (or key) + @param password_len The length of the password (octet) + @param salt The salt (or nonce) which is 8 octets long + @param iteration_count The PKCS #5 v1 iteration count + @param hash_idx The index of the hash desired + @param out [out] The destination for this algorithm + @param outlen [in/out] The max size and resulting size of the algorithm output + @return CRYPT_OK if successful +*/ +int pkcs_5_alg1(const unsigned char *password, unsigned long password_len, + const unsigned char *salt, + int iteration_count, int hash_idx, + unsigned char *out, unsigned long *outlen) +{ + return _pkcs_5_alg1_common(password, password_len, salt, iteration_count, + hash_idx, out, outlen, 0); +} + +/** + Execute PKCS #5 v1 - OpenSSL-extension-compatible mode + + Use this one if you need to derive keys as "openssl enc" does by default. + OpenSSL (for better or worse), uses MD5 as the hash and iteration_count=1. + @param password The password (or key) + @param password_len The length of the password (octet) + @param salt The salt (or nonce) which is 8 octets long + @param iteration_count The PKCS #5 v1 iteration count + @param hash_idx The index of the hash desired + @param out [out] The destination for this algorithm + @param outlen [in/out] The max size and resulting size of the algorithm output + @return CRYPT_OK if successful +*/ +int pkcs_5_alg1_openssl(const unsigned char *password, + unsigned long password_len, + const unsigned char *salt, + int iteration_count, int hash_idx, + unsigned char *out, unsigned long *outlen) +{ + return _pkcs_5_alg1_common(password, password_len, salt, iteration_count, + hash_idx, out, outlen, 1); +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/pkcs5/pkcs_5_2.c b/src/ltc/misc/pkcs5/pkcs_5_2.c new file mode 100644 index 0000000..9b9b78a --- /dev/null +++ b/src/ltc/misc/pkcs5/pkcs_5_2.c @@ -0,0 +1,129 @@ +/* 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://libtom.org + */ +#include + +/** + @file pkcs_5_2.c + PKCS #5, Algorithm #2, Tom St Denis +*/ +#ifdef LTC_PKCS_5 + +/** + Execute PKCS #5 v2 + @param password The input password (or key) + @param password_len The length of the password (octets) + @param salt The salt (or nonce) + @param salt_len The length of the salt (octets) + @param iteration_count # of iterations desired for PKCS #5 v2 [read specs for more] + @param hash_idx The index of the hash desired + @param out [out] The destination for this algorithm + @param outlen [in/out] The max size and resulting size of the algorithm output + @return CRYPT_OK if successful +*/ +int pkcs_5_alg2(const unsigned char *password, unsigned long password_len, + const unsigned char *salt, unsigned long salt_len, + int iteration_count, int hash_idx, + unsigned char *out, unsigned long *outlen) +{ + int err, itts; + ulong32 blkno; + unsigned long stored, left, x, y; + unsigned char *buf[2]; + hmac_state *hmac; + + LTC_ARGCHK(password != NULL); + LTC_ARGCHK(salt != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* test hash IDX */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + + buf[0] = XMALLOC(MAXBLOCKSIZE * 2); + hmac = XMALLOC(sizeof(hmac_state)); + if (hmac == NULL || buf[0] == NULL) { + if (hmac != NULL) { + XFREE(hmac); + } + if (buf[0] != NULL) { + XFREE(buf[0]); + } + return CRYPT_MEM; + } + /* buf[1] points to the second block of MAXBLOCKSIZE bytes */ + buf[1] = buf[0] + MAXBLOCKSIZE; + + left = *outlen; + blkno = 1; + stored = 0; + while (left != 0) { + /* process block number blkno */ + zeromem(buf[0], MAXBLOCKSIZE*2); + + /* store current block number and increment for next pass */ + STORE32H(blkno, buf[1]); + ++blkno; + + /* get PRF(P, S||int(blkno)) */ + if ((err = hmac_init(hmac, hash_idx, password, password_len)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hmac_process(hmac, salt, salt_len)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hmac_process(hmac, buf[1], 4)) != CRYPT_OK) { + goto LBL_ERR; + } + x = MAXBLOCKSIZE; + if ((err = hmac_done(hmac, buf[0], &x)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* now compute repeated and XOR it in buf[1] */ + XMEMCPY(buf[1], buf[0], x); + for (itts = 1; itts < iteration_count; ++itts) { + if ((err = hmac_memory(hash_idx, password, password_len, buf[0], x, buf[0], &x)) != CRYPT_OK) { + goto LBL_ERR; + } + for (y = 0; y < x; y++) { + buf[1][y] ^= buf[0][y]; + } + } + + /* now emit upto x bytes of buf[1] to output */ + for (y = 0; y < x && left != 0; ++y) { + out[stored++] = buf[1][y]; + --left; + } + } + *outlen = stored; + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(buf[0], MAXBLOCKSIZE*2); + zeromem(hmac, sizeof(hmac_state)); +#endif + + XFREE(hmac); + XFREE(buf[0]); + + return err; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/misc/zeromem.c b/src/ltc/misc/zeromem.c new file mode 100644 index 0000000..3564cc1 --- /dev/null +++ b/src/ltc/misc/zeromem.c @@ -0,0 +1,34 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file zeromem.c + Zero a block of memory, Tom St Denis +*/ + +/** + Zero a block of memory + @param out The destination of the area to zero + @param outlen The length of the area to zero (octets) +*/ +void zeromem(volatile void *out, size_t outlen) +{ + volatile char *mem = out; + LTC_ARGCHKVD(out != NULL); + while (outlen-- > 0) { + *mem++ = '\0'; + } +} + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/modes/cbc/cbc_decrypt.c b/src/ltc/modes/cbc/cbc_decrypt.c new file mode 100644 index 0000000..b4fa466 --- /dev/null +++ b/src/ltc/modes/cbc/cbc_decrypt.c @@ -0,0 +1,97 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file cbc_decrypt.c + CBC implementation, encrypt block, Tom St Denis +*/ + + +#ifdef LTC_CBC_MODE + +/** + 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, unsigned long len, symmetric_CBC *cbc) +{ + int x, err; + 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(cbc != NULL); + + if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) { + return err; + } + + /* is blocklen valid? */ + if (cbc->blocklen < 1 || cbc->blocklen > (int)sizeof(cbc->IV) || cbc->blocklen > (int)sizeof(tmp)) { + return CRYPT_INVALID_ARG; + } + + if (len % cbc->blocklen) { + return CRYPT_INVALID_ARG; + } +#ifdef LTC_FAST + if (cbc->blocklen % sizeof(LTC_FAST_TYPE)) { + return CRYPT_INVALID_ARG; + } +#endif + + if (cipher_descriptor[cbc->cipher].accel_cbc_decrypt != NULL) { + return cipher_descriptor[cbc->cipher].accel_cbc_decrypt(ct, pt, len / cbc->blocklen, cbc->IV, &cbc->key); + } else { + while (len) { + /* decrypt */ + if ((err = cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key)) != CRYPT_OK) { + return err; + } + + /* xor IV against plaintext */ + #if defined(LTC_FAST) + for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) { + tmpy = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)cbc->IV + x)) ^ *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)tmp + x)); + *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)cbc->IV + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ct + x)); + *(LTC_FAST_TYPE_PTR_CAST((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; + } + } + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/modes/cbc/cbc_done.c b/src/ltc/modes/cbc/cbc_done.c new file mode 100644 index 0000000..4824940 --- /dev/null +++ b/src/ltc/modes/cbc/cbc_done.c @@ -0,0 +1,42 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file cbc_done.c + CBC implementation, finish chain, Tom St Denis +*/ + +#ifdef LTC_CBC_MODE + +/** 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 + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/modes/cbc/cbc_encrypt.c b/src/ltc/modes/cbc/cbc_encrypt.c new file mode 100644 index 0000000..f304d0e --- /dev/null +++ b/src/ltc/modes/cbc/cbc_encrypt.c @@ -0,0 +1,98 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file cbc_encrypt.c + CBC implementation, encrypt block, Tom St Denis +*/ + + +#ifdef LTC_CBC_MODE + +/** + 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, unsigned long len, symmetric_CBC *cbc) +{ + int x, err; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(cbc != NULL); + + if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) { + return err; + } + + /* is blocklen valid? */ + if (cbc->blocklen < 1 || cbc->blocklen > (int)sizeof(cbc->IV)) { + return CRYPT_INVALID_ARG; + } + + if (len % cbc->blocklen) { + return CRYPT_INVALID_ARG; + } +#ifdef LTC_FAST + if (cbc->blocklen % sizeof(LTC_FAST_TYPE)) { + return CRYPT_INVALID_ARG; + } +#endif + + if (cipher_descriptor[cbc->cipher].accel_cbc_encrypt != NULL) { + return 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_PTR_CAST((unsigned char *)cbc->IV + x)) ^= *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x)); + } + #else + for (x = 0; x < cbc->blocklen; x++) { + cbc->IV[x] ^= pt[x]; + } + #endif + + /* encrypt */ + if ((err = cipher_descriptor[cbc->cipher].ecb_encrypt(cbc->IV, ct, &cbc->key)) != CRYPT_OK) { + return err; + } + + /* 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_PTR_CAST((unsigned char *)cbc->IV + x)) = *(LTC_FAST_TYPE_PTR_CAST((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; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/modes/cbc/cbc_getiv.c b/src/ltc/modes/cbc/cbc_getiv.c new file mode 100644 index 0000000..6587743 --- /dev/null +++ b/src/ltc/modes/cbc/cbc_getiv.c @@ -0,0 +1,46 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file cbc_getiv.c + CBC implementation, get IV, Tom St Denis +*/ + +#ifdef LTC_CBC_MODE + +/** + Get the current initial vector + @param IV [out] The destination of the initial vector + @param len [in/out] The max size and resulting size of the initial vector + @param cbc The CBC state + @return CRYPT_OK if successful +*/ +int cbc_getiv(unsigned char *IV, unsigned long *len, symmetric_CBC *cbc) +{ + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(len != NULL); + LTC_ARGCHK(cbc != NULL); + if ((unsigned long)cbc->blocklen > *len) { + *len = cbc->blocklen; + return CRYPT_BUFFER_OVERFLOW; + } + XMEMCPY(IV, cbc->IV, cbc->blocklen); + *len = cbc->blocklen; + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/modes/cbc/cbc_setiv.c b/src/ltc/modes/cbc/cbc_setiv.c new file mode 100644 index 0000000..3d02093 --- /dev/null +++ b/src/ltc/modes/cbc/cbc_setiv.c @@ -0,0 +1,44 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file cbc_setiv.c + CBC implementation, set IV, Tom St Denis +*/ + + +#ifdef LTC_CBC_MODE + +/** + Set an initial vector + @param IV The initial vector + @param len The length of the vector (in octets) + @param cbc The CBC state + @return CRYPT_OK if successful +*/ +int cbc_setiv(const unsigned char *IV, unsigned long len, symmetric_CBC *cbc) +{ + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(cbc != NULL); + if (len != (unsigned long)cbc->blocklen) { + return CRYPT_INVALID_ARG; + } + XMEMCPY(cbc->IV, IV, len); + return CRYPT_OK; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/modes/cbc/cbc_start.c b/src/ltc/modes/cbc/cbc_start.c new file mode 100644 index 0000000..71b6fa8 --- /dev/null +++ b/src/ltc/modes/cbc/cbc_start.c @@ -0,0 +1,62 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file cbc_start.c + CBC implementation, start chain, Tom St Denis +*/ + +#ifdef LTC_CBC_MODE + +/** + Initialize a CBC context + @param cipher The index of the cipher desired + @param IV The initial vector + @param key The secret key + @param keylen The length of the secret key (octets) + @param num_rounds Number of rounds in the cipher desired (0 for default) + @param cbc The CBC state to initialize + @return CRYPT_OK if successful +*/ +int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_CBC *cbc) +{ + int x, err; + + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(cbc != NULL); + + /* bad param? */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + /* setup cipher */ + if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &cbc->key)) != CRYPT_OK) { + return err; + } + + /* copy IV */ + cbc->blocklen = cipher_descriptor[cipher].block_length; + cbc->cipher = cipher; + for (x = 0; x < cbc->blocklen; x++) { + cbc->IV[x] = IV[x]; + } + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/modes/cfb/cfb_decrypt.c b/src/ltc/modes/cfb/cfb_decrypt.c new file mode 100644 index 0000000..0c08c74 --- /dev/null +++ b/src/ltc/modes/cfb/cfb_decrypt.c @@ -0,0 +1,67 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file cfb_decrypt.c + CFB implementation, decrypt data, Tom St Denis +*/ + +#ifdef LTC_CFB_MODE + +/** + CFB decrypt + @param ct Ciphertext + @param pt [out] Plaintext + @param len Length of ciphertext (octets) + @param cfb CFB state + @return CRYPT_OK if successful +*/ +int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CFB *cfb) +{ + int err; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(cfb != NULL); + + if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) { + return err; + } + + /* is blocklen/padlen valid? */ + if (cfb->blocklen < 0 || cfb->blocklen > (int)sizeof(cfb->IV) || + cfb->padlen < 0 || cfb->padlen > (int)sizeof(cfb->pad)) { + return CRYPT_INVALID_ARG; + } + + while (len-- > 0) { + if (cfb->padlen == cfb->blocklen) { + if ((err = cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key)) != CRYPT_OK) { + return err; + } + cfb->padlen = 0; + } + cfb->pad[cfb->padlen] = *ct; + *pt = *ct ^ cfb->IV[cfb->padlen]; + ++pt; + ++ct; + ++(cfb->padlen); + } + return CRYPT_OK; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/modes/cfb/cfb_done.c b/src/ltc/modes/cfb/cfb_done.c new file mode 100644 index 0000000..bacfa28 --- /dev/null +++ b/src/ltc/modes/cfb/cfb_done.c @@ -0,0 +1,42 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file cfb_done.c + CFB implementation, finish chain, Tom St Denis +*/ + +#ifdef LTC_CFB_MODE + +/** 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 + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/modes/cfb/cfb_encrypt.c b/src/ltc/modes/cfb/cfb_encrypt.c new file mode 100644 index 0000000..e762143 --- /dev/null +++ b/src/ltc/modes/cfb/cfb_encrypt.c @@ -0,0 +1,65 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file cfb_encrypt.c + CFB implementation, encrypt data, Tom St Denis +*/ + +#ifdef LTC_CFB_MODE + +/** + CFB encrypt + @param pt Plaintext + @param ct [out] Ciphertext + @param len Length of plaintext (octets) + @param cfb CFB state + @return CRYPT_OK if successful +*/ +int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CFB *cfb) +{ + int err; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(cfb != NULL); + + if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) { + return err; + } + + /* is blocklen/padlen valid? */ + if (cfb->blocklen < 0 || cfb->blocklen > (int)sizeof(cfb->IV) || + cfb->padlen < 0 || cfb->padlen > (int)sizeof(cfb->pad)) { + return CRYPT_INVALID_ARG; + } + + while (len-- > 0) { + if (cfb->padlen == cfb->blocklen) { + if ((err = cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key)) != CRYPT_OK) { + return err; + } + cfb->padlen = 0; + } + cfb->pad[cfb->padlen] = (*ct = *pt ^ cfb->IV[cfb->padlen]); + ++pt; + ++ct; + ++(cfb->padlen); + } + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/modes/cfb/cfb_getiv.c b/src/ltc/modes/cfb/cfb_getiv.c new file mode 100644 index 0000000..b6786e1 --- /dev/null +++ b/src/ltc/modes/cfb/cfb_getiv.c @@ -0,0 +1,46 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file cfb_getiv.c + CFB implementation, get IV, Tom St Denis +*/ + +#ifdef LTC_CFB_MODE + +/** + Get the current initial vector + @param IV [out] The destination of the initial vector + @param len [in/out] The max size and resulting size of the initial vector + @param cfb The CFB state + @return CRYPT_OK if successful +*/ +int cfb_getiv(unsigned char *IV, unsigned long *len, symmetric_CFB *cfb) +{ + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(len != NULL); + LTC_ARGCHK(cfb != NULL); + if ((unsigned long)cfb->blocklen > *len) { + *len = cfb->blocklen; + return CRYPT_BUFFER_OVERFLOW; + } + XMEMCPY(IV, cfb->IV, cfb->blocklen); + *len = cfb->blocklen; + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/modes/cfb/cfb_setiv.c b/src/ltc/modes/cfb/cfb_setiv.c new file mode 100644 index 0000000..4a22110 --- /dev/null +++ b/src/ltc/modes/cfb/cfb_setiv.c @@ -0,0 +1,52 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file cfb_setiv.c + CFB implementation, set IV, Tom St Denis +*/ + +#ifdef LTC_CFB_MODE + +/** + Set an initial vector + @param IV The initial vector + @param len The length of the vector (in octets) + @param cfb The CFB state + @return CRYPT_OK if successful +*/ +int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb) +{ + int err; + + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(cfb != NULL); + + if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) { + return err; + } + + if (len != (unsigned long)cfb->blocklen) { + return CRYPT_INVALID_ARG; + } + + /* force next block */ + cfb->padlen = 0; + return cipher_descriptor[cfb->cipher].ecb_encrypt(IV, cfb->IV, &cfb->key); +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/modes/cfb/cfb_start.c b/src/ltc/modes/cfb/cfb_start.c new file mode 100644 index 0000000..b42c97f --- /dev/null +++ b/src/ltc/modes/cfb/cfb_start.c @@ -0,0 +1,65 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file cfb_start.c + CFB implementation, start chain, Tom St Denis +*/ + + +#ifdef LTC_CFB_MODE + +/** + Initialize a CFB context + @param cipher The index of the cipher desired + @param IV The initial vector + @param key The secret key + @param keylen The length of the secret key (octets) + @param num_rounds Number of rounds in the cipher desired (0 for default) + @param cfb The CFB state to initialize + @return CRYPT_OK if successful +*/ +int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_CFB *cfb) +{ + int x, err; + + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(cfb != NULL); + + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + + /* copy data */ + cfb->cipher = cipher; + cfb->blocklen = cipher_descriptor[cipher].block_length; + for (x = 0; x < cfb->blocklen; x++) + cfb->IV[x] = IV[x]; + + /* init the cipher */ + if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &cfb->key)) != CRYPT_OK) { + return err; + } + + /* encrypt the IV */ + cfb->padlen = 0; + return cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->IV, cfb->IV, &cfb->key); +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/modes/ctr/ctr_decrypt.c b/src/ltc/modes/ctr/ctr_decrypt.c new file mode 100644 index 0000000..9537249 --- /dev/null +++ b/src/ltc/modes/ctr/ctr_decrypt.c @@ -0,0 +1,42 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ctr_decrypt.c + CTR implementation, decrypt data, Tom St Denis +*/ + +#ifdef LTC_CTR_MODE + +/** + CTR decrypt + @param ct Ciphertext + @param pt [out] Plaintext + @param len Length of ciphertext (octets) + @param ctr CTR state + @return CRYPT_OK if successful +*/ +int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr) +{ + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(ctr != NULL); + + return ctr_encrypt(ct, pt, len, ctr); +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/modes/ctr/ctr_done.c b/src/ltc/modes/ctr/ctr_done.c new file mode 100644 index 0000000..77d888b --- /dev/null +++ b/src/ltc/modes/ctr/ctr_done.c @@ -0,0 +1,42 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ctr_done.c + CTR implementation, finish chain, Tom St Denis +*/ + +#ifdef LTC_CTR_MODE + +/** 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 + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/modes/ctr/ctr_encrypt.c b/src/ltc/modes/ctr/ctr_encrypt.c new file mode 100644 index 0000000..6117785 --- /dev/null +++ b/src/ltc/modes/ctr/ctr_encrypt.c @@ -0,0 +1,112 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ctr_encrypt.c + CTR implementation, encrypt data, Tom St Denis +*/ + + +#ifdef LTC_CTR_MODE + +/** + CTR encrypt + @param pt Plaintext + @param ct [out] Ciphertext + @param len Length of plaintext (octets) + @param ctr CTR state + @return CRYPT_OK if successful +*/ +int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr) +{ + int x, err; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(ctr != NULL); + + if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) { + return err; + } + + /* is blocklen/padlen valid? */ + if (ctr->blocklen < 1 || ctr->blocklen > (int)sizeof(ctr->ctr) || + ctr->padlen < 0 || ctr->padlen > (int)sizeof(ctr->pad)) { + return CRYPT_INVALID_ARG; + } + +#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)) { + if ((err = cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key)) != CRYPT_OK) { + return err; + } + len %= ctr->blocklen; + } + + while (len) { + /* is the pad empty? */ + if (ctr->padlen == ctr->blocklen) { + /* increment counter */ + if (ctr->mode == CTR_COUNTER_LITTLE_ENDIAN) { + /* little-endian */ + for (x = 0; x < ctr->ctrlen; x++) { + ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255; + if (ctr->ctr[x] != (unsigned char)0) { + break; + } + } + } else { + /* big-endian */ + for (x = ctr->blocklen-1; x >= ctr->ctrlen; x--) { + ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255; + if (ctr->ctr[x] != (unsigned char)0) { + break; + } + } + } + + /* encrypt it */ + if ((err = cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key)) != CRYPT_OK) { + return err; + } + ctr->padlen = 0; + } +#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_PTR_CAST((unsigned char *)ct + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x)) ^ + *(LTC_FAST_TYPE_PTR_CAST((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; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/modes/ctr/ctr_getiv.c b/src/ltc/modes/ctr/ctr_getiv.c new file mode 100644 index 0000000..6242323 --- /dev/null +++ b/src/ltc/modes/ctr/ctr_getiv.c @@ -0,0 +1,46 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ctr_getiv.c + CTR implementation, get IV, Tom St Denis +*/ + +#ifdef LTC_CTR_MODE + +/** + Get the current initial vector + @param IV [out] The destination of the initial vector + @param len [in/out] The max size and resulting size of the initial vector + @param ctr The CTR state + @return CRYPT_OK if successful +*/ +int ctr_getiv(unsigned char *IV, unsigned long *len, symmetric_CTR *ctr) +{ + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(len != NULL); + LTC_ARGCHK(ctr != NULL); + if ((unsigned long)ctr->blocklen > *len) { + *len = ctr->blocklen; + return CRYPT_BUFFER_OVERFLOW; + } + XMEMCPY(IV, ctr->ctr, ctr->blocklen); + *len = ctr->blocklen; + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/modes/ctr/ctr_setiv.c b/src/ltc/modes/ctr/ctr_setiv.c new file mode 100644 index 0000000..50c6539 --- /dev/null +++ b/src/ltc/modes/ctr/ctr_setiv.c @@ -0,0 +1,56 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ctr_setiv.c + CTR implementation, set IV, Tom St Denis +*/ + +#ifdef LTC_CTR_MODE + +/** + Set an initial vector + @param IV The initial vector + @param len The length of the vector (in octets) + @param ctr The CTR state + @return CRYPT_OK if successful +*/ +int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr) +{ + int err; + + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(ctr != NULL); + + /* bad param? */ + if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) { + return err; + } + + if (len != (unsigned long)ctr->blocklen) { + return CRYPT_INVALID_ARG; + } + + /* set IV */ + XMEMCPY(ctr->ctr, IV, len); + + /* force next block */ + ctr->padlen = 0; + return cipher_descriptor[ctr->cipher].ecb_encrypt(IV, ctr->pad, &ctr->key); +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/modes/ctr/ctr_start.c b/src/ltc/modes/ctr/ctr_start.c new file mode 100644 index 0000000..8544636 --- /dev/null +++ b/src/ltc/modes/ctr/ctr_start.c @@ -0,0 +1,101 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ctr_start.c + CTR implementation, start chain, Tom St Denis +*/ + + +#ifdef LTC_CTR_MODE + +/** + Initialize a CTR context + @param cipher The index of the cipher desired + @param IV The initial vector + @param key The secret key + @param keylen The length of the secret key (octets) + @param num_rounds Number of rounds in the cipher desired (0 for default) + @param ctr_mode The counter mode (CTR_COUNTER_LITTLE_ENDIAN or CTR_COUNTER_BIG_ENDIAN) + @param ctr The CTR state to initialize + @return CRYPT_OK if successful +*/ +int ctr_start( int cipher, + const unsigned char *IV, + const unsigned char *key, int keylen, + int num_rounds, int ctr_mode, + symmetric_CTR *ctr) +{ + int x, err; + + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(ctr != NULL); + + /* bad param? */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + /* ctrlen == counter width */ + ctr->ctrlen = (ctr_mode & 255) ? (ctr_mode & 255) : cipher_descriptor[cipher].block_length; + if (ctr->ctrlen > cipher_descriptor[cipher].block_length) { + return CRYPT_INVALID_ARG; + } + + if ((ctr_mode & 0x1000) == CTR_COUNTER_BIG_ENDIAN) { + ctr->ctrlen = cipher_descriptor[cipher].block_length - ctr->ctrlen; + } + + /* setup cipher */ + if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ctr->key)) != CRYPT_OK) { + return err; + } + + /* copy ctr */ + ctr->blocklen = cipher_descriptor[cipher].block_length; + ctr->cipher = cipher; + ctr->padlen = 0; + ctr->mode = ctr_mode & 0x1000; + for (x = 0; x < ctr->blocklen; x++) { + ctr->ctr[x] = IV[x]; + } + + if (ctr_mode & LTC_CTR_RFC3686) { + /* increment the IV as per RFC 3686 */ + if (ctr->mode == CTR_COUNTER_LITTLE_ENDIAN) { + /* little-endian */ + for (x = 0; x < ctr->ctrlen; x++) { + ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255; + if (ctr->ctr[x] != (unsigned char)0) { + break; + } + } + } else { + /* big-endian */ + for (x = ctr->blocklen-1; x >= ctr->ctrlen; x--) { + ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255; + if (ctr->ctr[x] != (unsigned char)0) { + break; + } + } + } + } + + return cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key); +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/modes/ecb/ecb_decrypt.c b/src/ltc/modes/ecb/ecb_decrypt.c new file mode 100644 index 0000000..84842c2 --- /dev/null +++ b/src/ltc/modes/ecb/ecb_decrypt.c @@ -0,0 +1,61 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ecb_decrypt.c + ECB implementation, decrypt a block, Tom St Denis +*/ + +#ifdef LTC_ECB_MODE + +/** + 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, 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; + } + if (len % cipher_descriptor[ecb->cipher].block_length) { + return CRYPT_INVALID_ARG; + } + + /* check for accel */ + if (cipher_descriptor[ecb->cipher].accel_ecb_decrypt != NULL) { + return cipher_descriptor[ecb->cipher].accel_ecb_decrypt(ct, pt, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key); + } else { + while (len) { + if ((err = cipher_descriptor[ecb->cipher].ecb_decrypt(ct, pt, &ecb->key)) != CRYPT_OK) { + return err; + } + 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 + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/modes/ecb/ecb_done.c b/src/ltc/modes/ecb/ecb_done.c new file mode 100644 index 0000000..9199eae --- /dev/null +++ b/src/ltc/modes/ecb/ecb_done.c @@ -0,0 +1,42 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ecb_done.c + ECB implementation, finish chain, Tom St Denis +*/ + +#ifdef LTC_ECB_MODE + +/** Terminate the chain + @param ecb 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 + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/modes/ecb/ecb_encrypt.c b/src/ltc/modes/ecb/ecb_encrypt.c new file mode 100644 index 0000000..801e0fd --- /dev/null +++ b/src/ltc/modes/ecb/ecb_encrypt.c @@ -0,0 +1,61 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ecb_encrypt.c + ECB implementation, encrypt a block, Tom St Denis +*/ + +#ifdef LTC_ECB_MODE + +/** + 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, 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; + } + if (len % cipher_descriptor[ecb->cipher].block_length) { + return CRYPT_INVALID_ARG; + } + + /* check for accel */ + if (cipher_descriptor[ecb->cipher].accel_ecb_encrypt != NULL) { + return cipher_descriptor[ecb->cipher].accel_ecb_encrypt(pt, ct, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key); + } else { + while (len) { + if ((err = cipher_descriptor[ecb->cipher].ecb_encrypt(pt, ct, &ecb->key)) != CRYPT_OK) { + return err; + } + 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 + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/modes/ecb/ecb_start.c b/src/ltc/modes/ecb/ecb_start.c new file mode 100644 index 0000000..67061ca --- /dev/null +++ b/src/ltc/modes/ecb/ecb_start.c @@ -0,0 +1,48 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ecb_start.c + ECB implementation, start chain, Tom St Denis +*/ + + +#ifdef LTC_ECB_MODE + +/** + Initialize a ECB context + @param cipher The index of the cipher desired + @param key The secret key + @param keylen The length of the secret key (octets) + @param num_rounds Number of rounds in the cipher desired (0 for default) + @param ecb The ECB state to initialize + @return CRYPT_OK if successful +*/ +int ecb_start(int cipher, const unsigned char *key, int keylen, int num_rounds, symmetric_ECB *ecb) +{ + int err; + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(ecb != NULL); + + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + ecb->cipher = cipher; + ecb->blocklen = cipher_descriptor[cipher].block_length; + return cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ecb->key); +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/modes/ofb/ofb_decrypt.c b/src/ltc/modes/ofb/ofb_decrypt.c new file mode 100644 index 0000000..b741887 --- /dev/null +++ b/src/ltc/modes/ofb/ofb_decrypt.c @@ -0,0 +1,43 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ofb_decrypt.c + OFB implementation, decrypt data, Tom St Denis +*/ + +#ifdef LTC_OFB_MODE + +/** + OFB decrypt + @param ct Ciphertext + @param pt [out] Plaintext + @param len Length of ciphertext (octets) + @param ofb OFB state + @return CRYPT_OK if successful +*/ +int ofb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_OFB *ofb) +{ + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(ofb != NULL); + return ofb_encrypt(ct, pt, len, ofb); +} + + +#endif + + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/modes/ofb/ofb_done.c b/src/ltc/modes/ofb/ofb_done.c new file mode 100644 index 0000000..412b4d1 --- /dev/null +++ b/src/ltc/modes/ofb/ofb_done.c @@ -0,0 +1,42 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ofb_done.c + OFB implementation, finish chain, Tom St Denis +*/ + +#ifdef LTC_OFB_MODE + +/** 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 + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/modes/ofb/ofb_encrypt.c b/src/ltc/modes/ofb/ofb_encrypt.c new file mode 100644 index 0000000..f32fd39 --- /dev/null +++ b/src/ltc/modes/ofb/ofb_encrypt.c @@ -0,0 +1,60 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ofb_encrypt.c + OFB implementation, encrypt data, Tom St Denis +*/ + +#ifdef LTC_OFB_MODE + +/** + OFB encrypt + @param pt Plaintext + @param ct [out] Ciphertext + @param len Length of plaintext (octets) + @param ofb OFB state + @return CRYPT_OK if successful +*/ +int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_OFB *ofb) +{ + int err; + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(ofb != NULL); + if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) { + return err; + } + + /* is blocklen/padlen valid? */ + if (ofb->blocklen < 0 || ofb->blocklen > (int)sizeof(ofb->IV) || + ofb->padlen < 0 || ofb->padlen > (int)sizeof(ofb->IV)) { + return CRYPT_INVALID_ARG; + } + + while (len-- > 0) { + if (ofb->padlen == ofb->blocklen) { + if ((err = cipher_descriptor[ofb->cipher].ecb_encrypt(ofb->IV, ofb->IV, &ofb->key)) != CRYPT_OK) { + return err; + } + ofb->padlen = 0; + } + *ct++ = *pt++ ^ ofb->IV[(ofb->padlen)++]; + } + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/modes/ofb/ofb_getiv.c b/src/ltc/modes/ofb/ofb_getiv.c new file mode 100644 index 0000000..c009e33 --- /dev/null +++ b/src/ltc/modes/ofb/ofb_getiv.c @@ -0,0 +1,46 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ofb_getiv.c + OFB implementation, get IV, Tom St Denis +*/ + +#ifdef LTC_OFB_MODE + +/** + Get the current initial vector + @param IV [out] The destination of the initial vector + @param len [in/out] The max size and resulting size of the initial vector + @param ofb The OFB state + @return CRYPT_OK if successful +*/ +int ofb_getiv(unsigned char *IV, unsigned long *len, symmetric_OFB *ofb) +{ + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(len != NULL); + LTC_ARGCHK(ofb != NULL); + if ((unsigned long)ofb->blocklen > *len) { + *len = ofb->blocklen; + return CRYPT_BUFFER_OVERFLOW; + } + XMEMCPY(IV, ofb->IV, ofb->blocklen); + *len = ofb->blocklen; + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/modes/ofb/ofb_setiv.c b/src/ltc/modes/ofb/ofb_setiv.c new file mode 100644 index 0000000..77a96ad --- /dev/null +++ b/src/ltc/modes/ofb/ofb_setiv.c @@ -0,0 +1,52 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ofb_setiv.c + OFB implementation, set IV, Tom St Denis +*/ + +#ifdef LTC_OFB_MODE + +/** + Set an initial vector + @param IV The initial vector + @param len The length of the vector (in octets) + @param ofb The OFB state + @return CRYPT_OK if successful +*/ +int ofb_setiv(const unsigned char *IV, unsigned long len, symmetric_OFB *ofb) +{ + int err; + + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(ofb != NULL); + + if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) { + return err; + } + + if (len != (unsigned long)ofb->blocklen) { + return CRYPT_INVALID_ARG; + } + + /* force next block */ + ofb->padlen = 0; + return cipher_descriptor[ofb->cipher].ecb_encrypt(IV, ofb->IV, &ofb->key); +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/modes/ofb/ofb_start.c b/src/ltc/modes/ofb/ofb_start.c new file mode 100644 index 0000000..f701d69 --- /dev/null +++ b/src/ltc/modes/ofb/ofb_start.c @@ -0,0 +1,60 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file ofb_start.c + OFB implementation, start chain, Tom St Denis +*/ + + +#ifdef LTC_OFB_MODE + +/** + Initialize a OFB context + @param cipher The index of the cipher desired + @param IV The initial vector + @param key The secret key + @param keylen The length of the secret key (octets) + @param num_rounds Number of rounds in the cipher desired (0 for default) + @param ofb The OFB state to initialize + @return CRYPT_OK if successful +*/ +int ofb_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_OFB *ofb) +{ + int x, err; + + LTC_ARGCHK(IV != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(ofb != NULL); + + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + /* copy details */ + ofb->cipher = cipher; + ofb->blocklen = cipher_descriptor[cipher].block_length; + for (x = 0; x < ofb->blocklen; x++) { + ofb->IV[x] = IV[x]; + } + + /* init the cipher */ + ofb->padlen = ofb->blocklen; + return cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ofb->key); +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/bit/der_decode_bit_string.c b/src/ltc/pk/asn1/der/bit/der_decode_bit_string.c new file mode 100644 index 0000000..05d19cb --- /dev/null +++ b/src/ltc/pk/asn1/der/bit/der_decode_bit_string.c @@ -0,0 +1,102 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_bit_string.c + ASN.1 DER, encode a BIT STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a BIT STRING + @param in The DER encoded BIT STRING + @param inlen The size of the DER BIT STRING + @param out [out] The array of bits stored (one per char) + @param outlen [in/out] The number of bits stored + @return CRYPT_OK if successful +*/ +int der_decode_bit_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long dlen, blen, x, y; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* packet must be at least 4 bytes */ + if (inlen < 4) { + return CRYPT_INVALID_ARG; + } + + /* check for 0x03 */ + if ((in[0]&0x1F) != 0x03) { + return CRYPT_INVALID_PACKET; + } + + /* offset in the data */ + x = 1; + + /* get the length of the data */ + if (in[x] & 0x80) { + /* long format get number of length bytes */ + y = in[x++] & 0x7F; + + /* invalid if 0 or > 2 */ + if (y == 0 || y > 2) { + return CRYPT_INVALID_PACKET; + } + + /* read the data len */ + dlen = 0; + while (y--) { + dlen = (dlen << 8) | (unsigned long)in[x++]; + } + } else { + /* short format */ + dlen = in[x++] & 0x7F; + } + + /* is the data len too long or too short? */ + if ((dlen == 0) || (dlen + x > inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* get padding count */ + blen = ((dlen - 1) << 3) - (in[x++] & 7); + + /* too many bits? */ + if (blen > *outlen) { + *outlen = blen; + return CRYPT_BUFFER_OVERFLOW; + } + + /* decode/store the bits */ + for (y = 0; y < blen; y++) { + out[y] = (in[x] & (1 << (7 - (y & 7)))) ? 1 : 0; + if ((y & 7) == 7) { + ++x; + } + } + + /* we done */ + *outlen = blen; + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/bit/der_decode_raw_bit_string.c b/src/ltc/pk/asn1/der/bit/der_decode_raw_bit_string.c new file mode 100644 index 0000000..a4a3cb3 --- /dev/null +++ b/src/ltc/pk/asn1/der/bit/der_decode_raw_bit_string.c @@ -0,0 +1,106 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_bit_string.c + ASN.1 DER, encode a BIT STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +#define SETBIT(v, n) (v=((unsigned char)(v) | (1U << (unsigned char)(n)))) + +/** + Store a BIT STRING + @param in The DER encoded BIT STRING + @param inlen The size of the DER BIT STRING + @param out [out] The array of bits stored (8 per char) + @param outlen [in/out] The number of bits stored + @return CRYPT_OK if successful +*/ +int der_decode_raw_bit_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long dlen, blen, x, y; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* packet must be at least 4 bytes */ + if (inlen < 4) { + return CRYPT_INVALID_ARG; + } + + /* check for 0x03 */ + if ((in[0]&0x1F) != 0x03) { + return CRYPT_INVALID_PACKET; + } + + /* offset in the data */ + x = 1; + + /* get the length of the data */ + if (in[x] & 0x80) { + /* long format get number of length bytes */ + y = in[x++] & 0x7F; + + /* invalid if 0 or > 2 */ + if (y == 0 || y > 2) { + return CRYPT_INVALID_PACKET; + } + + /* read the data len */ + dlen = 0; + while (y--) { + dlen = (dlen << 8) | (unsigned long)in[x++]; + } + } else { + /* short format */ + dlen = in[x++] & 0x7F; + } + + /* is the data len too long or too short? */ + if ((dlen == 0) || (dlen + x > inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* get padding count */ + blen = ((dlen - 1) << 3) - (in[x++] & 7); + + /* too many bits? */ + if (blen > *outlen) { + *outlen = blen; + return CRYPT_BUFFER_OVERFLOW; + } + + /* decode/store the bits */ + for (y = 0; y < blen; y++) { + if (in[x] & (1 << (7 - (y & 7)))) { + SETBIT(out[y/8], 7-(y%8)); + } + if ((y & 7) == 7) { + ++x; + } + } + + /* we done */ + *outlen = blen; + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/bit/der_encode_bit_string.c b/src/ltc/pk/asn1/der/bit/der_encode_bit_string.c new file mode 100644 index 0000000..e64bd1f --- /dev/null +++ b/src/ltc/pk/asn1/der/bit/der_encode_bit_string.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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_bit_string.c + ASN.1 DER, encode a BIT STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a BIT STRING + @param in The array of bits to store (one per char) + @param inlen The number of bits tostore + @param out [out] The destination for the DER encoded BIT STRING + @param outlen [in/out] The max size and resulting size of the DER BIT STRING + @return CRYPT_OK if successful +*/ +int der_encode_bit_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long len, x, y; + unsigned char buf; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* avoid overflows */ + if ((err = der_length_bit_string(inlen, &len)) != CRYPT_OK) { + return err; + } + + if (len > *outlen) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + /* store header (include bit padding count in length) */ + x = 0; + y = (inlen >> 3) + ((inlen&7) ? 1 : 0) + 1; + + out[x++] = 0x03; + if (y < 128) { + out[x++] = (unsigned char)y; + } else if (y < 256) { + out[x++] = 0x81; + out[x++] = (unsigned char)y; + } else if (y < 65536) { + out[x++] = 0x82; + out[x++] = (unsigned char)((y>>8)&255); + out[x++] = (unsigned char)(y&255); + } + + /* store number of zero padding bits */ + out[x++] = (unsigned char)((8 - inlen) & 7); + + /* store the bits in big endian format */ + for (y = buf = 0; y < inlen; y++) { + buf |= (in[y] ? 1 : 0) << (7 - (y & 7)); + if ((y & 7) == 7) { + out[x++] = buf; + buf = 0; + } + } + /* store last byte */ + if (inlen & 7) { + out[x++] = buf; + } + *outlen = x; + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/bit/der_encode_raw_bit_string.c b/src/ltc/pk/asn1/der/bit/der_encode_raw_bit_string.c new file mode 100644 index 0000000..014a037 --- /dev/null +++ b/src/ltc/pk/asn1/der/bit/der_encode_raw_bit_string.c @@ -0,0 +1,92 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_bit_string.c + ASN.1 DER, encode a BIT STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +#define getbit(n, k) (((n) & ( 1 << (k) )) >> (k)) + +/** + Store a BIT STRING + @param in The array of bits to store (8 per char) + @param inlen The number of bits tostore + @param out [out] The destination for the DER encoded BIT STRING + @param outlen [in/out] The max size and resulting size of the DER BIT STRING + @return CRYPT_OK if successful +*/ +int der_encode_raw_bit_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long len, x, y; + unsigned char buf; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* avoid overflows */ + if ((err = der_length_bit_string(inlen, &len)) != CRYPT_OK) { + return err; + } + + if (len > *outlen) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + /* store header (include bit padding count in length) */ + x = 0; + y = (inlen >> 3) + ((inlen&7) ? 1 : 0) + 1; + + out[x++] = 0x03; + if (y < 128) { + out[x++] = (unsigned char)y; + } else if (y < 256) { + out[x++] = 0x81; + out[x++] = (unsigned char)y; + } else if (y < 65536) { + out[x++] = 0x82; + out[x++] = (unsigned char)((y>>8)&255); + out[x++] = (unsigned char)(y&255); + } + + /* store number of zero padding bits */ + out[x++] = (unsigned char)((8 - inlen) & 7); + + /* store the bits in big endian format */ + for (y = buf = 0; y < inlen; y++) { + buf |= (getbit(in[y/8],7-y%8)?1:0) << (7 - (y & 7)); + if ((y & 7) == 7) { + out[x++] = buf; + buf = 0; + } + } + /* store last byte */ + if (inlen & 7) { + out[x++] = buf; + } + + *outlen = x; + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/bit/der_length_bit_string.c b/src/ltc/pk/asn1/der/bit/der_length_bit_string.c new file mode 100644 index 0000000..45472e9 --- /dev/null +++ b/src/ltc/pk/asn1/der/bit/der_length_bit_string.c @@ -0,0 +1,54 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_length_bit_string.c + ASN.1 DER, get length of BIT STRING, Tom St Denis +*/ + +#ifdef LTC_DER +/** + Gets length of DER encoding of BIT STRING + @param nbits The number of bits in the string to encode + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_bit_string(unsigned long nbits, unsigned long *outlen) +{ + unsigned long nbytes; + LTC_ARGCHK(outlen != NULL); + + /* get the number of the bytes */ + nbytes = (nbits >> 3) + ((nbits & 7) ? 1 : 0) + 1; + + if (nbytes < 128) { + /* 03 LL PP DD DD DD ... */ + *outlen = 2 + nbytes; + } else if (nbytes < 256) { + /* 03 81 LL PP DD DD DD ... */ + *outlen = 3 + nbytes; + } else if (nbytes < 65536) { + /* 03 82 LL LL PP DD DD DD ... */ + *outlen = 4 + nbytes; + } else { + return CRYPT_INVALID_ARG; + } + + return CRYPT_OK; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/boolean/der_decode_boolean.c b/src/ltc/pk/asn1/der/boolean/der_decode_boolean.c new file mode 100644 index 0000000..4e25012 --- /dev/null +++ b/src/ltc/pk/asn1/der/boolean/der_decode_boolean.c @@ -0,0 +1,47 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_boolean.c + ASN.1 DER, decode a BOOLEAN, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Read a BOOLEAN + @param in The destination for the DER encoded BOOLEAN + @param inlen The size of the DER BOOLEAN + @param out [out] The boolean to decode + @return CRYPT_OK if successful +*/ +int der_decode_boolean(const unsigned char *in, unsigned long inlen, + int *out) +{ + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + + if (inlen < 3 || in[0] != 0x01 || in[1] != 0x01 || (in[2] != 0x00 && in[2] != 0xFF)) { + return CRYPT_INVALID_ARG; + } + + *out = (in[2]==0xFF) ? 1 : 0; + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/boolean/der_encode_boolean.c b/src/ltc/pk/asn1/der/boolean/der_encode_boolean.c new file mode 100644 index 0000000..48e9090 --- /dev/null +++ b/src/ltc/pk/asn1/der/boolean/der_encode_boolean.c @@ -0,0 +1,51 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_boolean.c + ASN.1 DER, encode a BOOLEAN, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a BOOLEAN + @param in The boolean to encode + @param out [out] The destination for the DER encoded BOOLEAN + @param outlen [in/out] The max size and resulting size of the DER BOOLEAN + @return CRYPT_OK if successful +*/ +int der_encode_boolean(int in, + unsigned char *out, unsigned long *outlen) +{ + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(out != NULL); + + if (*outlen < 3) { + *outlen = 3; + return CRYPT_BUFFER_OVERFLOW; + } + + *outlen = 3; + out[0] = 0x01; + out[1] = 0x01; + out[2] = in ? 0xFF : 0x00; + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/boolean/der_length_boolean.c b/src/ltc/pk/asn1/der/boolean/der_length_boolean.c new file mode 100644 index 0000000..fa19064 --- /dev/null +++ b/src/ltc/pk/asn1/der/boolean/der_length_boolean.c @@ -0,0 +1,35 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_length_boolean.c + ASN.1 DER, get length of a BOOLEAN, Tom St Denis +*/ + +#ifdef LTC_DER +/** + Gets length of DER encoding of a BOOLEAN + @param outlen [out] The length of the DER encoding + @return CRYPT_OK if successful +*/ +int der_length_boolean(unsigned long *outlen) +{ + LTC_ARGCHK(outlen != NULL); + *outlen = 3; + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/choice/der_decode_choice.c b/src/ltc/pk/asn1/der/choice/der_decode_choice.c new file mode 100644 index 0000000..eb71513 --- /dev/null +++ b/src/ltc/pk/asn1/der/choice/der_decode_choice.c @@ -0,0 +1,225 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_choice.c + ASN.1 DER, decode a CHOICE, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Decode a CHOICE + @param in The DER encoded input + @param inlen [in/out] The size of the input and resulting size of read type + @param list The list of items to decode + @param outlen The number of items in the list + @return CRYPT_OK on success +*/ +int der_decode_choice(const unsigned char *in, unsigned long *inlen, + ltc_asn1_list *list, unsigned long outlen) +{ + unsigned long size, x, z; + void *data; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen != NULL); + LTC_ARGCHK(list != NULL); + + /* get blk size */ + if (*inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* set all of the "used" flags to zero */ + for (x = 0; x < outlen; x++) { + list[x].used = 0; + } + + /* now scan until we have a winner */ + for (x = 0; x < outlen; x++) { + size = list[x].size; + data = list[x].data; + + switch (list[x].type) { + case LTC_ASN1_BOOLEAN: + if (der_decode_boolean(in, *inlen, data) == CRYPT_OK) { + if (der_length_boolean(&z) == CRYPT_OK) { + list[x].used = 1; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_INTEGER: + if (der_decode_integer(in, *inlen, data) == CRYPT_OK) { + if (der_length_integer(data, &z) == CRYPT_OK) { + list[x].used = 1; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_SHORT_INTEGER: + if (der_decode_short_integer(in, *inlen, data) == CRYPT_OK) { + if (der_length_short_integer(size, &z) == CRYPT_OK) { + list[x].used = 1; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_BIT_STRING: + if (der_decode_bit_string(in, *inlen, data, &size) == CRYPT_OK) { + if (der_length_bit_string(size, &z) == CRYPT_OK) { + list[x].used = 1; + list[x].size = size; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_RAW_BIT_STRING: + if (der_decode_raw_bit_string(in, *inlen, data, &size) == CRYPT_OK) { + if (der_length_bit_string(size, &z) == CRYPT_OK) { + list[x].used = 1; + list[x].size = size; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_OCTET_STRING: + if (der_decode_octet_string(in, *inlen, data, &size) == CRYPT_OK) { + if (der_length_octet_string(size, &z) == CRYPT_OK) { + list[x].used = 1; + list[x].size = size; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_NULL: + if (*inlen == 2 && in[x] == 0x05 && in[x+1] == 0x00) { + *inlen = 2; + list[x].used = 1; + return CRYPT_OK; + } + break; + + case LTC_ASN1_OBJECT_IDENTIFIER: + if (der_decode_object_identifier(in, *inlen, data, &size) == CRYPT_OK) { + if (der_length_object_identifier(data, size, &z) == CRYPT_OK) { + list[x].used = 1; + list[x].size = size; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_TELETEX_STRING: + if (der_decode_teletex_string(in, *inlen, data, &size) == CRYPT_OK) { + if (der_length_teletex_string(data, size, &z) == CRYPT_OK) { + list[x].used = 1; + list[x].size = size; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_IA5_STRING: + if (der_decode_ia5_string(in, *inlen, data, &size) == CRYPT_OK) { + if (der_length_ia5_string(data, size, &z) == CRYPT_OK) { + list[x].used = 1; + list[x].size = size; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_PRINTABLE_STRING: + if (der_decode_printable_string(in, *inlen, data, &size) == CRYPT_OK) { + if (der_length_printable_string(data, size, &z) == CRYPT_OK) { + list[x].used = 1; + list[x].size = size; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_UTF8_STRING: + if (der_decode_utf8_string(in, *inlen, data, &size) == CRYPT_OK) { + if (der_length_utf8_string(data, size, &z) == CRYPT_OK) { + list[x].used = 1; + list[x].size = size; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_UTCTIME: + z = *inlen; + if (der_decode_utctime(in, &z, data) == CRYPT_OK) { + list[x].used = 1; + *inlen = z; + return CRYPT_OK; + } + break; + + case LTC_ASN1_GENERALIZEDTIME: + z = *inlen; + if (der_decode_generalizedtime(in, &z, data) == CRYPT_OK) { + list[x].used = 1; + *inlen = z; + return CRYPT_OK; + } + break; + + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: + case LTC_ASN1_SEQUENCE: + if (der_decode_sequence(in, *inlen, data, size) == CRYPT_OK) { + if (der_length_sequence(data, size, &z) == CRYPT_OK) { + list[x].used = 1; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_CHOICE: + case LTC_ASN1_CONSTRUCTED: + case LTC_ASN1_CONTEXT_SPECIFIC: + case LTC_ASN1_EOL: + return CRYPT_INVALID_ARG; + } + } + + return CRYPT_INVALID_PACKET; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c b/src/ltc/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c new file mode 100644 index 0000000..f8997ee --- /dev/null +++ b/src/ltc/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c @@ -0,0 +1,146 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_generalizedtime.c + ASN.1 DER, decode a GeneralizedTime, Steffen Jaeckel + Based on der_decode_utctime.c +*/ + +#ifdef LTC_DER + +static int char_to_int(unsigned char x) +{ + switch (x) { + case '0': return 0; + case '1': return 1; + case '2': return 2; + case '3': return 3; + case '4': return 4; + case '5': return 5; + case '6': return 6; + case '7': return 7; + case '8': return 8; + case '9': return 9; + } + return 100; +} + +#define DECODE_V(y, max) do {\ + y = char_to_int(buf[x])*10 + char_to_int(buf[x+1]); \ + if (y >= max) return CRYPT_INVALID_PACKET; \ + x += 2; \ +} while(0) + +#define DECODE_V4(y, max) do {\ + y = char_to_int(buf[x])*1000 + char_to_int(buf[x+1])*100 + char_to_int(buf[x+2])*10 + char_to_int(buf[x+3]); \ + if (y >= max) return CRYPT_INVALID_PACKET; \ + x += 4; \ +} while(0) + +/** + Decodes a Generalized time structure in DER format (reads all 6 valid encoding formats) + @param in Input buffer + @param inlen Length of input buffer in octets + @param out [out] Destination of Generalized time structure + @return CRYPT_OK if successful +*/ +int der_decode_generalizedtime(const unsigned char *in, unsigned long *inlen, + ltc_generalizedtime *out) +{ + unsigned char buf[32]; + unsigned long x; + int y; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen != NULL); + LTC_ARGCHK(out != NULL); + + /* check header */ + if (*inlen < 2UL || (in[1] >= sizeof(buf)) || ((in[1] + 2UL) > *inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* decode the string */ + for (x = 0; x < in[1]; x++) { + y = der_ia5_value_decode(in[x+2]); + if (y == -1) { + return CRYPT_INVALID_PACKET; + } + if (!((y >= '0' && y <= '9') + || y == 'Z' || y == '.' + || y == '+' || y == '-')) { + return CRYPT_INVALID_PACKET; + } + buf[x] = y; + } + *inlen = 2 + x; + + if (x < 15) { + return CRYPT_INVALID_PACKET; + } + + /* possible encodings are +YYYYMMDDhhmmssZ +YYYYMMDDhhmmss+hh'mm' +YYYYMMDDhhmmss-hh'mm' +YYYYMMDDhhmmss.fsZ +YYYYMMDDhhmmss.fs+hh'mm' +YYYYMMDDhhmmss.fs-hh'mm' + + So let's do a trivial decode upto [including] ss + */ + + x = 0; + DECODE_V4(out->YYYY, 10000); + DECODE_V(out->MM, 13); + DECODE_V(out->DD, 32); + DECODE_V(out->hh, 24); + DECODE_V(out->mm, 60); + DECODE_V(out->ss, 60); + + /* clear fractional seconds info */ + out->fs = 0; + + /* now is it Z or . */ + if (buf[x] == 'Z') { + return CRYPT_OK; + } else if (buf[x] == '.') { + x++; + while (buf[x] >= '0' && buf[x] <= '9') { + unsigned fs = out->fs; + if (x >= sizeof(buf)) return CRYPT_INVALID_PACKET; + out->fs *= 10; + out->fs += char_to_int(buf[x]); + if (fs > out->fs) return CRYPT_OVERFLOW; + x++; + } + } + + /* now is it Z, +, - */ + if (buf[x] == 'Z') { + return CRYPT_OK; + } else if (buf[x] == '+' || buf[x] == '-') { + out->off_dir = (buf[x++] == '+') ? 0 : 1; + DECODE_V(out->off_hh, 24); + DECODE_V(out->off_mm, 60); + return CRYPT_OK; + } else { + return CRYPT_INVALID_PACKET; + } +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/generalizedtime/der_encode_generalizedtime.c b/src/ltc/pk/asn1/der/generalizedtime/der_encode_generalizedtime.c new file mode 100644 index 0000000..b2198d9 --- /dev/null +++ b/src/ltc/pk/asn1/der/generalizedtime/der_encode_generalizedtime.c @@ -0,0 +1,110 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_utctime.c + ASN.1 DER, encode a GeneralizedTime, Steffen Jaeckel + Based on der_encode_utctime.c +*/ + +#ifdef LTC_DER + +static const char * const baseten = "0123456789"; + +#define STORE_V(y) do {\ + out[x++] = der_ia5_char_encode(baseten[(y/10) % 10]); \ + out[x++] = der_ia5_char_encode(baseten[y % 10]); \ +} while(0) + +#define STORE_V4(y) do {\ + out[x++] = der_ia5_char_encode(baseten[(y/1000) % 10]); \ + out[x++] = der_ia5_char_encode(baseten[(y/100) % 10]); \ + out[x++] = der_ia5_char_encode(baseten[(y/10) % 10]); \ + out[x++] = der_ia5_char_encode(baseten[y % 10]); \ +} while(0) + +/** + Encodes a Generalized time structure in DER format + @param utctime The UTC time structure to encode + @param out The destination of the DER encoding of the UTC time structure + @param outlen [in/out] The length of the DER encoding + @return CRYPT_OK if successful +*/ +int der_encode_generalizedtime(ltc_generalizedtime *gtime, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, tmplen; + int err; + + LTC_ARGCHK(gtime != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + if ((err = der_length_generalizedtime(gtime, &tmplen)) != CRYPT_OK) { + return err; + } + if (tmplen > *outlen) { + *outlen = tmplen; + return CRYPT_BUFFER_OVERFLOW; + } + + /* store header */ + out[0] = 0x18; + + /* store values */ + x = 2; + STORE_V4(gtime->YYYY); + STORE_V(gtime->MM); + STORE_V(gtime->DD); + STORE_V(gtime->hh); + STORE_V(gtime->mm); + STORE_V(gtime->ss); + + if (gtime->fs) { + unsigned long divisor; + unsigned fs = gtime->fs; + unsigned len = 0; + out[x++] = der_ia5_char_encode('.'); + divisor = 1; + do { + fs /= 10; + divisor *= 10; + len++; + } while(fs != 0); + while (len-- > 1) { + divisor /= 10; + out[x++] = der_ia5_char_encode(baseten[(gtime->fs/divisor) % 10]); + } + out[x++] = der_ia5_char_encode(baseten[gtime->fs % 10]); + } + + if (gtime->off_mm || gtime->off_hh) { + out[x++] = der_ia5_char_encode(gtime->off_dir ? '-' : '+'); + STORE_V(gtime->off_hh); + STORE_V(gtime->off_mm); + } else { + out[x++] = der_ia5_char_encode('Z'); + } + + /* store length */ + out[1] = (unsigned char)(x - 2); + + /* all good let's return */ + *outlen = x; + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/generalizedtime/der_length_generalizedtime.c b/src/ltc/pk/asn1/der/generalizedtime/der_length_generalizedtime.c new file mode 100644 index 0000000..e5abf9f --- /dev/null +++ b/src/ltc/pk/asn1/der/generalizedtime/der_length_generalizedtime.c @@ -0,0 +1,60 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_length_utctime.c + ASN.1 DER, get length of GeneralizedTime, Steffen Jaeckel + Based on der_length_utctime.c +*/ + +#ifdef LTC_DER + +/** + Gets length of DER encoding of GeneralizedTime + @param utctime The UTC time structure to get the size of + @param outlen [out] The length of the DER encoding + @return CRYPT_OK if successful +*/ +int der_length_generalizedtime(ltc_generalizedtime *gtime, unsigned long *outlen) +{ + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(gtime != NULL); + + if (gtime->fs == 0) { + /* we encode as YYYYMMDDhhmmssZ */ + *outlen = 2 + 14 + 1; + } else { + unsigned long len = 2 + 14 + 1; + unsigned fs = gtime->fs; + do { + fs /= 10; + len++; + } while(fs != 0); + if (gtime->off_hh == 0 && gtime->off_mm == 0) { + /* we encode as YYYYMMDDhhmmss.fsZ */ + len += 1; + } + else { + /* we encode as YYYYMMDDhhmmss.fs{+|-}hh'mm' */ + len += 5; + } + *outlen = len; + } + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/ia5/der_decode_ia5_string.c b/src/ltc/pk/asn1/der/ia5/der_decode_ia5_string.c new file mode 100644 index 0000000..4699e31 --- /dev/null +++ b/src/ltc/pk/asn1/der/ia5/der_decode_ia5_string.c @@ -0,0 +1,96 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_ia5_string.c + ASN.1 DER, encode a IA5 STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a IA5 STRING + @param in The DER encoded IA5 STRING + @param inlen The size of the DER IA5 STRING + @param out [out] The array of octets stored (one per char) + @param outlen [in/out] The number of octets stored + @return CRYPT_OK if successful +*/ +int der_decode_ia5_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + int t; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* must have header at least */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* check for 0x16 */ + if ((in[0] & 0x1F) != 0x16) { + return CRYPT_INVALID_PACKET; + } + x = 1; + + /* decode the length */ + if (in[x] & 0x80) { + /* valid # of bytes in length are 1,2,3 */ + y = in[x] & 0x7F; + if ((y == 0) || (y > 3) || ((x + y) > inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* read the length in */ + len = 0; + ++x; + while (y--) { + len = (len << 8) | in[x++]; + } + } else { + len = in[x++] & 0x7F; + } + + /* is it too long? */ + if (len > *outlen) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + if (len + x > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* read the data */ + for (y = 0; y < len; y++) { + t = der_ia5_value_decode(in[x++]); + if (t == -1) { + return CRYPT_INVALID_ARG; + } + out[y] = t; + } + + *outlen = y; + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/ia5/der_encode_ia5_string.c b/src/ltc/pk/asn1/der/ia5/der_encode_ia5_string.c new file mode 100644 index 0000000..42b3f58 --- /dev/null +++ b/src/ltc/pk/asn1/der/ia5/der_encode_ia5_string.c @@ -0,0 +1,85 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_ia5_string.c + ASN.1 DER, encode a IA5 STRING, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Store an IA5 STRING + @param in The array of IA5 to store (one per char) + @param inlen The number of IA5 to store + @param out [out] The destination for the DER encoded IA5 STRING + @param outlen [in/out] The max size and resulting size of the DER IA5 STRING + @return CRYPT_OK if successful +*/ +int der_encode_ia5_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get the size */ + if ((err = der_length_ia5_string(in, inlen, &len)) != CRYPT_OK) { + return err; + } + + /* too big? */ + if (len > *outlen) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + /* encode the header+len */ + x = 0; + out[x++] = 0x16; + if (inlen < 128) { + out[x++] = (unsigned char)inlen; + } else if (inlen < 256) { + out[x++] = 0x81; + out[x++] = (unsigned char)inlen; + } else if (inlen < 65536UL) { + out[x++] = 0x82; + out[x++] = (unsigned char)((inlen>>8)&255); + out[x++] = (unsigned char)(inlen&255); + } else if (inlen < 16777216UL) { + out[x++] = 0x83; + out[x++] = (unsigned char)((inlen>>16)&255); + out[x++] = (unsigned char)((inlen>>8)&255); + out[x++] = (unsigned char)(inlen&255); + } else { + return CRYPT_INVALID_ARG; + } + + /* store octets */ + for (y = 0; y < inlen; y++) { + out[x++] = der_ia5_char_encode(in[y]); + } + + /* retun length */ + *outlen = x; + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/ia5/der_length_ia5_string.c b/src/ltc/pk/asn1/der/ia5/der_length_ia5_string.c new file mode 100644 index 0000000..04debaf --- /dev/null +++ b/src/ltc/pk/asn1/der/ia5/der_length_ia5_string.c @@ -0,0 +1,194 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_length_ia5_string.c + ASN.1 DER, get length of IA5 STRING, Tom St Denis +*/ + +#ifdef LTC_DER + +static const struct { + int code, value; +} ia5_table[] = { +{ '\0', 0 }, +{ '\a', 7 }, +{ '\b', 8 }, +{ '\t', 9 }, +{ '\n', 10 }, +{ '\f', 12 }, +{ '\r', 13 }, +{ ' ', 32 }, +{ '!', 33 }, +{ '"', 34 }, +{ '#', 35 }, +{ '$', 36 }, +{ '%', 37 }, +{ '&', 38 }, +{ '\'', 39 }, +{ '(', 40 }, +{ ')', 41 }, +{ '*', 42 }, +{ '+', 43 }, +{ ',', 44 }, +{ '-', 45 }, +{ '.', 46 }, +{ '/', 47 }, +{ '0', 48 }, +{ '1', 49 }, +{ '2', 50 }, +{ '3', 51 }, +{ '4', 52 }, +{ '5', 53 }, +{ '6', 54 }, +{ '7', 55 }, +{ '8', 56 }, +{ '9', 57 }, +{ ':', 58 }, +{ ';', 59 }, +{ '<', 60 }, +{ '=', 61 }, +{ '>', 62 }, +{ '?', 63 }, +{ '@', 64 }, +{ 'A', 65 }, +{ 'B', 66 }, +{ 'C', 67 }, +{ 'D', 68 }, +{ 'E', 69 }, +{ 'F', 70 }, +{ 'G', 71 }, +{ 'H', 72 }, +{ 'I', 73 }, +{ 'J', 74 }, +{ 'K', 75 }, +{ 'L', 76 }, +{ 'M', 77 }, +{ 'N', 78 }, +{ 'O', 79 }, +{ 'P', 80 }, +{ 'Q', 81 }, +{ 'R', 82 }, +{ 'S', 83 }, +{ 'T', 84 }, +{ 'U', 85 }, +{ 'V', 86 }, +{ 'W', 87 }, +{ 'X', 88 }, +{ 'Y', 89 }, +{ 'Z', 90 }, +{ '[', 91 }, +{ '\\', 92 }, +{ ']', 93 }, +{ '^', 94 }, +{ '_', 95 }, +{ '`', 96 }, +{ 'a', 97 }, +{ 'b', 98 }, +{ 'c', 99 }, +{ 'd', 100 }, +{ 'e', 101 }, +{ 'f', 102 }, +{ 'g', 103 }, +{ 'h', 104 }, +{ 'i', 105 }, +{ 'j', 106 }, +{ 'k', 107 }, +{ 'l', 108 }, +{ 'm', 109 }, +{ 'n', 110 }, +{ 'o', 111 }, +{ 'p', 112 }, +{ 'q', 113 }, +{ 'r', 114 }, +{ 's', 115 }, +{ 't', 116 }, +{ 'u', 117 }, +{ 'v', 118 }, +{ 'w', 119 }, +{ 'x', 120 }, +{ 'y', 121 }, +{ 'z', 122 }, +{ '{', 123 }, +{ '|', 124 }, +{ '}', 125 }, +{ '~', 126 } +}; + +int der_ia5_char_encode(int c) +{ + int x; + for (x = 0; x < (int)(sizeof(ia5_table)/sizeof(ia5_table[0])); x++) { + if (ia5_table[x].code == c) { + return ia5_table[x].value; + } + } + return -1; +} + +int der_ia5_value_decode(int v) +{ + int x; + for (x = 0; x < (int)(sizeof(ia5_table)/sizeof(ia5_table[0])); x++) { + if (ia5_table[x].value == v) { + return ia5_table[x].code; + } + } + return -1; +} + +/** + Gets length of DER encoding of IA5 STRING + @param octets The values you want to encode + @param noctets The number of octets in the string to encode + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen) +{ + unsigned long x; + + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(octets != NULL); + + /* scan string for validity */ + for (x = 0; x < noctets; x++) { + if (der_ia5_char_encode(octets[x]) == -1) { + return CRYPT_INVALID_ARG; + } + } + + if (noctets < 128) { + /* 16 LL DD DD DD ... */ + *outlen = 2 + noctets; + } else if (noctets < 256) { + /* 16 81 LL DD DD DD ... */ + *outlen = 3 + noctets; + } else if (noctets < 65536UL) { + /* 16 82 LL LL DD DD DD ... */ + *outlen = 4 + noctets; + } else if (noctets < 16777216UL) { + /* 16 83 LL LL LL DD DD DD ... */ + *outlen = 5 + noctets; + } else { + return CRYPT_INVALID_ARG; + } + + return CRYPT_OK; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/integer/der_decode_integer.c b/src/ltc/pk/asn1/der/integer/der_decode_integer.c new file mode 100644 index 0000000..768e28a --- /dev/null +++ b/src/ltc/pk/asn1/der/integer/der_decode_integer.c @@ -0,0 +1,110 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_integer.c + ASN.1 DER, decode an integer, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Read a mp_int integer + @param in The DER encoded data + @param inlen Size of DER encoded data + @param num The first mp_int to decode + @return CRYPT_OK if successful +*/ +int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num) +{ + unsigned long x, y, z; + int err; + + LTC_ARGCHK(num != NULL); + LTC_ARGCHK(in != NULL); + + /* min DER INTEGER is 0x02 01 00 == 0 */ + if (inlen < (1 + 1 + 1)) { + return CRYPT_INVALID_PACKET; + } + + /* ok expect 0x02 when we AND with 0001 1111 [1F] */ + x = 0; + if ((in[x++] & 0x1F) != 0x02) { + return CRYPT_INVALID_PACKET; + } + + /* now decode the len stuff */ + z = in[x++]; + + if ((z & 0x80) == 0x00) { + /* short form */ + + /* will it overflow? */ + if (x + z > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* no so read it */ + if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, z)) != CRYPT_OK) { + return err; + } + } else { + /* long form */ + z &= 0x7F; + + /* will number of length bytes overflow? (or > 4) */ + if (((x + z) > inlen) || (z > 4) || (z == 0)) { + return CRYPT_INVALID_PACKET; + } + + /* now read it in */ + y = 0; + while (z--) { + y = ((unsigned long)(in[x++])) | (y << 8); + } + + /* now will reading y bytes overrun? */ + if ((x + y) > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* no so read it */ + if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, y)) != CRYPT_OK) { + return err; + } + } + + /* see if it's negative */ + if (in[x] & 0x80) { + void *tmp; + if (mp_init(&tmp) != CRYPT_OK) { + return CRYPT_MEM; + } + + if (mp_2expt(tmp, mp_count_bits(num)) != CRYPT_OK || mp_sub(num, tmp, num) != CRYPT_OK) { + mp_clear(tmp); + return CRYPT_MEM; + } + mp_clear(tmp); + } + + return CRYPT_OK; + +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/integer/der_encode_integer.c b/src/ltc/pk/asn1/der/integer/der_encode_integer.c new file mode 100644 index 0000000..544bfb0 --- /dev/null +++ b/src/ltc/pk/asn1/der/integer/der_encode_integer.c @@ -0,0 +1,130 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_integer.c + ASN.1 DER, encode an integer, Tom St Denis +*/ + + +#ifdef LTC_DER + +/* Exports a positive bignum as DER format (upto 2^32 bytes in size) */ +/** + Store a mp_int integer + @param num The first mp_int to encode + @param out [out] The destination for the DER encoded integers + @param outlen [in/out] The max size and resulting size of the DER encoded integers + @return CRYPT_OK if successful +*/ +int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen) +{ + unsigned long tmplen, y; + int err, leading_zero; + + LTC_ARGCHK(num != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* find out how big this will be */ + if ((err = der_length_integer(num, &tmplen)) != CRYPT_OK) { + return err; + } + + if (*outlen < tmplen) { + *outlen = tmplen; + return CRYPT_BUFFER_OVERFLOW; + } + + if (mp_cmp_d(num, 0) != LTC_MP_LT) { + /* we only need a leading zero if the msb of the first byte is one */ + if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == LTC_MP_YES) { + leading_zero = 1; + } else { + leading_zero = 0; + } + + /* get length of num in bytes (plus 1 since we force the msbyte to zero) */ + y = mp_unsigned_bin_size(num) + leading_zero; + } else { + leading_zero = 0; + y = mp_count_bits(num); + y = y + (8 - (y & 7)); + y = y >> 3; + if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) --y; + } + + /* now store initial data */ + *out++ = 0x02; + if (y < 128) { + /* short form */ + *out++ = (unsigned char)y; + } else if (y < 256) { + *out++ = 0x81; + *out++ = (unsigned char)y; + } else if (y < 65536UL) { + *out++ = 0x82; + *out++ = (unsigned char)((y>>8)&255); + *out++ = (unsigned char)y; + } else if (y < 16777216UL) { + *out++ = 0x83; + *out++ = (unsigned char)((y>>16)&255); + *out++ = (unsigned char)((y>>8)&255); + *out++ = (unsigned char)y; + } else { + return CRYPT_INVALID_ARG; + } + + /* now store msbyte of zero if num is non-zero */ + if (leading_zero) { + *out++ = 0x00; + } + + /* if it's not zero store it as big endian */ + if (mp_cmp_d(num, 0) == LTC_MP_GT) { + /* now store the mpint */ + if ((err = mp_to_unsigned_bin(num, out)) != CRYPT_OK) { + return err; + } + } else if (mp_iszero(num) != LTC_MP_YES) { + void *tmp; + + /* negative */ + if (mp_init(&tmp) != CRYPT_OK) { + return CRYPT_MEM; + } + + /* 2^roundup and subtract */ + y = mp_count_bits(num); + y = y + (8 - (y & 7)); + if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) y -= 8; + if (mp_2expt(tmp, y) != CRYPT_OK || mp_add(tmp, num, tmp) != CRYPT_OK) { + mp_clear(tmp); + return CRYPT_MEM; + } + if ((err = mp_to_unsigned_bin(tmp, out)) != CRYPT_OK) { + mp_clear(tmp); + return err; + } + mp_clear(tmp); + } + + /* we good */ + *outlen = tmplen; + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/integer/der_length_integer.c b/src/ltc/pk/asn1/der/integer/der_length_integer.c new file mode 100644 index 0000000..61584f7 --- /dev/null +++ b/src/ltc/pk/asn1/der/integer/der_length_integer.c @@ -0,0 +1,81 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_length_integer.c + ASN.1 DER, get length of encoding, Tom St Denis +*/ + + +#ifdef LTC_DER +/** + Gets length of DER encoding of num + @param num The int to get the size of + @param outlen [out] The length of the DER encoding for the given integer + @return CRYPT_OK if successful +*/ +int der_length_integer(void *num, unsigned long *outlen) +{ + unsigned long z, len; + int leading_zero; + + LTC_ARGCHK(num != NULL); + LTC_ARGCHK(outlen != NULL); + + if (mp_cmp_d(num, 0) != LTC_MP_LT) { + /* positive */ + + /* we only need a leading zero if the msb of the first byte is one */ + if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == LTC_MP_YES) { + leading_zero = 1; + } else { + leading_zero = 0; + } + + /* size for bignum */ + z = len = leading_zero + mp_unsigned_bin_size(num); + } else { + /* it's negative */ + /* find power of 2 that is a multiple of eight and greater than count bits */ + z = mp_count_bits(num); + z = z + (8 - (z & 7)); + if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) --z; + len = z = z >> 3; + } + + /* now we need a length */ + if (z < 128) { + /* short form */ + ++len; + } else { + /* long form (relies on z != 0), assumes length bytes < 128 */ + ++len; + + while (z) { + ++len; + z >>= 8; + } + } + + /* we need a 0x02 to indicate it's INTEGER */ + ++len; + + /* return length */ + *outlen = len; + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.c b/src/ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.c new file mode 100644 index 0000000..47547f0 --- /dev/null +++ b/src/ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.c @@ -0,0 +1,99 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_object_identifier.c + ASN.1 DER, Decode Object Identifier, Tom St Denis +*/ + +#ifdef LTC_DER +/** + Decode OID data and store the array of integers in words + @param in The OID DER encoded data + @param inlen The length of the OID data + @param words [out] The destination of the OID words + @param outlen [in/out] The number of OID words + @return CRYPT_OK if successful +*/ +int der_decode_object_identifier(const unsigned char *in, unsigned long inlen, + unsigned long *words, unsigned long *outlen) +{ + unsigned long x, y, t, len; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(words != NULL); + LTC_ARGCHK(outlen != NULL); + + /* header is at least 3 bytes */ + if (inlen < 3) { + return CRYPT_INVALID_PACKET; + } + + /* must be room for at least two words */ + if (*outlen < 2) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* decode the packet header */ + x = 0; + if ((in[x++] & 0x1F) != 0x06) { + return CRYPT_INVALID_PACKET; + } + + /* get the length */ + if (in[x] < 128) { + len = in[x++]; + } else { + if (in[x] < 0x81 || in[x] > 0x82) { + return CRYPT_INVALID_PACKET; + } + y = in[x++] & 0x7F; + len = 0; + while (y--) { + len = (len << 8) | (unsigned long)in[x++]; + } + } + + if (len < 1 || (len + x) > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* decode words */ + y = 0; + t = 0; + while (len--) { + t = (t << 7) | (in[x] & 0x7F); + if (!(in[x++] & 0x80)) { + /* store t */ + if (y >= *outlen) { + return CRYPT_BUFFER_OVERFLOW; + } + if (y == 0) { + words[0] = t / 40; + words[1] = t % 40; + y = 2; + } else { + words[y++] = t; + } + t = 0; + } + } + + *outlen = y; + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/object_identifier/der_encode_object_identifier.c b/src/ltc/pk/asn1/der/object_identifier/der_encode_object_identifier.c new file mode 100644 index 0000000..ccecd98 --- /dev/null +++ b/src/ltc/pk/asn1/der/object_identifier/der_encode_object_identifier.c @@ -0,0 +1,111 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_object_identifier.c + ASN.1 DER, Encode Object Identifier, Tom St Denis +*/ + +#ifdef LTC_DER +/** + Encode an OID + @param words The words to encode (upto 32-bits each) + @param nwords The number of words in the OID + @param out [out] Destination of OID data + @param outlen [in/out] The max and resulting size of the OID + @return CRYPT_OK if successful +*/ +int der_encode_object_identifier(unsigned long *words, unsigned long nwords, + unsigned char *out, unsigned long *outlen) +{ + unsigned long i, x, y, z, t, mask, wordbuf; + int err; + + LTC_ARGCHK(words != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* check length */ + if ((err = der_length_object_identifier(words, nwords, &x)) != CRYPT_OK) { + return err; + } + if (x > *outlen) { + *outlen = x; + return CRYPT_BUFFER_OVERFLOW; + } + + /* compute length to store OID data */ + z = 0; + wordbuf = words[0] * 40 + words[1]; + for (y = 1; y < nwords; y++) { + t = der_object_identifier_bits(wordbuf); + z += t/7 + ((t%7) ? 1 : 0) + (wordbuf == 0 ? 1 : 0); + if (y < nwords - 1) { + wordbuf = words[y + 1]; + } + } + + /* store header + length */ + x = 0; + out[x++] = 0x06; + if (z < 128) { + out[x++] = (unsigned char)z; + } else if (z < 256) { + out[x++] = 0x81; + out[x++] = (unsigned char)z; + } else if (z < 65536UL) { + out[x++] = 0x82; + out[x++] = (unsigned char)((z>>8)&255); + out[x++] = (unsigned char)(z&255); + } else { + return CRYPT_INVALID_ARG; + } + + /* store first byte */ + wordbuf = words[0] * 40 + words[1]; + for (i = 1; i < nwords; i++) { + /* store 7 bit words in little endian */ + t = wordbuf & 0xFFFFFFFF; + if (t) { + y = x; + mask = 0; + while (t) { + out[x++] = (unsigned char)((t & 0x7F) | mask); + t >>= 7; + mask |= 0x80; /* upper bit is set on all but the last byte */ + } + /* now swap bytes y...x-1 */ + z = x - 1; + while (y < z) { + t = out[y]; out[y] = out[z]; out[z] = (unsigned char)t; + ++y; + --z; + } + } else { + /* zero word */ + out[x++] = 0x00; + } + + if (i < nwords - 1) { + wordbuf = words[i + 1]; + } + } + + *outlen = x; + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/object_identifier/der_length_object_identifier.c b/src/ltc/pk/asn1/der/object_identifier/der_length_object_identifier.c new file mode 100644 index 0000000..3b6826a --- /dev/null +++ b/src/ltc/pk/asn1/der/object_identifier/der_length_object_identifier.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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_length_object_identifier.c + ASN.1 DER, get length of Object Identifier, Tom St Denis +*/ + +#ifdef LTC_DER + +unsigned long der_object_identifier_bits(unsigned long x) +{ + unsigned long c; + x &= 0xFFFFFFFF; + c = 0; + while (x) { + ++c; + x >>= 1; + } + return c; +} + + +/** + Gets length of DER encoding of Object Identifier + @param nwords The number of OID words + @param words The actual OID words to get the size of + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen) +{ + unsigned long y, z, t, wordbuf; + + LTC_ARGCHK(words != NULL); + LTC_ARGCHK(outlen != NULL); + + + /* must be >= 2 words */ + if (nwords < 2) { + return CRYPT_INVALID_ARG; + } + + /* word1 = 0,1,2,3 and word2 0..39 */ + if (words[0] > 3 || (words[0] < 2 && words[1] > 39)) { + return CRYPT_INVALID_ARG; + } + + /* leading word is the first two */ + z = 0; + wordbuf = words[0] * 40 + words[1]; + for (y = 1; y < nwords; y++) { + t = der_object_identifier_bits(wordbuf); + z += t/7 + ((t%7) ? 1 : 0) + (wordbuf == 0 ? 1 : 0); + if (y < nwords - 1) { + /* grab next word */ + wordbuf = words[y+1]; + } + } + + /* now depending on the length our length encoding changes */ + if (z < 128) { + z += 2; + } else if (z < 256) { + z += 3; + } else if (z < 65536UL) { + z += 4; + } else { + return CRYPT_INVALID_ARG; + } + + *outlen = z; + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/octet/der_decode_octet_string.c b/src/ltc/pk/asn1/der/octet/der_decode_octet_string.c new file mode 100644 index 0000000..a656b25 --- /dev/null +++ b/src/ltc/pk/asn1/der/octet/der_decode_octet_string.c @@ -0,0 +1,91 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_octet_string.c + ASN.1 DER, encode a OCTET STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a OCTET STRING + @param in The DER encoded OCTET STRING + @param inlen The size of the DER OCTET STRING + @param out [out] The array of octets stored (one per char) + @param outlen [in/out] The number of octets stored + @return CRYPT_OK if successful +*/ +int der_decode_octet_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* must have header at least */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* check for 0x04 */ + if ((in[0] & 0x1F) != 0x04) { + return CRYPT_INVALID_PACKET; + } + x = 1; + + /* decode the length */ + if (in[x] & 0x80) { + /* valid # of bytes in length are 1,2,3 */ + y = in[x] & 0x7F; + if ((y == 0) || (y > 3) || ((x + y) > inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* read the length in */ + len = 0; + ++x; + while (y--) { + len = (len << 8) | in[x++]; + } + } else { + len = in[x++] & 0x7F; + } + + /* is it too long? */ + if (len > *outlen) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + if (len + x > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* read the data */ + for (y = 0; y < len; y++) { + out[y] = in[x++]; + } + + *outlen = y; + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/octet/der_encode_octet_string.c b/src/ltc/pk/asn1/der/octet/der_encode_octet_string.c new file mode 100644 index 0000000..23d337d --- /dev/null +++ b/src/ltc/pk/asn1/der/octet/der_encode_octet_string.c @@ -0,0 +1,86 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_octet_string.c + ASN.1 DER, encode a OCTET STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store an OCTET STRING + @param in The array of OCTETS to store (one per char) + @param inlen The number of OCTETS to store + @param out [out] The destination for the DER encoded OCTET STRING + @param outlen [in/out] The max size and resulting size of the DER OCTET STRING + @return CRYPT_OK if successful +*/ +int der_encode_octet_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get the size */ + if ((err = der_length_octet_string(inlen, &len)) != CRYPT_OK) { + return err; + } + + /* too big? */ + if (len > *outlen) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + /* encode the header+len */ + x = 0; + out[x++] = 0x04; + if (inlen < 128) { + out[x++] = (unsigned char)inlen; + } else if (inlen < 256) { + out[x++] = 0x81; + out[x++] = (unsigned char)inlen; + } else if (inlen < 65536UL) { + out[x++] = 0x82; + out[x++] = (unsigned char)((inlen>>8)&255); + out[x++] = (unsigned char)(inlen&255); + } else if (inlen < 16777216UL) { + out[x++] = 0x83; + out[x++] = (unsigned char)((inlen>>16)&255); + out[x++] = (unsigned char)((inlen>>8)&255); + out[x++] = (unsigned char)(inlen&255); + } else { + return CRYPT_INVALID_ARG; + } + + /* store octets */ + for (y = 0; y < inlen; y++) { + out[x++] = in[y]; + } + + /* retun length */ + *outlen = x; + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/octet/der_length_octet_string.c b/src/ltc/pk/asn1/der/octet/der_length_octet_string.c new file mode 100644 index 0000000..6e37ca7 --- /dev/null +++ b/src/ltc/pk/asn1/der/octet/der_length_octet_string.c @@ -0,0 +1,53 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_length_octet_string.c + ASN.1 DER, get length of OCTET STRING, Tom St Denis +*/ + +#ifdef LTC_DER +/** + Gets length of DER encoding of OCTET STRING + @param noctets The number of octets in the string to encode + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_octet_string(unsigned long noctets, unsigned long *outlen) +{ + LTC_ARGCHK(outlen != NULL); + + if (noctets < 128) { + /* 04 LL DD DD DD ... */ + *outlen = 2 + noctets; + } else if (noctets < 256) { + /* 04 81 LL DD DD DD ... */ + *outlen = 3 + noctets; + } else if (noctets < 65536UL) { + /* 04 82 LL LL DD DD DD ... */ + *outlen = 4 + noctets; + } else if (noctets < 16777216UL) { + /* 04 83 LL LL LL DD DD DD ... */ + *outlen = 5 + noctets; + } else { + return CRYPT_INVALID_ARG; + } + + return CRYPT_OK; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/printable_string/der_decode_printable_string.c b/src/ltc/pk/asn1/der/printable_string/der_decode_printable_string.c new file mode 100644 index 0000000..726387d --- /dev/null +++ b/src/ltc/pk/asn1/der/printable_string/der_decode_printable_string.c @@ -0,0 +1,96 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_printable_string.c + ASN.1 DER, encode a printable STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a printable STRING + @param in The DER encoded printable STRING + @param inlen The size of the DER printable STRING + @param out [out] The array of octets stored (one per char) + @param outlen [in/out] The number of octets stored + @return CRYPT_OK if successful +*/ +int der_decode_printable_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + int t; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* must have header at least */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* check for 0x13 */ + if ((in[0] & 0x1F) != 0x13) { + return CRYPT_INVALID_PACKET; + } + x = 1; + + /* decode the length */ + if (in[x] & 0x80) { + /* valid # of bytes in length are 1,2,3 */ + y = in[x] & 0x7F; + if ((y == 0) || (y > 3) || ((x + y) > inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* read the length in */ + len = 0; + ++x; + while (y--) { + len = (len << 8) | in[x++]; + } + } else { + len = in[x++] & 0x7F; + } + + /* is it too long? */ + if (len > *outlen) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + if (len + x > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* read the data */ + for (y = 0; y < len; y++) { + t = der_printable_value_decode(in[x++]); + if (t == -1) { + return CRYPT_INVALID_ARG; + } + out[y] = t; + } + + *outlen = y; + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/printable_string/der_encode_printable_string.c b/src/ltc/pk/asn1/der/printable_string/der_encode_printable_string.c new file mode 100644 index 0000000..21fa511 --- /dev/null +++ b/src/ltc/pk/asn1/der/printable_string/der_encode_printable_string.c @@ -0,0 +1,85 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_printable_string.c + ASN.1 DER, encode a printable STRING, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Store an printable STRING + @param in The array of printable to store (one per char) + @param inlen The number of printable to store + @param out [out] The destination for the DER encoded printable STRING + @param outlen [in/out] The max size and resulting size of the DER printable STRING + @return CRYPT_OK if successful +*/ +int der_encode_printable_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get the size */ + if ((err = der_length_printable_string(in, inlen, &len)) != CRYPT_OK) { + return err; + } + + /* too big? */ + if (len > *outlen) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + /* encode the header+len */ + x = 0; + out[x++] = 0x13; + if (inlen < 128) { + out[x++] = (unsigned char)inlen; + } else if (inlen < 256) { + out[x++] = 0x81; + out[x++] = (unsigned char)inlen; + } else if (inlen < 65536UL) { + out[x++] = 0x82; + out[x++] = (unsigned char)((inlen>>8)&255); + out[x++] = (unsigned char)(inlen&255); + } else if (inlen < 16777216UL) { + out[x++] = 0x83; + out[x++] = (unsigned char)((inlen>>16)&255); + out[x++] = (unsigned char)((inlen>>8)&255); + out[x++] = (unsigned char)(inlen&255); + } else { + return CRYPT_INVALID_ARG; + } + + /* store octets */ + for (y = 0; y < inlen; y++) { + out[x++] = der_printable_char_encode(in[y]); + } + + /* retun length */ + *outlen = x; + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/printable_string/der_length_printable_string.c b/src/ltc/pk/asn1/der/printable_string/der_length_printable_string.c new file mode 100644 index 0000000..64d9608 --- /dev/null +++ b/src/ltc/pk/asn1/der/printable_string/der_length_printable_string.c @@ -0,0 +1,166 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_length_printable_string.c + ASN.1 DER, get length of Printable STRING, Tom St Denis +*/ + +#ifdef LTC_DER + +static const struct { + int code, value; +} printable_table[] = { +{ ' ', 32 }, +{ '\'', 39 }, +{ '(', 40 }, +{ ')', 41 }, +{ '+', 43 }, +{ ',', 44 }, +{ '-', 45 }, +{ '.', 46 }, +{ '/', 47 }, +{ '0', 48 }, +{ '1', 49 }, +{ '2', 50 }, +{ '3', 51 }, +{ '4', 52 }, +{ '5', 53 }, +{ '6', 54 }, +{ '7', 55 }, +{ '8', 56 }, +{ '9', 57 }, +{ ':', 58 }, +{ '=', 61 }, +{ '?', 63 }, +{ 'A', 65 }, +{ 'B', 66 }, +{ 'C', 67 }, +{ 'D', 68 }, +{ 'E', 69 }, +{ 'F', 70 }, +{ 'G', 71 }, +{ 'H', 72 }, +{ 'I', 73 }, +{ 'J', 74 }, +{ 'K', 75 }, +{ 'L', 76 }, +{ 'M', 77 }, +{ 'N', 78 }, +{ 'O', 79 }, +{ 'P', 80 }, +{ 'Q', 81 }, +{ 'R', 82 }, +{ 'S', 83 }, +{ 'T', 84 }, +{ 'U', 85 }, +{ 'V', 86 }, +{ 'W', 87 }, +{ 'X', 88 }, +{ 'Y', 89 }, +{ 'Z', 90 }, +{ 'a', 97 }, +{ 'b', 98 }, +{ 'c', 99 }, +{ 'd', 100 }, +{ 'e', 101 }, +{ 'f', 102 }, +{ 'g', 103 }, +{ 'h', 104 }, +{ 'i', 105 }, +{ 'j', 106 }, +{ 'k', 107 }, +{ 'l', 108 }, +{ 'm', 109 }, +{ 'n', 110 }, +{ 'o', 111 }, +{ 'p', 112 }, +{ 'q', 113 }, +{ 'r', 114 }, +{ 's', 115 }, +{ 't', 116 }, +{ 'u', 117 }, +{ 'v', 118 }, +{ 'w', 119 }, +{ 'x', 120 }, +{ 'y', 121 }, +{ 'z', 122 }, +}; + +int der_printable_char_encode(int c) +{ + int x; + for (x = 0; x < (int)(sizeof(printable_table)/sizeof(printable_table[0])); x++) { + if (printable_table[x].code == c) { + return printable_table[x].value; + } + } + return -1; +} + +int der_printable_value_decode(int v) +{ + int x; + for (x = 0; x < (int)(sizeof(printable_table)/sizeof(printable_table[0])); x++) { + if (printable_table[x].value == v) { + return printable_table[x].code; + } + } + return -1; +} + +/** + Gets length of DER encoding of Printable STRING + @param octets The values you want to encode + @param noctets The number of octets in the string to encode + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen) +{ + unsigned long x; + + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(octets != NULL); + + /* scan string for validity */ + for (x = 0; x < noctets; x++) { + if (der_printable_char_encode(octets[x]) == -1) { + return CRYPT_INVALID_ARG; + } + } + + if (noctets < 128) { + /* 16 LL DD DD DD ... */ + *outlen = 2 + noctets; + } else if (noctets < 256) { + /* 16 81 LL DD DD DD ... */ + *outlen = 3 + noctets; + } else if (noctets < 65536UL) { + /* 16 82 LL LL DD DD DD ... */ + *outlen = 4 + noctets; + } else if (noctets < 16777216UL) { + /* 16 83 LL LL LL DD DD DD ... */ + *outlen = 5 + noctets; + } else { + return CRYPT_INVALID_ARG; + } + + return CRYPT_OK; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/sequence/der_decode_sequence_ex.c b/src/ltc/pk/asn1/der/sequence/der_decode_sequence_ex.c new file mode 100644 index 0000000..60692b5 --- /dev/null +++ b/src/ltc/pk/asn1/der/sequence/der_decode_sequence_ex.c @@ -0,0 +1,339 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + + +/** + @file der_decode_sequence_ex.c + ASN.1 DER, decode a SEQUENCE, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Decode a SEQUENCE + @param in The DER encoded input + @param inlen The size of the input + @param list The list of items to decode + @param outlen The number of items in the list + @param ordered Search an unordeded or ordered list + @return CRYPT_OK on success +*/ +int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen, + ltc_asn1_list *list, unsigned long outlen, int ordered) +{ + int err, i; + ltc_asn1_type type; + unsigned long size, x, y, z, blksize; + void *data; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(list != NULL); + + /* get blk size */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* sequence type? We allow 0x30 SEQUENCE and 0x31 SET since fundamentally they're the same structure */ + x = 0; + if (in[x] != 0x30 && in[x] != 0x31) { + return CRYPT_INVALID_PACKET; + } + ++x; + + /* check if the msb is set, which signals that the + * 7 lsb bits represent the number of bytes of the length + */ + if (in[x] < 128) { + blksize = in[x++]; + } else { + if (in[x] < 0x81 || in[x] > 0x83) { + return CRYPT_INVALID_PACKET; + } + y = in[x++] & 0x7F; + + /* would reading the len bytes overrun? */ + if (x + y > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* read len */ + blksize = 0; + while (y--) { + blksize = (blksize << 8) | (unsigned long)in[x++]; + } + } + + /* would this blksize overflow? */ + if (x + blksize > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* mark all as unused */ + for (i = 0; i < (int)outlen; i++) { + list[i].used = 0; + } + + /* ok read data */ + inlen = blksize; + for (i = 0; i < (int)outlen; i++) { + z = 0; + type = list[i].type; + size = list[i].size; + data = list[i].data; + if (!ordered && list[i].used == 1) { continue; } + + if (type == LTC_ASN1_EOL) { + break; + } + + /* handle context specific tags - just skip the tag + len bytes */ + z = 0; + if (list[i].tag > 0 && list[i].tag == in[x + z++]) { + if (in[x+z] & 0x80) { + y = in[x + z++] & 0x7F; + if (y == 0 || y > 2) { return CRYPT_INVALID_PACKET; } + z += y; + } else { + z++; + } + x += z; + inlen -= z; + } + + switch (type) { + case LTC_ASN1_BOOLEAN: + z = inlen; + if ((err = der_decode_boolean(in + x, z, ((int *)data))) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + if ((err = der_length_boolean(&z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_INTEGER: + z = inlen; + if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + if ((err = der_length_integer(data, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_SHORT_INTEGER: + z = inlen; + if ((err = der_decode_short_integer(in + x, z, data)) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + if ((err = der_length_short_integer(((unsigned long*)data)[0], &z)) != CRYPT_OK) { + goto LBL_ERR; + } + + break; + + case LTC_ASN1_BIT_STRING: + z = inlen; + if ((err = der_decode_bit_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_RAW_BIT_STRING: + z = inlen; + if ((err = der_decode_raw_bit_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_OCTET_STRING: + z = inlen; + if ((err = der_decode_octet_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_octet_string(size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_NULL: + if (inlen < 2 || in[x] != 0x05 || in[x+1] != 0x00) { + if (!ordered || list[i].optional) { continue; } + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + z = 2; + break; + + case LTC_ASN1_OBJECT_IDENTIFIER: + z = inlen; + if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_object_identifier(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_TELETEX_STRING: + z = inlen; + if ((err = der_decode_teletex_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_teletex_string(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_IA5_STRING: + z = inlen; + if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_ia5_string(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + + case LTC_ASN1_PRINTABLE_STRING: + z = inlen; + if ((err = der_decode_printable_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_printable_string(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_UTF8_STRING: + z = inlen; + if ((err = der_decode_utf8_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_utf8_string(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_UTCTIME: + z = inlen; + if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + break; + + case LTC_ASN1_GENERALIZEDTIME: + z = inlen; + if ((err = der_decode_generalizedtime(in + x, &z, data)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + break; + + case LTC_ASN1_SET: + z = inlen; + if ((err = der_decode_set(in + x, z, data, size)) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_SETOF: + case LTC_ASN1_SEQUENCE: + /* detect if we have the right type */ + if ((type == LTC_ASN1_SETOF && (in[x] & 0x3F) != 0x31) || (type == LTC_ASN1_SEQUENCE && (in[x] & 0x3F) != 0x30)) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + + z = inlen; + if ((err = der_decode_sequence(in + x, z, data, size)) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + + case LTC_ASN1_CHOICE: + z = inlen; + if ((err = der_decode_choice(in + x, &z, data, size)) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + break; + + case LTC_ASN1_CONSTRUCTED: + case LTC_ASN1_CONTEXT_SPECIFIC: + case LTC_ASN1_EOL: + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + x += z; + inlen -= z; + list[i].used = 1; + if (!ordered) { + /* restart the decoder */ + i = -1; + } + } + + for (i = 0; i < (int)outlen; i++) { + if (list[i].used == 0 && list[i].optional == 0) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + } + err = CRYPT_OK; + +LBL_ERR: + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.c b/src/ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.c new file mode 100644 index 0000000..d76f403 --- /dev/null +++ b/src/ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.c @@ -0,0 +1,475 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_sequence_flexi.c + ASN.1 DER, decode an array of ASN.1 types with a flexi parser, Tom St Denis +*/ + +#ifdef LTC_DER + +static unsigned long fetch_length(const unsigned char *in, unsigned long inlen, unsigned long *data_offset) +{ + unsigned long x, z; + + *data_offset = 0; + + /* skip type and read len */ + if (inlen < 2) { + return 0xFFFFFFFF; + } + ++in; ++(*data_offset); + + /* read len */ + x = *in++; ++(*data_offset); + + /* <128 means literal */ + if (x < 128) { + return x+*data_offset; + } + x &= 0x7F; /* the lower 7 bits are the length of the length */ + inlen -= 2; + + /* len means len of len! */ + if (x == 0 || x > 4 || x > inlen) { + return 0xFFFFFFFF; + } + + *data_offset += x; + z = 0; + while (x--) { + z = (z<<8) | ((unsigned long)*in); + ++in; + } + return z+*data_offset; +} + +static int new_element(ltc_asn1_list **l) +{ + /* alloc new link */ + if (*l == NULL) { + *l = XCALLOC(1, sizeof(ltc_asn1_list)); + if (*l == NULL) { + return CRYPT_MEM; + } + } else { + (*l)->next = XCALLOC(1, sizeof(ltc_asn1_list)); + if ((*l)->next == NULL) { + return CRYPT_MEM; + } + (*l)->next->prev = *l; + *l = (*l)->next; + } + return CRYPT_OK; +} + +/** + ASN.1 DER Flexi(ble) decoder will decode arbitrary DER packets and create a linked list of the decoded elements. + @param in The input buffer + @param inlen [in/out] The length of the input buffer and on output the amount of decoded data + @param out [out] A pointer to the linked list + @return CRYPT_OK on success. +*/ +int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out) +{ + ltc_asn1_list *l; + unsigned long err, type, len, totlen, data_offset; + void *realloc_tmp; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen != NULL); + LTC_ARGCHK(out != NULL); + + l = NULL; + totlen = 0; + + if (*inlen == 0) { + /* alloc new link */ + if ((err = new_element(&l)) != CRYPT_OK) { + goto error; + } + } + + /* scan the input and and get lengths and what not */ + while (*inlen) { + /* read the type byte */ + type = *in; + + /* fetch length */ + len = fetch_length(in, *inlen, &data_offset); + if (len > *inlen) { + err = CRYPT_INVALID_PACKET; + goto error; + } + + /* alloc new link */ + if ((err = new_element(&l)) != CRYPT_OK) { + goto error; + } + + if ((type & 0x20) && (type != 0x30) && (type != 0x31)) { + /* constructed, use the 'used' field to store the original identifier */ + l->used = type; + /* treat constructed elements like SETs */ + type = 0x20; + } + else if ((type & 0xC0) == 0x80) { + /* context-specific, use the 'used' field to store the original identifier */ + l->used = type; + /* context-specific elements are treated as opaque data */ + type = 0x80; + } + + /* now switch on type */ + switch (type) { + case 0x01: /* BOOLEAN */ + l->type = LTC_ASN1_BOOLEAN; + l->size = 1; + l->data = XCALLOC(1, sizeof(int)); + + if ((err = der_decode_boolean(in, *inlen, l->data)) != CRYPT_OK) { + goto error; + } + + if ((err = der_length_boolean(&len)) != CRYPT_OK) { + goto error; + } + break; + + case 0x02: /* INTEGER */ + /* init field */ + l->type = LTC_ASN1_INTEGER; + l->size = 1; + if ((err = mp_init(&l->data)) != CRYPT_OK) { + goto error; + } + + /* decode field */ + if ((err = der_decode_integer(in, *inlen, l->data)) != CRYPT_OK) { + goto error; + } + + /* calc length of object */ + if ((err = der_length_integer(l->data, &len)) != CRYPT_OK) { + goto error; + } + break; + + case 0x03: /* BIT */ + /* init field */ + l->type = LTC_ASN1_BIT_STRING; + l->size = len * 8; /* *8 because we store decoded bits one per char and they are encoded 8 per char. */ + + if ((l->data = XCALLOC(1, l->size)) == NULL) { + err = CRYPT_MEM; + goto error; + } + + if ((err = der_decode_bit_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { + goto error; + } + + if ((err = der_length_bit_string(l->size, &len)) != CRYPT_OK) { + goto error; + } + break; + + case 0x04: /* OCTET */ + + /* init field */ + l->type = LTC_ASN1_OCTET_STRING; + l->size = len; + + if ((l->data = XCALLOC(1, l->size)) == NULL) { + err = CRYPT_MEM; + goto error; + } + + if ((err = der_decode_octet_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { + goto error; + } + + if ((err = der_length_octet_string(l->size, &len)) != CRYPT_OK) { + goto error; + } + break; + + case 0x05: /* NULL */ + + /* valid NULL is 0x05 0x00 */ + if (in[0] != 0x05 || in[1] != 0x00) { + err = CRYPT_INVALID_PACKET; + goto error; + } + + /* simple to store ;-) */ + l->type = LTC_ASN1_NULL; + l->data = NULL; + l->size = 0; + len = 2; + + break; + + case 0x06: /* OID */ + + /* init field */ + l->type = LTC_ASN1_OBJECT_IDENTIFIER; + l->size = len; + + if ((l->data = XCALLOC(len, sizeof(unsigned long))) == NULL) { + err = CRYPT_MEM; + goto error; + } + + if ((err = der_decode_object_identifier(in, *inlen, l->data, &l->size)) != CRYPT_OK) { + goto error; + } + + if ((err = der_length_object_identifier(l->data, l->size, &len)) != CRYPT_OK) { + goto error; + } + + /* resize it to save a bunch of mem */ + if ((realloc_tmp = XREALLOC(l->data, l->size * sizeof(unsigned long))) == NULL) { + /* out of heap but this is not an error */ + break; + } + l->data = realloc_tmp; + break; + + case 0x0C: /* UTF8 */ + + /* init field */ + l->type = LTC_ASN1_UTF8_STRING; + l->size = len; + + if ((l->data = XCALLOC(sizeof(wchar_t), l->size)) == NULL) { + err = CRYPT_MEM; + goto error; + } + + if ((err = der_decode_utf8_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { + goto error; + } + + if ((err = der_length_utf8_string(l->data, l->size, &len)) != CRYPT_OK) { + goto error; + } + break; + + case 0x13: /* PRINTABLE */ + + /* init field */ + l->type = LTC_ASN1_PRINTABLE_STRING; + l->size = len; + + if ((l->data = XCALLOC(1, l->size)) == NULL) { + err = CRYPT_MEM; + goto error; + } + + if ((err = der_decode_printable_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { + goto error; + } + + if ((err = der_length_printable_string(l->data, l->size, &len)) != CRYPT_OK) { + goto error; + } + break; + + case 0x14: /* TELETEXT */ + + /* init field */ + l->type = LTC_ASN1_TELETEX_STRING; + l->size = len; + + if ((l->data = XCALLOC(1, l->size)) == NULL) { + err = CRYPT_MEM; + goto error; + } + + if ((err = der_decode_teletex_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { + goto error; + } + + if ((err = der_length_teletex_string(l->data, l->size, &len)) != CRYPT_OK) { + goto error; + } + break; + + case 0x16: /* IA5 */ + + /* init field */ + l->type = LTC_ASN1_IA5_STRING; + l->size = len; + + if ((l->data = XCALLOC(1, l->size)) == NULL) { + err = CRYPT_MEM; + goto error; + } + + if ((err = der_decode_ia5_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { + goto error; + } + + if ((err = der_length_ia5_string(l->data, l->size, &len)) != CRYPT_OK) { + goto error; + } + break; + + case 0x17: /* UTC TIME */ + + /* init field */ + l->type = LTC_ASN1_UTCTIME; + l->size = 1; + + if ((l->data = XCALLOC(1, sizeof(ltc_utctime))) == NULL) { + err = CRYPT_MEM; + goto error; + } + + len = *inlen; + if ((err = der_decode_utctime(in, &len, l->data)) != CRYPT_OK) { + goto error; + } + + if ((err = der_length_utctime(l->data, &len)) != CRYPT_OK) { + goto error; + } + break; + + case 0x18: + l->type = LTC_ASN1_GENERALIZEDTIME; + l->size = len; + + if ((l->data = XCALLOC(1, sizeof(ltc_generalizedtime))) == NULL) { + err = CRYPT_MEM; + goto error; + } + + if ((err = der_decode_generalizedtime(in, &len, l->data)) != CRYPT_OK) { + goto error; + } + + if ((err = der_length_generalizedtime(l->data, &len)) != CRYPT_OK) { + goto error; + } + + break; + + case 0x20: /* Any CONSTRUCTED element that is neither SEQUENCE nor SET */ + case 0x30: /* SEQUENCE */ + case 0x31: /* SET */ + + /* init field */ + if (type == 0x20) { + l->type = LTC_ASN1_CONSTRUCTED; + } + else if (type == 0x30) { + l->type = LTC_ASN1_SEQUENCE; + } + else { + l->type = LTC_ASN1_SET; + } + + if ((l->data = XMALLOC(len)) == NULL) { + err = CRYPT_MEM; + goto error; + } + + XMEMCPY(l->data, in, len); + l->size = len; + + + /* jump to the start of the data */ + in += data_offset; + *inlen -= data_offset; + len = len - data_offset; + + /* Sequence elements go as child */ + if ((err = der_decode_sequence_flexi(in, &len, &(l->child))) != CRYPT_OK) { + goto error; + } + + /* len update */ + totlen += data_offset; + + /* the flexi decoder can also do nothing, so make sure a child has been allocated */ + if (l->child) { + /* link them up y0 */ + l->child->parent = l; + } + + break; + + case 0x80: /* Context-specific */ + l->type = LTC_ASN1_CONTEXT_SPECIFIC; + + if ((l->data = XCALLOC(1, len - data_offset)) == NULL) { + err = CRYPT_MEM; + goto error; + } + + XMEMCPY(l->data, in + data_offset, len - data_offset); + l->size = len - data_offset; + + break; + + default: + /* invalid byte ... this is a soft error */ + /* remove link */ + if (l->prev) { + l = l->prev; + XFREE(l->next); + l->next = NULL; + } + goto outside; + } + + /* advance pointers */ + totlen += len; + in += len; + *inlen -= len; + } + +outside: + + /* in case we processed anything */ + if (totlen) { + /* rewind l please */ + while (l->prev != NULL || l->parent != NULL) { + if (l->parent != NULL) { + l = l->parent; + } else { + l = l->prev; + } + } + } + + /* return */ + *out = l; + *inlen = totlen; + return CRYPT_OK; + +error: + /* free list */ + der_sequence_free(l); + + return err; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/sequence/der_decode_sequence_multi.c b/src/ltc/pk/asn1/der/sequence/der_decode_sequence_multi.c new file mode 100644 index 0000000..ba23412 --- /dev/null +++ b/src/ltc/pk/asn1/der/sequence/der_decode_sequence_multi.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://libtom.org + */ +#include "tomcrypt.h" +#include + + +/** + @file der_decode_sequence_multi.c + ASN.1 DER, decode a SEQUENCE, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Decode a SEQUENCE type using a VA list + @param in Input buffer + @param inlen Length of input in octets + @remark <...> is of the form (int, unsigned long, void*) + @return CRYPT_OK on success +*/ +int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...) +{ + int err; + ltc_asn1_type type; + unsigned long size, x; + void *data; + va_list args; + ltc_asn1_list *list; + + LTC_ARGCHK(in != NULL); + + /* get size of output that will be required */ + va_start(args, inlen); + x = 0; + for (;;) { + type = va_arg(args, ltc_asn1_type); + size = va_arg(args, unsigned long); + data = va_arg(args, void*); + LTC_UNUSED_PARAM(size); + LTC_UNUSED_PARAM(data); + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_BOOLEAN: + case LTC_ASN1_INTEGER: + case LTC_ASN1_SHORT_INTEGER: + case LTC_ASN1_BIT_STRING: + case LTC_ASN1_OCTET_STRING: + case LTC_ASN1_NULL: + case LTC_ASN1_OBJECT_IDENTIFIER: + case LTC_ASN1_IA5_STRING: + case LTC_ASN1_PRINTABLE_STRING: + case LTC_ASN1_UTF8_STRING: + case LTC_ASN1_UTCTIME: + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: + case LTC_ASN1_SEQUENCE: + case LTC_ASN1_CHOICE: + case LTC_ASN1_RAW_BIT_STRING: + case LTC_ASN1_TELETEX_STRING: + case LTC_ASN1_GENERALIZEDTIME: + ++x; + break; + + case LTC_ASN1_EOL: + case LTC_ASN1_CONSTRUCTED: + case LTC_ASN1_CONTEXT_SPECIFIC: + va_end(args); + return CRYPT_INVALID_ARG; + } + } + va_end(args); + + /* allocate structure for x elements */ + if (x == 0) { + return CRYPT_NOP; + } + + list = XCALLOC(sizeof(*list), x); + if (list == NULL) { + return CRYPT_MEM; + } + + /* fill in the structure */ + va_start(args, inlen); + x = 0; + for (;;) { + type = va_arg(args, ltc_asn1_type); + size = va_arg(args, unsigned long); + data = va_arg(args, void*); + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_BOOLEAN: + case LTC_ASN1_INTEGER: + case LTC_ASN1_SHORT_INTEGER: + case LTC_ASN1_BIT_STRING: + case LTC_ASN1_OCTET_STRING: + case LTC_ASN1_NULL: + case LTC_ASN1_OBJECT_IDENTIFIER: + case LTC_ASN1_IA5_STRING: + case LTC_ASN1_PRINTABLE_STRING: + case LTC_ASN1_UTF8_STRING: + case LTC_ASN1_UTCTIME: + case LTC_ASN1_SEQUENCE: + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: + case LTC_ASN1_CHOICE: + case LTC_ASN1_RAW_BIT_STRING: + case LTC_ASN1_TELETEX_STRING: + case LTC_ASN1_GENERALIZEDTIME: + LTC_SET_ASN1(list, x++, type, data, size); + break; + /* coverity[dead_error_line] */ + case LTC_ASN1_EOL: + case LTC_ASN1_CONSTRUCTED: + case LTC_ASN1_CONTEXT_SPECIFIC: + break; + } + } + va_end(args); + + err = der_decode_sequence(in, inlen, list, x); + XFREE(list); + return err; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/sequence/der_decode_subject_public_key_info.c b/src/ltc/pk/asn1/der/sequence/der_decode_subject_public_key_info.c new file mode 100644 index 0000000..c649913 --- /dev/null +++ b/src/ltc/pk/asn1/der/sequence/der_decode_subject_public_key_info.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. + * + */ +#include "tomcrypt.h" +/** + @file der_decode_subject_public_key_info.c + ASN.1 DER, encode a Subject Public Key structure --nmav +*/ + +#ifdef LTC_DER + +/* AlgorithmIdentifier := SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm + * } + * + * SubjectPublicKeyInfo := SEQUENCE { + * algorithm AlgorithmIdentifier, + * subjectPublicKey BIT STRING + * } + */ +/** + Decode a subject public key info + @param in The input buffer + @param inlen The length of the input buffer + @param algorithm One out of the enum #public_key_algorithms + @param public_key The buffer for the public key + @param public_key_len [in/out] The length of the public key buffer and the written length + @param parameters_type The parameters' type out of the enum #ltc_asn1_type + @param parameters The parameters to include + @param parameters_len The number of parameters to include + @return CRYPT_OK on success +*/ +int der_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen, + unsigned int algorithm, void* public_key, unsigned long* public_key_len, + unsigned long parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len) +{ + return der_decode_subject_public_key_info_ex(in, inlen, algorithm, public_key, public_key_len, + parameters_type, parameters, parameters_len, NULL); +} + +int der_decode_subject_public_key_info_ex(const unsigned char *in, unsigned long inlen, + unsigned int algorithm, void* public_key, unsigned long* public_key_len, + unsigned long parameters_type, void* parameters, unsigned long parameters_len, + unsigned long *parameters_outsize) +{ + int err; + unsigned long len; + oid_st oid; + unsigned char *tmpbuf; + unsigned long tmpoid[16]; + ltc_asn1_list alg_id[2]; + ltc_asn1_list subject_pubkey[2]; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen != 0); + LTC_ARGCHK(public_key_len != NULL); + + err = pk_get_oid(algorithm, &oid); + if (err != CRYPT_OK) { + return err; + } + + /* see if the OpenSSL DER format RSA public key will work */ + tmpbuf = XCALLOC(1, LTC_DER_MAX_PUBKEY_SIZE*8); + if (tmpbuf == NULL) { + err = CRYPT_MEM; + goto LBL_ERR; + } + + /* this includes the internal hash ID and optional params (NULL in this case) */ + LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid)/sizeof(tmpoid[0])); + LTC_SET_ASN1(alg_id, 1, (ltc_asn1_type)parameters_type, parameters, parameters_len); + + /* the actual format of the SSL DER key is odd, it stores a RSAPublicKey + * in a **BIT** string ... so we have to extract it then proceed to convert bit to octet + */ + LTC_SET_ASN1(subject_pubkey, 0, LTC_ASN1_SEQUENCE, alg_id, 2); + LTC_SET_ASN1(subject_pubkey, 1, LTC_ASN1_RAW_BIT_STRING, tmpbuf, LTC_DER_MAX_PUBKEY_SIZE*8); + + err=der_decode_sequence(in, inlen, subject_pubkey, 2UL); + if (err != CRYPT_OK) { + goto LBL_ERR; + } + + if (parameters_outsize) *parameters_outsize = alg_id[1].size; + + if ((alg_id[0].size != oid.OIDlen) || + XMEMCMP(oid.OID, alg_id[0].data, oid.OIDlen * sizeof(oid.OID[0]))) { + /* OID mismatch */ + err = CRYPT_PK_INVALID_TYPE; + goto LBL_ERR; + } + + len = subject_pubkey[1].size/8; + if (*public_key_len > len) { + XMEMCPY(public_key, subject_pubkey[1].data, len); + *public_key_len = len; + } else { + *public_key_len = len; + err = CRYPT_BUFFER_OVERFLOW; + goto LBL_ERR; + } + + err = CRYPT_OK; + +LBL_ERR: + + XFREE(tmpbuf); + + return err; +} + +#endif diff --git a/src/ltc/pk/asn1/der/sequence/der_encode_sequence_ex.c b/src/ltc/pk/asn1/der/sequence/der_encode_sequence_ex.c new file mode 100644 index 0000000..79d8711 --- /dev/null +++ b/src/ltc/pk/asn1/der/sequence/der_encode_sequence_ex.c @@ -0,0 +1,244 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + + +/** + @file der_encode_sequence_ex.c + ASN.1 DER, encode a SEQUENCE, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Encode a SEQUENCE + @param list The list of items to encode + @param inlen The number of items in the list + @param out [out] The destination + @param outlen [in/out] The size of the output + @param type_of LTC_ASN1_SEQUENCE or LTC_ASN1_SET/LTC_ASN1_SETOF + @return CRYPT_OK on success +*/ +int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int type_of) +{ + int err; + ltc_asn1_type type; + unsigned long size, x, y, z, i; + unsigned char tmptag[6]; + void *data; + + LTC_ARGCHK(list != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get size of output that will be required */ + y = 0; z = 0; + if ((err = der_length_sequence_ex(list, inlen, &y, &z)) != CRYPT_OK) return CRYPT_INVALID_ARG; + + /* too big ? */ + if (*outlen < y) { + *outlen = y; + err = CRYPT_BUFFER_OVERFLOW; + goto LBL_ERR; + } + + /* store header */ + x = 0; + out[x++] = (type_of == LTC_ASN1_SEQUENCE) ? 0x30 : 0x31; + + if (z < 128) { + out[x++] = (unsigned char)z; + } else if (z < 256) { + out[x++] = 0x81; + out[x++] = (unsigned char)z; + } else if (z < 65536UL) { + out[x++] = 0x82; + out[x++] = (unsigned char)((z>>8UL)&255); + out[x++] = (unsigned char)(z&255); + } else if (z < 16777216UL) { + out[x++] = 0x83; + out[x++] = (unsigned char)((z>>16UL)&255); + out[x++] = (unsigned char)((z>>8UL)&255); + out[x++] = (unsigned char)(z&255); + } + + /* store data */ + *outlen -= x; + for (i = 0; i < inlen; i++) { + type = list[i].type; + size = list[i].size; + data = list[i].data; + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_BOOLEAN: + z = *outlen; + if ((err = der_encode_boolean(*((int *)data), out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_INTEGER: + z = *outlen; + if ((err = der_encode_integer(data, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_SHORT_INTEGER: + z = *outlen; + if ((err = der_encode_short_integer(*((unsigned long*)data), out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_BIT_STRING: + z = *outlen; + if ((err = der_encode_bit_string(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_RAW_BIT_STRING: + z = *outlen; + if ((err = der_encode_raw_bit_string(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_OCTET_STRING: + z = *outlen; + if ((err = der_encode_octet_string(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_NULL: + out[x] = 0x05; + out[x+1] = 0x00; + z = 2; + break; + + case LTC_ASN1_OBJECT_IDENTIFIER: + z = *outlen; + if ((err = der_encode_object_identifier(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_IA5_STRING: + z = *outlen; + if ((err = der_encode_ia5_string(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_PRINTABLE_STRING: + z = *outlen; + if ((err = der_encode_printable_string(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_UTF8_STRING: + z = *outlen; + if ((err = der_encode_utf8_string(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_UTCTIME: + z = *outlen; + if ((err = der_encode_utctime(data, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_GENERALIZEDTIME: + z = *outlen; + if ((err = der_encode_generalizedtime(data, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_SET: + z = *outlen; + if ((err = der_encode_set(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_SETOF: + z = *outlen; + if ((err = der_encode_setof(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_SEQUENCE: + z = *outlen; + if ((err = der_encode_sequence_ex(data, size, out + x, &z, type)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_CHOICE: + case LTC_ASN1_CONSTRUCTED: + case LTC_ASN1_CONTEXT_SPECIFIC: + case LTC_ASN1_EOL: + case LTC_ASN1_TELETEX_STRING: + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + + if (list[i].tag > 0) { + tmptag[0] = list[i].tag; + y = 0; + if (z < 128) { + tmptag[1] = (unsigned char)z; + y = 2; + } else if (z < 256) { + tmptag[1] = 0x81; + tmptag[2] = (unsigned char)z; + y = 3; + } else if (z < 65536UL) { + tmptag[1] = 0x82; + tmptag[2] = (unsigned char)((z>>8UL)&255); + tmptag[3] = (unsigned char)(z&255); + y = 4; + } else if (z < 16777216UL) { + tmptag[1] = 0x83; + tmptag[2] = (unsigned char)((z>>16UL)&255); + tmptag[3] = (unsigned char)((z>>8UL)&255); + tmptag[4] = (unsigned char)(z&255); + y = 5; + } + XMEMMOVE(out + x + y, out + x, z); + XMEMCPY(out + x, tmptag, y); + + z += y; + } + + x += z; + *outlen -= z; + } + *outlen = x; + err = CRYPT_OK; + +LBL_ERR: + return err; +} + +#endif diff --git a/src/ltc/pk/asn1/der/sequence/der_encode_sequence_multi.c b/src/ltc/pk/asn1/der/sequence/der_encode_sequence_multi.c new file mode 100644 index 0000000..3bd76bf --- /dev/null +++ b/src/ltc/pk/asn1/der/sequence/der_encode_sequence_multi.c @@ -0,0 +1,151 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" +#include + + +/** + @file der_encode_sequence_multi.c + ASN.1 DER, encode a SEQUENCE, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Encode a SEQUENCE type using a VA list + @param out [out] Destination for data + @param outlen [in/out] Length of buffer and resulting length of output + @remark <...> is of the form (int, unsigned long, void*) + @return CRYPT_OK on success +*/ +int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...) +{ + int err; + ltc_asn1_type type; + unsigned long size, x; + void *data; + va_list args; + ltc_asn1_list *list; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get size of output that will be required */ + va_start(args, outlen); + x = 0; + for (;;) { + type = va_arg(args, ltc_asn1_type); + size = va_arg(args, unsigned long); + data = va_arg(args, void*); + LTC_UNUSED_PARAM(size); + LTC_UNUSED_PARAM(data); + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_BOOLEAN: + case LTC_ASN1_INTEGER: + case LTC_ASN1_SHORT_INTEGER: + case LTC_ASN1_BIT_STRING: + case LTC_ASN1_OCTET_STRING: + case LTC_ASN1_NULL: + case LTC_ASN1_OBJECT_IDENTIFIER: + case LTC_ASN1_IA5_STRING: + case LTC_ASN1_PRINTABLE_STRING: + case LTC_ASN1_UTF8_STRING: + case LTC_ASN1_UTCTIME: + case LTC_ASN1_SEQUENCE: + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: + case LTC_ASN1_RAW_BIT_STRING: + case LTC_ASN1_GENERALIZEDTIME: + ++x; + break; + + case LTC_ASN1_CHOICE: + case LTC_ASN1_CONSTRUCTED: + case LTC_ASN1_CONTEXT_SPECIFIC: + case LTC_ASN1_EOL: + case LTC_ASN1_TELETEX_STRING: + va_end(args); + return CRYPT_INVALID_ARG; + } + } + va_end(args); + + /* allocate structure for x elements */ + if (x == 0) { + return CRYPT_NOP; + } + + list = XCALLOC(sizeof(*list), x); + if (list == NULL) { + return CRYPT_MEM; + } + + /* fill in the structure */ + va_start(args, outlen); + x = 0; + for (;;) { + type = va_arg(args, ltc_asn1_type); + size = va_arg(args, unsigned long); + data = va_arg(args, void*); + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_BOOLEAN: + case LTC_ASN1_INTEGER: + case LTC_ASN1_SHORT_INTEGER: + case LTC_ASN1_BIT_STRING: + case LTC_ASN1_OCTET_STRING: + case LTC_ASN1_NULL: + case LTC_ASN1_OBJECT_IDENTIFIER: + case LTC_ASN1_IA5_STRING: + case LTC_ASN1_PRINTABLE_STRING: + case LTC_ASN1_UTF8_STRING: + case LTC_ASN1_UTCTIME: + case LTC_ASN1_SEQUENCE: + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: + case LTC_ASN1_RAW_BIT_STRING: + case LTC_ASN1_GENERALIZEDTIME: + LTC_SET_ASN1(list, x++, type, data, size); + break; + + case LTC_ASN1_CHOICE: + case LTC_ASN1_CONSTRUCTED: + case LTC_ASN1_CONTEXT_SPECIFIC: + case LTC_ASN1_EOL: + case LTC_ASN1_TELETEX_STRING: + va_end(args); + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + } + va_end(args); + + err = der_encode_sequence(list, x, out, outlen); +LBL_ERR: + XFREE(list); + return err; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/sequence/der_encode_subject_public_key_info.c b/src/ltc/pk/asn1/der/sequence/der_encode_subject_public_key_info.c new file mode 100644 index 0000000..0578d53 --- /dev/null +++ b/src/ltc/pk/asn1/der/sequence/der_encode_subject_public_key_info.c @@ -0,0 +1,69 @@ +/* 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. + * + */ +#include "tomcrypt.h" + +/** + @file der_encode_subject_public_key_info.c + ASN.1 DER, encode a Subject Public Key structure --nmav +*/ + +#ifdef LTC_DER + +/* AlgorithmIdentifier := SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm + * } + * + * SubjectPublicKeyInfo := SEQUENCE { + * algorithm AlgorithmIdentifier, + * subjectPublicKey BIT STRING + * } + */ +/** + Encode a subject public key info + @param out The output buffer + @param outlen [in/out] Length of buffer and resulting length of output + @param algorithm One out of the enum #public_key_algorithms + @param public_key The buffer for the public key + @param public_key_len The length of the public key buffer + @param parameters_type The parameters' type out of the enum #ltc_asn1_type + @param parameters The parameters to include + @param parameters_len The number of parameters to include + @return CRYPT_OK on success +*/ +int der_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen, + unsigned int algorithm, void* public_key, unsigned long public_key_len, + unsigned long parameters_type, void* parameters, unsigned long parameters_len) +{ + int err; + ltc_asn1_list alg_id[2]; + oid_st oid; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + err = pk_get_oid(algorithm, &oid); + if (err != CRYPT_OK) { + return err; + } + + LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid.OID, oid.OIDlen); + LTC_SET_ASN1(alg_id, 1, (ltc_asn1_type)parameters_type, parameters, parameters_len); + + return der_encode_sequence_multi(out, outlen, + LTC_ASN1_SEQUENCE, (unsigned long)sizeof(alg_id)/sizeof(alg_id[0]), alg_id, + LTC_ASN1_RAW_BIT_STRING, (unsigned long)(public_key_len*8), public_key, + LTC_ASN1_EOL, 0UL, NULL); + +} + +#endif + + diff --git a/src/ltc/pk/asn1/der/sequence/der_length_sequence.c b/src/ltc/pk/asn1/der/sequence/der_length_sequence.c new file mode 100644 index 0000000..a89d2f0 --- /dev/null +++ b/src/ltc/pk/asn1/der/sequence/der_length_sequence.c @@ -0,0 +1,214 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_length_sequence.c + ASN.1 DER, length a SEQUENCE, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Get the length of a DER sequence + @param list The sequences of items in the SEQUENCE + @param inlen The number of items + @param outlen [out] The length required in octets to store it + @return CRYPT_OK on success +*/ +int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, + unsigned long *outlen) +{ + return der_length_sequence_ex(list, inlen, outlen, NULL); +} + +int der_length_sequence_ex(ltc_asn1_list *list, unsigned long inlen, + unsigned long *outlen, unsigned long *payloadlen) +{ + int err; + ltc_asn1_type type; + unsigned long size, x, y, i, z; + void *data; + + LTC_ARGCHK(list != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get size of output that will be required */ + y = 0; + for (i = 0; i < inlen; i++) { + type = list[i].type; + size = list[i].size; + data = list[i].data; + + if (type == LTC_ASN1_EOL) { + break; + } + + /* some items may be optional during import */ + if (!list[i].used && list[i].optional) continue; + + switch (type) { + case LTC_ASN1_BOOLEAN: + if ((err = der_length_boolean(&x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_INTEGER: + if ((err = der_length_integer(data, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_SHORT_INTEGER: + if ((err = der_length_short_integer(*((unsigned long *)data), &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_BIT_STRING: + case LTC_ASN1_RAW_BIT_STRING: + if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_OCTET_STRING: + if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_NULL: + y += 2; + break; + + case LTC_ASN1_OBJECT_IDENTIFIER: + if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_IA5_STRING: + if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_TELETEX_STRING: + if ((err = der_length_teletex_string(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_PRINTABLE_STRING: + if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_UTCTIME: + if ((err = der_length_utctime(data, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_GENERALIZEDTIME: + if ((err = der_length_generalizedtime(data, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_UTF8_STRING: + if ((err = der_length_utf8_string(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: + case LTC_ASN1_SEQUENCE: + if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + + case LTC_ASN1_CHOICE: + case LTC_ASN1_CONSTRUCTED: + case LTC_ASN1_CONTEXT_SPECIFIC: + case LTC_ASN1_EOL: + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + + /* handle context specific tags size */ + if (list[i].tag > 0) { + if (x < 128) { + y += 2; + } else if (x < 256) { + y += 3; + } else if (x < 65536UL) { + y += 4; + } else if (x < 16777216UL) { + y += 5; + } else { + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + } + } + + /* calc header size */ + z = y; + if (y < 128) { + y += 2; + } else if (y < 256) { + /* 0x30 0x81 LL */ + y += 3; + } else if (y < 65536UL) { + /* 0x30 0x82 LL LL */ + y += 4; + } else if (y < 16777216UL) { + /* 0x30 0x83 LL LL LL */ + y += 5; + } else { + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + + /* store size */ + if (payloadlen) *payloadlen = z; + *outlen = y; + err = CRYPT_OK; + +LBL_ERR: + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/sequence/der_sequence_free.c b/src/ltc/pk/asn1/der/sequence/der_sequence_free.c new file mode 100644 index 0000000..4600d5f --- /dev/null +++ b/src/ltc/pk/asn1/der/sequence/der_sequence_free.c @@ -0,0 +1,65 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_sequence_free.c + ASN.1 DER, free's a structure allocated by der_decode_sequence_flexi(), Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Free memory allocated by der_decode_sequence_flexi() + @param in The list to free +*/ +void der_sequence_free(ltc_asn1_list *in) +{ + ltc_asn1_list *l; + + if (!in) return; + + /* walk to the start of the chain */ + while (in->prev != NULL || in->parent != NULL) { + if (in->parent != NULL) { + in = in->parent; + } else { + in = in->prev; + } + } + + /* now walk the list and free stuff */ + while (in != NULL) { + /* is there a child? */ + if (in->child) { + /* disconnect */ + in->child->parent = NULL; + der_sequence_free(in->child); + } + + switch (in->type) { + case LTC_ASN1_SETOF: break; + case LTC_ASN1_INTEGER : if (in->data != NULL) { mp_clear(in->data); } break; + default : if (in->data != NULL) { XFREE(in->data); } + } + + /* move to next and free current */ + l = in->next; + XFREE(in); + in = l; + } +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/set/der_encode_set.c b/src/ltc/pk/asn1/der/set/der_encode_set.c new file mode 100644 index 0000000..75de234 --- /dev/null +++ b/src/ltc/pk/asn1/der/set/der_encode_set.c @@ -0,0 +1,110 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_set.c + ASN.1 DER, Encode a SET, Tom St Denis +*/ + +#ifdef LTC_DER + +/* LTC define to ASN.1 TAG */ +static int ltc_to_asn1(ltc_asn1_type v) +{ + switch (v) { + case LTC_ASN1_BOOLEAN: return 0x01; + case LTC_ASN1_INTEGER: + case LTC_ASN1_SHORT_INTEGER: return 0x02; + case LTC_ASN1_RAW_BIT_STRING: + case LTC_ASN1_BIT_STRING: return 0x03; + case LTC_ASN1_OCTET_STRING: return 0x04; + case LTC_ASN1_NULL: return 0x05; + case LTC_ASN1_OBJECT_IDENTIFIER: return 0x06; + case LTC_ASN1_UTF8_STRING: return 0x0C; + case LTC_ASN1_PRINTABLE_STRING: return 0x13; + case LTC_ASN1_TELETEX_STRING: return 0x14; + case LTC_ASN1_IA5_STRING: return 0x16; + case LTC_ASN1_UTCTIME: return 0x17; + case LTC_ASN1_GENERALIZEDTIME: return 0x18; + case LTC_ASN1_SEQUENCE: return 0x30; + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: return 0x31; + case LTC_ASN1_CHOICE: + case LTC_ASN1_CONSTRUCTED: + case LTC_ASN1_CONTEXT_SPECIFIC: + case LTC_ASN1_EOL: return -1; + } + return -1; +} + + +static int qsort_helper(const void *a, const void *b) +{ + ltc_asn1_list *A = (ltc_asn1_list *)a, *B = (ltc_asn1_list *)b; + int r; + + r = ltc_to_asn1(A->type) - ltc_to_asn1(B->type); + + /* for QSORT the order is UNDEFINED if they are "equal" which means it is NOT DETERMINISTIC. So we force it to be :-) */ + if (r == 0) { + /* their order in the original list now determines the position */ + return A->used - B->used; + } else { + return r; + } +} + +/* + Encode a SET type + @param list The list of items to encode + @param inlen The number of items in the list + @param out [out] The destination + @param outlen [in/out] The size of the output + @return CRYPT_OK on success +*/ +int der_encode_set(ltc_asn1_list *list, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + ltc_asn1_list *copy; + unsigned long x; + int err; + + /* make copy of list */ + copy = XCALLOC(inlen, sizeof(*copy)); + if (copy == NULL) { + return CRYPT_MEM; + } + + /* fill in used member with index so we can fully sort it */ + for (x = 0; x < inlen; x++) { + copy[x] = list[x]; + copy[x].used = x; + } + + /* sort it by the "type" field */ + XQSORT(copy, inlen, sizeof(*copy), &qsort_helper); + + /* call der_encode_sequence_ex() */ + err = der_encode_sequence_ex(copy, inlen, out, outlen, LTC_ASN1_SET); + + /* free list */ + XFREE(copy); + + return err; +} + + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/set/der_encode_setof.c b/src/ltc/pk/asn1/der/set/der_encode_setof.c new file mode 100644 index 0000000..d4001f9 --- /dev/null +++ b/src/ltc/pk/asn1/der/set/der_encode_setof.c @@ -0,0 +1,163 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_setof.c + ASN.1 DER, Encode SET OF, Tom St Denis +*/ + +#ifdef LTC_DER + +struct edge { + unsigned char *start; + unsigned long size; +}; + +static int qsort_helper(const void *a, const void *b) +{ + struct edge *A = (struct edge *)a, *B = (struct edge *)b; + int r; + unsigned long x; + + /* compare min length */ + r = XMEMCMP(A->start, B->start, MIN(A->size, B->size)); + + if (r == 0 && A->size != B->size) { + if (A->size > B->size) { + for (x = B->size; x < A->size; x++) { + if (A->start[x]) { + return 1; + } + } + } else { + for (x = A->size; x < B->size; x++) { + if (B->start[x]) { + return -1; + } + } + } + } + + return r; +} + +/** + Encode a SETOF stucture + @param list The list of items to encode + @param inlen The number of items in the list + @param out [out] The destination + @param outlen [in/out] The size of the output + @return CRYPT_OK on success +*/ +int der_encode_setof(ltc_asn1_list *list, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, z; + ptrdiff_t hdrlen; + int err; + struct edge *edges; + unsigned char *ptr, *buf; + + /* check that they're all the same type */ + for (x = 1; x < inlen; x++) { + if (list[x].type != list[x-1].type) { + return CRYPT_INVALID_ARG; + } + } + + /* alloc buffer to store copy of output */ + buf = XCALLOC(1, *outlen); + if (buf == NULL) { + return CRYPT_MEM; + } + + /* encode list */ + if ((err = der_encode_sequence_ex(list, inlen, buf, outlen, LTC_ASN1_SETOF)) != CRYPT_OK) { + XFREE(buf); + return err; + } + + /* allocate edges */ + edges = XCALLOC(inlen, sizeof(*edges)); + if (edges == NULL) { + XFREE(buf); + return CRYPT_MEM; + } + + /* skip header */ + ptr = buf + 1; + + /* now skip length data */ + x = *ptr++; + if (x >= 0x80) { + ptr += (x & 0x7F); + } + + /* get the size of the static header */ + hdrlen = ptr - buf; + + + /* scan for edges */ + x = 0; + while (ptr < (buf + *outlen)) { + /* store start */ + edges[x].start = ptr; + + /* skip type */ + z = 1; + + /* parse length */ + y = ptr[z++]; + if (y < 128) { + edges[x].size = y; + } else { + y &= 0x7F; + edges[x].size = 0; + while (y--) { + edges[x].size = (edges[x].size << 8) | ((unsigned long)ptr[z++]); + } + } + + /* skip content */ + edges[x].size += z; + ptr += edges[x].size; + ++x; + } + + /* sort based on contents (using edges) */ + XQSORT(edges, inlen, sizeof(*edges), &qsort_helper); + + /* copy static header */ + XMEMCPY(out, buf, hdrlen); + + /* copy+sort using edges+indecies to output from buffer */ + for (y = (unsigned long)hdrlen, x = 0; x < inlen; x++) { + XMEMCPY(out+y, edges[x].start, edges[x].size); + y += edges[x].size; + } + +#ifdef LTC_CLEAN_STACK + zeromem(buf, *outlen); +#endif + + /* free buffers */ + XFREE(edges); + XFREE(buf); + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/short_integer/der_decode_short_integer.c b/src/ltc/pk/asn1/der/short_integer/der_decode_short_integer.c new file mode 100644 index 0000000..a174740 --- /dev/null +++ b/src/ltc/pk/asn1/der/short_integer/der_decode_short_integer.c @@ -0,0 +1,68 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_short_integer.c + ASN.1 DER, decode an integer, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Read a short integer + @param in The DER encoded data + @param inlen Size of data + @param num [out] The integer to decode + @return CRYPT_OK if successful +*/ +int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsigned long *num) +{ + unsigned long len, x, y; + + LTC_ARGCHK(num != NULL); + LTC_ARGCHK(in != NULL); + + /* check length */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* check header */ + x = 0; + if ((in[x++] & 0x1F) != 0x02) { + return CRYPT_INVALID_PACKET; + } + + /* get the packet len */ + len = in[x++]; + + if (x + len > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* read number */ + y = 0; + while (len--) { + y = (y<<8) | (unsigned long)in[x++]; + } + *num = y; + + return CRYPT_OK; + +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/short_integer/der_encode_short_integer.c b/src/ltc/pk/asn1/der/short_integer/der_encode_short_integer.c new file mode 100644 index 0000000..7b4f527 --- /dev/null +++ b/src/ltc/pk/asn1/der/short_integer/der_encode_short_integer.c @@ -0,0 +1,97 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_short_integer.c + ASN.1 DER, encode an integer, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a short integer in the range (0,2^32-1) + @param num The integer to encode + @param out [out] The destination for the DER encoded integers + @param outlen [in/out] The max size and resulting size of the DER encoded integers + @return CRYPT_OK if successful +*/ +int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned long *outlen) +{ + unsigned long len, x, y, z; + int err; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* force to 32 bits */ + num &= 0xFFFFFFFFUL; + + /* find out how big this will be */ + if ((err = der_length_short_integer(num, &len)) != CRYPT_OK) { + return err; + } + + if (*outlen < len) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + /* get len of output */ + z = 0; + y = num; + while (y) { + ++z; + y >>= 8; + } + + /* handle zero */ + if (z == 0) { + z = 1; + } + + /* see if msb is set */ + z += (num&(1UL<<((z<<3) - 1))) ? 1 : 0; + + /* adjust the number so the msB is non-zero */ + for (x = 0; (z <= 4) && (x < (4 - z)); x++) { + num <<= 8; + } + + /* store header */ + x = 0; + out[x++] = 0x02; + out[x++] = (unsigned char)z; + + /* if 31st bit is set output a leading zero and decrement count */ + if (z == 5) { + out[x++] = 0; + --z; + } + + /* store values */ + for (y = 0; y < z; y++) { + out[x++] = (unsigned char)((num >> 24) & 0xFF); + num <<= 8; + } + + /* we good */ + *outlen = x; + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/short_integer/der_length_short_integer.c b/src/ltc/pk/asn1/der/short_integer/der_length_short_integer.c new file mode 100644 index 0000000..f248e64 --- /dev/null +++ b/src/ltc/pk/asn1/der/short_integer/der_length_short_integer.c @@ -0,0 +1,70 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_length_short_integer.c + ASN.1 DER, get length of encoding, Tom St Denis +*/ + + +#ifdef LTC_DER +/** + Gets length of DER encoding of num + @param num The integer to get the size of + @param outlen [out] The length of the DER encoding for the given integer + @return CRYPT_OK if successful +*/ +int der_length_short_integer(unsigned long num, unsigned long *outlen) +{ + unsigned long z, y, len; + + LTC_ARGCHK(outlen != NULL); + + /* force to 32 bits */ + num &= 0xFFFFFFFFUL; + + /* get the number of bytes */ + z = 0; + y = num; + while (y) { + ++z; + y >>= 8; + } + + /* handle zero */ + if (z == 0) { + z = 1; + } + + /* we need a 0x02 to indicate it's INTEGER */ + len = 1; + + /* length byte */ + ++len; + + /* bytes in value */ + len += z; + + /* see if msb is set */ + len += (num&(1UL<<((z<<3) - 1))) ? 1 : 0; + + /* return length */ + *outlen = len; + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/teletex_string/der_decode_teletex_string.c b/src/ltc/pk/asn1/der/teletex_string/der_decode_teletex_string.c new file mode 100644 index 0000000..b935745 --- /dev/null +++ b/src/ltc/pk/asn1/der/teletex_string/der_decode_teletex_string.c @@ -0,0 +1,95 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_teletex_string.c + ASN.1 DER, encode a teletex STRING +*/ + +#ifdef LTC_DER + +/** + Store a teletex STRING + @param in The DER encoded teletex STRING + @param inlen The size of the DER teletex STRING + @param out [out] The array of octets stored (one per char) + @param outlen [in/out] The number of octets stored + @return CRYPT_OK if successful +*/ +int der_decode_teletex_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + int t; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* must have header at least */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* check for 0x14 */ + if ((in[0] & 0x1F) != 0x14) { + return CRYPT_INVALID_PACKET; + } + x = 1; + + /* decode the length */ + if (in[x] & 0x80) { + /* valid # of bytes in length are 1,2,3 */ + y = in[x] & 0x7F; + if ((y == 0) || (y > 3) || ((x + y) > inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* read the length in */ + len = 0; + ++x; + while (y--) { + len = (len << 8) | in[x++]; + } + } else { + len = in[x++] & 0x7F; + } + + /* is it too long? */ + if (len > *outlen) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + if (len + x > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* read the data */ + for (y = 0; y < len; y++) { + t = der_teletex_value_decode(in[x++]); + if (t == -1) { + return CRYPT_INVALID_ARG; + } + out[y] = t; + } + + *outlen = y; + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/teletex_string/der_length_teletex_string.c b/src/ltc/pk/asn1/der/teletex_string/der_length_teletex_string.c new file mode 100644 index 0000000..b5ae8b4 --- /dev/null +++ b/src/ltc/pk/asn1/der/teletex_string/der_length_teletex_string.c @@ -0,0 +1,210 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_length_teletex_string.c + ASN.1 DER, get length of teletex STRING +*/ + +#ifdef LTC_DER + +static const struct { + int code, value; +} teletex_table[] = { +{ '\0', 0 }, +{ '\a', 7 }, +{ '\b', 8 }, +{ '\t', 9 }, +{ '\n', 10 }, +{ '\v', 11 }, +{ '\f', 12 }, +{ '\r', 13 }, +{ ' ', 32 }, +{ '!', 33 }, +{ '"', 34 }, +{ '%', 37 }, +{ '&', 38 }, +{ '\'', 39 }, +{ '(', 40 }, +{ ')', 41 }, +{ '+', 43 }, +{ ',', 44 }, +{ '-', 45 }, +{ '.', 46 }, +{ '/', 47 }, +{ '0', 48 }, +{ '1', 49 }, +{ '2', 50 }, +{ '3', 51 }, +{ '4', 52 }, +{ '5', 53 }, +{ '6', 54 }, +{ '7', 55 }, +{ '8', 56 }, +{ '9', 57 }, +{ ':', 58 }, +{ ';', 59 }, +{ '<', 60 }, +{ '=', 61 }, +{ '>', 62 }, +{ '?', 63 }, +{ '@', 64 }, +{ 'A', 65 }, +{ 'B', 66 }, +{ 'C', 67 }, +{ 'D', 68 }, +{ 'E', 69 }, +{ 'F', 70 }, +{ 'G', 71 }, +{ 'H', 72 }, +{ 'I', 73 }, +{ 'J', 74 }, +{ 'K', 75 }, +{ 'L', 76 }, +{ 'M', 77 }, +{ 'N', 78 }, +{ 'O', 79 }, +{ 'P', 80 }, +{ 'Q', 81 }, +{ 'R', 82 }, +{ 'S', 83 }, +{ 'T', 84 }, +{ 'U', 85 }, +{ 'V', 86 }, +{ 'W', 87 }, +{ 'X', 88 }, +{ 'Y', 89 }, +{ 'Z', 90 }, +{ '[', 91 }, +{ ']', 93 }, +{ '_', 95 }, +{ 'a', 97 }, +{ 'b', 98 }, +{ 'c', 99 }, +{ 'd', 100 }, +{ 'e', 101 }, +{ 'f', 102 }, +{ 'g', 103 }, +{ 'h', 104 }, +{ 'i', 105 }, +{ 'j', 106 }, +{ 'k', 107 }, +{ 'l', 108 }, +{ 'm', 109 }, +{ 'n', 110 }, +{ 'o', 111 }, +{ 'p', 112 }, +{ 'q', 113 }, +{ 'r', 114 }, +{ 's', 115 }, +{ 't', 116 }, +{ 'u', 117 }, +{ 'v', 118 }, +{ 'w', 119 }, +{ 'x', 120 }, +{ 'y', 121 }, +{ 'z', 122 }, +{ '|', 124 }, +{ ' ', 160 }, +{ 0xa1, 161 }, +{ 0xa2, 162 }, +{ 0xa3, 163 }, +{ '$', 164 }, +{ 0xa5, 165 }, +{ '#', 166 }, +{ 0xa7, 167 }, +{ 0xa4, 168 }, +{ 0xab, 171 }, +{ 0xb0, 176 }, +{ 0xb1, 177 }, +{ 0xb2, 178 }, +{ 0xb3, 179 }, +{ 0xd7, 180 }, +{ 0xb5, 181 }, +{ 0xb6, 182 }, +{ 0xb7, 183 }, +{ 0xf7, 184 }, +{ 0xbb, 187 }, +{ 0xbc, 188 }, +{ 0xbd, 189 }, +{ 0xbe, 190 }, +{ 0xbf, 191 }, +}; + +int der_teletex_char_encode(int c) +{ + int x; + for (x = 0; x < (int)(sizeof(teletex_table)/sizeof(teletex_table[0])); x++) { + if (teletex_table[x].code == c) { + return teletex_table[x].value; + } + } + return -1; +} + +int der_teletex_value_decode(int v) +{ + int x; + for (x = 0; x < (int)(sizeof(teletex_table)/sizeof(teletex_table[0])); x++) { + if (teletex_table[x].value == v) { + return teletex_table[x].code; + } + } + return -1; +} + +/** + Gets length of DER encoding of teletex STRING + @param octets The values you want to encode + @param noctets The number of octets in the string to encode + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_teletex_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen) +{ + unsigned long x; + + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(octets != NULL); + + /* scan string for validity */ + for (x = 0; x < noctets; x++) { + if (der_teletex_char_encode(octets[x]) == -1) { + return CRYPT_INVALID_ARG; + } + } + + if (noctets < 128) { + /* 16 LL DD DD DD ... */ + *outlen = 2 + noctets; + } else if (noctets < 256) { + /* 16 81 LL DD DD DD ... */ + *outlen = 3 + noctets; + } else if (noctets < 65536UL) { + /* 16 82 LL LL DD DD DD ... */ + *outlen = 4 + noctets; + } else if (noctets < 16777216UL) { + /* 16 83 LL LL LL DD DD DD ... */ + *outlen = 5 + noctets; + } else { + return CRYPT_INVALID_ARG; + } + + return CRYPT_OK; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/utctime/der_decode_utctime.c b/src/ltc/pk/asn1/der/utctime/der_decode_utctime.c new file mode 100644 index 0000000..ca12799 --- /dev/null +++ b/src/ltc/pk/asn1/der/utctime/der_decode_utctime.c @@ -0,0 +1,127 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_utctime.c + ASN.1 DER, decode a UTCTIME, Tom St Denis +*/ + +#ifdef LTC_DER + +static int char_to_int(unsigned char x) +{ + switch (x) { + case '0': return 0; + case '1': return 1; + case '2': return 2; + case '3': return 3; + case '4': return 4; + case '5': return 5; + case '6': return 6; + case '7': return 7; + case '8': return 8; + case '9': return 9; + } + return 100; +} + +#define DECODE_V(y, max) \ + y = char_to_int(buf[x])*10 + char_to_int(buf[x+1]); \ + if (y >= max) return CRYPT_INVALID_PACKET; \ + x += 2; + +/** + Decodes a UTC time structure in DER format (reads all 6 valid encoding formats) + @param in Input buffer + @param inlen Length of input buffer in octets + @param out [out] Destination of UTC time structure + @return CRYPT_OK if successful +*/ +int der_decode_utctime(const unsigned char *in, unsigned long *inlen, + ltc_utctime *out) +{ + unsigned char buf[32]; + unsigned long x; + int y; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen != NULL); + LTC_ARGCHK(out != NULL); + + /* check header */ + if (*inlen < 2UL || (in[1] >= sizeof(buf)) || ((in[1] + 2UL) > *inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* decode the string */ + for (x = 0; x < in[1]; x++) { + y = der_ia5_value_decode(in[x+2]); + if (y == -1) { + return CRYPT_INVALID_PACKET; + } + buf[x] = y; + } + *inlen = 2 + x; + + + /* possible encodings are +YYMMDDhhmmZ +YYMMDDhhmm+hh'mm' +YYMMDDhhmm-hh'mm' +YYMMDDhhmmssZ +YYMMDDhhmmss+hh'mm' +YYMMDDhhmmss-hh'mm' + + So let's do a trivial decode upto [including] mm + */ + + x = 0; + DECODE_V(out->YY, 100); + DECODE_V(out->MM, 13); + DECODE_V(out->DD, 32); + DECODE_V(out->hh, 24); + DECODE_V(out->mm, 60); + + /* clear timezone and seconds info */ + out->off_dir = out->off_hh = out->off_mm = out->ss = 0; + + /* now is it Z, +, - or 0-9 */ + if (buf[x] == 'Z') { + return CRYPT_OK; + } else if (buf[x] == '+' || buf[x] == '-') { + out->off_dir = (buf[x++] == '+') ? 0 : 1; + DECODE_V(out->off_hh, 24); + DECODE_V(out->off_mm, 60); + return CRYPT_OK; + } + + /* decode seconds */ + DECODE_V(out->ss, 60); + + /* now is it Z, +, - */ + if (buf[x] == 'Z') { + return CRYPT_OK; + } else if (buf[x] == '+' || buf[x] == '-') { + out->off_dir = (buf[x++] == '+') ? 0 : 1; + DECODE_V(out->off_hh, 24); + DECODE_V(out->off_mm, 60); + return CRYPT_OK; + } else { + return CRYPT_INVALID_PACKET; + } +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/utctime/der_encode_utctime.c b/src/ltc/pk/asn1/der/utctime/der_encode_utctime.c new file mode 100644 index 0000000..92fffe5 --- /dev/null +++ b/src/ltc/pk/asn1/der/utctime/der_encode_utctime.c @@ -0,0 +1,83 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_utctime.c + ASN.1 DER, encode a UTCTIME, Tom St Denis +*/ + +#ifdef LTC_DER + +static const char * const baseten = "0123456789"; + +#define STORE_V(y) \ + out[x++] = der_ia5_char_encode(baseten[(y/10) % 10]); \ + out[x++] = der_ia5_char_encode(baseten[y % 10]); + +/** + Encodes a UTC time structure in DER format + @param utctime The UTC time structure to encode + @param out The destination of the DER encoding of the UTC time structure + @param outlen [in/out] The length of the DER encoding + @return CRYPT_OK if successful +*/ +int der_encode_utctime(ltc_utctime *utctime, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, tmplen; + int err; + + LTC_ARGCHK(utctime != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + if ((err = der_length_utctime(utctime, &tmplen)) != CRYPT_OK) { + return err; + } + if (tmplen > *outlen) { + *outlen = tmplen; + return CRYPT_BUFFER_OVERFLOW; + } + + /* store header */ + out[0] = 0x17; + + /* store values */ + x = 2; + STORE_V(utctime->YY); + STORE_V(utctime->MM); + STORE_V(utctime->DD); + STORE_V(utctime->hh); + STORE_V(utctime->mm); + STORE_V(utctime->ss); + + if (utctime->off_mm || utctime->off_hh) { + out[x++] = der_ia5_char_encode(utctime->off_dir ? '-' : '+'); + STORE_V(utctime->off_hh); + STORE_V(utctime->off_mm); + } else { + out[x++] = der_ia5_char_encode('Z'); + } + + /* store length */ + out[1] = (unsigned char)(x - 2); + + /* all good let's return */ + *outlen = x; + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/utctime/der_length_utctime.c b/src/ltc/pk/asn1/der/utctime/der_length_utctime.c new file mode 100644 index 0000000..e33c4f3 --- /dev/null +++ b/src/ltc/pk/asn1/der/utctime/der_length_utctime.c @@ -0,0 +1,46 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_length_utctime.c + ASN.1 DER, get length of UTCTIME, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Gets length of DER encoding of UTCTIME + @param utctime The UTC time structure to get the size of + @param outlen [out] The length of the DER encoding + @return CRYPT_OK if successful +*/ +int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen) +{ + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(utctime != NULL); + + if (utctime->off_hh == 0 && utctime->off_mm == 0) { + /* we encode as YYMMDDhhmmssZ */ + *outlen = 2 + 13; + } else { + /* we encode as YYMMDDhhmmss{+|-}hh'mm' */ + *outlen = 2 + 17; + } + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/utf8/der_decode_utf8_string.c b/src/ltc/pk/asn1/der/utf8/der_decode_utf8_string.c new file mode 100644 index 0000000..d67362a --- /dev/null +++ b/src/ltc/pk/asn1/der/utf8/der_decode_utf8_string.c @@ -0,0 +1,111 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_utf8_string.c + ASN.1 DER, encode a UTF8 STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a UTF8 STRING + @param in The DER encoded UTF8 STRING + @param inlen The size of the DER UTF8 STRING + @param out [out] The array of utf8s stored (one per char) + @param outlen [in/out] The number of utf8s stored + @return CRYPT_OK if successful +*/ +int der_decode_utf8_string(const unsigned char *in, unsigned long inlen, + wchar_t *out, unsigned long *outlen) +{ + wchar_t tmp; + unsigned long x, y, z, len; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* must have header at least */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* check for 0x0C */ + if ((in[0] & 0x1F) != 0x0C) { + return CRYPT_INVALID_PACKET; + } + x = 1; + + /* decode the length */ + if (in[x] & 0x80) { + /* valid # of bytes in length are 1,2,3 */ + y = in[x] & 0x7F; + if ((y == 0) || (y > 3) || ((x + y) > inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* read the length in */ + len = 0; + ++x; + while (y--) { + len = (len << 8) | in[x++]; + } + } else { + len = in[x++] & 0x7F; + } + + if (len + x > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* proceed to decode */ + for (y = 0; x < inlen; ) { + /* get first byte */ + tmp = in[x++]; + + /* count number of bytes */ + for (z = 0; (tmp & 0x80) && (z <= 4); z++, tmp = (tmp << 1) & 0xFF); + + if (z > 4 || (x + (z - 1) > inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* decode, grab upper bits */ + tmp >>= z; + + /* grab remaining bytes */ + if (z > 1) { --z; } + while (z-- != 0) { + if ((in[x] & 0xC0) != 0x80) { + return CRYPT_INVALID_PACKET; + } + tmp = (tmp << 6) | ((wchar_t)in[x++] & 0x3F); + } + + if (y > *outlen) { + *outlen = y; + return CRYPT_BUFFER_OVERFLOW; + } + out[y++] = tmp; + } + *outlen = y; + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/utf8/der_encode_utf8_string.c b/src/ltc/pk/asn1/der/utf8/der_encode_utf8_string.c new file mode 100644 index 0000000..ef0e6eb --- /dev/null +++ b/src/ltc/pk/asn1/der/utf8/der_encode_utf8_string.c @@ -0,0 +1,106 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_utf8_string.c + ASN.1 DER, encode a UTF8 STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store an UTF8 STRING + @param in The array of UTF8 to store (one per wchar_t) + @param inlen The number of UTF8 to store + @param out [out] The destination for the DER encoded UTF8 STRING + @param outlen [in/out] The max size and resulting size of the DER UTF8 STRING + @return CRYPT_OK if successful +*/ +int der_encode_utf8_string(const wchar_t *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get the size */ + for (x = len = 0; x < inlen; x++) { + if (!der_utf8_valid_char(in[x])) return CRYPT_INVALID_ARG; + len += der_utf8_charsize(in[x]); + } + + if (len < 128) { + y = 2 + len; + } else if (len < 256) { + y = 3 + len; + } else if (len < 65536UL) { + y = 4 + len; + } else if (len < 16777216UL) { + y = 5 + len; + } else { + return CRYPT_INVALID_ARG; + } + + /* too big? */ + if (y > *outlen) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + /* encode the header+len */ + x = 0; + out[x++] = 0x0C; + if (len < 128) { + out[x++] = (unsigned char)len; + } else if (len < 256) { + out[x++] = 0x81; + out[x++] = (unsigned char)len; + } else if (len < 65536UL) { + out[x++] = 0x82; + out[x++] = (unsigned char)((len>>8)&255); + out[x++] = (unsigned char)(len&255); + } else if (len < 16777216UL) { + out[x++] = 0x83; + out[x++] = (unsigned char)((len>>16)&255); + out[x++] = (unsigned char)((len>>8)&255); + out[x++] = (unsigned char)(len&255); + } else { + /* coverity[dead_error_line] */ + return CRYPT_INVALID_ARG; + } + + /* store UTF8 */ + for (y = 0; y < inlen; y++) { + switch (der_utf8_charsize(in[y])) { + case 1: out[x++] = (unsigned char)in[y]; break; + case 2: out[x++] = 0xC0 | ((in[y] >> 6) & 0x1F); out[x++] = 0x80 | (in[y] & 0x3F); break; + case 3: out[x++] = 0xE0 | ((in[y] >> 12) & 0x0F); out[x++] = 0x80 | ((in[y] >> 6) & 0x3F); out[x++] = 0x80 | (in[y] & 0x3F); break; +#if !defined(LTC_WCHAR_MAX) || LTC_WCHAR_MAX > 0xFFFF + case 4: out[x++] = 0xF0 | ((in[y] >> 18) & 0x07); out[x++] = 0x80 | ((in[y] >> 12) & 0x3F); out[x++] = 0x80 | ((in[y] >> 6) & 0x3F); out[x++] = 0x80 | (in[y] & 0x3F); break; +#endif + } + } + + /* retun length */ + *outlen = x; + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/asn1/der/utf8/der_length_utf8_string.c b/src/ltc/pk/asn1/der/utf8/der_length_utf8_string.c new file mode 100644 index 0000000..2bab445 --- /dev/null +++ b/src/ltc/pk/asn1/der/utf8/der_length_utf8_string.c @@ -0,0 +1,104 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file der_length_utf8_string.c + ASN.1 DER, get length of UTF8 STRING, Tom St Denis +*/ + +#ifdef LTC_DER + +/** Return the size in bytes of a UTF-8 character + @param c The UTF-8 character to measure + @return The size in bytes +*/ +unsigned long der_utf8_charsize(const wchar_t c) +{ + if (c <= 0x7F) { + return 1; + } else if (c <= 0x7FF) { + return 2; +#if LTC_WCHAR_MAX == 0xFFFF + } else { + return 3; + } +#else + } else if (c <= 0xFFFF) { + return 3; + } else { + return 4; + } +#endif +} + +/** + Test whether the given code point is valid character + @param c The UTF-8 character to test + @return 1 - valid, 0 - invalid +*/ +int der_utf8_valid_char(const wchar_t c) +{ + LTC_UNUSED_PARAM(c); +#if !defined(LTC_WCHAR_MAX) || LTC_WCHAR_MAX > 0xFFFF + if (c > 0x10FFFF) return 0; +#endif +#if LTC_WCHAR_MAX != 0xFFFF && LTC_WCHAR_MAX != 0xFFFFFFFF + if (c < 0) return 0; +#endif + return 1; +} + +/** + Gets length of DER encoding of UTF8 STRING + @param in The characters to measure the length of + @param noctets The number of octets in the string to encode + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned long *outlen) +{ + unsigned long x, len; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(outlen != NULL); + + len = 0; + for (x = 0; x < noctets; x++) { + if (!der_utf8_valid_char(in[x])) return CRYPT_INVALID_ARG; + len += der_utf8_charsize(in[x]); + } + + if (len < 128) { + /* 0C LL DD DD DD ... */ + *outlen = 2 + len; + } else if (len < 256) { + /* 0C 81 LL DD DD DD ... */ + *outlen = 3 + len; + } else if (len < 65536UL) { + /* 0C 82 LL LL DD DD DD ... */ + *outlen = 4 + len; + } else if (len < 16777216UL) { + /* 0C 83 LL LL LL DD DD DD ... */ + *outlen = 5 + len; + } else { + return CRYPT_INVALID_ARG; + } + + return CRYPT_OK; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/dh/dh.c b/src/ltc/pk/dh/dh.c new file mode 100644 index 0000000..693e5a4 --- /dev/null +++ b/src/ltc/pk/dh/dh.c @@ -0,0 +1,505 @@ +/* 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 dh.c + DH crypto, Tom St Denis +*/ + +#ifdef LTC_MDH + + +#include "dh_static.h" + +/** + Test the DH sub-system (can take a while) + @return CRYPT_OK if successful +*/ +int dh_compat_test(void) +{ + void *p, *g, *tmp; + int x, err, primality; + + if ((err = mp_init_multi(&p, &g, &tmp, NULL)) != CRYPT_OK) { goto error; } + + for (x = 0; sets[x].size != 0; x++) { +#if 0 + printf("dh_test():testing size %d-bits\n", sets[x].size * 8); +#endif + if ((err = mp_read_radix(g,(char *)sets[x].base, 64)) != CRYPT_OK) { goto error; } + if ((err = mp_read_radix(p,(char *)sets[x].prime, 64)) != CRYPT_OK) { goto error; } + + /* ensure p is prime */ + if ((err = mp_prime_is_prime(p, 8, &primality)) != CRYPT_OK) { goto done; } + if (primality != LTC_MP_YES ) { + err = CRYPT_FAIL_TESTVECTOR; + goto done; + } + + if ((err = mp_sub_d(p, 1, tmp)) != CRYPT_OK) { goto error; } + if ((err = mp_div_2(tmp, tmp)) != CRYPT_OK) { goto error; } + + /* ensure (p-1)/2 is prime */ + if ((err = mp_prime_is_prime(tmp, 8, &primality)) != CRYPT_OK) { goto done; } + if (primality == 0) { + err = CRYPT_FAIL_TESTVECTOR; + goto done; + } + + /* now see if g^((p-1)/2) mod p is in fact 1 */ + if ((err = mp_exptmod(g, tmp, p, tmp)) != CRYPT_OK) { goto error; } + if (mp_cmp_d(tmp, 1)) { + err = CRYPT_FAIL_TESTVECTOR; + goto done; + } + } + err = CRYPT_OK; +error: +done: + mp_clear_multi(tmp, g, p, NULL); + return err; +} + +/** + Get the min and max DH key sizes (octets) + @param low [out] The smallest key size supported + @param high [out] The largest key size supported +*/ +void dh_sizes(int *low, int *high) +{ + int x; + LTC_ARGCHKVD(low != NULL); + LTC_ARGCHKVD(high != NULL); + *low = INT_MAX; + *high = 0; + for (x = 0; sets[x].size != 0; x++) { + if (*low > sets[x].size) *low = sets[x].size; + if (*high < sets[x].size) *high = sets[x].size; + } +} + +/** + Returns the key size of a given DH key (octets) + @param key The DH key to get the size of + @return The size if valid or INT_MAX if not +*/ +int dh_get_size(dh_key *key) +{ + LTC_ARGCHK(key != NULL); + if (key->idx == SUPPLIED_PRIME) { + return mp_unsigned_bin_size(key->prime); + } + if (dh_is_valid_idx(key->idx) == 1) { + return sets[key->idx].size; + } else { + return INT_MAX; /* large value that would cause dh_make_key() to fail */ + } +} + +/** + Make a DH key [private key pair] + @param prng An active PRNG state + @param wprng The index for the PRNG you desire to use + @param keysize The key size (octets) desired + @param key [out] Where the newly created DH key will be stored + @return CRYPT_OK if successful, note: on error all allocated memory will be freed automatically. +*/ +int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key) +{ + unsigned long x; + int err; + + /* find key size */ + for (x = 0; (keysize > sets[x].size) && (sets[x].size != 0); x++); +#ifdef FAST_PK + keysize = MIN(sets[x].size, 32); +#else + keysize = sets[x].size; +#endif + if (sets[x].size == 0) { + return CRYPT_INVALID_KEYSIZE; + } + key->idx = x; + + if ((err = mp_init_multi(&key->base, &key->prime, NULL)) != CRYPT_OK) { + goto error; + } + if ((err = mp_read_radix(key->base, sets[key->idx].base, 64)) != CRYPT_OK) { goto error; } + if ((err = mp_read_radix(key->prime, sets[key->idx].prime, 64)) != CRYPT_OK) { goto error; } + return dh_make_key_internal(prng, wprng, key); +error: + mp_clear_multi(key->base, key->prime, NULL); + return err; +} + +/** + Make a DH key [private key pair] from provided base and prime + @param prng An active PRNG state + @param wprng The index for the PRNG you desire to use + @param keysize The key size (octets) desired + @param base The base (generator) to create the key from + @param prime The prime to create the key from + @param key [out] Where the newly created DH key will be stored + @return CRYPT_OK if successful, note: on error all allocated memory will be freed automatically. +*/ +int dh_make_key_ex(prng_state *prng, int wprng, const char *base_hex, const char *prime_hex, dh_key *key) +{ + int err; + + LTC_ARGCHK(base_hex != NULL); + LTC_ARGCHK(prime_hex != NULL); + LTC_ARGCHK(key != NULL); + + /* good prng? */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + if ((err = mp_init_multi(&key->base, &key->prime, NULL)) != CRYPT_OK) { + goto error; + } + if ((err = mp_read_radix(key->base, base_hex, 16)) != CRYPT_OK) { goto error; } + if ((err = mp_read_radix(key->prime, prime_hex, 16)) != CRYPT_OK) { goto error; } + key->idx = SUPPLIED_PRIME; + return dh_make_key_internal(prng, wprng, key); +error: + mp_clear_multi(key->base, key->prime, NULL); + return err; +} + + +int dh_make_key_internal(prng_state *prng, int wprng, dh_key *key) +{ + unsigned char *buf = NULL; + int err, keysize; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(key->prime != NULL); + LTC_ARGCHK(key->base != NULL); + + /* init parameters */ + if ((err = mp_init_multi(&key->x, &key->y, NULL)) != CRYPT_OK) { + goto error; + } + + keysize = dh_get_size(key); + if (keysize < 96) { + return CRYPT_INVALID_KEYSIZE; + } + + /* allocate buffer */ + buf = XMALLOC(keysize); + if (buf == NULL) { + return CRYPT_MEM; + } + + /* make up random string */ + if ( (err = rng_make_prng( keysize, wprng, prng, NULL)) != CRYPT_OK) { + /*err = CRYPT_ERROR_READPRNG;*/ + goto error2; + } + + if (prng_descriptor[wprng].read(buf, keysize, prng) != (unsigned long)keysize) { + err = CRYPT_ERROR_READPRNG; + goto error2; + } + + /* load the x value */ + if ((err = mp_read_unsigned_bin(key->x, buf, keysize)) != CRYPT_OK) { goto error; } + if ((err = mp_exptmod(key->base, key->x, key->prime, key->y)) != CRYPT_OK) { goto error; } + key->type = PK_PRIVATE; + + /* free up ram */ + err = CRYPT_OK; + goto done; +error: + mp_clear_multi(key->base, key->prime, key->x, key->y, NULL); +done: +error2: +#ifdef LTC_CLEAN_STACK + zeromem(buf, keysize); +#endif + XFREE(buf); + return err; +} + +/** + Free the allocated ram for a DH key + @param key The key which you wish to free +*/ +void dh_free(dh_key *key) +{ + LTC_ARGCHKVD(key != NULL); + if ( key->base ) { + mp_clear( key->base ); + key->base = NULL; + } + if ( key->prime ) { + mp_clear( key->prime ); + key->prime = NULL; + } + if ( key->x ) { + mp_clear( key->x ); + key->x = NULL; + } + if ( key->y ) { + mp_clear( key->y ); + key->y = NULL; + } +} + +/** + Export a DH key to a binary packet + @param out [out] The destination for the key + @param outlen [in/out] The max size and resulting size of the DH key + @param type Which type of key (PK_PRIVATE or PK_PUBLIC) + @param key The key you wish to export + @return CRYPT_OK if successful +*/ +int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_key *key) +{ + unsigned long y, z; + int err; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* can we store the static header? */ + if (*outlen < (PACKET_SIZE + 2)) { + return CRYPT_BUFFER_OVERFLOW; + } + + if (type == PK_PRIVATE && key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* header */ + y = PACKET_SIZE; + + /* header */ + out[y++] = type; + out[y++] = key->idx == SUPPLIED_PRIME ? + SUPPLIED_PRIME : + (unsigned char)(sets[key->idx].size / 8); + + /* export y */ + OUTPUT_BIGNUM(key->y, out, y, z); + + if (type == PK_PRIVATE) { + /* export x */ + OUTPUT_BIGNUM(key->x, out, y, z); + } + /* export g and p */ + if (key->idx == SUPPLIED_PRIME) { + OUTPUT_BIGNUM(key->base, out, y, z); + OUTPUT_BIGNUM(key->prime, out, y, z); + } + + /* store header */ + packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_KEY); + + /* store len */ + *outlen = y; + return CRYPT_OK; +} + +/** + Import a DH key from a binary string + @param in The string to read + @param inlen The length of the input packet + @param type The type of key. PK_PRIVATE or PK_PUBLIC + @param base The base (generator) in hex string + @param prime The prime in hex string + @param key [out] Where to import the key to + @return CRYPT_OK if successful, on error all allocated memory is freed automatically +*/ +int dh_import_raw(unsigned char *in, unsigned long inlen, int type, + const char *base_hex, const char *prime_hex, dh_key *key) +{ + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(base_hex != NULL); + LTC_ARGCHK(prime_hex != NULL); + LTC_ARGCHK(key != NULL); + + if ((err = mp_init_multi(&key->x, &key->y, &key->base, &key->prime, NULL)) != CRYPT_OK) { + goto error; + } + if ((err = mp_read_radix(key->base, base_hex, 16)) != CRYPT_OK) { goto error; } + if ((err = mp_read_radix(key->prime, prime_hex, 16)) != CRYPT_OK) { goto error; } + key->idx = SUPPLIED_PRIME; + + if (type == PK_PRIVATE) { + /* load the x value */ + if ((err = mp_read_unsigned_bin(key->x, in, inlen)) != CRYPT_OK) { goto error; } + if ((err = mp_exptmod(key->base, key->x, key->prime, key->y)) != CRYPT_OK) { goto error; } + key->type = PK_PRIVATE; + } else { + /* load the y value */ + if ((err = mp_read_unsigned_bin(key->y, in, inlen)) != CRYPT_OK) { goto error; } + key->type = PK_PUBLIC; + mp_clear(key->x); + key->x = NULL; + } + key->idx = SUPPLIED_PRIME; + return CRYPT_OK; +error: + mp_clear_multi(key->y, key->x, key->base, key->prime, NULL); + return err; +} + +/** + Import a DH key from a binary packet + @param in The packet to read + @param inlen The length of the input packet + @param key [out] Where to import the key to + @return CRYPT_OK if successful, on error all allocated memory is freed automatically +*/ +int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key) +{ + unsigned long x, y; + int s, err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(key != NULL); + + /* make sure valid length */ + if ((2+PACKET_SIZE) > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* check type byte */ + if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_DH, PACKET_SUB_KEY)) != CRYPT_OK) { + return err; + } + + /* init */ + if ((err = mp_init_multi(&key->x, &key->y, &key->base, &key->prime, NULL)) != CRYPT_OK) { + return err; + } + + /* advance past packet header */ + y = PACKET_SIZE; + + /* key type, e.g. private, public */ + key->type = (int)in[y++]; + + /* key size in bytes */ + s = (int)in[y++]; + + if (s == SUPPLIED_PRIME) { + /* key from provided p,g values */ + key->idx = SUPPLIED_PRIME; + } else { + s *= 8; + for (x = 0; (s > sets[x].size) && (sets[x].size != 0); x++); + if (sets[x].size == 0) { + err = CRYPT_INVALID_KEYSIZE; + goto error; + } + key->idx = (int)x; + if ((err = mp_read_radix(key->base, (char *)sets[x].base, 64)) != CRYPT_OK) { goto error; } + if ((err = mp_read_radix(key->prime, (char *)sets[x].prime, 64)) != CRYPT_OK) { goto error; } + } + + /* type check both values */ + if ((key->type != PK_PUBLIC) && (key->type != PK_PRIVATE)) { + err = CRYPT_PK_TYPE_MISMATCH; + goto error; + } + + /* is the key idx valid? */ + if (dh_is_valid_idx(key->idx) != 1) { + err = CRYPT_PK_TYPE_MISMATCH; + goto error; + } + + /* load public value g^x mod p*/ + INPUT_BIGNUM(key->y, in, x, y, inlen); + + if (key->type == PK_PRIVATE) { + INPUT_BIGNUM(key->x, in, x, y, inlen); + /* if idx = SUPPLIED_PRIME then prime is not from static table */ + } + if (key->idx == SUPPLIED_PRIME) { + INPUT_BIGNUM(key->base, in, x, y, inlen); + INPUT_BIGNUM(key->prime, in, x, y, inlen); + } + + /* eliminate private key if public */ + if (key->type == PK_PUBLIC) { + mp_clear(key->x); + key->x = NULL; + } + + return CRYPT_OK; +error: + mp_clear_multi(key->y, key->x, key->base, key->prime, NULL); + return err; +} + +/** + Create a DH shared secret. + @param private_key The private DH key in the pair + @param public_key The public DH key in the pair + @param out [out] The destination of the shared data + @param outlen [in/out] The max size and resulting size of the shared data. + @return CRYPT_OK if successful +*/ +int dh_shared_secret(dh_key *private_key, dh_key *public_key, + unsigned char *out, unsigned long *outlen) +{ + void *tmp; + unsigned long x; + int err; + + LTC_ARGCHK(private_key != NULL); + LTC_ARGCHK(public_key != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* types valid? */ + if (private_key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* same idx? */ + if (private_key->idx != public_key->idx) { + return CRYPT_PK_TYPE_MISMATCH; + } + + /* compute y^x mod p */ + if ((err = mp_init(&tmp)) != CRYPT_OK) { + return err; + } + + if ((err = mp_exptmod(public_key->y, private_key->x, private_key->prime, tmp)) != CRYPT_OK) { goto error; } + + /* enough space for output? */ + x = (unsigned long)mp_unsigned_bin_size(tmp); + if (*outlen < x) { + err = CRYPT_BUFFER_OVERFLOW; + goto done; + } + if ((err = mp_to_unsigned_bin(tmp, out)) != CRYPT_OK) { goto error; } + *outlen = x; + err = CRYPT_OK; + goto done; +error: +done: + mp_clear(tmp); + return err; +} + +#endif /* LTC_MDH */ diff --git a/src/ltc/pk/dh/dh_static.c b/src/ltc/pk/dh/dh_static.c new file mode 100644 index 0000000..117835f --- /dev/null +++ b/src/ltc/pk/dh/dh_static.c @@ -0,0 +1,165 @@ +/* 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 dh_static.c + DH crypto, Tom St Denis +*/ + +#ifdef LTC_MDH + +#define __DECL_DH_STATIC_H__ +#include "dh_static.h" + +/* This holds the key settings. ***MUST*** be organized by size from smallest to largest. */ +const dh_set sets[] = { +#ifdef LTC_DH768 +{ + 96, + "DH-768", + "4", + "F///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "//////m3wvV" +}, +#endif +#ifdef LTC_DH1024 +{ + 128, + "DH-1024", + "4", + "F///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////m3C47" +}, +#endif +#ifdef LTC_DH1280 +{ + 160, + "DH-1280", + "4", + "F///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "//////////////////////////////m4kSN" +}, +#endif +#ifdef LTC_DH1536 +{ + 192, + "DH-1536", + "4", + "F///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////m5uqd" +}, +#endif +#ifdef LTC_DH1792 +{ + 224, + "DH-1792", + "4", + "F///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////mT/sd" +}, +#endif +#ifdef LTC_DH2048 +{ + 256, + "DH-2048", + "4", + "3///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "/////////////////////////////////////////m8MPh" +}, +#endif +#ifdef LTC_DH2560 +{ + 320, + "DH-2560", + "4", + "3///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "/////mKFpF" +}, +#endif +#ifdef LTC_DH3072 +{ + 384, + "DH-3072", + "4", + "3///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "/////////////////////////////m32nN" +}, +#endif +#ifdef LTC_DH4096 +{ + 512, + "DH-4096", + "4", + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "/////////////////////m8pOF" +}, +#endif +{ + 0, + NULL, + NULL, + NULL +} +}; + +int dh_is_valid_idx(int n) +{ + int x; + + if (n == SUPPLIED_PRIME) + return 1; + for (x = 0; sets[x].size; x++); + if ((n < 0) || (n >= x)) { + return 0; + } + return 1; +} + + +#endif /* LTC_MDH */ diff --git a/src/ltc/pk/dh/dh_static.h b/src/ltc/pk/dh/dh_static.h new file mode 100644 index 0000000..42db578 --- /dev/null +++ b/src/ltc/pk/dh/dh_static.h @@ -0,0 +1,129 @@ +#ifndef __DH_STATIC_H__ +#define __DH_STATIC_H__ +#ifndef __DECL_DH_STATIC_H__ +#define __DECL_DH_STATIC_H__ extern +#endif + +/* 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 dh_static.h + DH crypto, Tom St Denis +*/ + +#ifdef LTC_MDH + +/* size of a packet header in bytes */ +#define PACKET_SIZE 4 + +/* Section tags */ +#define PACKET_SECT_DH 1 + +/* Subsection Tags for the first three sections */ +#define PACKET_SUB_KEY 0 +#define PACKET_SUB_ENCRYPTED 1 +#define PACKET_SUB_SIGNED 2 +#define PACKET_SUB_ENC_KEY 3 + +#define OUTPUT_BIGNUM(num, out, y, z) \ +{ \ + if ((y + 4) > *outlen) { return CRYPT_BUFFER_OVERFLOW; } \ + z = (unsigned long)mp_unsigned_bin_size(num); \ + STORE32L(z, out+y); \ + y += 4; \ + if ((y + z) > *outlen) { return CRYPT_BUFFER_OVERFLOW; } \ + if ((err = mp_to_unsigned_bin(num, out+y)) != CRYPT_OK) { return err; } \ + y += z; \ +} + +#define INPUT_BIGNUM(num, in, x, y, inlen) \ +{ \ + /* load value */ \ + if ((y + 4) > inlen) { \ + err = CRYPT_INVALID_PACKET; \ + goto error; \ + } \ + LOAD32L(x, in+y); \ + y += 4; \ + \ + /* sanity check... */ \ + if ((x+y) > inlen) { \ + err = CRYPT_INVALID_PACKET; \ + goto error; \ + } \ + \ + /* load it */ \ + if ((err = mp_read_unsigned_bin(num, (unsigned char *)in+y, (int)x)) != CRYPT_OK) {\ + goto error; \ + } \ + y += x; \ +} + +#define SUPPLIED_PRIME 255 + +/* XXX: HP C compiler + IBM C compiler do not like "static inline" */ +static void packet_store_header (unsigned char *dst, int section, int subsection) +{ + LTC_ARGCHKVD(dst != NULL); + + /* store version number */ + dst[0] = (unsigned char)(CRYPT&255); + dst[1] = (unsigned char)((CRYPT>>8)&255); + + /* store section and subsection */ + dst[2] = (unsigned char)(section & 255); + dst[3] = (unsigned char)(subsection & 255); + +} + +/* XXX: HP C compiler + IBM C compiler do not like "static inline" */ +static int packet_valid_header (unsigned char *src, int section, int subsection) +{ + unsigned long ver; + + LTC_ARGCHK(src != NULL); + + /* check version */ + ver = ((unsigned long)src[0]) | ((unsigned long)src[1] << 8U); + if (CRYPT < ver) { + return CRYPT_INVALID_PACKET; + } + + /* check section and subsection */ + if (section != (int)src[2] || subsection != (int)src[3]) { + return CRYPT_INVALID_PACKET; + } + + return CRYPT_OK; +} + +#ifndef DH_BUF_SIZE +/* max export size we'll encounter (smaller than this but lets round up a bit) */ +#define DH_BUF_SIZE 1200 +#endif /* DH_BUF_SIZE */ + +typedef struct { + int size; + char *name, *base, *prime; +} dh_set; + +/* This holds the key settings. ***MUST*** be organized by size from smallest to largest. */ +__DECL_DH_STATIC_H__ const dh_set sets[]; + + +int dh_is_valid_idx(int n); + + +#endif /* __DH_STATIC_H__ */ + +#endif /* LTC_MDH */ diff --git a/src/ltc/pk/dh/dh_sys.c b/src/ltc/pk/dh/dh_sys.c new file mode 100644 index 0000000..67af043 --- /dev/null +++ b/src/ltc/pk/dh/dh_sys.c @@ -0,0 +1,487 @@ +/* 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" + +#ifdef LTC_MDH +/** + @file dh_sys.c + DH Crypto, Tom St Denis +*/ + +#include "dh_static.h" + + +/** + Encrypt a short symmetric key with a public DH key + @param in The symmetric key to encrypt + @param inlen The length of the key (octets) + @param out [out] The ciphertext + @param outlen [in/out] The max size and resulting size of the ciphertext + @param prng An active PRNG state + @param wprng The index of the PRNG desired + @param hash The index of the hash desired (must produce a digest of size >= the size of the plaintext) + @param key The public key you wish to encrypt with. + @return CRYPT_OK if successful +*/ +int dh_encrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, int hash, + dh_key *key) +{ + unsigned char *pub_expt, *dh_shared, *skey; + dh_key pubkey; + unsigned long x, y, z, pubkeysize; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* check that wprng/hash are not invalid */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + if (inlen > hash_descriptor[hash].hashsize) { + return CRYPT_INVALID_HASH; + } + + /* allocate memory */ + pub_expt = XMALLOC(DH_BUF_SIZE); + dh_shared = XMALLOC(DH_BUF_SIZE); + skey = XMALLOC(MAXBLOCKSIZE); + if (pub_expt == NULL || dh_shared == NULL || skey == NULL) { + if (pub_expt != NULL) { + XFREE(pub_expt); + } + if (dh_shared != NULL) { + XFREE(dh_shared); + } + if (skey != NULL) { + XFREE(skey); + } + return CRYPT_MEM; + } + + /* make a random key and export the public copy */ + pubkey.idx = key->idx; + if ((err = mp_init_multi(&pubkey.base, &pubkey.prime, NULL)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = mp_copy(key->base, pubkey.base)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = mp_copy(key->prime, pubkey.prime)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = dh_make_key_internal(prng, wprng, &pubkey)) != CRYPT_OK) { + goto LBL_ERR; + } + + pubkeysize = DH_BUF_SIZE; + if ((err = dh_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) { + dh_free(&pubkey); + goto LBL_ERR; + } + + /* now check if the out buffer is big enough */ + if (*outlen < (1 + 4 + 4 + PACKET_SIZE + pubkeysize + inlen)) { + dh_free(&pubkey); + err = CRYPT_BUFFER_OVERFLOW; + goto LBL_ERR; + } + + x = DH_BUF_SIZE; + if ((err = dh_shared_secret(&pubkey, key, dh_shared, &x)) != CRYPT_OK) { + dh_free(&pubkey); + goto LBL_ERR; + } + dh_free(&pubkey); + + z = MAXBLOCKSIZE; + if ((err = hash_memory(hash, dh_shared, x, skey, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* store header */ + packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_ENC_KEY); + + /* output header */ + y = PACKET_SIZE; + + /* size of hash name and the name itself */ + out[y++] = hash_descriptor[hash].ID; + + /* length of DH pubkey and the key itself */ + STORE32L(pubkeysize, out+y); + y += 4; + for (x = 0; x < pubkeysize; x++, y++) { + out[y] = pub_expt[x]; + } + + /* Store the encrypted key */ + STORE32L(inlen, out+y); + y += 4; + + for (x = 0; x < inlen; x++, y++) { + out[y] = skey[x] ^ in[x]; + } + *outlen = y; + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + /* clean up */ + zeromem(pub_expt, DH_BUF_SIZE); + zeromem(dh_shared, DH_BUF_SIZE); + zeromem(skey, MAXBLOCKSIZE); +#endif + XFREE(skey); + XFREE(dh_shared); + XFREE(pub_expt); + + return err; +} + +/** + Decrypt a DH encrypted symmetric key + @param in The DH encrypted packet + @param inlen The length of the DH encrypted packet + @param out The plaintext + @param outlen [in/out] The max size and resulting size of the plaintext + @param key The private DH key corresponding to the public key that encrypted the plaintext + @return CRYPT_OK if successful +*/ +int dh_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + dh_key *key) +{ + unsigned char *shared_secret, *skey; + unsigned long x, y, z, keysize; + int hash, err; + dh_key pubkey; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* right key type? */ + if (key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* allocate ram */ + shared_secret = XMALLOC(DH_BUF_SIZE); + skey = XMALLOC(MAXBLOCKSIZE); + if (shared_secret == NULL || skey == NULL) { + if (shared_secret != NULL) { + XFREE(shared_secret); + } + if (skey != NULL) { + XFREE(skey); + } + return CRYPT_MEM; + } + + /* check if initial header should fit */ + if (inlen < PACKET_SIZE+1+4+4) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } else { + inlen -= PACKET_SIZE+1+4+4; + } + + /* is header correct? */ + if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_DH, PACKET_SUB_ENC_KEY)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* now lets get the hash name */ + y = PACKET_SIZE; + hash = find_hash_id(in[y++]); + if (hash == -1) { + err = CRYPT_INVALID_HASH; + goto LBL_ERR; + } + + /* get public key */ + LOAD32L(x, in+y); + + /* now check if the imported key will fit */ + if (inlen < x) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } else { + inlen -= x; + } + + y += 4; + if ((err = dh_import(in+y, x, &pubkey)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + + /* make shared key */ + x = DH_BUF_SIZE; + if ((err = dh_shared_secret(key, &pubkey, shared_secret, &x)) != CRYPT_OK) { + dh_free(&pubkey); + goto LBL_ERR; + } + dh_free(&pubkey); + + z = MAXBLOCKSIZE; + if ((err = hash_memory(hash, shared_secret, x, skey, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* load in the encrypted key */ + LOAD32L(keysize, in+y); + + /* will the out fit as part of the input */ + if (inlen < keysize) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + + if (keysize > *outlen) { + err = CRYPT_BUFFER_OVERFLOW; + goto LBL_ERR; + } + y += 4; + + *outlen = keysize; + + for (x = 0; x < keysize; x++, y++) { + out[x] = skey[x] ^ in[y]; + } + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(shared_secret, DH_BUF_SIZE); + zeromem(skey, MAXBLOCKSIZE); +#endif + + XFREE(skey); + XFREE(shared_secret); + + return err; +} + +/* perform an ElGamal Signature of a hash + * + * The math works as follows. x is the private key, M is the message to sign + + 1. pick a random k + 2. compute a = g^k mod p + 3. compute b = (M - xa)/k mod p + 4. Send (a,b) + + Now to verify with y=g^x mod p, a and b + + 1. compute y^a * a^b = g^(xa) * g^(k*(M-xa)/k) + = g^(xa + (M - xa)) + = g^M [all mod p] + + 2. Compare against g^M mod p [based on input hash]. + 3. If result of #2 == result of #1 then signature valid +*/ + +/** + Sign a message digest using a DH private key + @param in The data to sign + @param inlen The length of the input (octets) + @param out [out] The destination of the signature + @param outlen [in/out] The max size and resulting size of the output + @param prng An active PRNG state + @param wprng The index of the PRNG desired + @param key A private DH key + @return CRYPT_OK if successful +*/ +int dh_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, dh_key *key) +{ + void *a, *b, *k, *m, *p1, *tmp; + unsigned char *buf; + unsigned long x, y; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* check parameters */ + if (key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + /* is the IDX valid ? */ + if (dh_is_valid_idx(key->idx) != 1) { + return CRYPT_PK_INVALID_TYPE; + } + + /* allocate ram for buf */ + buf = XMALLOC(520); + + /* make up a random value k, + * since the order of the group is prime + * we need not check if gcd(k, r) is 1 + */ + if (prng_descriptor[wprng].read(buf, dh_get_size(key), prng) != + (unsigned long)(dh_get_size(key))) { + err = CRYPT_ERROR_READPRNG; + goto LBL_ERR_1; + } + + /* init bignums */ + if ((err = mp_init_multi(&a, &b, &k, &m, &p1, &tmp, NULL)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* load k, m and p1 */ + if ((err = mp_read_unsigned_bin(m, (unsigned char *)in, inlen)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = mp_read_unsigned_bin(k, buf, dh_get_size(key))) != CRYPT_OK) { goto LBL_ERR; } + if ((err = mp_sub_d(key->prime, 1, p1)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = mp_div_2(p1, p1)) != CRYPT_OK) { goto LBL_ERR; } /* p1 = (p-1)/2 */ + /* now get a = g^k mod p */ + if ((err = mp_exptmod(key->base, k, key->prime, a)) != CRYPT_OK) { goto LBL_ERR; } + + /* now find M = xa + kb mod p1 or just b = (M - xa)/k mod p1 */ + if ((err = mp_invmod(k, p1, k)) != CRYPT_OK) { goto LBL_ERR; } /* k = 1/k mod p1 */ + if ((err = mp_mulmod(a, key->x, p1, tmp)) != CRYPT_OK) { goto LBL_ERR; } /* tmp = xa */ + if ((err = mp_submod(m, tmp, p1, tmp)) != CRYPT_OK) { goto LBL_ERR; } /* tmp = M - xa */ + if ((err = mp_mulmod(k, tmp, p1, b)) != CRYPT_OK) { goto LBL_ERR; } /* b = (M - xa)/k */ + + /* check for overflow */ + if ((unsigned long)(PACKET_SIZE + 4 + 4 + mp_unsigned_bin_size(a) + mp_unsigned_bin_size(b)) > *outlen) { + err = CRYPT_BUFFER_OVERFLOW; + goto LBL_ERR; + } + + /* store header */ + y = PACKET_SIZE; + + /* now store them both (a,b) */ + x = (unsigned long)mp_unsigned_bin_size(a); + STORE32L(x, out+y); y += 4; + if ((err = mp_to_unsigned_bin(a, out+y)) != CRYPT_OK) { goto LBL_ERR; } + y += x; + + x = (unsigned long)mp_unsigned_bin_size(b); + STORE32L(x, out+y); y += 4; + if ((err = mp_to_unsigned_bin(b, out+y)) != CRYPT_OK) { goto LBL_ERR; } + y += x; + + /* check if size too big */ + if (*outlen < y) { + err = CRYPT_BUFFER_OVERFLOW; + goto LBL_ERR; + } + + /* store header */ + packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_SIGNED); + *outlen = y; + + err = CRYPT_OK; +LBL_ERR: + mp_clear_multi(tmp, p1, m, k, b, a, NULL); +LBL_ERR_1: + + XFREE(buf); + + return err; +} + + +/** + Verify the signature given + @param sig The signature + @param siglen The length of the signature (octets) + @param hash The hash that was signed + @param hashlen The length of the hash (octets) + @param stat [out] Result of signature comparison, 1==valid, 0==invalid + @param key The public DH key that signed the hash + @return CRYPT_OK if succsessful (even if signature is invalid) +*/ +int dh_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, dh_key *key) +{ + void *a, *b, *m, *tmp; + unsigned long x, y; + int err; + + LTC_ARGCHK(sig != NULL); + LTC_ARGCHK(hash != NULL); + LTC_ARGCHK(stat != NULL); + LTC_ARGCHK(key != NULL); + + /* default to invalid */ + *stat = 0; + + /* check initial input length */ + if (siglen < PACKET_SIZE+4+4) { + return CRYPT_INVALID_PACKET; + } + + /* header ok? */ + if ((err = packet_valid_header((unsigned char *)sig, PACKET_SECT_DH, PACKET_SUB_SIGNED)) != CRYPT_OK) { + return err; + } + + /* get hash out of packet */ + y = PACKET_SIZE; + + /* init all bignums */ + if ((err = mp_init_multi(&a, &b, &m, &tmp, NULL)) != CRYPT_OK) { + return err; + } + + /* load a and b */ + INPUT_BIGNUM(a, sig, x, y, siglen); + INPUT_BIGNUM(b, sig, x, y, siglen); + + /* load m */ + if ((err = mp_read_unsigned_bin(m, (unsigned char *)hash, hashlen)) != CRYPT_OK) { goto error1; } + + /* find g^m mod p */ + if ((err = mp_exptmod(key->base, m, key->prime, m)) != CRYPT_OK) { goto error1; } /* m = g^m mod p */ + + /* find y^a * a^b */ + if ((err = mp_exptmod(key->y, a, key->prime, tmp)) != CRYPT_OK) { goto error1; } /* tmp = y^a mod p */ + if ((err = mp_exptmod(a, b, key->prime, a)) != CRYPT_OK) { goto error1; } /* a = a^b mod p */ + if ((err = mp_mulmod(a, tmp, key->prime, a)) != CRYPT_OK) { goto error1; } /* a = y^a * a^b mod p */ + + /* y^a * a^b == g^m ??? */ + if (mp_cmp(a, m) == 0) { + *stat = 1; + } + + /* clean up */ + err = CRYPT_OK; + goto done; +error1: +error: +done: + mp_clear_multi(tmp, m, b, a, NULL); + return err; +} + +#endif /* LTC_MDH */ diff --git a/src/ltc/pk/dsa/dsa_decrypt_key.c b/src/ltc/pk/dsa/dsa_decrypt_key.c new file mode 100644 index 0000000..25a9db0 --- /dev/null +++ b/src/ltc/pk/dsa/dsa_decrypt_key.c @@ -0,0 +1,140 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file dsa_decrypt_key.c + DSA Crypto, Tom St Denis +*/ + +#ifdef LTC_MDSA + +/** + Decrypt an DSA encrypted key + @param in The ciphertext + @param inlen The length of the ciphertext (octets) + @param out [out] The plaintext + @param outlen [in/out] The max size and resulting size of the plaintext + @param key The corresponding private DSA key + @return CRYPT_OK if successful +*/ +int dsa_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + dsa_key *key) +{ + unsigned char *skey, *expt; + void *g_pub; + unsigned long x, y, hashOID[32]; + int hash, err; + ltc_asn1_list decode[3]; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* right key type? */ + if (key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* decode to find out hash */ + LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0])); + + if ((err = der_decode_sequence(in, inlen, decode, 1)) != CRYPT_OK) { + return err; + } + + hash = find_hash_oid(hashOID, decode[0].size); + if (hash_is_valid(hash) != CRYPT_OK) { + return CRYPT_INVALID_PACKET; + } + + /* we now have the hash! */ + + if ((err = mp_init(&g_pub)) != CRYPT_OK) { + return err; + } + + /* allocate memory */ + expt = XMALLOC(mp_unsigned_bin_size(key->p) + 1); + skey = XMALLOC(MAXBLOCKSIZE); + if (expt == NULL || skey == NULL) { + if (expt != NULL) { + XFREE(expt); + } + if (skey != NULL) { + XFREE(skey); + } + mp_clear(g_pub); + return CRYPT_MEM; + } + + LTC_SET_ASN1(decode, 1, LTC_ASN1_INTEGER, g_pub, 1UL); + LTC_SET_ASN1(decode, 2, LTC_ASN1_OCTET_STRING, skey, MAXBLOCKSIZE); + + /* read the structure in now */ + if ((err = der_decode_sequence(in, inlen, decode, 3)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* make shared key */ + x = mp_unsigned_bin_size(key->p) + 1; + if ((err = dsa_shared_secret(key->x, g_pub, key, expt, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + + y = mp_unsigned_bin_size(key->p) + 1; + y = MIN(y, MAXBLOCKSIZE); + if ((err = hash_memory(hash, expt, x, expt, &y)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* ensure the hash of the shared secret is at least as big as the encrypt itself */ + if (decode[2].size > y) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + + /* avoid buffer overflow */ + if (*outlen < decode[2].size) { + *outlen = decode[2].size; + err = CRYPT_BUFFER_OVERFLOW; + goto LBL_ERR; + } + + /* Decrypt the key */ + for (x = 0; x < decode[2].size; x++) { + out[x] = expt[x] ^ skey[x]; + } + *outlen = x; + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(expt, mp_unsigned_bin_size(key->p) + 1); + zeromem(skey, MAXBLOCKSIZE); +#endif + + XFREE(expt); + XFREE(skey); + + mp_clear(g_pub); + + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ + diff --git a/src/ltc/pk/dsa/dsa_encrypt_key.c b/src/ltc/pk/dsa/dsa_encrypt_key.c new file mode 100644 index 0000000..a7e9ed2 --- /dev/null +++ b/src/ltc/pk/dsa/dsa_encrypt_key.c @@ -0,0 +1,132 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file dsa_encrypt_key.c + DSA Crypto, Tom St Denis +*/ + +#ifdef LTC_MDSA + +/** + Encrypt a symmetric key with DSA + @param in The symmetric key you want to encrypt + @param inlen The length of the key to encrypt (octets) + @param out [out] The destination for the ciphertext + @param outlen [in/out] The max size and resulting size of the ciphertext + @param prng An active PRNG state + @param wprng The index of the PRNG you wish to use + @param hash The index of the hash you want to use + @param key The DSA key you want to encrypt to + @return CRYPT_OK if successful +*/ +int dsa_encrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, int hash, + dsa_key *key) +{ + unsigned char *expt, *skey; + void *g_pub, *g_priv; + unsigned long x, y; + int err, qbits; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* check that wprng/cipher/hash are not invalid */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + if (inlen > hash_descriptor[hash].hashsize) { + return CRYPT_INVALID_HASH; + } + + /* make a random key and export the public copy */ + if ((err = mp_init_multi(&g_pub, &g_priv, NULL)) != CRYPT_OK) { + return err; + } + + expt = XMALLOC(mp_unsigned_bin_size(key->p) + 1); + skey = XMALLOC(MAXBLOCKSIZE); + if (expt == NULL || skey == NULL) { + if (expt != NULL) { + XFREE(expt); + } + if (skey != NULL) { + XFREE(skey); + } + mp_clear_multi(g_pub, g_priv, NULL); + return CRYPT_MEM; + } + + /* make a random g_priv, g_pub = g^x pair */ + qbits = mp_count_bits(key->q); + do { + if ((err = rand_bn_bits(g_priv, qbits, prng, wprng)) != CRYPT_OK) { + goto LBL_ERR; + } + /* private key x should be from range: 1 <= x <= q-1 (see FIPS 186-4 B.1.2) */ + } while (mp_cmp_d(g_priv, 0) != LTC_MP_GT || mp_cmp(g_priv, key->q) != LTC_MP_LT); + + /* compute y */ + if ((err = mp_exptmod(key->g, g_priv, key->p, g_pub)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* make random key */ + x = mp_unsigned_bin_size(key->p) + 1; + if ((err = dsa_shared_secret(g_priv, key->y, key, expt, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + + y = MAXBLOCKSIZE; + if ((err = hash_memory(hash, expt, x, skey, &y)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* Encrypt key */ + for (x = 0; x < inlen; x++) { + skey[x] ^= in[x]; + } + + err = der_encode_sequence_multi(out, outlen, + LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash].OIDlen, hash_descriptor[hash].OID, + LTC_ASN1_INTEGER, 1UL, g_pub, + LTC_ASN1_OCTET_STRING, inlen, skey, + LTC_ASN1_EOL, 0UL, NULL); + +LBL_ERR: +#ifdef LTC_CLEAN_STACK + /* clean up */ + zeromem(expt, mp_unsigned_bin_size(key->p) + 1); + zeromem(skey, MAXBLOCKSIZE); +#endif + + XFREE(skey); + XFREE(expt); + + mp_clear_multi(g_pub, g_priv, NULL); + return err; +} + +#endif +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ + diff --git a/src/ltc/pk/dsa/dsa_export.c b/src/ltc/pk/dsa/dsa_export.c new file mode 100644 index 0000000..60e8b6f --- /dev/null +++ b/src/ltc/pk/dsa/dsa_export.c @@ -0,0 +1,118 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file dsa_export.c + DSA implementation, export key, Tom St Denis +*/ + +#ifdef LTC_MDSA + +/** + Export a DSA key to a binary packet + @param out [out] Where to store the packet + @param outlen [in/out] The max size and resulting size of the packet + @param type The type of key to export (PK_PRIVATE or PK_PUBLIC) + @param key The key to export + @return CRYPT_OK if successful +*/ +int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key) +{ + unsigned long zero=0; + int err, std; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + std = type & PK_STD; + type &= ~PK_STD; + + /* can we store the static header? */ + if (type == PK_PRIVATE && key->type != PK_PRIVATE) { + return CRYPT_PK_TYPE_MISMATCH; + } + + if (type != PK_PUBLIC && type != PK_PRIVATE) { + return CRYPT_INVALID_ARG; + } + + if (type == PK_PRIVATE) { + if (std) { + return der_encode_sequence_multi(out, outlen, + LTC_ASN1_SHORT_INTEGER, 1UL, &zero, + LTC_ASN1_INTEGER, 1UL, key->p, + LTC_ASN1_INTEGER, 1UL, key->q, + LTC_ASN1_INTEGER, 1UL, key->g, + LTC_ASN1_INTEGER, 1UL, key->y, + LTC_ASN1_INTEGER, 1UL, key->x, + LTC_ASN1_EOL, 0UL, NULL); + } + else { + unsigned char flags[1]; + flags[0] = 1; + return der_encode_sequence_multi(out, outlen, + LTC_ASN1_BIT_STRING, 1UL, flags, + LTC_ASN1_INTEGER, 1UL, key->g, + LTC_ASN1_INTEGER, 1UL, key->p, + LTC_ASN1_INTEGER, 1UL, key->q, + LTC_ASN1_INTEGER, 1UL, key->y, + LTC_ASN1_INTEGER, 1UL, key->x, + LTC_ASN1_EOL, 0UL, NULL); + } + } else { + if (std) { + unsigned long tmplen = (mp_count_bits(key->y) / 8) + 8; + unsigned char* tmp = XMALLOC(tmplen); + ltc_asn1_list int_list[3]; + + if (tmp == NULL) { + return CRYPT_MEM; + } + + err = der_encode_integer(key->y, tmp, &tmplen); + if (err != CRYPT_OK) { + goto error; + } + + LTC_SET_ASN1(int_list, 0, LTC_ASN1_INTEGER, key->p, 1UL); + LTC_SET_ASN1(int_list, 1, LTC_ASN1_INTEGER, key->q, 1UL); + LTC_SET_ASN1(int_list, 2, LTC_ASN1_INTEGER, key->g, 1UL); + + err = der_encode_subject_public_key_info(out, outlen, PKA_DSA, tmp, + tmplen, LTC_ASN1_SEQUENCE, int_list, + sizeof(int_list) / sizeof(int_list[0])); + +error: + XFREE(tmp); + return err; + } + else { + unsigned char flags[1]; + flags[0] = 0; + return der_encode_sequence_multi(out, outlen, + LTC_ASN1_BIT_STRING, 1UL, flags, + LTC_ASN1_INTEGER, 1UL, key->g, + LTC_ASN1_INTEGER, 1UL, key->p, + LTC_ASN1_INTEGER, 1UL, key->q, + LTC_ASN1_INTEGER, 1UL, key->y, + LTC_ASN1_EOL, 0UL, NULL); + } + } +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/dsa/dsa_free.c b/src/ltc/pk/dsa/dsa_free.c new file mode 100644 index 0000000..5f5ce72 --- /dev/null +++ b/src/ltc/pk/dsa/dsa_free.c @@ -0,0 +1,34 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file dsa_free.c + DSA implementation, free a DSA key, Tom St Denis +*/ + +#ifdef LTC_MDSA + +/** + Free a DSA key + @param key The key to free from memory +*/ +void dsa_free(dsa_key *key) +{ + LTC_ARGCHKVD(key != NULL); + mp_clear_multi(key->g, key->q, key->p, key->x, key->y, NULL); +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/dsa/dsa_import.c b/src/ltc/pk/dsa/dsa_import.c new file mode 100644 index 0000000..ca522c7 --- /dev/null +++ b/src/ltc/pk/dsa/dsa_import.c @@ -0,0 +1,138 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file dsa_import.c + DSA implementation, import a DSA key, Tom St Denis +*/ + +#ifdef LTC_MDSA + +/** + Import a DSA key + @param in The binary packet to import from + @param inlen The length of the binary packet + @param key [out] Where to store the imported key + @return CRYPT_OK if successful, upon error this function will free all allocated memory +*/ +int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key) +{ + int err; + unsigned long zero = 0; + unsigned char* tmpbuf = NULL; + unsigned char flags[1]; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(ltc_mp.name != NULL); + + /* init key */ + if (mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL) != CRYPT_OK) { + return CRYPT_MEM; + } + + /* try to match the old libtomcrypt format */ + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_BIT_STRING, 1UL, flags, + LTC_ASN1_EOL, 0UL, NULL)) == CRYPT_OK) { + /* private key */ + if (flags[0]) { + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_BIT_STRING, 1UL, flags, + LTC_ASN1_INTEGER, 1UL, key->g, + LTC_ASN1_INTEGER, 1UL, key->p, + LTC_ASN1_INTEGER, 1UL, key->q, + LTC_ASN1_INTEGER, 1UL, key->y, + LTC_ASN1_INTEGER, 1UL, key->x, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto LBL_ERR; + } + key->type = PK_PRIVATE; + goto LBL_OK; + } + /* public key */ + else { + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_BIT_STRING, 1UL, flags, + LTC_ASN1_INTEGER, 1UL, key->g, + LTC_ASN1_INTEGER, 1UL, key->p, + LTC_ASN1_INTEGER, 1UL, key->q, + LTC_ASN1_INTEGER, 1UL, key->y, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto LBL_ERR; + } + key->type = PK_PUBLIC; + goto LBL_OK; + } + } + /* get key type */ + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_SHORT_INTEGER, 1UL, &zero, + LTC_ASN1_INTEGER, 1UL, key->p, + LTC_ASN1_INTEGER, 1UL, key->q, + LTC_ASN1_INTEGER, 1UL, key->g, + LTC_ASN1_INTEGER, 1UL, key->y, + LTC_ASN1_INTEGER, 1UL, key->x, + LTC_ASN1_EOL, 0UL, NULL)) == CRYPT_OK) { + + key->type = PK_PRIVATE; + } else { /* public */ + ltc_asn1_list params[3]; + unsigned long tmpbuf_len = MAX_RSA_SIZE*8; + + LTC_SET_ASN1(params, 0, LTC_ASN1_INTEGER, key->p, 1UL); + LTC_SET_ASN1(params, 1, LTC_ASN1_INTEGER, key->q, 1UL); + LTC_SET_ASN1(params, 2, LTC_ASN1_INTEGER, key->g, 1UL); + + tmpbuf = XCALLOC(1, tmpbuf_len); + if (tmpbuf == NULL) { + err = CRYPT_MEM; + goto LBL_ERR; + } + + err = der_decode_subject_public_key_info(in, inlen, PKA_DSA, + tmpbuf, &tmpbuf_len, + LTC_ASN1_SEQUENCE, params, 3); + if (err != CRYPT_OK) { + XFREE(tmpbuf); + goto LBL_ERR; + } + + if ((err=der_decode_integer(tmpbuf, tmpbuf_len, key->y)) != CRYPT_OK) { + XFREE(tmpbuf); + goto LBL_ERR; + } + + XFREE(tmpbuf); + key->type = PK_PUBLIC; + } + +LBL_OK: + key->qord = mp_unsigned_bin_size(key->q); + + if (key->qord >= LTC_MDSA_MAX_GROUP || key->qord <= 15 || + (unsigned long)key->qord >= mp_unsigned_bin_size(key->p) || (mp_unsigned_bin_size(key->p) - key->qord) >= LTC_MDSA_DELTA) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + + return CRYPT_OK; +LBL_ERR: + mp_clear_multi(key->p, key->g, key->q, key->x, key->y, NULL); + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/dsa/dsa_import_radix.c b/src/ltc/pk/dsa/dsa_import_radix.c new file mode 100644 index 0000000..03e1ba7 --- /dev/null +++ b/src/ltc/pk/dsa/dsa_import_radix.c @@ -0,0 +1,67 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + Import DSA public or private key from raw numbers + @param radix the radix the numbers are represented in (2-64, 16 = hexadecimal) + @param p DSA's p in radix representation + @param q DSA's q in radix representation + @param g DSA's g in radix representation + @param x DSA's x in radix representation (only private key, NULL for public key) + @param y DSA's y in radix representation + @param key [out] the destination for the imported key + @return CRYPT_OK if successful, upon error allocated memory is freed +*/ + +#ifdef LTC_MDSA + +int dsa_import_radix(int radix, char *p, char *q, char *g, char *x, char *y, dsa_key *key) +{ + int err; + + LTC_ARGCHK(p != NULL); + LTC_ARGCHK(q != NULL); + LTC_ARGCHK(g != NULL); + LTC_ARGCHK(y != NULL); + LTC_ARGCHK(ltc_mp.name != NULL); + + /* init key */ + err = mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL); + if (err != CRYPT_OK) return err; + + if ((err = mp_read_radix(key->p , p , radix)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = mp_read_radix(key->q , q , radix)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = mp_read_radix(key->g , g , radix)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = mp_read_radix(key->y , y , radix)) != CRYPT_OK) { goto LBL_ERR; } + if (x && strlen(x) > 0) { + key->type = PK_PRIVATE; + if ((err = mp_read_radix(key->x , x , radix)) != CRYPT_OK) { goto LBL_ERR; } + } + else { + key->type = PK_PUBLIC; + } + + key->qord = mp_unsigned_bin_size(key->q); + + if (key->qord >= LTC_MDSA_MAX_GROUP || key->qord <= 15 || + (unsigned long)key->qord >= mp_unsigned_bin_size(key->p) || (mp_unsigned_bin_size(key->p) - key->qord) >= LTC_MDSA_DELTA) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + return CRYPT_OK; + +LBL_ERR: + mp_clear_multi(key->p, key->g, key->q, key->x, key->y, NULL); + return err; +} + +#endif diff --git a/src/ltc/pk/dsa/dsa_make_key.c b/src/ltc/pk/dsa/dsa_make_key.c new file mode 100644 index 0000000..0cca7a8 --- /dev/null +++ b/src/ltc/pk/dsa/dsa_make_key.c @@ -0,0 +1,268 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file dsa_make_key.c + DSA implementation, generate a DSA key, Tom St Denis +*/ + +#ifdef LTC_MDSA + +/** + Create DSA parameters + @param prng An active PRNG state + @param wprng The index of the PRNG desired + @param group_size Size of the multiplicative group (octets) + @param modulus_size Size of the modulus (octets) + @param p [out] bignum where generated 'p' is stored (must be initialized by caller) + @param q [out] bignum where generated 'q' is stored (must be initialized by caller) + @param g [out] bignum where generated 'g' is stored (must be initialized by caller) + @return CRYPT_OK if successful, upon error this function will free all allocated memory +*/ +int dsa_make_params(prng_state *prng, int wprng, int group_size, int modulus_size, void *p, void *q, void *g) +{ + unsigned long L, N, n, outbytes, seedbytes, counter, j, i; + int err, res, mr_tests_q, mr_tests_p, found_p, found_q, hash; + unsigned char *wbuf, *sbuf, digest[MAXBLOCKSIZE]; + void *t2L1, *t2N1, *t2q, *t2seedlen, *U, *W, *X, *c, *h, *e, *seedinc; + + /* check size */ + if (group_size >= LTC_MDSA_MAX_GROUP || group_size < 1 || group_size >= modulus_size) { + return CRYPT_INVALID_ARG; + } + + /* FIPS-186-4 A.1.1.2 Generation of the Probable Primes p and q Using an Approved Hash Function + * + * L = The desired length of the prime p (in bits e.g. L = 1024) + * N = The desired length of the prime q (in bits e.g. N = 160) + * seedlen = The desired bit length of the domain parameter seed; seedlen shallbe equal to or greater than N + * outlen = The bit length of Hash function + * + * 1. Check that the (L, N) + * 2. If (seedlen = 2^(L-1)) { + * Test whether or not p is prime as specified in Appendix C.3. + * If p is determined to be prime, then return VALID and the values of p, qand (optionally) the values of domain_parameter_seed and counter + * } + * offset = offset + n + 1 Comment: Increment offset + * } + */ + + seedbytes = group_size; + L = modulus_size * 8; + N = group_size * 8; + + /* M-R tests (when followed by one Lucas test) according FIPS-186-4 - Appendix C.3 - table C.1 */ + mr_tests_p = (L <= 2048) ? 3 : 2; + if (N <= 160) { mr_tests_q = 19; } + else if (N <= 224) { mr_tests_q = 24; } + else { mr_tests_q = 27; } + + if (N <= 256) { + hash = register_hash(&sha256_desc); + } + else if (N <= 384) { + hash = register_hash(&sha384_desc); + } + else if (N <= 512) { + hash = register_hash(&sha512_desc); + } + else { + return CRYPT_INVALID_ARG; /* group_size too big */ + } + + if ((err = hash_is_valid(hash)) != CRYPT_OK) { return err; } + outbytes = hash_descriptor[hash].hashsize; + + n = ((L + outbytes*8 - 1) / (outbytes*8)) - 1; + + if ((wbuf = XMALLOC((n+1)*outbytes)) == NULL) { err = CRYPT_MEM; goto cleanup3; } + if ((sbuf = XMALLOC(seedbytes)) == NULL) { err = CRYPT_MEM; goto cleanup2; } + + err = mp_init_multi(&t2L1, &t2N1, &t2q, &t2seedlen, &U, &W, &X, &c, &h, &e, &seedinc, NULL); + if (err != CRYPT_OK) { goto cleanup1; } + + if ((err = mp_2expt(t2L1, L-1)) != CRYPT_OK) { goto cleanup; } + /* t2L1 = 2^(L-1) */ + if ((err = mp_2expt(t2N1, N-1)) != CRYPT_OK) { goto cleanup; } + /* t2N1 = 2^(N-1) */ + if ((err = mp_2expt(t2seedlen, seedbytes*8)) != CRYPT_OK) { goto cleanup; } + /* t2seedlen = 2^seedlen */ + + for(found_p=0; !found_p;) { + /* q */ + for(found_q=0; !found_q;) { + if (prng_descriptor[wprng].read(sbuf, seedbytes, prng) != seedbytes) { err = CRYPT_ERROR_READPRNG; goto cleanup; } + i = outbytes; + if ((err = hash_memory(hash, sbuf, seedbytes, digest, &i)) != CRYPT_OK) { goto cleanup; } + if ((err = mp_read_unsigned_bin(U, digest, outbytes)) != CRYPT_OK) { goto cleanup; } + if ((err = mp_mod(U, t2N1, U)) != CRYPT_OK) { goto cleanup; } + if ((err = mp_add(t2N1, U, q)) != CRYPT_OK) { goto cleanup; } + if (!mp_isodd(q)) mp_add_d(q, 1, q); + if ((err = mp_prime_is_prime(q, mr_tests_q, &res)) != CRYPT_OK) { goto cleanup; } /* XXX-TODO rounds are ignored; no Lucas test */ + if (res == LTC_MP_YES) found_q = 1; + } + + /* p */ + if ((err = mp_read_unsigned_bin(seedinc, sbuf, seedbytes)) != CRYPT_OK) { goto cleanup; } + if ((err = mp_add(q, q, t2q)) != CRYPT_OK) { goto cleanup; } + for(counter=0; counter < 4*L && !found_p; counter++) { + for(j=0; j<=n; j++) { + if ((err = mp_add_d(seedinc, 1, seedinc)) != CRYPT_OK) { goto cleanup; } + if ((err = mp_mod(seedinc, t2seedlen, seedinc)) != CRYPT_OK) { goto cleanup; } + /* seedinc = (seedinc+1) % 2^seed_bitlen */ + if ((i = mp_unsigned_bin_size(seedinc)) > seedbytes) { err = CRYPT_INVALID_ARG; goto cleanup; } + zeromem(sbuf, seedbytes); + if ((err = mp_to_unsigned_bin(seedinc, sbuf + seedbytes-i)) != CRYPT_OK) { goto cleanup; } + i = outbytes; + err = hash_memory(hash, sbuf, seedbytes, wbuf+(n-j)*outbytes, &i); + if (err != CRYPT_OK) { goto cleanup; } + } + if ((err = mp_read_unsigned_bin(W, wbuf, (n+1)*outbytes)) != CRYPT_OK) { goto cleanup; } + if ((err = mp_mod(W, t2L1, W)) != CRYPT_OK) { goto cleanup; } + if ((err = mp_add(W, t2L1, X)) != CRYPT_OK) { goto cleanup; } + if ((err = mp_mod(X, t2q, c)) != CRYPT_OK) { goto cleanup; } + if ((err = mp_sub_d(c, 1, p)) != CRYPT_OK) { goto cleanup; } + if ((err = mp_sub(X, p, p)) != CRYPT_OK) { goto cleanup; } + if (mp_cmp(p, t2L1) != LTC_MP_LT) { + /* p >= 2^(L-1) */ + if ((err = mp_prime_is_prime(p, mr_tests_p, &res)) != CRYPT_OK) { goto cleanup; } /* XXX-TODO rounds are ignored; no Lucas test */ + if (res == LTC_MP_YES) { + found_p = 1; + } + } + } + } + + /* FIPS-186-4 A.2.1 Unverifiable Generation of the Generator g + * 1. e = (p - 1)/q + * 2. h = any integer satisfying: 1 < h < (p - 1) + * h could be obtained from a random number generator or from a counter that changes after each use + * 3. g = h^e mod p + * 4. if (g == 1), then go to step 2. + * + */ + + if ((err = mp_sub_d(p, 1, e)) != CRYPT_OK) { goto cleanup; } + if ((err = mp_div(e, q, e, c)) != CRYPT_OK) { goto cleanup; } + /* e = (p - 1)/q */ + i = mp_count_bits(p); + do { + do { + if ((err = rand_bn_bits(h, i, prng, wprng)) != CRYPT_OK) { goto cleanup; } + } while (mp_cmp(h, p) != LTC_MP_LT || mp_cmp_d(h, 2) != LTC_MP_GT); + if ((err = mp_sub_d(h, 1, h)) != CRYPT_OK) { goto cleanup; } + /* h is randon and 1 < h < (p-1) */ + if ((err = mp_exptmod(h, e, p, g)) != CRYPT_OK) { goto cleanup; } + } while (mp_cmp_d(g, 1) == LTC_MP_EQ); + + err = CRYPT_OK; +cleanup: + mp_clear_multi(t2L1, t2N1, t2q, t2seedlen, U, W, X, c, h, e, seedinc, NULL); +cleanup1: + XFREE(sbuf); +cleanup2: + XFREE(wbuf); +cleanup3: + return err; +} + +/** + Create a DSA key (with given params) + @param prng An active PRNG state + @param wprng The index of the PRNG desired + @param group_size Size of the multiplicative group (octets) + @param modulus_size Size of the modulus (octets) + @param key [out] Where to store the created key + @param p_hex Hexadecimal string 'p' + @param q_hex Hexadecimal string 'q' + @param g_hex Hexadecimal string 'g' + @return CRYPT_OK if successful, upon error this function will free all allocated memory +*/ +int dsa_make_key_ex(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key, char* p_hex, char* q_hex, char* g_hex) +{ + int err, qbits; + + LTC_ARGCHK(key != NULL); + + /* init mp_ints */ + if ((err = mp_init_multi(&key->g, &key->q, &key->p, &key->x, &key->y, NULL)) != CRYPT_OK) { + return err; + } + + if (p_hex == NULL || q_hex == NULL || g_hex == NULL) { + /* generate params */ + err = dsa_make_params(prng, wprng, group_size, modulus_size, key->p, key->q, key->g); + if (err != CRYPT_OK) { goto cleanup; } + } + else { + /* read params */ + if ((err = mp_read_radix(key->p, p_hex, 16)) != CRYPT_OK) { goto cleanup; } + if ((err = mp_read_radix(key->q, q_hex, 16)) != CRYPT_OK) { goto cleanup; } + if ((err = mp_read_radix(key->g, g_hex, 16)) != CRYPT_OK) { goto cleanup; } + /* XXX-TODO maybe do some validity check for p, q, g */ + } + + /* so now we have our DH structure, generator g, order q, modulus p + Now we need a random exponent [mod q] and it's power g^x mod p + */ + qbits = mp_count_bits(key->q); + do { + if ((err = rand_bn_bits(key->x, qbits, prng, wprng)) != CRYPT_OK) { goto cleanup; } + /* private key x should be from range: 1 <= x <= q-1 (see FIPS 186-4 B.1.2) */ + } while (mp_cmp_d(key->x, 0) != LTC_MP_GT || mp_cmp(key->x, key->q) != LTC_MP_LT); + if ((err = mp_exptmod(key->g, key->x, key->p, key->y)) != CRYPT_OK) { goto cleanup; } + key->type = PK_PRIVATE; + key->qord = group_size; + + return CRYPT_OK; + +cleanup: + mp_clear_multi(key->g, key->q, key->p, key->x, key->y, NULL); + return err; +} + +/** + Create a DSA key + @param prng An active PRNG state + @param wprng The index of the PRNG desired + @param group_size Size of the multiplicative group (octets) + @param modulus_size Size of the modulus (octets) + @param key [out] Where to store the created key + @return CRYPT_OK if successful, upon error this function will free all allocated memory +*/ +int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key) +{ + return dsa_make_key_ex(prng, wprng, group_size, modulus_size, key, NULL, NULL, NULL); +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/dsa/dsa_shared_secret.c b/src/ltc/pk/dsa/dsa_shared_secret.c new file mode 100644 index 0000000..8ae9d4d --- /dev/null +++ b/src/ltc/pk/dsa/dsa_shared_secret.c @@ -0,0 +1,72 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file dsa_shared_secret.c + DSA Crypto, Tom St Denis +*/ + +#ifdef LTC_MDSA + +/** + Create a DSA shared secret between two keys + @param private_key The private DSA key (the exponent) + @param base The base of the exponentiation (allows this to be used for both encrypt and decrypt) + @param public_key The public key + @param out [out] Destination of the shared secret + @param outlen [in/out] The max size and resulting size of the shared secret + @return CRYPT_OK if successful +*/ +int dsa_shared_secret(void *private_key, void *base, + dsa_key *public_key, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x; + void *res; + int err; + + LTC_ARGCHK(private_key != NULL); + LTC_ARGCHK(public_key != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* make new point */ + if ((err = mp_init(&res)) != CRYPT_OK) { + return err; + } + + if ((err = mp_exptmod(base, private_key, public_key->p, res)) != CRYPT_OK) { + mp_clear(res); + return err; + } + + x = (unsigned long)mp_unsigned_bin_size(res); + if (*outlen < x) { + *outlen = x; + err = CRYPT_BUFFER_OVERFLOW; + goto done; + } + zeromem(out, x); + if ((err = mp_to_unsigned_bin(res, out + (x - mp_unsigned_bin_size(res)))) != CRYPT_OK) { goto done; } + + err = CRYPT_OK; + *outlen = x; +done: + mp_clear(res); + return err; +} + +#endif +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ + diff --git a/src/ltc/pk/dsa/dsa_sign_hash.c b/src/ltc/pk/dsa/dsa_sign_hash.c new file mode 100644 index 0000000..c9da8cf --- /dev/null +++ b/src/ltc/pk/dsa/dsa_sign_hash.c @@ -0,0 +1,154 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file dsa_sign_hash.c + DSA implementation, sign a hash, Tom St Denis +*/ + +#ifdef LTC_MDSA + +/** + Sign a hash with DSA + @param in The hash to sign + @param inlen The length of the hash to sign + @param r The "r" integer of the signature (caller must initialize with mp_init() first) + @param s The "s" integer of the signature (caller must initialize with mp_init() first) + @param prng An active PRNG state + @param wprng The index of the PRNG desired + @param key A private DSA key + @return CRYPT_OK if successful +*/ +int dsa_sign_hash_raw(const unsigned char *in, unsigned long inlen, + void *r, void *s, + prng_state *prng, int wprng, dsa_key *key) +{ + void *k, *kinv, *tmp; + unsigned char *buf; + int err, qbits; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(r != NULL); + LTC_ARGCHK(s != NULL); + LTC_ARGCHK(key != NULL); + + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + if (key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* check group order size */ + if (key->qord >= LTC_MDSA_MAX_GROUP) { + return CRYPT_INVALID_ARG; + } + + buf = XMALLOC(LTC_MDSA_MAX_GROUP); + if (buf == NULL) { + return CRYPT_MEM; + } + + /* Init our temps */ + if ((err = mp_init_multi(&k, &kinv, &tmp, NULL)) != CRYPT_OK) { goto ERRBUF; } + + qbits = mp_count_bits(key->q); +retry: + + do { + /* gen random k */ + if ((err = rand_bn_bits(k, qbits, prng, wprng)) != CRYPT_OK) { goto error; } + + /* k should be from range: 1 <= k <= q-1 (see FIPS 186-4 B.2.2) */ + if (mp_cmp_d(k, 0) != LTC_MP_GT || mp_cmp(k, key->q) != LTC_MP_LT) { goto retry; } + + /* test gcd */ + if ((err = mp_gcd(k, key->q, tmp)) != CRYPT_OK) { goto error; } + } while (mp_cmp_d(tmp, 1) != LTC_MP_EQ); + + /* now find 1/k mod q */ + if ((err = mp_invmod(k, key->q, kinv)) != CRYPT_OK) { goto error; } + + /* now find r = g^k mod p mod q */ + if ((err = mp_exptmod(key->g, k, key->p, r)) != CRYPT_OK) { goto error; } + if ((err = mp_mod(r, key->q, r)) != CRYPT_OK) { goto error; } + + if (mp_iszero(r) == LTC_MP_YES) { goto retry; } + + /* FIPS 186-4 4.6: use leftmost min(bitlen(q), bitlen(hash)) bits of 'hash'*/ + inlen = MIN(inlen, (unsigned long)(key->qord)); + + /* now find s = (in + xr)/k mod q */ + if ((err = mp_read_unsigned_bin(tmp, (unsigned char *)in, inlen)) != CRYPT_OK) { goto error; } + if ((err = mp_mul(key->x, r, s)) != CRYPT_OK) { goto error; } + if ((err = mp_add(s, tmp, s)) != CRYPT_OK) { goto error; } + if ((err = mp_mulmod(s, kinv, key->q, s)) != CRYPT_OK) { goto error; } + + if (mp_iszero(s) == LTC_MP_YES) { goto retry; } + + err = CRYPT_OK; +error: + mp_clear_multi(k, kinv, tmp, NULL); +ERRBUF: +#ifdef LTC_CLEAN_STACK + zeromem(buf, LTC_MDSA_MAX_GROUP); +#endif + XFREE(buf); + return err; +} + +/** + Sign a hash with DSA + @param in The hash to sign + @param inlen The length of the hash to sign + @param out [out] Where to store the signature + @param outlen [in/out] The max size and resulting size of the signature + @param prng An active PRNG state + @param wprng The index of the PRNG desired + @param key A private DSA key + @return CRYPT_OK if successful +*/ +int dsa_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, dsa_key *key) +{ + void *r, *s; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + if (mp_init_multi(&r, &s, NULL) != CRYPT_OK) { + return CRYPT_MEM; + } + + if ((err = dsa_sign_hash_raw(in, inlen, r, s, prng, wprng, key)) != CRYPT_OK) { + goto error; + } + + err = der_encode_sequence_multi(out, outlen, + LTC_ASN1_INTEGER, 1UL, r, + LTC_ASN1_INTEGER, 1UL, s, + LTC_ASN1_EOL, 0UL, NULL); + +error: + mp_clear_multi(r, s, NULL); + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/dsa/dsa_verify_hash.c b/src/ltc/pk/dsa/dsa_verify_hash.c new file mode 100644 index 0000000..7df472c --- /dev/null +++ b/src/ltc/pk/dsa/dsa_verify_hash.c @@ -0,0 +1,129 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file dsa_verify_hash.c + DSA implementation, verify a signature, Tom St Denis +*/ + + +#ifdef LTC_MDSA + +/** + Verify a DSA signature + @param r DSA "r" parameter + @param s DSA "s" parameter + @param hash The hash that was signed + @param hashlen The length of the hash that was signed + @param stat [out] The result of the signature verification, 1==valid, 0==invalid + @param key The corresponding public DH key + @return CRYPT_OK if successful (even if the signature is invalid) +*/ +int dsa_verify_hash_raw( void *r, void *s, + const unsigned char *hash, unsigned long hashlen, + int *stat, dsa_key *key) +{ + void *w, *v, *u1, *u2; + int err; + + LTC_ARGCHK(r != NULL); + LTC_ARGCHK(s != NULL); + LTC_ARGCHK(stat != NULL); + LTC_ARGCHK(key != NULL); + + /* default to invalid signature */ + *stat = 0; + + /* init our variables */ + if ((err = mp_init_multi(&w, &v, &u1, &u2, NULL)) != CRYPT_OK) { + return err; + } + + /* neither r or s can be null or >q*/ + if (mp_iszero(r) == LTC_MP_YES || mp_iszero(s) == LTC_MP_YES || mp_cmp(r, key->q) != LTC_MP_LT || mp_cmp(s, key->q) != LTC_MP_LT) { + err = CRYPT_INVALID_PACKET; + goto error; + } + + /* FIPS 186-4 4.7: use leftmost min(bitlen(q), bitlen(hash)) bits of 'hash' */ + hashlen = MIN(hashlen, (unsigned long)(key->qord)); + + /* w = 1/s mod q */ + if ((err = mp_invmod(s, key->q, w)) != CRYPT_OK) { goto error; } + + /* u1 = m * w mod q */ + if ((err = mp_read_unsigned_bin(u1, (unsigned char *)hash, hashlen)) != CRYPT_OK) { goto error; } + if ((err = mp_mulmod(u1, w, key->q, u1)) != CRYPT_OK) { goto error; } + + /* u2 = r*w mod q */ + if ((err = mp_mulmod(r, w, key->q, u2)) != CRYPT_OK) { goto error; } + + /* v = g^u1 * y^u2 mod p mod q */ + if ((err = mp_exptmod(key->g, u1, key->p, u1)) != CRYPT_OK) { goto error; } + if ((err = mp_exptmod(key->y, u2, key->p, u2)) != CRYPT_OK) { goto error; } + if ((err = mp_mulmod(u1, u2, key->p, v)) != CRYPT_OK) { goto error; } + if ((err = mp_mod(v, key->q, v)) != CRYPT_OK) { goto error; } + + /* if r = v then we're set */ + if (mp_cmp(r, v) == LTC_MP_EQ) { + *stat = 1; + } + + err = CRYPT_OK; +error: + mp_clear_multi(w, v, u1, u2, NULL); + return err; +} + +/** + Verify a DSA signature + @param sig The signature + @param siglen The length of the signature (octets) + @param hash The hash that was signed + @param hashlen The length of the hash that was signed + @param stat [out] The result of the signature verification, 1==valid, 0==invalid + @param key The corresponding public DH key + @return CRYPT_OK if successful (even if the signature is invalid) +*/ +int dsa_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, dsa_key *key) +{ + int err; + void *r, *s; + + if ((err = mp_init_multi(&r, &s, NULL)) != CRYPT_OK) { + return err; + } + + /* decode the sequence */ + if ((err = der_decode_sequence_multi(sig, siglen, + LTC_ASN1_INTEGER, 1UL, r, + LTC_ASN1_INTEGER, 1UL, s, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* do the op */ + err = dsa_verify_hash_raw(r, s, hash, hashlen, stat, key); + +LBL_ERR: + mp_clear_multi(r, s, NULL); + return err; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/dsa/dsa_verify_key.c b/src/ltc/pk/dsa/dsa_verify_key.c new file mode 100644 index 0000000..5afdb3b --- /dev/null +++ b/src/ltc/pk/dsa/dsa_verify_key.c @@ -0,0 +1,100 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file dsa_verify_key.c + DSA implementation, verify a key, Tom St Denis +*/ + +#ifdef LTC_MDSA + +/** + Verify a DSA key for validity + @param key The key to verify + @param stat [out] Result of test, 1==valid, 0==invalid + @return CRYPT_OK if successful +*/ +int dsa_verify_key(dsa_key *key, int *stat) +{ + void *tmp, *tmp2; + int res, err; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(stat != NULL); + + /* default to an invalid key */ + *stat = 0; + + /* first make sure key->q and key->p are prime */ + if ((err = mp_prime_is_prime(key->q, 8, &res)) != CRYPT_OK) { + return err; + } + if (res == 0) { + return CRYPT_OK; + } + + if ((err = mp_prime_is_prime(key->p, 8, &res)) != CRYPT_OK) { + return err; + } + if (res == 0) { + return CRYPT_OK; + } + + /* now make sure that g is not -1, 0 or 1 and

g, 0) == LTC_MP_EQ || mp_cmp_d(key->g, 1) == LTC_MP_EQ) { + return CRYPT_OK; + } + if ((err = mp_init_multi(&tmp, &tmp2, NULL)) != CRYPT_OK) { return err; } + if ((err = mp_sub_d(key->p, 1, tmp)) != CRYPT_OK) { goto error; } + if (mp_cmp(tmp, key->g) == LTC_MP_EQ || mp_cmp(key->g, key->p) != LTC_MP_LT) { + err = CRYPT_OK; + goto error; + } + + /* 1 < y < p-1 */ + if (!(mp_cmp_d(key->y, 1) == LTC_MP_GT && mp_cmp(key->y, tmp) == LTC_MP_LT)) { + err = CRYPT_OK; + goto error; + } + + /* now we have to make sure that g^q = 1, and that p-1/q gives 0 remainder */ + if ((err = mp_div(tmp, key->q, tmp, tmp2)) != CRYPT_OK) { goto error; } + if (mp_iszero(tmp2) != LTC_MP_YES) { + err = CRYPT_OK; + goto error; + } + + if ((err = mp_exptmod(key->g, key->q, key->p, tmp)) != CRYPT_OK) { goto error; } + if (mp_cmp_d(tmp, 1) != LTC_MP_EQ) { + err = CRYPT_OK; + goto error; + } + + /* now we have to make sure that y^q = 1, this makes sure y \in g^x mod p */ + if ((err = mp_exptmod(key->y, key->q, key->p, tmp)) != CRYPT_OK) { goto error; } + if (mp_cmp_d(tmp, 1) != LTC_MP_EQ) { + err = CRYPT_OK; + goto error; + } + + /* at this point we are out of tests ;-( */ + err = CRYPT_OK; + *stat = 1; +error: + mp_clear_multi(tmp, tmp2, NULL); + return err; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/ecc/ecc.c b/src/ltc/pk/ecc/ecc.c new file mode 100644 index 0000000..b48b3f5 --- /dev/null +++ b/src/ltc/pk/ecc/ecc.c @@ -0,0 +1,426 @@ +/* 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://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ +#include "tomcrypt.h" + +/** + @file ecc.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/* This array holds the curve parameters: + * - it ***MUST*** be organized by size from smallest to largest + * - due to curve lookup by keysize the ordering is very important + * - be careful when adding/removing items to/from this list + * Curves (prime field only) are taken from: + * - http://www.secg.org/collateral/sec2_final.pdf (named: SECP*) + * - http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf (named: NISTP*) + * - ANS X9.62 (named: PRIMEP*) + * - http://www.ecc-brainpool.org/download/Domain-parameters.pdf (named: BRAINPOOLP*) + */ +const ltc_ecc_set_type ltc_ecc_sets[] = { +#if defined(LTC_ECC_SECP112R1) || defined(LTC_ECC112) +{ /* this curve ***MUST*** be the first from all with size 14 (backward compatibility reasons) */ + /* size/bytes */ 14, + /* curve name */ "SECP112R1", + /* prime */ "DB7C2ABF62E35E668076BEAD208B", + /* A */ "DB7C2ABF62E35E668076BEAD2088", + /* B */ "659EF8BA043916EEDE8911702B22", + /* order */ "DB7C2ABF62E35E7628DFAC6561C5", + /* Gx */ "09487239995A5EE76B55F9C2F098", + /* Gy */ "A89CE5AF8724C0A23E0E0FF77500", + /* cofactor */ 1, + /* OID struct */ { {1,3,132,0,6}, 5 } +}, +#endif +#ifdef LTC_ECC_SECP112R2 +{ + /* size/bytes */ 14, + /* curve name */ "SECP112R2", + /* prime */ "DB7C2ABF62E35E668076BEAD208B", + /* A */ "6127C24C05F38A0AAAF65C0EF02C", + /* B */ "51DEF1815DB5ED74FCC34C85D709", + /* order */ "36DF0AAFD8B8D7597CA10520D04B", + /* Gx */ "4BA30AB5E892B4E1649DD0928643", + /* Gy */ "ADCD46F5882E3747DEF36E956E97", + /* cofactor */ 4, + /* OID struct */ { {1,3,132,0,7}, 5 } +}, +#endif +#if defined(LTC_ECC_SECP128R1) || defined(LTC_ECC128) +{ /* this curve ***MUST*** be the first from all with size 16 (backward compatibility reasons) */ + /* size/bytes */ 16, + /* curve name */ "SECP128R1", + /* prime */ "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", + /* A */ "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", + /* B */ "E87579C11079F43DD824993C2CEE5ED3", + /* order */ "FFFFFFFE0000000075A30D1B9038A115", + /* Gx */ "161FF7528B899B2D0C28607CA52C5B86", + /* Gy */ "CF5AC8395BAFEB13C02DA292DDED7A83", + /* cofactor */ 1, + /* OID struct */ { {1,3,132,0,28}, 5 } +}, +#endif +#ifdef LTC_ECC_SECP128R2 +{ + /* size/bytes */ 16, + /* curve name */ "SECP128R2", + /* prime */ "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", + /* A */ "D6031998D1B3BBFEBF59CC9BBFF9AEE1", + /* B */ "5EEEFCA380D02919DC2C6558BB6D8A5D", + /* order */ "3FFFFFFF7FFFFFFFBE0024720613B5A3", + /* Gx */ "7B6AA5D85E572983E6FB32A7CDEBC140", + /* Gy */ "27B6916A894D3AEE7106FE805FC34B44", + /* cofactor */ 4, + /* OID struct */ { {1,3,132,0,29}, 5 } +}, +#endif +#if defined(LTC_ECC_SECP160R1) || defined(LTC_ECC160) +{ /* this curve ***MUST*** be the first from all with size 20 (backward compatibility reasons) */ + /* size/bytes */ 20, + /* curve name */ "SECP160R1", + /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", + /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", + /* B */ "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", + /* order */ "0100000000000000000001F4C8F927AED3CA752257", + /* Gx */ "4A96B5688EF573284664698968C38BB913CBFC82", + /* Gy */ "23A628553168947D59DCC912042351377AC5FB32", + /* cofactor */ 1, + /* OID struct */ { {1,3,132,0,8}, 5 } +}, +#endif +#ifdef LTC_ECC_SECP160R2 +{ + /* size/bytes */ 20, + /* curve name */ "SECP160R2", + /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", + /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", + /* B */ "B4E134D3FB59EB8BAB57274904664D5AF50388BA", + /* order */ "0100000000000000000000351EE786A818F3A1A16B", + /* Gx */ "52DCB034293A117E1F4FF11B30F7199D3144CE6D", + /* Gy */ "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", + /* cofactor */ 1, + /* OID struct */ { {1,3,132,0,30}, 5 } +}, +#endif +#ifdef LTC_ECC_SECP160K1 +{ + /* size/bytes */ 20, + /* curve name */ "SECP160K1", + /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", + /* A */ "0000000000000000000000000000000000000000", + /* B */ "0000000000000000000000000000000000000007", + /* order */ "0100000000000000000001B8FA16DFAB9ACA16B6B3", + /* Gx */ "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", + /* Gy */ "938CF935318FDCED6BC28286531733C3F03C4FEE", + /* cofactor */ 1, + /* OID struct */ { {1,3,132,0,9}, 5 } +}, +#endif +#ifdef LTC_ECC_BRAINPOOLP160R1 +{ + /* size/bytes */ 20, + /* curve name */ "BRAINPOOLP160R1", + /* prime */ "E95E4A5F737059DC60DFC7AD95B3D8139515620F", + /* A */ "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", + /* B */ "1E589A8595423412134FAA2DBDEC95C8D8675E58", + /* order */ "E95E4A5F737059DC60DF5991D45029409E60FC09", + /* Gx */ "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3", + /* Gy */ "1667CB477A1A8EC338F94741669C976316DA6321", + /* cofactor */ 1, + /* OID struct */ { {1,3,36,3,3,2,8,1,1,1}, 10 } +}, +#endif +#if defined(LTC_ECC_SECP192R1) || defined(LTC_ECC192) +{ /* this curve ***MUST*** be the first from all with size 24 (backward compatibility reasons) */ + /* size/bytes */ 24, + /* curve name */ "SECP192R1", /* same as: NISTP192 PRIME192V1, old libtomcrypt name: ECC-192 */ + /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", + /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", + /* B */ "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", + /* order */ "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", + /* Gx */ "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", + /* Gy */ "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811", + /* cofactor */ 1, + /* OID struct */ { {1,2,840,10045,3,1,1}, 7 } +}, +#endif +#ifdef LTC_ECC_PRIME192V2 +{ + /* size/bytes */ 24, + /* curve name */ "PRIME192V2", + /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", + /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", + /* B */ "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", + /* order */ "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31", + /* Gx */ "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A", + /* Gy */ "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15", + /* cofactor */ 1, + /* OID struct */ { {1,2,840,10045,3,1,2}, 7 } +}, +#endif +#ifdef LTC_ECC_PRIME192V3 +{ + /* size/bytes */ 24, + /* curve name */ "PRIME192V3", + /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", + /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", + /* B */ "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", + /* order */ "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13", + /* Gx */ "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896", + /* Gy */ "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0", + /* cofactor */ 1, + /* OID struct */ { {1,2,840,10045,3,1,3}, 7 } +}, +#endif +#ifdef LTC_ECC_SECP192K1 +{ + /* size/bytes */ 24, + /* curve name */ "SECP192K1", + /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", + /* A */ "000000000000000000000000000000000000000000000000", + /* B */ "000000000000000000000000000000000000000000000003", + /* order */ "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", + /* Gx */ "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", + /* Gy */ "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", + /* cofactor */ 1, + /* OID struct */ { {1,3,132,0,31}, 5 } +}, +#endif +#ifdef LTC_ECC_BRAINPOOLP192R1 +{ + /* size/bytes */ 24, + /* curve name */ "BRAINPOOLP192R1", + /* prime */ "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", + /* A */ "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", + /* B */ "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", + /* order */ "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", + /* Gx */ "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6", + /* Gy */ "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", + /* cofactor */ 1, + /* OID struct */ { {1,3,36,3,3,2,8,1,1,3}, 10 } +}, +#endif +#if defined(LTC_ECC_SECP224R1) || defined(LTC_ECC224) +{ /* this curve ***MUST*** be the first from all with size 28 (backward compatibility reasons) */ + /* size/bytes */ 28, + /* curve name */ "SECP224R1", /* same as: NISTP224, old libtomcrypt name: ECC-224 */ + /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", + /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", + /* B */ "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", + /* order */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", + /* Gx */ "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", + /* Gy */ "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", + /* cofactor */ 1, + /* OID struct */ { {1,3,132,0,33}, 5 } +}, +#endif +#ifdef LTC_ECC_SECP224K1 +{ + /* size/bytes */ 28, + /* curve name */ "SECP224K1", + /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", + /* A */ "00000000000000000000000000000000000000000000000000000000", + /* B */ "00000000000000000000000000000000000000000000000000000005", + /* order */ "010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7", + /* Gx */ "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", + /* Gy */ "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", + /* cofactor */ 1, + /* OID struct */ { {1,3,132,0,32}, 5 } +}, +#endif +#ifdef LTC_ECC_BRAINPOOLP224R1 +{ + /* size/bytes */ 28, + /* curve name */ "BRAINPOOLP224R1", + /* prime */ "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", + /* A */ "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", + /* B */ "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", + /* order */ "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", + /* Gx */ "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D", + /* Gy */ "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", + /* cofactor */ 1, + /* OID struct */ { {1,3,36,3,3,2,8,1,1,5}, 10 } +}, +#endif +#ifdef LTC_ECC_PRIME239V1 +{ + /* size/bytes */ 30, + /* curve name */ "PRIME239V1", + /* prime */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", + /* A */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", + /* B */ "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", + /* order */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B", + /* Gx */ "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF", + /* Gy */ "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE", + /* cofactor */ 1, + /* OID struct */ { {1,2,840,10045,3,1,4}, 7 } +}, +#endif +#ifdef LTC_ECC_PRIME239V2 +{ + /* size/bytes */ 30, + /* curve name */ "PRIME239V2", + /* prime */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", + /* A */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", + /* B */ "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", + /* order */ "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063", + /* Gx */ "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7", + /* Gy */ "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA", + /* cofactor */ 1, + /* OID struct */ { {1,2,840,10045,3,1,5}, 7 } +}, +#endif +#ifdef LTC_ECC_PRIME239V3 +{ + /* size/bytes */ 30, + /* curve name */ "PRIME239V3", + /* prime */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", + /* A */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", + /* B */ "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", + /* order */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551", + /* Gx */ "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A", + /* Gy */ "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3", + /* cofactor */ 1, + /* OID struct */ { {1,2,840,10045,3,1,6}, 7 } +}, +#endif +#if defined(LTC_ECC_SECP256R1) || defined(LTC_ECC256) +{ /* this curve ***MUST*** be the first from all with size 32 (backward compatibility reasons) */ + /* size/bytes */ 32, + /* curve name */ "SECP256R1", /* same as: NISTP256 PRIME256V1, old libtomcrypt name: ECC-256 */ + /* prime */ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", + /* A */ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", + /* B */ "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", + /* order */ "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", + /* Gx */ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", + /* Gy */ "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", + /* cofactor */ 1, + /* OID struct */ { {1,2,840,10045,3,1,7}, 7 } +}, +#endif +#ifdef LTC_ECC_SECP256K1 +{ + /* size/bytes */ 32, + /* curve name */ "SECP256K1", + /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", + /* A */ "0000000000000000000000000000000000000000000000000000000000000000", + /* B */ "0000000000000000000000000000000000000000000000000000000000000007", + /* order */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", + /* Gx */ "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", + /* Gy */ "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", + /* cofactor */ 1, + /* OID struct */ { {1,3,132,0,10}, 5 } +}, +#endif +#ifdef LTC_ECC_BRAINPOOLP256R1 +{ + /* size/bytes */ 32, + /* curve name */ "BRAINPOOLP256R1", + /* prime */ "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", + /* A */ "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", + /* B */ "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", + /* order */ "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", + /* Gx */ "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", + /* Gy */ "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", + /* cofactor */ 1, + /* OID struct */ { {1,3,36,3,3,2,8,1,1,7}, 10 } +}, +#endif +#ifdef LTC_ECC_BRAINPOOLP320R1 +{ + /* size/bytes */ 40, + /* curve name */ "BRAINPOOLP320R1", + /* prime */ "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", + /* A */ "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", + /* B */ "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", + /* order */ "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", + /* Gx */ "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611", + /* Gy */ "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", + /* cofactor */ 1, + /* OID struct */ { {1,3,36,3,3,2,8,1,1,9}, 10 } +}, +#endif +#if defined(LTC_ECC_SECP384R1) || defined(LTC_ECC384) +{ /* this curve ***MUST*** be the first from all with size 48 (backward compatibility reasons) */ + /* size/bytes */ 48, + /* curve name */ "SECP384R1", /* same as: NISTP384, old libtomcrypt name: ECC-384 */ + /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", + /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", + /* B */ "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", + /* order */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", + /* Gx */ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", + /* Gy */ "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", + /* cofactor */ 1, + /* OID struct */ { {1,3,132,0,34}, 5 } +}, +#endif +#ifdef LTC_ECC_BRAINPOOLP384R1 +{ + /* size/bytes */ 48, + /* curve name */ "BRAINPOOLP384R1", + /* prime */ "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", + /* A */ "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", + /* B */ "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", + /* order */ "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", + /* Gx */ "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", + /* Gy */ "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", + /* cofactor */ 1, + /* OID struct */ { {1,3,36,3,3,2,8,1,1,11}, 10 } +}, +#endif +#ifdef LTC_ECC_BRAINPOOLP512R1 +{ + /* size/bytes */ 64, + /* curve name */ "BRAINPOOLP512R1", + /* prime */ "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", + /* A */ "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", + /* B */ "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", + /* order */ "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", + /* Gx */ "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", + /* Gy */ "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", + /* cofactor */ 1, + /* OID struct */ { {1,3,36,3,3,2,8,1,1,13}, 10 } +}, +#endif +#if defined(LTC_ECC_SECP521R1) || defined(LTC_ECC521) +{ /* this curve ***MUST*** be the first from all with size 66 (backward compatibility reasons) */ + /* size/bytes */ 66, + /* curve name */ "SECP521R1", /* same as: NISTP521, old libtomcrypt name: ECC-521 */ + /* prime */ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + /* A */ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", + /* B */ "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", + /* order */ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", + /* Gx */ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", + /* Gy */ "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", + /* cofactor */ 1, + /* OID struct */ { {1,3,132,0,35}, 5 } +}, +#endif +{ + 0, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + 0, + { { 0 }, 0 } +} +}; + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ + diff --git a/src/ltc/pk/ecc/ecc_ansi_x963_export.c b/src/ltc/pk/ecc/ecc_ansi_x963_export.c new file mode 100644 index 0000000..fec560b --- /dev/null +++ b/src/ltc/pk/ecc/ecc_ansi_x963_export.c @@ -0,0 +1,76 @@ +/* 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://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ +#include "tomcrypt.h" + +/** + @file ecc_ansi_x963_export.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/** ECC X9.63 (Sec. 4.3.6) uncompressed export + @param key Key to export + @param out [out] destination of export + @param outlen [in/out] Length of destination and final output size + Return CRYPT_OK on success +*/ +int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen) +{ + unsigned char buf[ECC_BUF_SIZE]; + unsigned long numlen, xlen, ylen; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + if (ltc_ecc_is_valid_idx(key->idx) == 0) { + return CRYPT_INVALID_ARG; + } + numlen = key->dp->size; + xlen = mp_unsigned_bin_size(key->pubkey.x); + ylen = mp_unsigned_bin_size(key->pubkey.y); + + if (xlen > numlen || ylen > numlen || sizeof(buf) < numlen) { + return CRYPT_BUFFER_OVERFLOW; + } + + if (*outlen < (1 + 2*numlen)) { + *outlen = 1 + 2*numlen; + return CRYPT_BUFFER_OVERFLOW; + } + + /* store byte 0x04 */ + out[0] = 0x04; + + /* pad and store x */ + zeromem(buf, sizeof(buf)); + mp_to_unsigned_bin(key->pubkey.x, buf + (numlen - xlen)); + XMEMCPY(out+1, buf, numlen); + + /* pad and store y */ + zeromem(buf, sizeof(buf)); + mp_to_unsigned_bin(key->pubkey.y, buf + (numlen - ylen)); + XMEMCPY(out+1+numlen, buf, numlen); + + *outlen = 1 + 2*numlen; + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/ecc/ecc_ansi_x963_import.c b/src/ltc/pk/ecc/ecc_ansi_x963_import.c new file mode 100644 index 0000000..081cf64 --- /dev/null +++ b/src/ltc/pk/ecc/ecc_ansi_x963_import.c @@ -0,0 +1,106 @@ +/* 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://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ +#include "tomcrypt.h" + +/** + @file ecc_ansi_x963_import.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/** Import an ANSI X9.63 format public key + @param in The input data to read + @param inlen The length of the input data + @param key [out] destination to store imported key \ +*/ +int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, ecc_key *key) +{ + return ecc_ansi_x963_import_ex(in, inlen, key, NULL); +} + +int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp) +{ + int x, err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(key != NULL); + + /* must be odd */ + if ((inlen & 1) == 0) { + return CRYPT_INVALID_ARG; + } + + /* init key */ + if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL) != CRYPT_OK) { + return CRYPT_MEM; + } + + /* check for 4, 6 or 7 */ + if (in[0] != 4 && in[0] != 6 && in[0] != 7) { + err = CRYPT_INVALID_PACKET; + goto error; + } + + /* read data */ + if ((err = mp_read_unsigned_bin(key->pubkey.x, (unsigned char *)in+1, (inlen-1)>>1)) != CRYPT_OK) { + goto error; + } + + if ((err = mp_read_unsigned_bin(key->pubkey.y, (unsigned char *)in+1+((inlen-1)>>1), (inlen-1)>>1)) != CRYPT_OK) { + goto error; + } + if ((err = mp_set(key->pubkey.z, 1)) != CRYPT_OK) { goto error; } + + if (dp == NULL) { + /* BEWARE: Here we are looking up the curve params by keysize (neither curve name nor curve oid), + * which might be ambiguous (there can more than one curve for given keysize). + * Thus the chosen curve depends on order of items in ltc_ecc_sets[] - see ecc.c file. + */ + /* determine the idx */ + for (x = 0; ltc_ecc_sets[x].size != 0; x++) { + if ((unsigned)ltc_ecc_sets[x].size >= ((inlen-1)>>1)) { + break; + } + } + if (ltc_ecc_sets[x].size == 0) { + err = CRYPT_INVALID_PACKET; + goto error; + } + /* set the idx */ + key->idx = x; + key->dp = <c_ecc_sets[x]; + } else { + if (((inlen-1)>>1) != (unsigned long) dp->size) { + err = CRYPT_INVALID_PACKET; + goto error; + } + key->idx = -1; + key->dp = dp; + } + key->type = PK_PUBLIC; + + /* we're done */ + return CRYPT_OK; +error: + mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL); + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/ecc/ecc_decrypt_key.c b/src/ltc/pk/ecc/ecc_decrypt_key.c new file mode 100644 index 0000000..6e1d34d --- /dev/null +++ b/src/ltc/pk/ecc/ecc_decrypt_key.c @@ -0,0 +1,148 @@ +/* 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://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ +#include "tomcrypt.h" + +/** + @file ecc_decrypt_key.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/** + Decrypt an ECC encrypted key + @param in The ciphertext + @param inlen The length of the ciphertext (octets) + @param out [out] The plaintext + @param outlen [in/out] The max size and resulting size of the plaintext + @param key The corresponding private ECC key + @return CRYPT_OK if successful +*/ +int ecc_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + ecc_key *key) +{ + unsigned char *ecc_shared, *skey, *pub_expt; + unsigned long x, y, hashOID[32]; + int hash, err; + ecc_key pubkey; + ltc_asn1_list decode[3]; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* right key type? */ + if (key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* decode to find out hash */ + LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0])); + + if ((err = der_decode_sequence(in, inlen, decode, 1)) != CRYPT_OK) { + return err; + } + + hash = find_hash_oid(hashOID, decode[0].size); + if (hash_is_valid(hash) != CRYPT_OK) { + return CRYPT_INVALID_PACKET; + } + + /* we now have the hash! */ + + /* allocate memory */ + pub_expt = XMALLOC(ECC_BUF_SIZE); + ecc_shared = XMALLOC(ECC_BUF_SIZE); + skey = XMALLOC(MAXBLOCKSIZE); + if (pub_expt == NULL || ecc_shared == NULL || skey == NULL) { + if (pub_expt != NULL) { + XFREE(pub_expt); + } + if (ecc_shared != NULL) { + XFREE(ecc_shared); + } + if (skey != NULL) { + XFREE(skey); + } + return CRYPT_MEM; + } + LTC_SET_ASN1(decode, 1, LTC_ASN1_OCTET_STRING, pub_expt, ECC_BUF_SIZE); + LTC_SET_ASN1(decode, 2, LTC_ASN1_OCTET_STRING, skey, MAXBLOCKSIZE); + + /* read the structure in now */ + if ((err = der_decode_sequence(in, inlen, decode, 3)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* import ECC key from packet */ + if ((err = ecc_import_raw(decode[1].data, decode[1].size, &pubkey, (ltc_ecc_set_type *)key->dp)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* make shared key */ + x = ECC_BUF_SIZE; + if ((err = ecc_shared_secret(key, &pubkey, ecc_shared, &x)) != CRYPT_OK) { + ecc_free(&pubkey); + goto LBL_ERR; + } + ecc_free(&pubkey); + + y = MIN(ECC_BUF_SIZE, MAXBLOCKSIZE); + if ((err = hash_memory(hash, ecc_shared, x, ecc_shared, &y)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* ensure the hash of the shared secret is at least as big as the encrypt itself */ + if (decode[2].size > y) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + + /* avoid buffer overflow */ + if (*outlen < decode[2].size) { + *outlen = decode[2].size; + err = CRYPT_BUFFER_OVERFLOW; + goto LBL_ERR; + } + + /* Decrypt the key */ + for (x = 0; x < decode[2].size; x++) { + out[x] = skey[x] ^ ecc_shared[x]; + } + *outlen = x; + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(pub_expt, ECC_BUF_SIZE); + zeromem(ecc_shared, ECC_BUF_SIZE); + zeromem(skey, MAXBLOCKSIZE); +#endif + + XFREE(pub_expt); + XFREE(ecc_shared); + XFREE(skey); + + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ + diff --git a/src/ltc/pk/ecc/ecc_dp_clear.c b/src/ltc/pk/ecc/ecc_dp_clear.c new file mode 100644 index 0000000..76fa375 --- /dev/null +++ b/src/ltc/pk/ecc/ecc_dp_clear.c @@ -0,0 +1,36 @@ +/* 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. + * + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ + +#include "tomcrypt.h" + +#ifdef LTC_MECC + +int ecc_dp_clear(ltc_ecc_set_type *dp) +{ + if (dp == NULL) return CRYPT_INVALID_ARG; + + if (dp->name != NULL) { XFREE(dp->name ); dp->name = NULL; } + if (dp->prime != NULL) { XFREE(dp->prime); dp->prime = NULL; } + if (dp->A != NULL) { XFREE(dp->A ); dp->A = NULL; } + if (dp->B != NULL) { XFREE(dp->B ); dp->B = NULL; } + if (dp->order != NULL) { XFREE(dp->order); dp->order = NULL; } + if (dp->Gx != NULL) { XFREE(dp->Gx ); dp->Gx = NULL; } + if (dp->Gy != NULL) { XFREE(dp->Gy ); dp->Gy = NULL; } + dp->cofactor = 0; + dp->oid.OIDlen = 0; + + return CRYPT_OK; +} + +#endif diff --git a/src/ltc/pk/ecc/ecc_dp_fill_from_sets.c b/src/ltc/pk/ecc/ecc_dp_fill_from_sets.c new file mode 100644 index 0000000..06c66be --- /dev/null +++ b/src/ltc/pk/ecc/ecc_dp_fill_from_sets.c @@ -0,0 +1,76 @@ +/* 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. + * + */ + +#include "tomcrypt.h" + +#ifdef LTC_MECC + +static int hexstrcmp(const char *hexa, const char *hexb) +{ + #define MY_TOLOWER(a) ((((a)>='A')&&((a)<='Z')) ? ((a)|0x60) : (a)) + /* ignore leading zeroes */ + while(*hexa == '0') hexa++; + while(*hexb == '0') hexb++; + /* compare: case insensitive, hexadecimal chars only */ + while (*hexa && *hexb) { + if ( (*hexa < '0' || *hexa > '9') && + (*hexa < 'a' || *hexa > 'f') && + (*hexa < 'A' || *hexa > 'F') ) return 1; + if ( (*hexb < '0' || *hexb > '9') && + (*hexb < 'a' || *hexb > 'f') && + (*hexb < 'A' || *hexb > 'F') ) return 1; + if (MY_TOLOWER(*hexa) != MY_TOLOWER(*hexb)) return 1; + hexa++; + hexb++; + } + if (*hexa == '\0' && *hexb == '\0') return 0; /* success - match */ + return 1; +} + +/* search known curve by curve parameters and fill in missing parameters into dp + * we assume every parameter has the same case (usually uppercase) and no leading zeros + */ +int ecc_dp_fill_from_sets(ltc_ecc_set_type *dp) +{ + ltc_ecc_set_type params; + int x; + + if (!dp) return CRYPT_INVALID_ARG; + if (dp->oid.OIDlen > 0) return CRYPT_OK; + if (!dp->prime || !dp->A || !dp->B || !dp->order || !dp->Gx || !dp->Gy || dp->cofactor == 0) return CRYPT_INVALID_ARG; + + for (x = 0; ltc_ecc_sets[x].size != 0; x++) { + if (hexstrcmp(ltc_ecc_sets[x].prime, dp->prime) == 0 && + hexstrcmp(ltc_ecc_sets[x].A, dp->A) == 0 && + hexstrcmp(ltc_ecc_sets[x].B, dp->B) == 0 && + hexstrcmp(ltc_ecc_sets[x].order, dp->order) == 0 && + hexstrcmp(ltc_ecc_sets[x].Gx, dp->Gx) == 0 && + hexstrcmp(ltc_ecc_sets[x].Gy, dp->Gy) == 0 && + ltc_ecc_sets[x].cofactor == dp->cofactor) { + + params = ltc_ecc_sets[x]; + + /* copy oid */ + dp->oid.OIDlen = params.oid.OIDlen; + XMEMCPY(dp->oid.OID, params.oid.OID, dp->oid.OIDlen * sizeof(dp->oid.OID[0])); + + /* copy name */ + if (dp->name != NULL) XFREE(dp->name); + if ((dp->name = XMALLOC(1+strlen(params.name))) == NULL) return CRYPT_MEM; + strcpy(dp->name, params.name); + + return CRYPT_OK; + } + } + + return CRYPT_INVALID_ARG; +} + +#endif diff --git a/src/ltc/pk/ecc/ecc_dp_from_oid.c b/src/ltc/pk/ecc/ecc_dp_from_oid.c new file mode 100644 index 0000000..2b9d40e --- /dev/null +++ b/src/ltc/pk/ecc/ecc_dp_from_oid.c @@ -0,0 +1,86 @@ +/* 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://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ + +#include "tomcrypt.h" + +#ifdef LTC_MECC + +int ecc_dp_set_by_oid(ltc_ecc_set_type *dp, unsigned long *oid, unsigned long oidsize) +{ + int i; + unsigned long len; + + for(i=0; ltc_ecc_sets[i].size != 0; i++) { + if ((oidsize == ltc_ecc_sets[i].oid.OIDlen) && + (XMEM_NEQ(oid, ltc_ecc_sets[i].oid.OID, sizeof(unsigned long) * ltc_ecc_sets[i].oid.OIDlen) == 0)) { + break; + } + } + if (ltc_ecc_sets[i].size == 0) return CRYPT_INVALID_ARG; /* not found */ + + /* a */ + len = (unsigned long)strlen(ltc_ecc_sets[i].A); + if ((dp->A = XMALLOC(1+len)) == NULL) goto cleanup1; + strncpy(dp->A, ltc_ecc_sets[i].A, 1+len); + /* b */ + len = (unsigned long)strlen(ltc_ecc_sets[i].B); + if ((dp->B = XMALLOC(1+len)) == NULL) goto cleanup2; + strncpy(dp->B, ltc_ecc_sets[i].B, 1+len); + /* order */ + len = (unsigned long)strlen(ltc_ecc_sets[i].order); + if ((dp->order = XMALLOC(1+len)) == NULL) goto cleanup3; + strncpy(dp->order, ltc_ecc_sets[i].order, 1+len); + /* prime */ + len = (unsigned long)strlen(ltc_ecc_sets[i].prime); + if ((dp->prime = XMALLOC(1+len)) == NULL) goto cleanup4; + strncpy(dp->prime, ltc_ecc_sets[i].prime, 1+len); + /* gx */ + len = (unsigned long)strlen(ltc_ecc_sets[i].Gx); + if ((dp->Gx = XMALLOC(1+len)) == NULL) goto cleanup5; + strncpy(dp->Gx, ltc_ecc_sets[i].Gx, 1+len); + /* gy */ + len = (unsigned long)strlen(ltc_ecc_sets[i].Gy); + if ((dp->Gy = XMALLOC(1+len)) == NULL) goto cleanup6; + strncpy(dp->Gy, ltc_ecc_sets[i].Gy, 1+len); + /* cofactor & size */ + dp->cofactor = ltc_ecc_sets[i].cofactor; + dp->size = ltc_ecc_sets[i].size; + /* name */ + len = (unsigned long)strlen(ltc_ecc_sets[i].name); + if ((dp->name = XMALLOC(1+len)) == NULL) goto cleanup7; + strncpy(dp->name, ltc_ecc_sets[i].name, 1+len); + /* oid */ + dp->oid.OIDlen = ltc_ecc_sets[i].oid.OIDlen; + XMEMCPY(dp->oid.OID, ltc_ecc_sets[i].oid.OID, dp->oid.OIDlen * sizeof(dp->oid.OID[0])); + /* done - success */ + return CRYPT_OK; + +cleanup7: + XFREE(dp->Gy); +cleanup6: + XFREE(dp->Gx); +cleanup5: + XFREE(dp->prime); +cleanup4: + XFREE(dp->order); +cleanup3: + XFREE(dp->B); +cleanup2: + XFREE(dp->A); +cleanup1: + return CRYPT_MEM; +} + +#endif diff --git a/src/ltc/pk/ecc/ecc_dp_from_params.c b/src/ltc/pk/ecc/ecc_dp_from_params.c new file mode 100644 index 0000000..fe38613 --- /dev/null +++ b/src/ltc/pk/ecc/ecc_dp_from_params.c @@ -0,0 +1,86 @@ +/* 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://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ + +#include "tomcrypt.h" + +#ifdef LTC_MECC + +int ecc_dp_set_bn(ltc_ecc_set_type *dp, void *a, void *b, void *prime, void *order, void *gx, void *gy, unsigned long cofactor) +{ + unsigned char buf[ECC_BUF_SIZE]; + unsigned long len; + + /* a */ + mp_tohex(a, (char *)buf); + len = (unsigned long)strlen((char *)buf); + if ((dp->A = XMALLOC(1+len)) == NULL) goto cleanup1; + strncpy(dp->A, (char*)buf, 1+len); + /* b */ + mp_tohex(b, (char *)buf); + len = (unsigned long)strlen((char *)buf); + if ((dp->B = XMALLOC(1+len)) == NULL) goto cleanup2; + strncpy(dp->B, (char*)buf, 1+len); + /* order */ + mp_tohex(order, (char *)buf); + len = (unsigned long)strlen((char *)buf); + if ((dp->order = XMALLOC(1+len)) == NULL) goto cleanup3; + strncpy(dp->order, (char*)buf, 1+len); + /* prime */ + mp_tohex(prime, (char *)buf); + len = (unsigned long)strlen((char *)buf); + if ((dp->prime = XMALLOC(1+len)) == NULL) goto cleanup4; + strncpy(dp->prime, (char*)buf, 1+len); + /* gx */ + mp_tohex(gx, (char *)buf); + len = (unsigned long)strlen((char *)buf); + if ((dp->Gx = XMALLOC(1+len)) == NULL) goto cleanup5; + strncpy(dp->Gx, (char*)buf, 1+len); + /* gy */ + mp_tohex(gy, (char *)buf); + len = (unsigned long)strlen((char *)buf); + if ((dp->Gy = XMALLOC(1+len)) == NULL) goto cleanup6; + strncpy(dp->Gy, (char*)buf, 1+len); + /* cofactor & size */ + dp->cofactor = cofactor; + dp->size = mp_unsigned_bin_size(prime); + /* see if we can fill in the missing parameters from known curves */ + if ((ecc_dp_fill_from_sets(dp)) != CRYPT_OK) { + /* custom name */ + if ((dp->name = XMALLOC(7)) == NULL) goto cleanup7; + strcpy(dp->name, "custom"); /* XXX-TODO check this */ + /* no oid */ + dp->oid.OIDlen = 0; + } + /* done - success */ + return CRYPT_OK; + + /* XFREE(dp->name); **** warning: statement not reached *** */ +cleanup7: + XFREE(dp->Gy); +cleanup6: + XFREE(dp->Gx); +cleanup5: + XFREE(dp->prime); +cleanup4: + XFREE(dp->order); +cleanup3: + XFREE(dp->B); +cleanup2: + XFREE(dp->A); +cleanup1: + return CRYPT_MEM; +} + +#endif diff --git a/src/ltc/pk/ecc/ecc_dp_init.c b/src/ltc/pk/ecc/ecc_dp_init.c new file mode 100644 index 0000000..36c8f5c --- /dev/null +++ b/src/ltc/pk/ecc/ecc_dp_init.c @@ -0,0 +1,36 @@ +/* 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. + * + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ + +#include "tomcrypt.h" + +#ifdef LTC_MECC + +int ecc_dp_init(ltc_ecc_set_type *dp) +{ + if (dp == NULL) return CRYPT_INVALID_ARG; + + dp->name = NULL; + dp->prime = NULL; + dp->A = NULL; + dp->B = NULL; + dp->order = NULL; + dp->Gx = NULL; + dp->Gy = NULL; + dp->oid.OIDlen = 0; + dp->cofactor = 0; + + return CRYPT_OK; +} + +#endif diff --git a/src/ltc/pk/ecc/ecc_dp_set.c b/src/ltc/pk/ecc/ecc_dp_set.c new file mode 100644 index 0000000..33c7281 --- /dev/null +++ b/src/ltc/pk/ecc/ecc_dp_set.c @@ -0,0 +1,100 @@ +/* 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. + * + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ + +#include "tomcrypt.h" +#include + +#ifdef LTC_MECC + +int ecc_dp_set(ltc_ecc_set_type *dp, char *ch_prime, char *ch_A, char *ch_B, char *ch_order, char *ch_Gx, char *ch_Gy, unsigned long cofactor, char *ch_name, char *oid) +{ + unsigned long l_name, l_prime, l_A, l_B, l_order, l_Gx, l_Gy; + + if (!dp || !ch_prime || !ch_A || !ch_B || !ch_order || !ch_Gx || !ch_Gy || cofactor==0) return CRYPT_INVALID_ARG; + + l_prime = (unsigned long)strlen(ch_prime); + l_A = (unsigned long)strlen(ch_A); + l_B = (unsigned long)strlen(ch_B); + l_order = (unsigned long)strlen(ch_order); + l_Gx = (unsigned long)strlen(ch_Gx); + l_Gy = (unsigned long)strlen(ch_Gy); + + dp->cofactor = cofactor; + + { /* calculate size */ + void *p_num; + mp_init(&p_num); + mp_read_radix(p_num, ch_prime, 16); + dp->size = mp_unsigned_bin_size(p_num); + mp_clear(p_num); + } + + if (dp->name != NULL) { XFREE(dp->name ); dp->name = NULL; } + if (dp->prime != NULL) { XFREE(dp->prime); dp->prime = NULL; } + if (dp->A != NULL) { XFREE(dp->A ); dp->A = NULL; } + if (dp->B != NULL) { XFREE(dp->B ); dp->B = NULL; } + if (dp->order != NULL) { XFREE(dp->order); dp->order = NULL; } + if (dp->Gx != NULL) { XFREE(dp->Gx ); dp->Gx = NULL; } + if (dp->Gy != NULL) { XFREE(dp->Gy ); dp->Gy = NULL; } + + dp->prime = XMALLOC(1+l_prime); strncpy(dp->prime, ch_prime, 1+l_prime); + dp->A = XMALLOC(1+l_A); strncpy(dp->A, ch_A, 1+l_A); + dp->B = XMALLOC(1+l_B); strncpy(dp->B, ch_B, 1+l_B); + dp->order = XMALLOC(1+l_order); strncpy(dp->order, ch_order, 1+l_order); + dp->Gx = XMALLOC(1+l_Gx); strncpy(dp->Gx, ch_Gx, 1+l_Gx); + dp->Gy = XMALLOC(1+l_Gy); strncpy(dp->Gy, ch_Gy, 1+l_Gy); + + /* optional parameters */ + if (ch_name == NULL && oid == NULL) { + (void)ecc_dp_fill_from_sets(dp); + } + else { + if (ch_name != NULL) { + l_name = (unsigned long)strlen(ch_name); + dp->name = XMALLOC(1+l_name); + strncpy(dp->name, ch_name, 1+l_name); + } + + if (oid != NULL) { + char *end_ptr; + unsigned int i = 0; + unsigned long val; + + end_ptr = oid; + while (i < sizeof(dp->oid.OID)/sizeof(dp->oid.OID[0]) && *oid != '\0') { + errno = 0; + val = strtoul(oid, &end_ptr, 10); + if (errno != 0 || oid == end_ptr) break; /* parsing failed */ + if (val > 0xFFFFFFFF) break; /* x64 check */ + dp->oid.OID[i++] = val; + oid = end_ptr; + if (*oid != '.') break; + oid++; + } + if (i == 0 || *end_ptr != '\0') return CRYPT_INVALID_ARG; + dp->oid.OIDlen = i; + } + } + + /* in case the parameters are really custom (unlikely) */ + if (dp->name == NULL) { + dp->name = XMALLOC(7); + strcpy(dp->name, "custom"); + dp->oid.OIDlen = 0; + } + + return CRYPT_OK; +} + +#endif diff --git a/src/ltc/pk/ecc/ecc_encrypt_key.c b/src/ltc/pk/ecc/ecc_encrypt_key.c new file mode 100644 index 0000000..2b94401 --- /dev/null +++ b/src/ltc/pk/ecc/ecc_encrypt_key.c @@ -0,0 +1,134 @@ +/* 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://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ +#include "tomcrypt.h" + +/** + @file ecc_encrypt_key.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/** + Encrypt a symmetric key with ECC + @param in The symmetric key you want to encrypt + @param inlen The length of the key to encrypt (octets) + @param out [out] The destination for the ciphertext + @param outlen [in/out] The max size and resulting size of the ciphertext + @param prng An active PRNG state + @param wprng The index of the PRNG you wish to use + @param hash The index of the hash you want to use + @param key The ECC key you want to encrypt to + @return CRYPT_OK if successful +*/ +int ecc_encrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, int hash, + ecc_key *key) +{ + unsigned char *pub_expt, *ecc_shared, *skey; + ecc_key pubkey; + unsigned long x, y, pubkeysize; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* check that wprng/cipher/hash are not invalid */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + if (inlen > hash_descriptor[hash].hashsize) { + return CRYPT_INVALID_HASH; + } + + /* make a random key and export the public copy */ + if ((err = ecc_make_key_ex(prng, wprng, &pubkey, key->dp)) != CRYPT_OK) { + return err; + } + + pub_expt = XMALLOC(ECC_BUF_SIZE); + ecc_shared = XMALLOC(ECC_BUF_SIZE); + skey = XMALLOC(MAXBLOCKSIZE); + if (pub_expt == NULL || ecc_shared == NULL || skey == NULL) { + if (pub_expt != NULL) { + XFREE(pub_expt); + } + if (ecc_shared != NULL) { + XFREE(ecc_shared); + } + if (skey != NULL) { + XFREE(skey); + } + ecc_free(&pubkey); + return CRYPT_MEM; + } + + pubkeysize = ECC_BUF_SIZE; + if ((err = ecc_export_raw(pub_expt, &pubkeysize, PK_PUBLIC_COMPRESSED, &pubkey)) != CRYPT_OK) { + ecc_free(&pubkey); + goto LBL_ERR; + } + + /* make random key */ + x = ECC_BUF_SIZE; + if ((err = ecc_shared_secret(&pubkey, key, ecc_shared, &x)) != CRYPT_OK) { + ecc_free(&pubkey); + goto LBL_ERR; + } + ecc_free(&pubkey); + y = MAXBLOCKSIZE; + if ((err = hash_memory(hash, ecc_shared, x, skey, &y)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* Encrypt key */ + for (x = 0; x < inlen; x++) { + skey[x] ^= in[x]; + } + + err = der_encode_sequence_multi(out, outlen, + LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash].OIDlen, hash_descriptor[hash].OID, + LTC_ASN1_OCTET_STRING, pubkeysize, pub_expt, + LTC_ASN1_OCTET_STRING, inlen, skey, + LTC_ASN1_EOL, 0UL, NULL); + +LBL_ERR: +#ifdef LTC_CLEAN_STACK + /* clean up */ + zeromem(pub_expt, ECC_BUF_SIZE); + zeromem(ecc_shared, ECC_BUF_SIZE); + zeromem(skey, MAXBLOCKSIZE); +#endif + + XFREE(skey); + XFREE(ecc_shared); + XFREE(pub_expt); + + return err; +} + +#endif +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ + diff --git a/src/ltc/pk/ecc/ecc_export.c b/src/ltc/pk/ecc/ecc_export.c new file mode 100644 index 0000000..49bb583 --- /dev/null +++ b/src/ltc/pk/ecc/ecc_export.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://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ +#include "tomcrypt.h" + +/** + @file ecc_export.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/** + Export an ECC key as a binary packet + @param out [out] Destination for the key + @param outlen [in/out] Max size and resulting size of the exported key + @param type The type of key you want to export (PK_PRIVATE or PK_PUBLIC) + @param key The key to export + @return CRYPT_OK if successful +*/ +int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key) +{ + int err; + unsigned char flags[1]; + unsigned long key_size; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* type valid? */ + if (key->type != PK_PRIVATE && type == PK_PRIVATE) { + return CRYPT_PK_TYPE_MISMATCH; + } + + if (ltc_ecc_is_valid_idx(key->idx) == 0) { + return CRYPT_INVALID_ARG; + } + + /* we store the NIST byte size */ + key_size = key->dp->size; + + if (type == PK_PRIVATE) { + flags[0] = 1; + err = der_encode_sequence_multi(out, outlen, + LTC_ASN1_BIT_STRING, 1UL, flags, + LTC_ASN1_SHORT_INTEGER, 1UL, &key_size, + LTC_ASN1_INTEGER, 1UL, key->pubkey.x, + LTC_ASN1_INTEGER, 1UL, key->pubkey.y, + LTC_ASN1_INTEGER, 1UL, key->k, + LTC_ASN1_EOL, 0UL, NULL); + } else { + flags[0] = 0; + err = der_encode_sequence_multi(out, outlen, + LTC_ASN1_BIT_STRING, 1UL, flags, + LTC_ASN1_SHORT_INTEGER, 1UL, &key_size, + LTC_ASN1_INTEGER, 1UL, key->pubkey.x, + LTC_ASN1_INTEGER, 1UL, key->pubkey.y, + LTC_ASN1_EOL, 0UL, NULL); + } + + return err; +} + +#endif +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ + diff --git a/src/ltc/pk/ecc/ecc_export_full.c b/src/ltc/pk/ecc/ecc_export_full.c new file mode 100644 index 0000000..6a9fe43 --- /dev/null +++ b/src/ltc/pk/ecc/ecc_export_full.c @@ -0,0 +1,182 @@ +/* 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. + * + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ + +#include "tomcrypt.h" + +#ifdef LTC_MECC + +/** + Export an ECC key as a binary packet + @param out [out] Destination for the key + @param outlen [in/out] Max size and resulting size of the exported key + @param type The type of key you want to export (PK_PRIVATE or PK_PUBLIC) + @param key The key to export + @return CRYPT_OK if successful +*/ + +int ecc_export_full(unsigned char *out, unsigned long *outlen, int type, ecc_key *key) +{ + int err; + void *prime, *order, *a, *b, *gx, *gy; + unsigned char bin_a[256], bin_b[256], bin_k[256], bin_g[512], bin_xy[512]; + unsigned long len_a, len_b, len_k, len_g, len_xy; + unsigned long cofactor, one = 1; + oid_st oid; + ltc_asn1_list seq_fieldid[2], seq_curve[2], seq_ecparams[6], seq_priv[4], asn_ecparams[1]; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + if (key->type != PK_PRIVATE && type == PK_PRIVATE) return CRYPT_PK_TYPE_MISMATCH; + if (ltc_ecc_is_valid_idx(key->idx) == 0) return CRYPT_INVALID_ARG; + if (key->dp == NULL) return CRYPT_INVALID_ARG; + + if ((err = mp_init_multi(&prime, &order, &a, &b, &gx, &gy, NULL)) != CRYPT_OK) return err; + + if ((err = mp_read_radix(prime, key->dp->prime, 16)) != CRYPT_OK) goto error; + if ((err = mp_read_radix(order, key->dp->order, 16)) != CRYPT_OK) goto error; + if ((err = mp_read_radix(b, key->dp->B, 16)) != CRYPT_OK) goto error; + if ((err = mp_read_radix(a, key->dp->A, 16)) != CRYPT_OK) goto error; + if ((err = mp_read_radix(gx, key->dp->Gx, 16)) != CRYPT_OK) goto error; + if ((err = mp_read_radix(gy, key->dp->Gy, 16)) != CRYPT_OK) goto error; + + /* curve param a */ + len_a = mp_unsigned_bin_size(a); + if (len_a > sizeof(bin_a)) { err = CRYPT_BUFFER_OVERFLOW; goto error; } + if ((err = mp_to_unsigned_bin(a, bin_a)) != CRYPT_OK) goto error; + if (len_a == 0) { len_a = 1; bin_a[0] = 0; } /* XXX-TODO hack to handle case a == 0 */ + + /* curve param b */ + len_b = mp_unsigned_bin_size(b); + if (len_b > sizeof(bin_b)) { err = CRYPT_BUFFER_OVERFLOW; goto error; } + if ((err = mp_to_unsigned_bin(b, bin_b)) != CRYPT_OK) goto error; + if (len_b == 0) { len_b = 1; bin_b[0] = 0; } /* XXX-TODO hack to handle case b == 0 */ + + /* base point - we export uncompressed form */ + len_g = sizeof(bin_g); + if ((err = ltc_ecc_export_point(bin_g, &len_g, gx, gy, key->dp->size, 0)) != CRYPT_OK) goto error; + + /* public key */ + len_xy = sizeof(bin_xy); + if ((err = ltc_ecc_export_point(bin_xy, &len_xy, key->pubkey.x, key->pubkey.y, key->dp->size, 0)) != CRYPT_OK) goto error; + + /* co-factor */ + cofactor = key->dp->cofactor; + + /* we support only prime-field EC */ + if ((err = pk_get_oid(EC_PRIME_FIELD, &oid)) != CRYPT_OK) goto error; + + if (type & PK_CURVEOID) { + /* from http://tools.ietf.org/html/rfc5912 + + ECParameters ::= CHOICE { + namedCurve CURVE.&id({NamedCurve}) # OBJECT + } + */ + + /* BEWARE: exporting PK_CURVEOID with custom OID means we're unable to read the curve again */ + if (key->dp->oid.OIDlen == 0) { err = CRYPT_INVALID_ARG; goto error; } + + /* ECParameters used by ECPrivateKey or SubjectPublicKeyInfo below */ + LTC_SET_ASN1(asn_ecparams, 0, LTC_ASN1_OBJECT_IDENTIFIER, key->dp->oid.OID, key->dp->oid.OIDlen); + type &= ~PK_CURVEOID; + } + else { + /* from http://tools.ietf.org/html/rfc3279 + + ECParameters ::= SEQUENCE { # SEQUENCE + version INTEGER { ecpVer1(1) } (ecpVer1), # INTEGER :01 + FieldID ::= SEQUENCE { # SEQUENCE + fieldType FIELD-ID.&id({IOSet}), # OBJECT :prime-field + parameters FIELD-ID.&Type({IOSet}{@fieldType}) # INTEGER + } + Curve ::= SEQUENCE { # SEQUENCE + a FieldElement ::= OCTET STRING # OCTET STRING + b FieldElement ::= OCTET STRING # OCTET STRING + seed BIT STRING OPTIONAL + } + base ECPoint ::= OCTET STRING # OCTET STRING + order INTEGER, # INTEGER + cofactor INTEGER OPTIONAL # INTEGER + } + */ + + /* FieldID SEQUENCE */ + LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid.OID, oid.OIDlen); + LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL); + + /* Curve SEQUENCE */ + LTC_SET_ASN1(seq_curve, 0, LTC_ASN1_OCTET_STRING, bin_a, len_a); + LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, len_b); + + /* ECParameters SEQUENCE */ + LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &one, 1UL); + LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL); + LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 2UL); + LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, len_g); + LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL); + LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL); + + /* ECParameters used by ECPrivateKey or SubjectPublicKeyInfo below */ + LTC_SET_ASN1(asn_ecparams, 0, LTC_ASN1_SEQUENCE, seq_ecparams, 6UL); + } + + if (type == PK_PRIVATE) { + /* private key format: http://tools.ietf.org/html/rfc5915 + + ECPrivateKey ::= SEQUENCE { # SEQUENCE + version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), # INTEGER :01 + privateKey OCTET STRING, # OCTET STRING + [0] ECParameters # see above + [1] publicKey # BIT STRING + } + */ + + /* private key */ + len_k = mp_unsigned_bin_size(key->k); + if (len_k > sizeof(bin_k)) { err = CRYPT_BUFFER_OVERFLOW; goto error; } + if ((err = mp_to_unsigned_bin(key->k, bin_k)) != CRYPT_OK) goto error; + + LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &one, 1UL); + LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, len_k); + LTC_SET_ASN1(seq_priv, 2, asn_ecparams[0].type, asn_ecparams[0].data, asn_ecparams[0].size); + LTC_SET_ASN1(seq_priv, 3, LTC_ASN1_RAW_BIT_STRING, bin_xy, 8*len_xy); + seq_priv[2].tag = 0xA0; + seq_priv[3].tag = 0xA1; + + err = der_encode_sequence(seq_priv, 4, out, outlen); + } + else { + /* public key format: http://tools.ietf.org/html/rfc5480 + + SubjectPublicKeyInfo ::= SEQUENCE { # SEQUENCE + AlgorithmIdentifier ::= SEQUENCE { # SEQUENCE + algorithm OBJECT IDENTIFIER # OBJECT :id-ecPublicKey + ECParameters # see above + } + subjectPublicKey BIT STRING # BIT STRING + } + */ + err = der_encode_subject_public_key_info( out, outlen, + PKA_EC, bin_xy, len_xy, + asn_ecparams[0].type, asn_ecparams[0].data, asn_ecparams[0].size ); + } + +error: + mp_clear_multi(prime, order, a, b, gx, gy, NULL); + return err; +} + +#endif diff --git a/src/ltc/pk/ecc/ecc_export_raw.c b/src/ltc/pk/ecc/ecc_export_raw.c new file mode 100644 index 0000000..5206290 --- /dev/null +++ b/src/ltc/pk/ecc/ecc_export_raw.c @@ -0,0 +1,63 @@ +/* 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. + * + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ + +#include "tomcrypt.h" + +#ifdef LTC_MECC + +/** Export raw public or private key (public keys = ANS X9.63 compressed or uncompressed; private keys = raw bytes) + @param out [out] destination of export + @param outlen [in/out] Length of destination and final output size + @param type PK_PRIVATE, PK_PUBLIC or PK_PUBLIC_COMPRESSED + @param key Key to export + Return CRYPT_OK on success +*/ + +int ecc_export_raw(unsigned char *out, unsigned long *outlen, int type, ecc_key *key) +{ + unsigned long size, ksize; + int err; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + if (ltc_ecc_is_valid_idx(key->idx) == 0) { + return CRYPT_INVALID_ARG; + } + size = key->dp->size; + + if (type == PK_PUBLIC_COMPRESSED) { + if ((err = ltc_ecc_export_point(out, outlen, key->pubkey.x, key->pubkey.y, size, 1)) != CRYPT_OK) return err; + } + else if (type == PK_PUBLIC) { + if ((err = ltc_ecc_export_point(out, outlen, key->pubkey.x, key->pubkey.y, size, 0)) != CRYPT_OK) return err; + } + else if (type == PK_PRIVATE) { + if (key->type != PK_PRIVATE) return CRYPT_PK_TYPE_MISMATCH; + *outlen = size; + if (size > *outlen) return CRYPT_BUFFER_OVERFLOW; + if ((ksize = mp_unsigned_bin_size(key->k)) > size) return CRYPT_BUFFER_OVERFLOW; + /* pad and store k */ + if ((err = mp_to_unsigned_bin(key->k, out + (size - ksize))) != CRYPT_OK) return err; + zeromem(out, size - ksize); + } + else { + return CRYPT_INVALID_ARG; + } + + return CRYPT_OK; +} + +#endif diff --git a/src/ltc/pk/ecc/ecc_free.c b/src/ltc/pk/ecc/ecc_free.c new file mode 100644 index 0000000..358c7fe --- /dev/null +++ b/src/ltc/pk/ecc/ecc_free.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://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ +#include "tomcrypt.h" + +/** + @file ecc_free.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/** + Free an ECC key from memory + @param key The key you wish to free +*/ +void ecc_free(ecc_key *key) +{ + LTC_ARGCHKVD(key != NULL); + mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL); +} + +#endif +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ + diff --git a/src/ltc/pk/ecc/ecc_get_size.c b/src/ltc/pk/ecc/ecc_get_size.c new file mode 100644 index 0000000..6f24c4e --- /dev/null +++ b/src/ltc/pk/ecc/ecc_get_size.c @@ -0,0 +1,42 @@ +/* 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://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ +#include "tomcrypt.h" + +/** + @file ecc_get_size.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/** + Get the size of an ECC key + @param key The key to get the size of + @return The size (octets) of the key or INT_MAX on error +*/ +int ecc_get_size(ecc_key *key) +{ + LTC_ARGCHK(key != NULL); + if (ltc_ecc_is_valid_idx(key->idx)) + return key->dp->size; + else + return INT_MAX; /* large value known to cause it to fail when passed to ecc_make_key() */ +} + +#endif +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ + diff --git a/src/ltc/pk/ecc/ecc_import.c b/src/ltc/pk/ecc/ecc_import.c new file mode 100644 index 0000000..95cb7e2 --- /dev/null +++ b/src/ltc/pk/ecc/ecc_import.c @@ -0,0 +1,126 @@ +/* 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://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ +#include "tomcrypt.h" + +/** + @file ecc_import.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/** + Import an ECC key from a binary packet + @param in The packet to import + @param inlen The length of the packet + @param key [out] The destination of the import + @return CRYPT_OK if successful, upon error all allocated memory will be freed +*/ +int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key) +{ + return ecc_import_ex(in, inlen, key, NULL); +} + +/** + Import an ECC key from a binary packet, using user supplied domain params rather than one of the NIST ones + @param in The packet to import + @param inlen The length of the packet + @param key [out] The destination of the import + @param dp pointer to user supplied params; must be the same as the params used when exporting + @return CRYPT_OK if successful, upon error all allocated memory will be freed +*/ +int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp) +{ + unsigned long key_size; + unsigned char flags[1]; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(ltc_mp.name != NULL); + + /* init key */ + if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL) != CRYPT_OK) { + return CRYPT_MEM; + } + + /* find out what type of key it is */ + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_BIT_STRING, 1UL, &flags, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto done; + } + + + if (flags[0] == 1) { + /* private key */ + key->type = PK_PRIVATE; + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_BIT_STRING, 1UL, flags, + LTC_ASN1_SHORT_INTEGER, 1UL, &key_size, + LTC_ASN1_INTEGER, 1UL, key->pubkey.x, + LTC_ASN1_INTEGER, 1UL, key->pubkey.y, + LTC_ASN1_INTEGER, 1UL, key->k, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto done; + } + } else { + /* public key */ + key->type = PK_PUBLIC; + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_BIT_STRING, 1UL, flags, + LTC_ASN1_SHORT_INTEGER, 1UL, &key_size, + LTC_ASN1_INTEGER, 1UL, key->pubkey.x, + LTC_ASN1_INTEGER, 1UL, key->pubkey.y, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto done; + } + } + + if (dp == NULL) { + /* BEWARE: Here we are looking up the curve params by keysize (neither curve name nor curve oid), + * which might be ambiguous (there can more than one curve for given keysize). + * Thus the chosen curve depends on order of items in ltc_ecc_sets[] - see ecc.c file. + */ + /* find the idx */ + for (key->idx = 0; ltc_ecc_sets[key->idx].size && (unsigned long)ltc_ecc_sets[key->idx].size != key_size; ++key->idx); + if (ltc_ecc_sets[key->idx].size == 0) { + err = CRYPT_INVALID_PACKET; + goto done; + } + key->dp = <c_ecc_sets[key->idx]; + } else { + key->idx = -1; + key->dp = dp; + } + /* set z */ + if ((err = mp_set(key->pubkey.z, 1)) != CRYPT_OK) { goto done; } + + /* is it a point on the curve? */ + if ((err = ltc_ecc_is_point(key->dp, key->pubkey.x, key->pubkey.y)) != CRYPT_OK) { + goto done; + } + + /* we're good */ + return CRYPT_OK; +done: + mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL); + return err; +} +#endif +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ + diff --git a/src/ltc/pk/ecc/ecc_import_full.c b/src/ltc/pk/ecc/ecc_import_full.c new file mode 100644 index 0000000..9c18f7a --- /dev/null +++ b/src/ltc/pk/ecc/ecc_import_full.c @@ -0,0 +1,154 @@ +/* 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://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ + +#include "tomcrypt.h" + +#ifdef LTC_MECC + +int ecc_import_full(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp) +{ + void *prime, *order, *a, *b, *gx, *gy; + ltc_asn1_list seq_fieldid[2], seq_curve[3], seq_ecparams[6], seq_priv[4]; + unsigned char bin_a[ECC_MAXSIZE], bin_b[ECC_MAXSIZE], bin_k[ECC_MAXSIZE], bin_g[2*ECC_MAXSIZE+1], bin_xy[2*ECC_MAXSIZE+2], bin_seed[128]; + unsigned long len_a, len_b, len_k, len_g, len_xy, len_oid; + unsigned long cofactor = 0, ecver = 0, pkver = 0, tmpoid[16], curveoid[16]; + int err; + + if ((err = mp_init_multi(&prime, &order, &a, &b, &gx, &gy, NULL)) != CRYPT_OK) return err; + + /* ### 1. try to load public key - no curve parameters just curve OID */ + + len_xy = sizeof(bin_xy); + err = der_decode_subject_public_key_info_ex(in, inlen, PKA_EC, bin_xy, &len_xy, LTC_ASN1_OBJECT_IDENTIFIER, curveoid, 16UL, &len_oid); + if (err == CRYPT_OK) { + /* load curve parameters for given curve OID */ + if ((err = ecc_dp_set_by_oid(dp, curveoid, len_oid)) != CRYPT_OK) { goto error; } + /* load public key */ + if ((err = ecc_import_raw(bin_xy, len_xy, key, dp)) != CRYPT_OK) { goto error; } + goto success; + } + + /* ### 2. try to load public key - curve parameters included */ + + /* ECParameters SEQUENCE */ + LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &ecver, 1UL); + LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL); + LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 3UL); + LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, (unsigned long)2*ECC_MAXSIZE+1); + LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL); + LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL); + seq_ecparams[5].optional = 1; + /* FieldID SEQUENCE */ + LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, 16UL); + LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL); + /* Curve SEQUENCE */ + LTC_SET_ASN1(seq_curve, 0, LTC_ASN1_OCTET_STRING, bin_a, (unsigned long)ECC_MAXSIZE); + LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, (unsigned long)ECC_MAXSIZE); + LTC_SET_ASN1(seq_curve, 2, LTC_ASN1_RAW_BIT_STRING, bin_seed, (unsigned long)8*128); + seq_curve[2].optional = 1; + /* try to load public key */ + len_xy = sizeof(bin_xy); + err = der_decode_subject_public_key_info(in, inlen, PKA_EC, bin_xy, &len_xy, LTC_ASN1_SEQUENCE, seq_ecparams, 6); + + if (err == CRYPT_OK) { + len_a = seq_curve[0].size; + len_b = seq_curve[1].size; + len_g = seq_ecparams[3].size; + /* create bignums */ + if ((err = mp_read_unsigned_bin(a, bin_a, len_a)) != CRYPT_OK) { goto error; } + if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto error; } + if ((err = ltc_ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto error; } + /* load curve parameters */ + if ((err = ecc_dp_set_bn(dp, a, b, prime, order, gx, gy, cofactor)) != CRYPT_OK) { goto error; } + /* load public key */ + if ((err = ecc_import_raw(bin_xy, len_xy, key, dp)) != CRYPT_OK) { goto error; } + goto success; + } + + /* ### 3. try to load private key - no curve parameters just curve OID */ + + /* ECPrivateKey SEQUENCE */ + LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &pkver, 1UL); + LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, (unsigned long)ECC_MAXSIZE); + LTC_SET_ASN1(seq_priv, 2, LTC_ASN1_OBJECT_IDENTIFIER, curveoid, 16UL); + LTC_SET_ASN1(seq_priv, 3, LTC_ASN1_RAW_BIT_STRING, bin_xy, (unsigned long)8*(2*ECC_MAXSIZE+2)); + seq_priv[2].tag = 0xA0; /* context specific 0 */ + seq_priv[3].tag = 0xA1; /* context specific 1 */ + /* try to load private key */ + err = der_decode_sequence(in, inlen, seq_priv, 4); + + if (err == CRYPT_OK) { + /* load curve parameters for given curve OID */ + if ((err = ecc_dp_set_by_oid(dp, curveoid, seq_priv[2].size)) != CRYPT_OK) { goto error; } + /* load private+public key */ + if ((err = ecc_import_raw(bin_k, seq_priv[1].size, key, dp)) != CRYPT_OK) { goto error; } + goto success; + } + + /* ### 4. try to load private key - curve parameters included */ + + /* ECPrivateKey SEQUENCE */ + LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &pkver, 1UL); + LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, (unsigned long)ECC_MAXSIZE); + LTC_SET_ASN1(seq_priv, 2, LTC_ASN1_SEQUENCE, seq_ecparams, 6UL); + LTC_SET_ASN1(seq_priv, 3, LTC_ASN1_RAW_BIT_STRING, bin_xy, (unsigned long)8*(2*ECC_MAXSIZE+2)); + seq_priv[2].tag = 0xA0; /* context specific 0 */ + seq_priv[3].tag = 0xA1; /* context specific 1 */ + /* ECParameters SEQUENCE */ + LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &ecver, 1UL); + LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL); + LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 3UL); + LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, (unsigned long)2*ECC_MAXSIZE+1); + LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL); + LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL); + seq_ecparams[5].optional = 1; + /* FieldID SEQUENCE */ + LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, 16UL); + LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL); + /* Curve SEQUENCE */ + LTC_SET_ASN1(seq_curve, 0, LTC_ASN1_OCTET_STRING, bin_a, (unsigned long)ECC_MAXSIZE); + LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, (unsigned long)ECC_MAXSIZE); + LTC_SET_ASN1(seq_curve, 2, LTC_ASN1_RAW_BIT_STRING, bin_seed, (unsigned long)8*128); + seq_curve[2].optional = 1; + /* try to load private key */ + err = der_decode_sequence(in, inlen, seq_priv, 4); + if (err == CRYPT_OK) { + len_k = seq_priv[1].size; + len_xy = seq_priv[3].size; + len_a = seq_curve[0].size; + len_b = seq_curve[1].size; + len_g = seq_ecparams[3].size; + /* create bignums */ + if ((err = mp_read_unsigned_bin(a, bin_a, len_a)) != CRYPT_OK) { goto error; } + if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto error; } + if ((err = ltc_ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto error; } + /* load curve parameters */ + if ((err = ecc_dp_set_bn(dp, a, b, prime, order, gx, gy, cofactor)) != CRYPT_OK) { goto error; } + /* load private+public key */ + if ((err = ecc_import_raw(bin_k, len_k, key, dp)) != CRYPT_OK) { goto error; } + goto success; + } + + /* ### 5. backward compatibility - try to load old-DER format */ + if ((err = ecc_import(in, inlen, key)) != CRYPT_OK) { goto error; } + +success: + err = CRYPT_OK; +error: + mp_clear_multi(prime, order, a, b, gx, gy, NULL); + return err; +} + +#endif diff --git a/src/ltc/pk/ecc/ecc_import_pkcs8.c b/src/ltc/pk/ecc/ecc_import_pkcs8.c new file mode 100644 index 0000000..8322859 --- /dev/null +++ b/src/ltc/pk/ecc/ecc_import_pkcs8.c @@ -0,0 +1,161 @@ +/* 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://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ + +#include "tomcrypt.h" + +#ifdef LTC_MECC + +int ecc_import_pkcs8(const unsigned char *in, unsigned long inlen, + const void *pwd, unsigned long pwdlen, + ecc_key *key, ltc_ecc_set_type *dp) +{ + int err; + void *zero, *one, *iter; + unsigned char *buf1=NULL, *buf2=NULL; + unsigned long buf1len, buf2len; + unsigned long oid[16]; + oid_st ecoid; + ltc_asn1_list alg_seq[2], top_seq[3]; + ltc_asn1_list alg_seq_e[2], key_seq_e[2], top_seq_e[2]; + unsigned char *decrypted=NULL; + unsigned long decryptedlen; + void *prime, *order, *a, *b, *gx, *gy; + ltc_asn1_list seq_fieldid[2], seq_curve[3], seq_ecparams[6], seq_priv[4]; + unsigned char bin_a[ECC_MAXSIZE], bin_b[ECC_MAXSIZE], bin_k[ECC_MAXSIZE], bin_g[2*ECC_MAXSIZE+1], bin_xy[2*ECC_MAXSIZE+2], bin_seed[128]; + unsigned long len_a, len_b, len_g; + unsigned long cofactor = 0, ecver = 0, tmpoid[16], curveoid[16]; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(ltc_mp.name != NULL); + + /* get EC alg oid */ + err = pk_get_oid(PKA_EC, &ecoid); + if (err != CRYPT_OK) { goto LBL_NOFREE; } + + /* alloc buffers */ + buf1len = inlen; /* approx. guess */ + buf1 = XMALLOC(buf1len); + if (buf1 == NULL) { err = CRYPT_MEM; goto LBL_NOFREE; } + buf2len = inlen; /* approx. guess */ + buf2 = XMALLOC(buf2len); + if (buf2 == NULL) { err = CRYPT_MEM; goto LBL_FREE; } + + /* init key */ + err = mp_init_multi(&prime, &order, &a, &b, &gx, &gy, &zero, &one, &iter, NULL); + if (err != CRYPT_OK) { goto LBL_NOCLEAR; } + + /* try to decode encrypted priv key */ + LTC_SET_ASN1(key_seq_e, 0, LTC_ASN1_OCTET_STRING, buf1, buf1len); + LTC_SET_ASN1(key_seq_e, 1, LTC_ASN1_INTEGER, iter, 1UL); + LTC_SET_ASN1(alg_seq_e, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, 16UL); + LTC_SET_ASN1(alg_seq_e, 1, LTC_ASN1_SEQUENCE, key_seq_e, 2UL); + LTC_SET_ASN1(top_seq_e, 0, LTC_ASN1_SEQUENCE, alg_seq_e, 2UL); + LTC_SET_ASN1(top_seq_e, 1, LTC_ASN1_OCTET_STRING, buf2, buf2len); + err=der_decode_sequence(in, inlen, top_seq_e, 2UL); + if (err == CRYPT_OK) { + LTC_UNUSED_PARAM(pwd); + LTC_UNUSED_PARAM(pwdlen); + /* unsigned long icount = mp_get_int(iter); */ + /* XXX: TODO decrypt buf1 with a key derived form password + salt + iter */ + /* fprintf(stderr, "XXX-DEBUG: gonna decrypt: iter=%ld salt.len=%ld encdata.len=%ld\n", icount, key_seq_e[0].size, top_seq_e[1].size); */ + err = CRYPT_PK_INVALID_TYPE; + goto LBL_ERR; + } + else { + decrypted = (unsigned char*)in; + decryptedlen = inlen; + } + + /* try to decode unencrypted priv key - curve defined by OID */ + LTC_SET_ASN1(alg_seq, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, 16UL); + LTC_SET_ASN1(alg_seq, 1, LTC_ASN1_OBJECT_IDENTIFIER, curveoid, 16UL); + LTC_SET_ASN1(top_seq, 0, LTC_ASN1_INTEGER, zero, 1UL); + LTC_SET_ASN1(top_seq, 1, LTC_ASN1_SEQUENCE, alg_seq, 2UL); + LTC_SET_ASN1(top_seq, 2, LTC_ASN1_OCTET_STRING, buf1, buf1len); + err=der_decode_sequence(decrypted, decryptedlen, top_seq, 3UL); + if (err == CRYPT_OK) { + /* load curve parameters for given curve OID */ + err = ecc_dp_set_by_oid(dp, curveoid, alg_seq[1].size); + if (err != CRYPT_OK) { goto LBL_ERR; } + } + else { + /* try to decode unencrypted priv key - curve defined by params */ + /* ECParameters SEQUENCE */ + LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &ecver, 1UL); + LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL); + LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 3UL); + LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, (unsigned long)2*ECC_MAXSIZE+1); + LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL); + LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL); + seq_ecparams[5].optional = 1; + /* FieldID SEQUENCE */ + LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, 16UL); + LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL); + /* Curve SEQUENCE */ + LTC_SET_ASN1(seq_curve, 0, LTC_ASN1_OCTET_STRING, bin_a, (unsigned long)ECC_MAXSIZE); + LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, (unsigned long)ECC_MAXSIZE); + LTC_SET_ASN1(seq_curve, 2, LTC_ASN1_RAW_BIT_STRING, bin_seed, (unsigned long)8*128); + /* */ + LTC_SET_ASN1(alg_seq, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, 16UL); + LTC_SET_ASN1(alg_seq, 1, LTC_ASN1_SEQUENCE, seq_ecparams, 6UL); + LTC_SET_ASN1(top_seq, 0, LTC_ASN1_INTEGER, zero, 1UL); + LTC_SET_ASN1(top_seq, 1, LTC_ASN1_SEQUENCE, alg_seq, 2UL); + LTC_SET_ASN1(top_seq, 2, LTC_ASN1_OCTET_STRING, buf1, buf1len); + seq_curve[2].optional = 1; + err=der_decode_sequence(decrypted, decryptedlen, top_seq, 3UL); + if (err != CRYPT_OK) { goto LBL_ERR; } + len_a = seq_curve[0].size; + len_b = seq_curve[1].size; + len_g = seq_ecparams[3].size; + /* create bignums */ + if ((err = mp_read_unsigned_bin(a, bin_a, len_a)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = ltc_ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto LBL_ERR; } + /* load curve parameters */ + if ((err = ecc_dp_set_bn(dp, a, b, prime, order, gx, gy, cofactor)) != CRYPT_OK) { goto LBL_ERR; } + } + + /* check alg oid */ + if ((alg_seq[0].size != ecoid.OIDlen) || + XMEMCMP(ecoid.OID, alg_seq[0].data, ecoid.OIDlen * sizeof(ecoid.OID[0]))) { + err = CRYPT_PK_INVALID_TYPE; + goto LBL_ERR; + } + + /* ECPrivateKey SEQUENCE */ + LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &one, 1UL); + LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, (unsigned long)ECC_MAXSIZE); + LTC_SET_ASN1(seq_priv, 2, LTC_ASN1_RAW_BIT_STRING, bin_xy, (unsigned long)8*(2*ECC_MAXSIZE+2)); + seq_priv[2].tag = 0xA1; /* context specific 1 */ + /* try to load private key */ + err = der_decode_sequence(buf1, top_seq[2].size, seq_priv, 3); + if (err != CRYPT_OK) { goto LBL_ERR; } + /* load private+public key */ + if ((err = ecc_import_raw(bin_k, seq_priv[1].size, key, dp)) != CRYPT_OK) { goto LBL_ERR; } + /* success */ + return err; + +LBL_ERR: + mp_clear_multi(prime, order, a, b, gx, gy, NULL); +LBL_NOCLEAR: + XFREE(buf2); +LBL_FREE: + XFREE(buf1); +LBL_NOFREE: + return err; +} + +#endif diff --git a/src/ltc/pk/ecc/ecc_import_raw.c b/src/ltc/pk/ecc/ecc_import_raw.c new file mode 100644 index 0000000..1ea4bb1 --- /dev/null +++ b/src/ltc/pk/ecc/ecc_import_raw.c @@ -0,0 +1,100 @@ +/* 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. + * + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ + +#include "tomcrypt.h" + +#ifdef LTC_MECC + +/** Import raw public or private key (public keys = ANSI X9.63 compressed or uncompressed; private keys = raw bytes) + @param in The input data to read + @param inlen The length of the input data + @param key [out] destination to store imported key + @param dp Curve parameters + Return CRYPT_OK on success +*/ + +int ecc_import_raw(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp) +{ + int err, type = -1; + unsigned long size = 0; + void *prime, *a, *b; + ecc_point *base; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(dp != NULL); + + /* init key + temporary numbers */ + if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, &prime, &a, &b, NULL) != CRYPT_OK) { + return CRYPT_MEM; + } + + if (inlen <= (unsigned long)dp->size) { + /* read PRIVATE key */ + type = PK_PRIVATE; + size = inlen; + /* load private k */ + if ((err = mp_read_unsigned_bin(key->k, (unsigned char *)in, size)) != CRYPT_OK) { + goto cleanup; + } + if (mp_iszero(key->k)) { + err = CRYPT_INVALID_PACKET; + goto cleanup; + } + /* init base point */ + if ((base = ltc_ecc_new_point()) == NULL) { + err = CRYPT_MEM; + goto cleanup; + } + /* load prime + base point */ + if ((err = mp_read_radix(prime, dp->prime, 16)) != CRYPT_OK) { goto cleanup; } + if ((err = mp_read_radix(base->x, dp->Gx, 16)) != CRYPT_OK) { goto cleanup; } + if ((err = mp_read_radix(base->y, dp->Gy, 16)) != CRYPT_OK) { goto cleanup; } + if ((err = mp_set(base->z, 1)) != CRYPT_OK) { goto cleanup; } + /* make the public key */ + if ((err = mp_read_radix(a, dp->A, 16)) != CRYPT_OK) { goto cleanup; } + if ((err = ltc_mp.ecc_ptmul(key->k, base, &key->pubkey, a, prime, 1)) != CRYPT_OK) { goto cleanup; } + /* cleanup */ + ltc_ecc_del_point(base); + } + else { + /* read PUBLIC key */ + type = PK_PUBLIC; + /* load prime + A + B */ + if ((err = mp_read_radix(prime, dp->prime, 16)) != CRYPT_OK) { goto cleanup; } + if ((err = mp_read_radix(b, dp->B, 16)) != CRYPT_OK) { goto cleanup; } + if ((err = mp_read_radix(a, dp->A, 16)) != CRYPT_OK) { goto cleanup; } + err = ltc_ecc_import_point(in, inlen, prime, a, b, key->pubkey.x, key->pubkey.y); + if (err != CRYPT_OK) { goto cleanup; } + if ((err = mp_set(key->pubkey.z, 1)) != CRYPT_OK) { goto cleanup; } + } + + if ((err = ltc_ecc_is_point(dp, key->pubkey.x, key->pubkey.y)) != CRYPT_OK) { + err = CRYPT_INVALID_PACKET; + goto cleanup; + } + + key->type = type; + key->idx = -1; + key->dp = dp; + + /* we're done */ + mp_clear_multi(prime, a, b, NULL); + return CRYPT_OK; +cleanup: + mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, prime, a, b, NULL); + return err; +} + +#endif diff --git a/src/ltc/pk/ecc/ecc_make_key.c b/src/ltc/pk/ecc/ecc_make_key.c new file mode 100644 index 0000000..1568b10 --- /dev/null +++ b/src/ltc/pk/ecc/ecc_make_key.c @@ -0,0 +1,141 @@ +/* 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://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ +#include "tomcrypt.h" + +/** + @file ecc_make_key.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/** + Make a new ECC key + @param prng An active PRNG state + @param wprng The index of the PRNG you wish to use + @param keysize The keysize for the new key (in octets from 20 to 65 bytes) + @param key [out] Destination of the newly created key + @return CRYPT_OK if successful, upon error all allocated memory will be freed +*/ +int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key) +{ + /* BEWARE: Here we are looking up the curve params by keysize (neither curve name nor curve oid), + * which might be ambiguous (there can more than one curve for given keysize). + * Thus the chosen curve depends on order of items in ltc_ecc_sets[] - see ecc.c file. + */ + int x, err; + + /* find key size */ + for (x = 0; (keysize > ltc_ecc_sets[x].size) && (ltc_ecc_sets[x].size != 0); x++); + keysize = ltc_ecc_sets[x].size; + + if (keysize > ECC_MAXSIZE || ltc_ecc_sets[x].size == 0) { + return CRYPT_INVALID_KEYSIZE; + } + err = ecc_make_key_ex(prng, wprng, key, <c_ecc_sets[x]); + key->idx = x; + return err; +} + +int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_set_type *dp) +{ + int err; + ecc_point *base; + void *prime, *order, *a; + unsigned char *buf; + int keysize, orderbits; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(ltc_mp.name != NULL); + LTC_ARGCHK(dp != NULL); + + /* good prng? */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + key->idx = -1; + key->dp = dp; + keysize = dp->size; + + /* allocate ram */ + base = NULL; + buf = XMALLOC(ECC_MAXSIZE); + if (buf == NULL) { + return CRYPT_MEM; + } + + /* make up random string */ + if (prng_descriptor[wprng].read(buf, (unsigned long)keysize, prng) != (unsigned long)keysize) { + err = CRYPT_ERROR_READPRNG; + goto ERR_BUF; + } + + /* setup the key variables */ + if ((err = mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, &prime, &order, &a, NULL)) != CRYPT_OK) { + goto ERR_BUF; + } + base = ltc_ecc_new_point(); + if (base == NULL) { + err = CRYPT_MEM; + goto errkey; + } + + /* read in the specs for this key */ + if ((err = mp_read_radix(prime, (char *)key->dp->prime, 16)) != CRYPT_OK) { goto errkey; } + if ((err = mp_read_radix(order, (char *)key->dp->order, 16)) != CRYPT_OK) { goto errkey; } + if ((err = mp_read_radix(base->x, (char *)key->dp->Gx, 16)) != CRYPT_OK) { goto errkey; } + if ((err = mp_read_radix(base->y, (char *)key->dp->Gy, 16)) != CRYPT_OK) { goto errkey; } + if ((err = mp_set(base->z, 1)) != CRYPT_OK) { goto errkey; } + if ((err = mp_read_unsigned_bin(key->k, (unsigned char *)buf, keysize)) != CRYPT_OK) { goto errkey; } + + /* ECC key pair generation according to FIPS-186-4 (B.4.2 Key Pair Generation by Testing Candidates): + * the generated private key k should be the range [1, order-1] + * a/ N = bitlen(order) + * b/ generate N random bits and convert them into big integer k + * c/ if k not in [1, order-1] go to b/ + * e/ Q = k*G + */ + orderbits = mp_count_bits(order); + do { + if ((err = rand_bn_bits(key->k, orderbits, prng, wprng)) != CRYPT_OK) { goto errkey; } + } while (mp_iszero(key->k) || mp_cmp(key->k, order) != LTC_MP_LT); + + /* make the public key */ + if ((err = mp_read_radix(a, (char *)key->dp->A, 16)) != CRYPT_OK) { goto errkey; } + if ((err = ltc_mp.ecc_ptmul(key->k, base, &key->pubkey, a, prime, 1)) != CRYPT_OK) { goto errkey; } + key->type = PK_PRIVATE; + + /* free up ram */ + err = CRYPT_OK; + goto cleanup; +errkey: + mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL); +cleanup: + ltc_ecc_del_point(base); + mp_clear_multi(prime, order, a, NULL); +ERR_BUF: +#ifdef LTC_CLEAN_STACK + zeromem(buf, ECC_MAXSIZE); +#endif + XFREE(buf); + return err; +} + +#endif +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ + diff --git a/src/ltc/pk/ecc/ecc_shared_secret.c b/src/ltc/pk/ecc/ecc_shared_secret.c new file mode 100644 index 0000000..df22f5c --- /dev/null +++ b/src/ltc/pk/ecc/ecc_shared_secret.c @@ -0,0 +1,95 @@ +/* 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://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ +#include "tomcrypt.h" + +/** + @file ecc_shared_secret.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/** + Create an ECC shared secret between two keys + @param private_key The private ECC key + @param public_key The public key + @param out [out] Destination of the shared secret (Conforms to EC-DH from ANSI X9.63) + @param outlen [in/out] The max size and resulting size of the shared secret + @return CRYPT_OK if successful +*/ +int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x; + ecc_point *result; + void *prime, *a; + int err; + + LTC_ARGCHK(private_key != NULL); + LTC_ARGCHK(public_key != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* type valid? */ + if (private_key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + if (ltc_ecc_is_valid_idx(private_key->idx) == 0 || ltc_ecc_is_valid_idx(public_key->idx) == 0) { + return CRYPT_INVALID_ARG; + } + +/* XXX FIXME names can be different in some situations + if (XSTRCMP(private_key->dp->name, public_key->dp->name) != 0) { + return CRYPT_PK_TYPE_MISMATCH; + } +*/ + /* make new point */ + result = ltc_ecc_new_point(); + if (result == NULL) { + return CRYPT_MEM; + } + + if ((err = mp_init_multi(&prime, &a, NULL)) != CRYPT_OK) { + ltc_ecc_del_point(result); + return err; + } + + if ((err = mp_read_radix(prime, (char *)private_key->dp->prime, 16)) != CRYPT_OK) { goto done; } + if ((err = mp_read_radix(a, (char *)private_key->dp->A, 16)) != CRYPT_OK) { goto done; } + if ((err = ltc_mp.ecc_ptmul(private_key->k, &public_key->pubkey, result, a, prime, 1)) != CRYPT_OK) { goto done; } + + x = (unsigned long)mp_unsigned_bin_size(prime); + if (*outlen < x) { + *outlen = x; + err = CRYPT_BUFFER_OVERFLOW; + goto done; + } + zeromem(out, x); + if ((err = mp_to_unsigned_bin(result->x, out + (x - mp_unsigned_bin_size(result->x)))) != CRYPT_OK) { goto done; } + + err = CRYPT_OK; + *outlen = x; +done: + mp_clear_multi(prime, a, NULL); + ltc_ecc_del_point(result); + return err; +} + +#endif +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ + diff --git a/src/ltc/pk/ecc/ecc_sign_hash.c b/src/ltc/pk/ecc/ecc_sign_hash.c new file mode 100644 index 0000000..7f1859c --- /dev/null +++ b/src/ltc/pk/ecc/ecc_sign_hash.c @@ -0,0 +1,165 @@ +/* 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://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ + +#include "tomcrypt.h" + +#ifdef LTC_MECC + +/** + @file ecc_sign_hash.c + ECC Crypto, Tom St Denis +*/ + +static int ecc_sign_hash_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, ecc_key *key, int sigformat) +{ + ecc_key pubkey; + void *r, *s, *e, *p; + int err; + unsigned long pbits, pbytes, i, shift_right; + unsigned char ch, buf[MAXBLOCKSIZE]; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* is this a private key? */ + if (key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* is the IDX valid ? */ + if (ltc_ecc_is_valid_idx(key->idx) != 1) { + return CRYPT_PK_INVALID_TYPE; + } + + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + /* init the bignums */ + if ((err = mp_init_multi(&r, &s, &p, &e, NULL)) != CRYPT_OK) { + return err; + } + if ((err = mp_read_radix(p, (char *)key->dp->order, 16)) != CRYPT_OK) { goto errnokey; } + + /* get the hash and load it as a bignum into 'e' */ + pbits = mp_count_bits(p); + pbytes = (pbits+7) >> 3; + if (pbits > inlen*8) { + if ((err = mp_read_unsigned_bin(e, (unsigned char *)in, inlen)) != CRYPT_OK) { goto errnokey; } + } + else if (pbits % 8 == 0) { + if ((err = mp_read_unsigned_bin(e, (unsigned char *)in, pbytes)) != CRYPT_OK) { goto errnokey; } + } + else { + shift_right = 8 - pbits % 8; + for (i=0, ch=0; i> shift_right); + } + if ((err = mp_read_unsigned_bin(e, (unsigned char *)buf, pbytes)) != CRYPT_OK) { goto errnokey; } + } + + /* make up a key and export the public copy */ + for (;;) { + if ((err = ecc_make_key_ex(prng, wprng, &pubkey, key->dp)) != CRYPT_OK) { goto errnokey; } + + /* find r = x1 mod n */ + if ((err = mp_mod(pubkey.pubkey.x, p, r)) != CRYPT_OK) { goto error; } + + if (mp_iszero(r) == LTC_MP_YES) { + ecc_free(&pubkey); + } + else { + /* find s = (e + xr)/k */ + if ((err = mp_invmod(pubkey.k, p, pubkey.k)) != CRYPT_OK) { goto error; } /* k = 1/k */ + if ((err = mp_mulmod(key->k, r, p, s)) != CRYPT_OK) { goto error; } /* s = xr */ + if ((err = mp_add(e, s, s)) != CRYPT_OK) { goto error; } /* s = e + xr */ + if ((err = mp_mod(s, p, s)) != CRYPT_OK) { goto error; } /* s = e + xr */ + if ((err = mp_mulmod(s, pubkey.k, p, s)) != CRYPT_OK) { goto error; } /* s = (e + xr)/k */ + ecc_free(&pubkey); + if (mp_iszero(s) == LTC_MP_NO) { + break; + } + } + } + + if (sigformat == 1) { + /* RFC7518 format */ + if (*outlen < 2*pbytes) { err = CRYPT_MEM; goto errnokey; } + zeromem(out, 2*pbytes); + i = mp_unsigned_bin_size(r); + if ((err = mp_to_unsigned_bin(r, out + (pbytes - i))) != CRYPT_OK) { goto errnokey; } + i = mp_unsigned_bin_size(s); + if ((err = mp_to_unsigned_bin(s, out + (2*pbytes - i))) != CRYPT_OK) { goto errnokey; } + *outlen = 2*pbytes; + err = CRYPT_OK; + } + else { + /* store as ASN.1 SEQUENCE { r, s -- integer } */ + err = der_encode_sequence_multi(out, outlen, + LTC_ASN1_INTEGER, 1UL, r, + LTC_ASN1_INTEGER, 1UL, s, + LTC_ASN1_EOL, 0UL, NULL); + } + goto errnokey; +error: + ecc_free(&pubkey); +errnokey: + mp_clear_multi(r, s, p, e, NULL); + return err; +} + +/** + Sign a message digest + @param in The message digest to sign + @param inlen The length of the digest + @param out [out] The destination for the signature + @param outlen [in/out] The max size and resulting size of the signature + @param prng An active PRNG state + @param wprng The index of the PRNG you wish to use + @param key A private ECC key + @return CRYPT_OK if successful +*/ +int ecc_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, ecc_key *key) +{ + return ecc_sign_hash_ex(in, inlen, out, outlen, prng, wprng, key, 0); +} + +/** + Sign a message digest in RFC7518 format + @param in The message digest to sign + @param inlen The length of the digest + @param out [out] The destination for the signature + @param outlen [in/out] The max size and resulting size of the signature + @param prng An active PRNG state + @param wprng The index of the PRNG you wish to use + @param key A private ECC key + @return CRYPT_OK if successful +*/ +int ecc_sign_hash_rfc7518(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, ecc_key *key) +{ + return ecc_sign_hash_ex(in, inlen, out, outlen, prng, wprng, key, 1); +} + +#endif diff --git a/src/ltc/pk/ecc/ecc_sizes.c b/src/ltc/pk/ecc/ecc_sizes.c new file mode 100644 index 0000000..3dbe37a --- /dev/null +++ b/src/ltc/pk/ecc/ecc_sizes.c @@ -0,0 +1,46 @@ +/* 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://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ +#include "tomcrypt.h" + +/** + @file ecc_sizes.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +void ecc_sizes(int *low, int *high) +{ + int i; + LTC_ARGCHKVD(low != NULL); + LTC_ARGCHKVD(high != NULL); + + *low = INT_MAX; + *high = 0; + for (i = 0; ltc_ecc_sets[i].size != 0; i++) { + if (ltc_ecc_sets[i].size < *low) { + *low = ltc_ecc_sets[i].size; + } + if (ltc_ecc_sets[i].size > *high) { + *high = ltc_ecc_sets[i].size; + } + } +} + +#endif +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ + diff --git a/src/ltc/pk/ecc/ecc_verify_hash.c b/src/ltc/pk/ecc/ecc_verify_hash.c new file mode 100644 index 0000000..c4d14c3 --- /dev/null +++ b/src/ltc/pk/ecc/ecc_verify_hash.c @@ -0,0 +1,207 @@ +/* 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://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ + +#include "tomcrypt.h" + +#ifdef LTC_MECC + +/** + @file ecc_verify_hash.c + ECC Crypto, Tom St Denis +*/ + +static int ecc_verify_hash_ex(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, ecc_key *key, int sigformat) +{ + ecc_point *mG, *mQ; + void *r, *s, *v, *w, *u1, *u2, *e, *p, *m, *a, *mu, *ma; + void *mp; + int err; + unsigned long pbits, pbytes, i, shift_right; + unsigned char ch, buf[MAXBLOCKSIZE]; + + LTC_ARGCHK(sig != NULL); + LTC_ARGCHK(hash != NULL); + LTC_ARGCHK(stat != NULL); + LTC_ARGCHK(key != NULL); + + /* default to invalid signature */ + *stat = 0; + mp = NULL; + + /* is the IDX valid ? */ + if (ltc_ecc_is_valid_idx(key->idx) != 1) { + return CRYPT_PK_INVALID_TYPE; + } + + /* allocate ints */ + if ((err = mp_init_multi(&r, &s, &v, &w, &u1, &u2, &p, &e, &m, &a, &mu, &ma, NULL)) != CRYPT_OK) { + return CRYPT_MEM; + } + + /* allocate points */ + mG = ltc_ecc_new_point(); + mQ = ltc_ecc_new_point(); + if (mQ == NULL || mG == NULL) { + err = CRYPT_MEM; + goto error; + } + + if (sigformat == 1) { + /* RFC7518 format */ + if ((siglen % 2) == 1) { + err = CRYPT_INVALID_PACKET; + goto error; + } + i = siglen / 2; + if ((err = mp_read_unsigned_bin(r, (unsigned char *)sig, i)) != CRYPT_OK) { goto error; } + if ((err = mp_read_unsigned_bin(s, (unsigned char *)sig+i, i)) != CRYPT_OK) { goto error; } + } + else { + /* ASN.1 format */ + if ((err = der_decode_sequence_multi(sig, siglen, + LTC_ASN1_INTEGER, 1UL, r, + LTC_ASN1_INTEGER, 1UL, s, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { goto error; } + } + + /* get the order */ + if ((err = mp_read_radix(p, (char *)key->dp->order, 16)) != CRYPT_OK) { goto error; } + + /* get the modulus */ + if ((err = mp_read_radix(m, (char *)key->dp->prime, 16)) != CRYPT_OK) { goto error; } + + /* get the a */ + if ((err = mp_read_radix(a, (char *)key->dp->A, 16)) != CRYPT_OK) { goto error; } + + /* check for zero */ + if (mp_iszero(r) || mp_iszero(s) || mp_cmp(r, p) != LTC_MP_LT || mp_cmp(s, p) != LTC_MP_LT) { + err = CRYPT_INVALID_PACKET; + goto error; + } + + /* read hash - truncate if needed */ + pbits = mp_count_bits(p); + pbytes = (pbits+7) >> 3; + if (pbits > hashlen*8) { + if ((err = mp_read_unsigned_bin(e, (unsigned char *)hash, hashlen)) != CRYPT_OK) { goto error; } + } + else if (pbits % 8 == 0) { + if ((err = mp_read_unsigned_bin(e, (unsigned char *)hash, pbytes)) != CRYPT_OK) { goto error; } + } + else { + shift_right = 8 - pbits % 8; + for (i=0, ch=0; i> shift_right); + } + if ((err = mp_read_unsigned_bin(e, (unsigned char *)buf, pbytes)) != CRYPT_OK) { goto error; } + } + + /* w = s^-1 mod n */ + if ((err = mp_invmod(s, p, w)) != CRYPT_OK) { goto error; } + + /* u1 = ew */ + if ((err = mp_mulmod(e, w, p, u1)) != CRYPT_OK) { goto error; } + + /* u2 = rw */ + if ((err = mp_mulmod(r, w, p, u2)) != CRYPT_OK) { goto error; } + + /* find mG and mQ */ + if ((err = mp_read_radix(mG->x, (char *)key->dp->Gx, 16)) != CRYPT_OK) { goto error; } + if ((err = mp_read_radix(mG->y, (char *)key->dp->Gy, 16)) != CRYPT_OK) { goto error; } + if ((err = mp_set(mG->z, 1)) != CRYPT_OK) { goto error; } + + if ((err = mp_copy(key->pubkey.x, mQ->x)) != CRYPT_OK) { goto error; } + if ((err = mp_copy(key->pubkey.y, mQ->y)) != CRYPT_OK) { goto error; } + if ((err = mp_copy(key->pubkey.z, mQ->z)) != CRYPT_OK) { goto error; } + + /* compute u1*mG + u2*mQ = mG */ + if (ltc_mp.ecc_mul2add == NULL) { + if ((err = ltc_mp.ecc_ptmul(u1, mG, mG, a, m, 0)) != CRYPT_OK) { goto error; } + if ((err = ltc_mp.ecc_ptmul(u2, mQ, mQ, a, m, 0)) != CRYPT_OK) { goto error; } + + /* find the montgomery mp */ + if ((err = mp_montgomery_setup(m, &mp)) != CRYPT_OK) { goto error; } + if ((err = mp_montgomery_normalization(mu, m)) != CRYPT_OK) { goto error; } + if ((err = mp_mulmod(a, mu, m, ma)) != CRYPT_OK) { goto error; } + + /* add them */ + if ((err = ltc_mp.ecc_ptadd(mQ, mG, mG, ma, m, mp)) != CRYPT_OK) { goto error; } + + /* reduce */ + if ((err = ltc_mp.ecc_map(mG, m, mp)) != CRYPT_OK) { goto error; } + } else { + /* use Shamir's trick to compute u1*mG + u2*mQ using half of the doubles */ + if ((err = ltc_mp.ecc_mul2add(mG, u1, mQ, u2, mG, a, m)) != CRYPT_OK) { goto error; } + } + + /* v = X_x1 mod n */ + if ((err = mp_mod(mG->x, p, v)) != CRYPT_OK) { goto error; } + + /* does v == r */ + if (mp_cmp(v, r) == LTC_MP_EQ) { + *stat = 1; + } + + /* clear up and return */ + err = CRYPT_OK; +error: + ltc_ecc_del_point(mG); + ltc_ecc_del_point(mQ); + mp_clear_multi(r, s, v, w, u1, u2, p, e, m, a, mu, ma, NULL); + if (mp != NULL) { + mp_montgomery_free(mp); + } + return err; +} + +/** + Verify an ECC signature + @param sig The signature to verify + @param siglen The length of the signature (octets) + @param hash The hash (message digest) that was signed + @param hashlen The length of the hash (octets) + @param stat Result of signature, 1==valid, 0==invalid + @param key The corresponding public ECC key + @return CRYPT_OK if successful (even if the signature is not valid) +*/ +int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, ecc_key *key) +{ + return ecc_verify_hash_ex(sig, siglen, hash, hashlen, stat, key, 0); +} + +/** + Verify an ECC signature in RFC7518 format + @param sig The signature to verify + @param siglen The length of the signature (octets) + @param hash The hash (message digest) that was signed + @param hashlen The length of the hash (octets) + @param stat Result of signature, 1==valid, 0==invalid + @param key The corresponding public ECC key + @return CRYPT_OK if successful (even if the signature is not valid) +*/ +int ecc_verify_hash_rfc7518(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, ecc_key *key) +{ + return ecc_verify_hash_ex(sig, siglen, hash, hashlen, stat, key, 1); +} + +#endif diff --git a/src/ltc/pk/ecc/ecc_verify_key.c b/src/ltc/pk/ecc/ecc_verify_key.c new file mode 100644 index 0000000..0ca1914 --- /dev/null +++ b/src/ltc/pk/ecc/ecc_verify_key.c @@ -0,0 +1,77 @@ +/* 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. + * + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ + +#include "tomcrypt.h" + +/* origin of this code - OLPC */ + +#ifdef LTC_MECC + +/** + Verify a key according to ANSI spec + @param key The key to validate + @return CRYPT_OK if successful +*/ + +int ecc_verify_key(ecc_key *key) +{ + int err; + void *prime = NULL; + void *order = NULL; + void *a = NULL; + ecc_point *point; + + if (mp_init_multi(&order, &prime, NULL) != CRYPT_OK) { + return CRYPT_MEM; + } + + /* Test 1: Are the x amd y points of the public key in the field? */ + if ((err = ltc_mp.read_radix(prime, key->dp->prime, 16)) != CRYPT_OK) { goto done2; } + + if (ltc_mp.compare_d(key->pubkey.z, 1) == LTC_MP_EQ) { + if ((ltc_mp.compare(key->pubkey.x, prime) != LTC_MP_LT) || + (ltc_mp.compare(key->pubkey.y, prime) != LTC_MP_LT) || + (ltc_mp.compare_d(key->pubkey.x, 0) != LTC_MP_GT) || + (ltc_mp.compare_d(key->pubkey.y, 0) != LTC_MP_GT) + ) + { + err = CRYPT_INVALID_PACKET; + goto done2; + } + } + + /* Test 2: is the public key on the curve? */ + if ((err = ltc_ecc_is_point(key->dp, key->pubkey.x, key->pubkey.y)) != CRYPT_OK) { goto done2; } + + /* Test 3: does nG = O? (n = order, O = point at infinity, G = public key) */ + point = ltc_ecc_new_point(); + if ((err = ltc_mp.read_radix(order, key->dp->order, 16)) != CRYPT_OK) { goto done1; } + if ((err = ltc_mp.read_radix(a, key->dp->A, 16)) != CRYPT_OK) { goto done1; } + if ((err = ltc_ecc_mulmod(order, &(key->pubkey), point, a, prime, 1)) != CRYPT_OK) { goto done1; } + + if (ltc_ecc_is_point_at_infinity(point, prime)) { + err = CRYPT_ERROR; + } + else { + err = CRYPT_OK; + } + +done1: + ltc_ecc_del_point(point); +done2: + mp_clear_multi(prime, order, NULL); + return err; +} + +#endif diff --git a/src/ltc/pk/ecc/ltc_ecc_export_point.c b/src/ltc/pk/ecc/ltc_ecc_export_point.c new file mode 100644 index 0000000..086e4c2 --- /dev/null +++ b/src/ltc/pk/ecc/ltc_ecc_export_point.c @@ -0,0 +1,64 @@ +/* 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. + * + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ + +#include "tomcrypt.h" + +#ifdef LTC_MECC + +int ltc_ecc_export_point(unsigned char *out, unsigned long *outlen, void *x, void *y, unsigned long size, int compressed) +{ + int err; + unsigned char buf[ECC_BUF_SIZE]; + unsigned long xsize, ysize; + + if (size > sizeof(buf)) return CRYPT_BUFFER_OVERFLOW; + if ((xsize = mp_unsigned_bin_size(x)) > size) return CRYPT_BUFFER_OVERFLOW; + if ((ysize = mp_unsigned_bin_size(y)) > size) return CRYPT_BUFFER_OVERFLOW; + + if(compressed) { + if (*outlen < (1 + size)) { + *outlen = 1 + size; + return CRYPT_BUFFER_OVERFLOW; + } + /* store first byte */ + out[0] = mp_isodd(y) ? 0x03 : 0x02; + /* pad and store x */ + zeromem(buf, sizeof(buf)); + if ((err = mp_to_unsigned_bin(x, buf + (size - xsize))) != CRYPT_OK) return err; + XMEMCPY(out+1, buf, size); + /* adjust outlen */ + *outlen = 1 + size; + } + else { + if (*outlen < (1 + 2*size)) { + *outlen = 1 + 2*size; + return CRYPT_BUFFER_OVERFLOW; + } + /* store byte 0x04 */ + out[0] = 0x04; + /* pad and store x */ + zeromem(buf, sizeof(buf)); + if ((err = mp_to_unsigned_bin(x, buf + (size - xsize))) != CRYPT_OK) return err; + XMEMCPY(out+1, buf, size); + /* pad and store y */ + zeromem(buf, sizeof(buf)); + if ((err = mp_to_unsigned_bin(y, buf + (size - ysize))) != CRYPT_OK) return err; + XMEMCPY(out+1+size, buf, size); + /* adjust outlen */ + *outlen = 1 + 2*size; + } + return CRYPT_OK; +} + +#endif diff --git a/src/ltc/pk/ecc/ltc_ecc_import_point.c b/src/ltc/pk/ecc/ltc_ecc_import_point.c new file mode 100644 index 0000000..d4d028d --- /dev/null +++ b/src/ltc/pk/ecc/ltc_ecc_import_point.c @@ -0,0 +1,72 @@ +/* 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. + * + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ + +#include "tomcrypt.h" + +#ifdef LTC_MECC + +int ltc_ecc_import_point(const unsigned char *in, unsigned long inlen, void *prime, void *a, void *b, void *x, void *y) +{ + int err; + unsigned long size; + void *t1, *t2; + + /* init key + temporary numbers */ + if (mp_init_multi(&t1, &t2, NULL) != CRYPT_OK) { + return CRYPT_MEM; + } + + size = mp_unsigned_bin_size(prime); + + if (in[0] == 0x04 && (inlen&1) && ((inlen-1)>>1) == size) { + /* read uncompressed point */ + /* load x */ + if ((err = mp_read_unsigned_bin(x, (unsigned char *)in+1, size)) != CRYPT_OK) { goto cleanup; } + /* load y */ + if ((err = mp_read_unsigned_bin(y, (unsigned char *)in+1+size, size)) != CRYPT_OK) { goto cleanup; } + } + else if ((in[0] == 0x02 || in[0] == 0x03) && (inlen-1) == size) { + /* read compressed point */ + /* load x */ + if ((err = mp_read_unsigned_bin(x, (unsigned char *)in+1, size)) != CRYPT_OK) { goto cleanup; } + /* compute x^3 */ + if ((err = mp_sqr(x, t1)) != CRYPT_OK) { goto cleanup; } + if ((err = mp_mulmod(t1, x, prime, t1)) != CRYPT_OK) { goto cleanup; } + /* compute x^3 + a*x */ + if ((err = mp_mulmod(a, x, prime, t2)) != CRYPT_OK) { goto cleanup; } + if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto cleanup; } + /* compute x^3 + a*x + b */ + if ((err = mp_add(t1, b, t1)) != CRYPT_OK) { goto cleanup; } + /* compute sqrt(x^3 + a*x + b) */ + if ((err = mp_sqrtmod_prime(t1, prime, t2)) != CRYPT_OK) { goto cleanup; } + /* adjust y */ + if ((mp_isodd(t2) && in[0] == 0x03) || (!mp_isodd(t2) && in[0] == 0x02)) { + if ((err = mp_mod(t2, prime, y)) != CRYPT_OK) { goto cleanup; } + } + else { + if ((err = mp_submod(prime, t2, prime, y)) != CRYPT_OK) { goto cleanup; } + } + } + else { + err = CRYPT_INVALID_PACKET; + goto cleanup; + } + + err = CRYPT_OK; +cleanup: + mp_clear_multi(t1, t2, NULL); + return err; +} + +#endif diff --git a/src/ltc/pk/ecc/ltc_ecc_is_point.c b/src/ltc/pk/ecc/ltc_ecc_is_point.c new file mode 100644 index 0000000..9ea963c --- /dev/null +++ b/src/ltc/pk/ecc/ltc_ecc_is_point.c @@ -0,0 +1,75 @@ +/* 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. + * + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + */ + +#include "tomcrypt.h" + +#ifdef LTC_MECC + +/** Returns whether [x,y] is a point on curve defined by dp + @param dp curve parameters + @param x x point coordinate + @param y y point coordinate + @return CRYPT_OK if valid +*/ + +int ltc_ecc_is_point(const ltc_ecc_set_type *dp, void *x, void *y) +{ + void *prime, *a, *b, *t1, *t2; + int err; + + if ((err = mp_init_multi(&prime, &a, &b, &t1, &t2, NULL)) != CRYPT_OK) { + return err; + } + + /* load prime, a and b */ + if ((err = mp_read_radix(prime, dp->prime, 16)) != CRYPT_OK) goto cleanup; + if ((err = mp_read_radix(b, dp->B, 16)) != CRYPT_OK) goto cleanup; + if ((err = mp_read_radix(a, dp->A, 16)) != CRYPT_OK) goto cleanup; + + /* compute y^2 */ + if ((err = mp_sqr(y, t1)) != CRYPT_OK) goto cleanup; + + /* compute x^3 */ + if ((err = mp_sqr(x, t2)) != CRYPT_OK) goto cleanup; + if ((err = mp_mod(t2, prime, t2)) != CRYPT_OK) goto cleanup; + if ((err = mp_mul(x, t2, t2)) != CRYPT_OK) goto cleanup; + + /* compute y^2 - x^3 */ + if ((err = mp_sub(t1, t2, t1)) != CRYPT_OK) goto cleanup; + + /* compute y^2 - x^3 - a*x */ + if ((err = mp_submod(prime, a, prime, t2)) != CRYPT_OK) goto cleanup; + if ((err = mp_mulmod(t2, x, prime, t2)) != CRYPT_OK) goto cleanup; + if ((err = mp_addmod(t1, t2, prime, t1)) != CRYPT_OK) goto cleanup; + + /* adjust range (0, prime) */ + while (mp_cmp_d(t1, 0) == LTC_MP_LT) { + if ((err = mp_add(t1, prime, t1)) != CRYPT_OK) goto cleanup; + } + while (mp_cmp(t1, prime) != LTC_MP_LT) { + if ((err = mp_sub(t1, prime, t1)) != CRYPT_OK) goto cleanup; + } + + /* compare to b */ + if (mp_cmp(t1, b) != LTC_MP_EQ) { + err = CRYPT_INVALID_PACKET; + } else { + err = CRYPT_OK; + } + +cleanup: + mp_clear_multi(prime, a, b, t1, t2, NULL); + return err; +} + +#endif diff --git a/src/ltc/pk/ecc/ltc_ecc_is_point_at_infinity.c b/src/ltc/pk/ecc/ltc_ecc_is_point_at_infinity.c new file mode 100644 index 0000000..1b94618 --- /dev/null +++ b/src/ltc/pk/ecc/ltc_ecc_is_point_at_infinity.c @@ -0,0 +1,50 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +#include "tomcrypt.h" + +#ifdef LTC_MECC + +/* http://crypto.stackexchange.com/questions/41468/point-at-infinity-for-jacobian-coordinates + * a point at infinity is any point (x,y,0) such that y^2 == x^3, except (0,0,0) + */ + +int ltc_ecc_is_point_at_infinity(ecc_point *P, void *modulus) +{ + int err, retval = 0; + void *x3, *y2; + + /* trivial case */ + if (!mp_iszero(P->z)) goto done; + + /* point (0,0,0) is not at infinity */ + if (mp_iszero(P->x) && mp_iszero(P->y)) goto done; + + /* initialize */ + if ((err = mp_init_multi(&x3, &y2, NULL)) != CRYPT_OK) goto done; + + /* compute y^2 */ + if ((err = mp_mulmod(P->y, P->y, modulus, y2)) != CRYPT_OK) goto cleanup; + + /* compute x^3 */ + if ((err = mp_mulmod(P->x, P->x, modulus, x3)) != CRYPT_OK) goto cleanup; + if ((err = mp_mulmod(P->x, x3, modulus, x3)) != CRYPT_OK) goto cleanup; + + /* test y^2 == x^3 */ + if ((mp_cmp(x3, y2) == LTC_MP_EQ) && !mp_iszero(y2)) retval = 1; + +cleanup: + mp_clear_multi(x3, y2, NULL); +done: + return retval; +} + +#endif diff --git a/src/ltc/pk/ecc/ltc_ecc_is_valid_idx.c b/src/ltc/pk/ecc/ltc_ecc_is_valid_idx.c new file mode 100644 index 0000000..b53eaca --- /dev/null +++ b/src/ltc/pk/ecc/ltc_ecc_is_valid_idx.c @@ -0,0 +1,44 @@ +/* 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://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ +#include "tomcrypt.h" + +/** + @file ltc_ecc_is_valid_idx.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/** Returns whether an ECC idx is valid or not + @param n The idx number to check + @return 1 if valid, 0 if not +*/ +int ltc_ecc_is_valid_idx(int n) +{ + int x; + + for (x = 0; ltc_ecc_sets[x].size != 0; x++); + /* -1 is a valid index --- indicating that the domain params were supplied by the user */ + if ((n >= -1) && (n < x)) { + return 1; + } + return 0; +} + +#endif +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ + diff --git a/src/ltc/pk/ecc/ltc_ecc_map.c b/src/ltc/pk/ecc/ltc_ecc_map.c new file mode 100644 index 0000000..75ea562 --- /dev/null +++ b/src/ltc/pk/ecc/ltc_ecc_map.c @@ -0,0 +1,81 @@ +/* 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://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ +#include "tomcrypt.h" + +/** + @file ltc_ecc_map.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/** + Map a projective jacbobian point back to affine space + @param P [in/out] The point to map + @param modulus The modulus of the field the ECC curve is in + @param mp The "b" value from montgomery_setup() + @return CRYPT_OK on success +*/ +int ltc_ecc_map(ecc_point *P, void *modulus, void *mp) +{ + void *t1, *t2; + int err; + + LTC_ARGCHK(P != NULL); + LTC_ARGCHK(modulus != NULL); + LTC_ARGCHK(mp != NULL); + + if (mp_iszero(P->z)) { + if ((err = mp_set(P->x, 0)) != CRYPT_OK) { return err; } + if ((err = mp_set(P->y, 0)) != CRYPT_OK) { return err; } + if ((err = mp_set(P->z, 1)) != CRYPT_OK) { return err; } + return CRYPT_OK; + } + + if ((err = mp_init_multi(&t1, &t2, NULL)) != CRYPT_OK) { + return CRYPT_MEM; + } + + /* first map z back to normal */ + if ((err = mp_montgomery_reduce(P->z, modulus, mp)) != CRYPT_OK) { goto done; } + + /* get 1/z */ + if ((err = mp_invmod(P->z, modulus, t1)) != CRYPT_OK) { goto done; } + + /* get 1/z^2 and 1/z^3 */ + if ((err = mp_sqr(t1, t2)) != CRYPT_OK) { goto done; } + if ((err = mp_mod(t2, modulus, t2)) != CRYPT_OK) { goto done; } + if ((err = mp_mul(t1, t2, t1)) != CRYPT_OK) { goto done; } + if ((err = mp_mod(t1, modulus, t1)) != CRYPT_OK) { goto done; } + + /* multiply against x/y */ + if ((err = mp_mul(P->x, t2, P->x)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(P->x, modulus, mp)) != CRYPT_OK) { goto done; } + if ((err = mp_mul(P->y, t1, P->y)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(P->y, modulus, mp)) != CRYPT_OK) { goto done; } + if ((err = mp_set(P->z, 1)) != CRYPT_OK) { goto done; } + + err = CRYPT_OK; +done: + mp_clear_multi(t1, t2, NULL); + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ + diff --git a/src/ltc/pk/ecc/ltc_ecc_mul2add.c b/src/ltc/pk/ecc/ltc_ecc_mul2add.c new file mode 100644 index 0000000..76febdc --- /dev/null +++ b/src/ltc/pk/ecc/ltc_ecc_mul2add.c @@ -0,0 +1,211 @@ +/* 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://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ +#include "tomcrypt.h" + +/** + @file ltc_ecc_mul2add.c + ECC Crypto, Shamir's Trick, Tom St Denis +*/ + +#ifdef LTC_MECC + +#ifdef LTC_ECC_SHAMIR + +/** Computes kA*A + kB*B = C using Shamir's Trick + @param A First point to multiply + @param kA What to multiple A by + @param B Second point to multiply + @param kB What to multiple B by + @param C [out] Destination point (can overlap with A or B + @param modulus Modulus for curve + @return CRYPT_OK on success +*/ +int ltc_ecc_mul2add(ecc_point *A, void *kA, + ecc_point *B, void *kB, + ecc_point *C, + void *a, + void *modulus) +{ + ecc_point *precomp[16]; + unsigned bitbufA, bitbufB, lenA, lenB, len, nA, nB, nibble; + unsigned x, y; + unsigned char *tA, *tB; + int err, first; + void *mp, *mu, *ma; + + /* argchks */ + LTC_ARGCHK(A != NULL); + LTC_ARGCHK(B != NULL); + LTC_ARGCHK(C != NULL); + LTC_ARGCHK(kA != NULL); + LTC_ARGCHK(kB != NULL); + LTC_ARGCHK(modulus != NULL); + + /* allocate memory */ + tA = XCALLOC(1, ECC_BUF_SIZE); + if (tA == NULL) { + return CRYPT_MEM; + } + tB = XCALLOC(1, ECC_BUF_SIZE); + if (tB == NULL) { + XFREE(tA); + return CRYPT_MEM; + } + + /* get sizes */ + lenA = mp_unsigned_bin_size(kA); + lenB = mp_unsigned_bin_size(kB); + len = MAX(lenA, lenB); + + /* sanity check */ + if ((lenA > ECC_BUF_SIZE) || (lenB > ECC_BUF_SIZE)) { + err = CRYPT_INVALID_ARG; + goto ERR_T; + } + + /* extract and justify kA */ + mp_to_unsigned_bin(kA, (len - lenA) + tA); + + /* extract and justify kB */ + mp_to_unsigned_bin(kB, (len - lenB) + tB); + + /* allocate the table */ + for (x = 0; x < 16; x++) { + precomp[x] = ltc_ecc_new_point(); + if (precomp[x] == NULL) { + for (y = 0; y < x; ++y) { + ltc_ecc_del_point(precomp[y]); + } + err = CRYPT_MEM; + goto ERR_T; + } + } + + /* init montgomery reduction */ + if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { + goto ERR_P; + } + if ((err = mp_init_multi(&mu, &ma, NULL)) != CRYPT_OK) { + goto ERR_MP; + } + if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { + goto ERR_MU; + } + if ((err = mp_mulmod(a, mu, modulus, ma)) != CRYPT_OK) { + goto ERR_MU; + } + + /* copy ones ... */ + if ((err = mp_mulmod(A->x, mu, modulus, precomp[1]->x)) != CRYPT_OK) { goto ERR_MU; } + if ((err = mp_mulmod(A->y, mu, modulus, precomp[1]->y)) != CRYPT_OK) { goto ERR_MU; } + if ((err = mp_mulmod(A->z, mu, modulus, precomp[1]->z)) != CRYPT_OK) { goto ERR_MU; } + + if ((err = mp_mulmod(B->x, mu, modulus, precomp[1<<2]->x)) != CRYPT_OK) { goto ERR_MU; } + if ((err = mp_mulmod(B->y, mu, modulus, precomp[1<<2]->y)) != CRYPT_OK) { goto ERR_MU; } + if ((err = mp_mulmod(B->z, mu, modulus, precomp[1<<2]->z)) != CRYPT_OK) { goto ERR_MU; } + + /* precomp [i,0](A + B) table */ + if ((err = ltc_mp.ecc_ptdbl(precomp[1], precomp[2], ma, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } + if ((err = ltc_mp.ecc_ptadd(precomp[1], precomp[2], precomp[3], ma, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } + + /* precomp [0,i](A + B) table */ + if ((err = ltc_mp.ecc_ptdbl(precomp[1<<2], precomp[2<<2], ma, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } + if ((err = ltc_mp.ecc_ptadd(precomp[1<<2], precomp[2<<2], precomp[3<<2], ma, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } + + /* precomp [i,j](A + B) table (i != 0, j != 0) */ + for (x = 1; x < 4; x++) { + for (y = 1; y < 4; y++) { + if ((err = ltc_mp.ecc_ptadd(precomp[x], precomp[(y<<2)], precomp[x+(y<<2)], ma, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } + } + } + + nibble = 3; + first = 1; + bitbufA = tA[0]; + bitbufB = tB[0]; + + /* for every byte of the multiplicands */ + for (x = 0;; ) { + /* grab a nibble */ + if (++nibble == 4) { + if (x == len) break; + bitbufA = tA[x]; + bitbufB = tB[x]; + nibble = 0; + ++x; + } + + /* extract two bits from both, shift/update */ + nA = (bitbufA >> 6) & 0x03; + nB = (bitbufB >> 6) & 0x03; + bitbufA = (bitbufA << 2) & 0xFF; + bitbufB = (bitbufB << 2) & 0xFF; + + /* if both zero, if first, continue */ + if ((nA == 0) && (nB == 0) && (first == 1)) { + continue; + } + + /* double twice, only if this isn't the first */ + if (first == 0) { + /* double twice */ + if ((err = ltc_mp.ecc_ptdbl(C, C, ma, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } + if ((err = ltc_mp.ecc_ptdbl(C, C, ma, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } + } + + /* if not both zero */ + if ((nA != 0) || (nB != 0)) { + if (first == 1) { + /* if first, copy from table */ + first = 0; + if ((err = mp_copy(precomp[nA + (nB<<2)]->x, C->x)) != CRYPT_OK) { goto ERR_MU; } + if ((err = mp_copy(precomp[nA + (nB<<2)]->y, C->y)) != CRYPT_OK) { goto ERR_MU; } + if ((err = mp_copy(precomp[nA + (nB<<2)]->z, C->z)) != CRYPT_OK) { goto ERR_MU; } + } else { + /* if not first, add from table */ + if ((err = ltc_mp.ecc_ptadd(C, precomp[nA + (nB<<2)], C, ma, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } + } + } + } + + /* reduce to affine */ + err = ltc_ecc_map(C, modulus, mp); + + /* clean up */ +ERR_MU: + mp_clear_multi(mu, ma, NULL); +ERR_MP: + mp_montgomery_free(mp); +ERR_P: + for (x = 0; x < 16; x++) { + ltc_ecc_del_point(precomp[x]); + } +ERR_T: +#ifdef LTC_CLEAN_STACK + zeromem(tA, ECC_BUF_SIZE); + zeromem(tB, ECC_BUF_SIZE); +#endif + XFREE(tA); + XFREE(tB); + + return err; +} + +#endif +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/ecc/ltc_ecc_mulmod.c b/src/ltc/pk/ecc/ltc_ecc_mulmod.c new file mode 100644 index 0000000..ec2bf8f --- /dev/null +++ b/src/ltc/pk/ecc/ltc_ecc_mulmod.c @@ -0,0 +1,234 @@ +/* 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://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ +#include "tomcrypt.h" + +/** + @file ltc_ecc_mulmod.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC +#ifndef LTC_ECC_TIMING_RESISTANT + +/* size of sliding window, don't change this! */ +#define WINSIZE 4 + +/** + Perform a point multiplication + @param k The scalar to multiply by + @param G The base point + @param R [out] Destination for kG + @param modulus The modulus of the field the ECC curve is in + @param map Boolean whether to map back to affine or not (1==map, 0 == leave in projective) + @return CRYPT_OK on success +*/ +int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map) +{ + ecc_point *tG, *M[8]; + int i, j, err; + void *mu, *mp, *ma; + ltc_mp_digit buf; + int first, bitbuf, bitcpy, bitcnt, mode, digidx; + + LTC_ARGCHK(k != NULL); + LTC_ARGCHK(G != NULL); + LTC_ARGCHK(R != NULL); + LTC_ARGCHK(modulus != NULL); + + if (ltc_ecc_is_point_at_infinity(G, modulus)) { + /* return the point at infinity */ + if ((err = mp_set(R->x, 1)) != CRYPT_OK) { return err; } + if ((err = mp_set(R->y, 1)) != CRYPT_OK) { return err; } + if ((err = mp_set(R->z, 0)) != CRYPT_OK) { return err; } + return CRYPT_OK; + } + + /* init montgomery reduction */ + if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { + return err; + } + if ((err = mp_init_multi(&mu, &ma, NULL)) != CRYPT_OK) { + mp_montgomery_free(mp); + return err; + } + if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { + mp_montgomery_free(mp); + mp_clear_multi(mu, ma, NULL); + return err; + } + if ((err = mp_mulmod(a, mu, modulus, ma)) != CRYPT_OK) { + mp_montgomery_free(mp); + mp_clear_multi(mu, ma, NULL); + return err; + } + + /* alloc ram for window temps */ + for (i = 0; i < 8; i++) { + M[i] = ltc_ecc_new_point(); + if (M[i] == NULL) { + for (j = 0; j < i; j++) { + ltc_ecc_del_point(M[j]); + } + mp_montgomery_free(mp); + mp_clear_multi(mu, ma, NULL); + return CRYPT_MEM; + } + } + + /* make a copy of G incase R==G */ + tG = ltc_ecc_new_point(); + if (tG == NULL) { err = CRYPT_MEM; goto done; } + + /* tG = G and convert to montgomery */ + if (mp_cmp_d(mu, 1) == LTC_MP_EQ) { + if ((err = mp_copy(G->x, tG->x)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(G->y, tG->y)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(G->z, tG->z)) != CRYPT_OK) { goto done; } + } else { + if ((err = mp_mulmod(G->x, mu, modulus, tG->x)) != CRYPT_OK) { goto done; } + if ((err = mp_mulmod(G->y, mu, modulus, tG->y)) != CRYPT_OK) { goto done; } + if ((err = mp_mulmod(G->z, mu, modulus, tG->z)) != CRYPT_OK) { goto done; } + } + mp_clear(mu); + mu = NULL; + + /* calc the M tab, which holds kG for k==8..15 */ + /* M[0] == 8G */ + if ((err = ltc_mp.ecc_ptdbl(tG, M[0], ma, modulus, mp)) != CRYPT_OK) { goto done; } + if ((err = ltc_mp.ecc_ptdbl(M[0], M[0], ma, modulus, mp)) != CRYPT_OK) { goto done; } + if ((err = ltc_mp.ecc_ptdbl(M[0], M[0], ma, modulus, mp)) != CRYPT_OK) { goto done; } + + /* now find (8+k)G for k=1..7 */ + for (j = 9; j < 16; j++) { + if ((err = ltc_mp.ecc_ptadd(M[j-9], tG, M[j-8], ma, modulus, mp)) != CRYPT_OK) { goto done; } + } + + /* setup sliding window */ + mode = 0; + bitcnt = 1; + buf = 0; + digidx = mp_get_digit_count(k) - 1; + bitcpy = bitbuf = 0; + first = 1; + + /* perform ops */ + for (;;) { + /* grab next digit as required */ + if (--bitcnt == 0) { + if (digidx == -1) { + break; + } + buf = mp_get_digit(k, digidx); + bitcnt = (int) ltc_mp.bits_per_digit; + --digidx; + } + + /* grab the next msb from the ltiplicand */ + i = (buf >> (ltc_mp.bits_per_digit - 1)) & 1; + buf <<= 1; + + /* skip leading zero bits */ + if (mode == 0 && i == 0) { + continue; + } + + /* if the bit is zero and mode == 1 then we double */ + if (mode == 1 && i == 0) { + if ((err = ltc_mp.ecc_ptdbl(R, R, ma, modulus, mp)) != CRYPT_OK) { goto done; } + continue; + } + + /* else we add it to the window */ + bitbuf |= (i << (WINSIZE - ++bitcpy)); + mode = 2; + + if (bitcpy == WINSIZE) { + /* if this is the first window we do a simple copy */ + if (first == 1) { + /* R = kG [k = first window] */ + if ((err = mp_copy(M[bitbuf-8]->x, R->x)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(M[bitbuf-8]->y, R->y)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(M[bitbuf-8]->z, R->z)) != CRYPT_OK) { goto done; } + first = 0; + } else { + /* normal window */ + /* ok window is filled so double as required and add */ + /* double first */ + for (j = 0; j < WINSIZE; j++) { + if ((err = ltc_mp.ecc_ptdbl(R, R, ma, modulus, mp)) != CRYPT_OK) { goto done; } + } + + /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */ + if ((err = ltc_mp.ecc_ptadd(R, M[bitbuf-8], R, ma, modulus, mp)) != CRYPT_OK) { goto done; } + } + /* empty window and reset */ + bitcpy = bitbuf = 0; + mode = 1; + } + } + + /* if bits remain then double/add */ + if (mode == 2 && bitcpy > 0) { + /* double then add */ + for (j = 0; j < bitcpy; j++) { + /* only double if we have had at least one add first */ + if (first == 0) { + if ((err = ltc_mp.ecc_ptdbl(R, R, ma, modulus, mp)) != CRYPT_OK) { goto done; } + } + + bitbuf <<= 1; + if ((bitbuf & (1 << WINSIZE)) != 0) { + if (first == 1){ + /* first add, so copy */ + if ((err = mp_copy(tG->x, R->x)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(tG->y, R->y)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(tG->z, R->z)) != CRYPT_OK) { goto done; } + first = 0; + } else { + /* then add */ + if ((err = ltc_mp.ecc_ptadd(R, tG, R, ma, modulus, mp)) != CRYPT_OK) { goto done; } + } + } + } + } + + /* map R back from projective space */ + if (map) { + err = ltc_ecc_map(R, modulus, mp); + } else { + err = CRYPT_OK; + } +done: + if (mu != NULL) { + mp_clear(mu); + } + mp_clear(ma); + mp_montgomery_free(mp); + ltc_ecc_del_point(tG); + for (i = 0; i < 8; i++) { + ltc_ecc_del_point(M[i]); + } + return err; +} + +#endif + +#undef WINSIZE + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/ecc/ltc_ecc_mulmod_timing.c b/src/ltc/pk/ecc/ltc_ecc_mulmod_timing.c new file mode 100644 index 0000000..73145e7 --- /dev/null +++ b/src/ltc/pk/ecc/ltc_ecc_mulmod_timing.c @@ -0,0 +1,178 @@ +/* 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://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ +#include "tomcrypt.h" + +/** + @file ltc_ecc_mulmod_timing.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +#ifdef LTC_ECC_TIMING_RESISTANT + +/** + Perform a point multiplication (timing resistant) + @param k The scalar to multiply by + @param G The base point + @param R [out] Destination for kG + @param a ECC curve parameter a + @param modulus The modulus of the field the ECC curve is in + @param map Boolean whether to map back to affine or not (1==map, 0 == leave in projective) + @return CRYPT_OK on success +*/ +int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map) +{ + ecc_point *tG, *M[3]; + int i, j, err; + void *mu, *mp, *ma; + ltc_mp_digit buf; + int bitcnt, mode, digidx; + + LTC_ARGCHK(k != NULL); + LTC_ARGCHK(G != NULL); + LTC_ARGCHK(R != NULL); + LTC_ARGCHK(modulus != NULL); + + if (ltc_ecc_is_point_at_infinity(G, modulus)) { + /* return the point at infinity */ + if ((err = mp_set(R->x, 1)) != CRYPT_OK) { return err; } + if ((err = mp_set(R->y, 1)) != CRYPT_OK) { return err; } + if ((err = mp_set(R->z, 0)) != CRYPT_OK) { return err; } + return CRYPT_OK; + } + + /* init montgomery reduction */ + if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { + return err; + } + if ((err = mp_init_multi(&mu, &ma, NULL)) != CRYPT_OK) { + mp_montgomery_free(mp); + return err; + } + if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { + mp_clear(mu); + mp_montgomery_free(mp); + return err; + } + if ((err = mp_mulmod(a, mu, modulus, ma)) != CRYPT_OK) { + mp_montgomery_free(mp); + mp_clear_multi(mu, ma, NULL); + return err; + } + + /* alloc ram for window temps */ + for (i = 0; i < 3; i++) { + M[i] = ltc_ecc_new_point(); + if (M[i] == NULL) { + for (j = 0; j < i; j++) { + ltc_ecc_del_point(M[j]); + } + mp_clear(mu); + mp_montgomery_free(mp); + return CRYPT_MEM; + } + } + + /* make a copy of G incase R==G */ + tG = ltc_ecc_new_point(); + if (tG == NULL) { err = CRYPT_MEM; goto done; } + + /* tG = G and convert to montgomery */ + if ((err = mp_mulmod(G->x, mu, modulus, tG->x)) != CRYPT_OK) { goto done; } + if ((err = mp_mulmod(G->y, mu, modulus, tG->y)) != CRYPT_OK) { goto done; } + if ((err = mp_mulmod(G->z, mu, modulus, tG->z)) != CRYPT_OK) { goto done; } + mp_clear(mu); + mu = NULL; + + /* calc the M tab */ + /* M[0] == G */ + if ((err = mp_copy(tG->x, M[0]->x)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(tG->y, M[0]->y)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(tG->z, M[0]->z)) != CRYPT_OK) { goto done; } + /* M[1] == 2G */ + if ((err = ltc_mp.ecc_ptdbl(tG, M[1], ma, modulus, mp)) != CRYPT_OK) { goto done; } + + /* setup sliding window */ + mode = 0; + bitcnt = 1; + buf = 0; + digidx = mp_get_digit_count(k) - 1; + + /* perform ops */ + for (;;) { + /* grab next digit as required */ + if (--bitcnt == 0) { + if (digidx == -1) { + break; + } + buf = mp_get_digit(k, digidx); + bitcnt = (int) MP_DIGIT_BIT; + --digidx; + } + + /* grab the next msb from the ltiplicand */ + i = (int)((buf >> (MP_DIGIT_BIT - 1)) & 1); + buf <<= 1; + + if (mode == 0 && i == 0) { + /* dummy operations */ + if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], ma, modulus, mp)) != CRYPT_OK) { goto done; } + if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], ma, modulus, mp)) != CRYPT_OK) { goto done; } + continue; + } + + if (mode == 0 && i == 1) { + mode = 1; + /* dummy operations */ + if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], ma, modulus, mp)) != CRYPT_OK) { goto done; } + if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], ma, modulus, mp)) != CRYPT_OK) { goto done; } + continue; + } + + if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[i^1], ma, modulus, mp)) != CRYPT_OK) { goto done; } + if ((err = ltc_mp.ecc_ptdbl(M[i], M[i], ma, modulus, mp)) != CRYPT_OK) { goto done; } + } + + /* copy result out */ + if ((err = mp_copy(M[0]->x, R->x)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(M[0]->y, R->y)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(M[0]->z, R->z)) != CRYPT_OK) { goto done; } + + /* map R back from projective space */ + if (map) { + err = ltc_ecc_map(R, modulus, mp); + } else { + err = CRYPT_OK; + } +done: + if (mu != NULL) { + mp_clear(mu); + } + mp_clear(ma); + mp_montgomery_free(mp); + ltc_ecc_del_point(tG); + for (i = 0; i < 3; i++) { + ltc_ecc_del_point(M[i]); + } + return err; +} + +#endif +#endif +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ + diff --git a/src/ltc/pk/ecc/ltc_ecc_points.c b/src/ltc/pk/ecc/ltc_ecc_points.c new file mode 100644 index 0000000..2b45c72 --- /dev/null +++ b/src/ltc/pk/ecc/ltc_ecc_points.c @@ -0,0 +1,58 @@ +/* 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://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ +#include "tomcrypt.h" + +/** + @file ltc_ecc_points.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/** + Allocate a new ECC point + @return A newly allocated point or NULL on error +*/ +ecc_point *ltc_ecc_new_point(void) +{ + ecc_point *p; + p = XCALLOC(1, sizeof(*p)); + if (p == NULL) { + return NULL; + } + if (mp_init_multi(&p->x, &p->y, &p->z, NULL) != CRYPT_OK) { + XFREE(p); + return NULL; + } + return p; +} + +/** Free an ECC point from memory + @param p The point to free +*/ +void ltc_ecc_del_point(ecc_point *p) +{ + /* prevents free'ing null arguments */ + if (p != NULL) { + mp_clear_multi(p->x, p->y, p->z, NULL); /* note: p->z may be NULL but that's ok with this function anyways */ + XFREE(p); + } +} + +#endif +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ + diff --git a/src/ltc/pk/ecc/ltc_ecc_projective_add_point.c b/src/ltc/pk/ecc/ltc_ecc_projective_add_point.c new file mode 100644 index 0000000..d3d31dc --- /dev/null +++ b/src/ltc/pk/ecc/ltc_ecc_projective_add_point.c @@ -0,0 +1,217 @@ +/* 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://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ +#include "tomcrypt.h" + +/** + @file ltc_ecc_projective_add_point.c + ECC Crypto, Tom St Denis +*/ + +#if defined(LTC_MECC) && (!defined(LTC_MECC_ACCEL) || defined(LTM_DESC)) + +/** + Add two ECC points + @param P The point to add + @param Q The point to add + @param R [out] The destination of the double + @param ma ECC curve parameter a in montgomery form (if NULL we assume a == -3) + @param modulus The modulus of the field the ECC curve is in + @param mp The "b" value from montgomery_setup() + @return CRYPT_OK on success +*/ +int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *ma, void *modulus, void *mp) +{ + void *t1, *t2, *x, *y, *z; + int err; + + LTC_ARGCHK(P != NULL); + LTC_ARGCHK(Q != NULL); + LTC_ARGCHK(R != NULL); + LTC_ARGCHK(modulus != NULL); + LTC_ARGCHK(mp != NULL); + + if ((err = mp_init_multi(&t1, &t2, &x, &y, &z, NULL)) != CRYPT_OK) { + return err; + } + + if (ltc_ecc_is_point_at_infinity(P, modulus)) { + /* P is point at infinity >> Result = Q */ + if ((err = ltc_mp.copy(Q->x, R->x)) != CRYPT_OK) { goto done; } + if ((err = ltc_mp.copy(Q->y, R->y)) != CRYPT_OK) { goto done; } + if ((err = ltc_mp.copy(Q->z, R->z)) != CRYPT_OK) { goto done; } + goto done; /* CRYPT_OK */ + } + + if (ltc_ecc_is_point_at_infinity(Q, modulus)) { + /* Q is point at infinity >> Result = P */ + if ((err = ltc_mp.copy(P->x, R->x)) != CRYPT_OK) { goto done; } + if ((err = ltc_mp.copy(P->y, R->y)) != CRYPT_OK) { goto done; } + if ((err = ltc_mp.copy(P->z, R->z)) != CRYPT_OK) { goto done; } + goto done; /* CRYPT_OK */ + } + + if ((mp_cmp(P->x, Q->x) == LTC_MP_EQ) && (mp_cmp(P->z, Q->z) == LTC_MP_EQ)) { + if (mp_cmp(P->y, Q->y) == LTC_MP_EQ) { + /* here P = Q >> Result = 2 * P (use doubling) */ + mp_clear_multi(t1, t2, x, y, z, NULL); + return ltc_ecc_projective_dbl_point(P, R, ma, modulus, mp); + } + if ((err = mp_sub(modulus, Q->y, t1)) != CRYPT_OK) { goto done; } + if (mp_cmp(P->y, t1) == LTC_MP_EQ) { + /* here Q = -P >>> Result = the point at infinity */ + if ((err = ltc_mp.set_int(R->x, 1)) != CRYPT_OK) { goto done; } + if ((err = ltc_mp.set_int(R->y, 1)) != CRYPT_OK) { goto done; } + if ((err = ltc_mp.set_int(R->z, 0)) != CRYPT_OK) { goto done; } + goto done; /* CRYPT_OK */ + } + } + + if ((err = mp_copy(P->x, x)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(P->y, y)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(P->z, z)) != CRYPT_OK) { goto done; } + + /* if Z is one then these are no-operations */ + if (Q->z != NULL) { + /* T1 = Z' * Z' */ + if ((err = mp_sqr(Q->z, t1)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } + /* X = X * T1 */ + if ((err = mp_mul(t1, x, x)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(x, modulus, mp)) != CRYPT_OK) { goto done; } + /* T1 = Z' * T1 */ + if ((err = mp_mul(Q->z, t1, t1)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } + /* Y = Y * T1 */ + if ((err = mp_mul(t1, y, y)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(y, modulus, mp)) != CRYPT_OK) { goto done; } + } + + /* T1 = Z*Z */ + if ((err = mp_sqr(z, t1)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } + /* T2 = X' * T1 */ + if ((err = mp_mul(Q->x, t1, t2)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } + /* T1 = Z * T1 */ + if ((err = mp_mul(z, t1, t1)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } + /* T1 = Y' * T1 */ + if ((err = mp_mul(Q->y, t1, t1)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } + + /* Y = Y - T1 */ + if ((err = mp_sub(y, t1, y)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(y, 0) == LTC_MP_LT) { + if ((err = mp_add(y, modulus, y)) != CRYPT_OK) { goto done; } + } + /* T1 = 2T1 */ + if ((err = mp_add(t1, t1, t1)) != CRYPT_OK) { goto done; } + if (mp_cmp(t1, modulus) != LTC_MP_LT) { + if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } + } + /* T1 = Y + T1 */ + if ((err = mp_add(t1, y, t1)) != CRYPT_OK) { goto done; } + if (mp_cmp(t1, modulus) != LTC_MP_LT) { + if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } + } + /* X = X - T2 */ + if ((err = mp_sub(x, t2, x)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(x, 0) == LTC_MP_LT) { + if ((err = mp_add(x, modulus, x)) != CRYPT_OK) { goto done; } + } + /* T2 = 2T2 */ + if ((err = mp_add(t2, t2, t2)) != CRYPT_OK) { goto done; } + if (mp_cmp(t2, modulus) != LTC_MP_LT) { + if ((err = mp_sub(t2, modulus, t2)) != CRYPT_OK) { goto done; } + } + /* T2 = X + T2 */ + if ((err = mp_add(t2, x, t2)) != CRYPT_OK) { goto done; } + if (mp_cmp(t2, modulus) != LTC_MP_LT) { + if ((err = mp_sub(t2, modulus, t2)) != CRYPT_OK) { goto done; } + } + + /* if Z' != 1 */ + if (Q->z != NULL) { + /* Z = Z * Z' */ + if ((err = mp_mul(z, Q->z, z)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(z, modulus, mp)) != CRYPT_OK) { goto done; } + } + + /* Z = Z * X */ + if ((err = mp_mul(z, x, z)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(z, modulus, mp)) != CRYPT_OK) { goto done; } + + /* T1 = T1 * X */ + if ((err = mp_mul(t1, x, t1)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } + /* X = X * X */ + if ((err = mp_sqr(x, x)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(x, modulus, mp)) != CRYPT_OK) { goto done; } + /* T2 = T2 * x */ + if ((err = mp_mul(t2, x, t2)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } + /* T1 = T1 * X */ + if ((err = mp_mul(t1, x, t1)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } + + /* X = Y*Y */ + if ((err = mp_sqr(y, x)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(x, modulus, mp)) != CRYPT_OK) { goto done; } + /* X = X - T2 */ + if ((err = mp_sub(x, t2, x)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(x, 0) == LTC_MP_LT) { + if ((err = mp_add(x, modulus, x)) != CRYPT_OK) { goto done; } + } + + /* T2 = T2 - X */ + if ((err = mp_sub(t2, x, t2)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(t2, 0) == LTC_MP_LT) { + if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; } + } + /* T2 = T2 - X */ + if ((err = mp_sub(t2, x, t2)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(t2, 0) == LTC_MP_LT) { + if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; } + } + /* T2 = T2 * Y */ + if ((err = mp_mul(t2, y, t2)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } + /* Y = T2 - T1 */ + if ((err = mp_sub(t2, t1, y)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(y, 0) == LTC_MP_LT) { + if ((err = mp_add(y, modulus, y)) != CRYPT_OK) { goto done; } + } + /* Y = Y/2 */ + if (mp_isodd(y)) { + if ((err = mp_add(y, modulus, y)) != CRYPT_OK) { goto done; } + } + if ((err = mp_div_2(y, y)) != CRYPT_OK) { goto done; } + + if ((err = mp_copy(x, R->x)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(y, R->y)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(z, R->z)) != CRYPT_OK) { goto done; } + + err = CRYPT_OK; +done: + mp_clear_multi(t1, t2, x, y, z, NULL); + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ + diff --git a/src/ltc/pk/ecc/ltc_ecc_projective_dbl_point.c b/src/ltc/pk/ecc/ltc_ecc_projective_dbl_point.c new file mode 100644 index 0000000..f954a59 --- /dev/null +++ b/src/ltc/pk/ecc/ltc_ecc_projective_dbl_point.c @@ -0,0 +1,200 @@ +/* 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://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b + * + */ +#include "tomcrypt.h" + +/* ### Point doubling in Jacobian coordinate system ### + * + * let us have a curve: y^2 = x^3 + a*x + b + * in Jacobian coordinates it becomes: y^2 = x^3 + a*x*z^4 + b*z^6 + * + * The doubling of P = (Xp, Yp, Zp) is given by R = (Xr, Yr, Zr) where: + * Xr = M^2 - 2*S + * Yr = M * (S - Xr) - 8*T + * Zr = 2 * Yp * Zp + * + * M = 3 * Xp^2 + a*Zp^4 + * T = Yp^4 + * S = 4 * Xp * Yp^2 + * + * SPECIAL CASE: when a == -3 we can compute M as + * M = 3 * (Xp^2 - Zp^4) = 3 * (Xp + Zp^2) * (Xp - Zp^2) + */ + +/** + @file ltc_ecc_projective_dbl_point.c + ECC Crypto, Tom St Denis +*/ + +#if defined(LTC_MECC) && (!defined(LTC_MECC_ACCEL) || defined(LTM_DESC)) + +/** + Double an ECC point + @param P The point to double + @param R [out] The destination of the double + @param ma ECC curve parameter a in montgomery form (if NULL we assume a == -3) + @param modulus The modulus of the field the ECC curve is in + @param mp The "b" value from montgomery_setup() + @return CRYPT_OK on success +*/ +int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *ma, void *modulus, void *mp) +{ + void *t1, *t2; + int err; + + LTC_ARGCHK(P != NULL); + LTC_ARGCHK(R != NULL); + LTC_ARGCHK(modulus != NULL); + LTC_ARGCHK(mp != NULL); + + if ((err = mp_init_multi(&t1, &t2, NULL)) != CRYPT_OK) { + return err; + } + + if (P != R) { + if ((err = mp_copy(P->x, R->x)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(P->y, R->y)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(P->z, R->z)) != CRYPT_OK) { goto done; } + } + + if (ltc_ecc_is_point_at_infinity(P, modulus)) { + /* if P is point at infinity >> Result = point at infinity */ + if ((err = ltc_mp.set_int(R->x, 1)) != CRYPT_OK) { goto done; } + if ((err = ltc_mp.set_int(R->y, 1)) != CRYPT_OK) { goto done; } + if ((err = ltc_mp.set_int(R->z, 0)) != CRYPT_OK) { goto done; } + goto done; /* CRYPT_OK */ + } + + /* t1 = Z * Z */ + if ((err = mp_sqr(R->z, t1)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } + /* Z = Y * Z */ + if ((err = mp_mul(R->z, R->y, R->z)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(R->z, modulus, mp)) != CRYPT_OK) { goto done; } + /* Z = 2Z */ + if ((err = mp_add(R->z, R->z, R->z)) != CRYPT_OK) { goto done; } + if (mp_cmp(R->z, modulus) != LTC_MP_LT) { + if ((err = mp_sub(R->z, modulus, R->z)) != CRYPT_OK) { goto done; } + } + + if (ma == NULL) { /* special case for ma == -3 (slightly faster than general case) */ + /* T2 = X - T1 */ + if ((err = mp_sub(R->x, t1, t2)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(t2, 0) == LTC_MP_LT) { + if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; } + } + /* T1 = X + T1 */ + if ((err = mp_add(t1, R->x, t1)) != CRYPT_OK) { goto done; } + if (mp_cmp(t1, modulus) != LTC_MP_LT) { + if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } + } + /* T2 = T1 * T2 */ + if ((err = mp_mul(t1, t2, t2)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } + /* T1 = 2T2 */ + if ((err = mp_add(t2, t2, t1)) != CRYPT_OK) { goto done; } + if (mp_cmp(t1, modulus) != LTC_MP_LT) { + if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } + } + /* T1 = T1 + T2 */ + if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; } + if (mp_cmp(t1, modulus) != LTC_MP_LT) { + if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } + } + } + else { + /* T2 = T1 * T1 */ + if ((err = mp_sqr(t1, t2)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } + /* T1 = T2 * a */ + if ((err = mp_mul(t2, ma, t1)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } + /* T2 = X * X */ + if ((err = mp_sqr(R->x, t2)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } + /* T1 = T2 + T1 */ + if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; } + if (mp_cmp(t1, modulus) != LTC_MP_LT) { + if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } + } + /* T1 = T2 + T1 */ + if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; } + if (mp_cmp(t1, modulus) != LTC_MP_LT) { + if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } + } + /* T1 = T2 + T1 */ + if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; } + if (mp_cmp(t1, modulus) != LTC_MP_LT) { + if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } + } + } + + /* Y = 2Y */ + if ((err = mp_add(R->y, R->y, R->y)) != CRYPT_OK) { goto done; } + if (mp_cmp(R->y, modulus) != LTC_MP_LT) { + if ((err = mp_sub(R->y, modulus, R->y)) != CRYPT_OK) { goto done; } + } + /* Y = Y * Y */ + if ((err = mp_sqr(R->y, R->y)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(R->y, modulus, mp)) != CRYPT_OK) { goto done; } + /* T2 = Y * Y */ + if ((err = mp_sqr(R->y, t2)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } + /* T2 = T2/2 */ + if (mp_isodd(t2)) { + if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; } + } + if ((err = mp_div_2(t2, t2)) != CRYPT_OK) { goto done; } + /* Y = Y * X */ + if ((err = mp_mul(R->y, R->x, R->y)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(R->y, modulus, mp)) != CRYPT_OK) { goto done; } + + /* X = T1 * T1 */ + if ((err = mp_sqr(t1, R->x)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(R->x, modulus, mp)) != CRYPT_OK) { goto done; } + /* X = X - Y */ + if ((err = mp_sub(R->x, R->y, R->x)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(R->x, 0) == LTC_MP_LT) { + if ((err = mp_add(R->x, modulus, R->x)) != CRYPT_OK) { goto done; } + } + /* X = X - Y */ + if ((err = mp_sub(R->x, R->y, R->x)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(R->x, 0) == LTC_MP_LT) { + if ((err = mp_add(R->x, modulus, R->x)) != CRYPT_OK) { goto done; } + } + + /* Y = Y - X */ + if ((err = mp_sub(R->y, R->x, R->y)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(R->y, 0) == LTC_MP_LT) { + if ((err = mp_add(R->y, modulus, R->y)) != CRYPT_OK) { goto done; } + } + /* Y = Y * T1 */ + if ((err = mp_mul(R->y, t1, R->y)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(R->y, modulus, mp)) != CRYPT_OK) { goto done; } + /* Y = Y - T2 */ + if ((err = mp_sub(R->y, t2, R->y)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(R->y, 0) == LTC_MP_LT) { + if ((err = mp_add(R->y, modulus, R->y)) != CRYPT_OK) { goto done; } + } + + err = CRYPT_OK; +done: + mp_clear_multi(t1, t2, NULL); + return err; +} +#endif +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ + diff --git a/src/ltc/pk/pkcs1/pkcs_1_i2osp.c b/src/ltc/pk/pkcs1/pkcs_1_i2osp.c new file mode 100644 index 0000000..b4cb4fe --- /dev/null +++ b/src/ltc/pk/pkcs1/pkcs_1_i2osp.c @@ -0,0 +1,51 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pkcs_1_i2osp.c + Integer to Octet I2OSP, Tom St Denis +*/ + +#ifdef LTC_PKCS_1 + +/* always stores the same # of bytes, pads with leading zero bytes + as required + */ + +/** + PKCS #1 Integer to binary + @param n The integer to store + @param modulus_len The length of the RSA modulus + @param out [out] The destination for the integer + @return CRYPT_OK if successful +*/ +int pkcs_1_i2osp(void *n, unsigned long modulus_len, unsigned char *out) +{ + unsigned long size; + + size = mp_unsigned_bin_size(n); + + if (size > modulus_len) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* store it */ + zeromem(out, modulus_len); + return mp_to_unsigned_bin(n, out+(modulus_len-size)); +} + +#endif /* LTC_PKCS_1 */ + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/pkcs1/pkcs_1_mgf1.c b/src/ltc/pk/pkcs1/pkcs_1_mgf1.c new file mode 100644 index 0000000..a063128 --- /dev/null +++ b/src/ltc/pk/pkcs1/pkcs_1_mgf1.c @@ -0,0 +1,108 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pkcs_1_mgf1.c + The Mask Generation Function (MGF1) for PKCS #1, Tom St Denis +*/ + +#ifdef LTC_PKCS_1 + +/** + Perform PKCS #1 MGF1 (internal) + @param hash_idx The index of the hash desired + @param seed The seed for MGF1 + @param seedlen The length of the seed + @param mask [out] The destination + @param masklen The length of the mask desired + @return CRYPT_OK if successful +*/ +int pkcs_1_mgf1(int hash_idx, + const unsigned char *seed, unsigned long seedlen, + unsigned char *mask, unsigned long masklen) +{ + unsigned long hLen, x; + ulong32 counter; + int err; + hash_state *md; + unsigned char *buf; + + LTC_ARGCHK(seed != NULL); + LTC_ARGCHK(mask != NULL); + + /* ensure valid hash */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + + /* get hash output size */ + hLen = hash_descriptor[hash_idx].hashsize; + + /* allocate memory */ + md = XMALLOC(sizeof(hash_state)); + buf = XMALLOC(hLen); + if (md == NULL || buf == NULL) { + if (md != NULL) { + XFREE(md); + } + if (buf != NULL) { + XFREE(buf); + } + return CRYPT_MEM; + } + + /* start counter */ + counter = 0; + + while (masklen > 0) { + /* handle counter */ + STORE32H(counter, buf); + ++counter; + + /* get hash of seed || counter */ + if ((err = hash_descriptor[hash_idx].init(md)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].process(md, seed, seedlen)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].process(md, buf, 4)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].done(md, buf)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* store it */ + for (x = 0; x < hLen && masklen > 0; x++, masklen--) { + *mask++ = buf[x]; + } + } + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(buf, hLen); + zeromem(md, sizeof(hash_state)); +#endif + + XFREE(buf); + XFREE(md); + + return err; +} + +#endif /* LTC_PKCS_1 */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/pkcs1/pkcs_1_oaep_decode.c b/src/ltc/pk/pkcs1/pkcs_1_oaep_decode.c new file mode 100644 index 0000000..469e3e1 --- /dev/null +++ b/src/ltc/pk/pkcs1/pkcs_1_oaep_decode.c @@ -0,0 +1,187 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pkcs_1_oaep_decode.c + OAEP Padding for PKCS #1, Tom St Denis +*/ + +#ifdef LTC_PKCS_1 + +/** + PKCS #1 v2.00 OAEP decode + @param msg The encoded data to decode + @param msglen The length of the encoded data (octets) + @param lparam The session or system data (can be NULL) + @param lparamlen The length of the lparam + @param modulus_bitlen The bit length of the RSA modulus + @param hash_idx The index of the hash desired + @param out [out] Destination of decoding + @param outlen [in/out] The max size and resulting size of the decoding + @param res [out] Result of decoding, 1==valid, 0==invalid + @return CRYPT_OK if successful +*/ +int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, + const unsigned char *lparam, unsigned long lparamlen, + unsigned long modulus_bitlen, int hash_idx, + unsigned char *out, unsigned long *outlen, + int *res) +{ + unsigned char *DB, *seed, *mask; + unsigned long hLen, x, y, modulus_len; + int err, ret; + + LTC_ARGCHK(msg != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(res != NULL); + + /* default to invalid packet */ + *res = 0; + + /* test valid hash */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + 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); + seed = XMALLOC(hLen); + if (DB == NULL || mask == NULL || seed == NULL) { + if (DB != NULL) { + XFREE(DB); + } + if (mask != NULL) { + XFREE(mask); + } + if (seed != NULL) { + XFREE(seed); + } + return CRYPT_MEM; + } + + /* ok so it's now in the form + + 0x00 || maskedseed || maskedDB + + 1 || hLen || modulus_len - hLen - 1 + + */ + + ret = CRYPT_OK; + + /* must have leading 0x00 byte */ + if (msg[0] != 0x00) { + ret = CRYPT_INVALID_PACKET; + } + + /* now read the masked seed */ + x = 1; + XMEMCPY(seed, msg + x, hLen); + x += hLen; + + /* now read the masked DB */ + XMEMCPY(DB, msg + x, modulus_len - hLen - 1); + x += modulus_len - hLen - 1; + + /* compute MGF1 of maskedDB (hLen) */ + if ((err = pkcs_1_mgf1(hash_idx, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* XOR against seed */ + for (y = 0; y < hLen; y++) { + seed[y] ^= mask[y]; + } + + /* compute MGF1 of seed (k - hlen - 1) */ + if ((err = pkcs_1_mgf1(hash_idx, seed, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* xor against DB */ + for (y = 0; y < (modulus_len - hLen - 1); y++) { + DB[y] ^= mask[y]; + } + + /* now DB == lhash || PS || 0x01 || M, PS == k - mlen - 2hlen - 2 zeroes */ + + /* compute lhash and store it in seed [reuse temps!] */ + x = modulus_len; + if (lparam != NULL) { + if ((err = hash_memory(hash_idx, lparam, lparamlen, seed, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + } else { + /* can't pass hash_memory a NULL so use DB with zero length */ + if ((err = hash_memory(hash_idx, DB, 0, seed, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + } + + /* compare the lhash'es */ + if (XMEM_NEQ(seed, DB, hLen) != 0) { + ret = CRYPT_INVALID_PACKET; + } + + /* now zeroes before a 0x01 */ + for (x = hLen; x < (modulus_len - hLen - 1) && DB[x] == 0x00; x++) { + /* step... */ + } + + /* error if wasn't 0x01 */ + if (x == (modulus_len - hLen - 1) || DB[x] != 0x01) { + ret = CRYPT_INVALID_PACKET; + } + + /* rest is the message (and skip 0x01) */ + if ((modulus_len - hLen - 1 - ++x) > *outlen) { + ret = CRYPT_INVALID_PACKET; + } + + if (ret == CRYPT_OK) { + /* copy message */ + *outlen = modulus_len - hLen - 1 - x; + XMEMCPY(out, DB + x, modulus_len - hLen - 1 - x); + + /* valid packet */ + *res = 1; + } + err = ret; + +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(DB, modulus_len); + zeromem(seed, hLen); + zeromem(mask, modulus_len); +#endif + + XFREE(seed); + XFREE(mask); + XFREE(DB); + + return err; +} + +#endif /* LTC_PKCS_1 */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/pkcs1/pkcs_1_oaep_encode.c b/src/ltc/pk/pkcs1/pkcs_1_oaep_encode.c new file mode 100644 index 0000000..fb215a1 --- /dev/null +++ b/src/ltc/pk/pkcs1/pkcs_1_oaep_encode.c @@ -0,0 +1,173 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pkcs_1_oaep_encode.c + OAEP Padding for PKCS #1, Tom St Denis +*/ + +#ifdef LTC_PKCS_1 + +/** + PKCS #1 v2.00 OAEP encode + @param msg The data to encode + @param msglen The length of the data to encode (octets) + @param lparam A session or system parameter (can be NULL) + @param lparamlen The length of the lparam data + @param modulus_bitlen The bit length of the RSA modulus + @param prng An active PRNG state + @param prng_idx The index of the PRNG desired + @param hash_idx The index of the hash desired + @param out [out] The destination for the encoded data + @param outlen [in/out] The max size and resulting size of the encoded data + @return CRYPT_OK if successful +*/ +int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, + const unsigned char *lparam, unsigned long lparamlen, + unsigned long modulus_bitlen, prng_state *prng, + int prng_idx, int hash_idx, + unsigned char *out, unsigned long *outlen) +{ + unsigned char *DB, *seed, *mask; + unsigned long hLen, x, y, modulus_len; + int err; + + LTC_ARGCHK(msg != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* test valid hash */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + + /* valid prng */ + if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { + return err; + } + + 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); + seed = XMALLOC(hLen); + if (DB == NULL || mask == NULL || seed == NULL) { + if (DB != NULL) { + XFREE(DB); + } + if (mask != NULL) { + XFREE(mask); + } + if (seed != NULL) { + XFREE(seed); + } + return CRYPT_MEM; + } + + /* get lhash */ + /* DB == lhash || PS || 0x01 || M, PS == k - mlen - 2hlen - 2 zeroes */ + x = modulus_len; + if (lparam != NULL) { + if ((err = hash_memory(hash_idx, lparam, lparamlen, DB, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + } else { + /* can't pass hash_memory a NULL so use DB with zero length */ + if ((err = hash_memory(hash_idx, DB, 0, DB, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + } + + /* append PS then 0x01 (to lhash) */ + x = hLen; + y = modulus_len - msglen - 2*hLen - 2; + XMEMSET(DB+x, 0, y); + x += y; + + /* 0x01 byte */ + DB[x++] = 0x01; + + /* message (length = msglen) */ + XMEMCPY(DB+x, msg, msglen); + x += msglen; + + /* now choose a random seed */ + if (prng_descriptor[prng_idx].read(seed, hLen, prng) != hLen) { + err = CRYPT_ERROR_READPRNG; + goto LBL_ERR; + } + + /* compute MGF1 of seed (k - hlen - 1) */ + if ((err = pkcs_1_mgf1(hash_idx, seed, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* xor against DB */ + for (y = 0; y < (modulus_len - hLen - 1); y++) { + DB[y] ^= mask[y]; + } + + /* compute MGF1 of maskedDB (hLen) */ + if ((err = pkcs_1_mgf1(hash_idx, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* XOR against seed */ + for (y = 0; y < hLen; y++) { + seed[y] ^= mask[y]; + } + + /* create string of length modulus_len */ + if (*outlen < modulus_len) { + *outlen = modulus_len; + err = CRYPT_BUFFER_OVERFLOW; + goto LBL_ERR; + } + + /* start output which is 0x00 || maskedSeed || maskedDB */ + x = 0; + out[x++] = 0x00; + XMEMCPY(out+x, seed, hLen); + x += hLen; + XMEMCPY(out+x, DB, modulus_len - hLen - 1); + x += modulus_len - hLen - 1; + + *outlen = x; + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(DB, modulus_len); + zeromem(seed, hLen); + zeromem(mask, modulus_len); +#endif + + XFREE(seed); + XFREE(mask); + XFREE(DB); + + return err; +} + +#endif /* LTC_PKCS_1 */ + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/pkcs1/pkcs_1_os2ip.c b/src/ltc/pk/pkcs1/pkcs_1_os2ip.c new file mode 100644 index 0000000..5fe97ea --- /dev/null +++ b/src/ltc/pk/pkcs1/pkcs_1_os2ip.c @@ -0,0 +1,36 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pkcs_1_os2ip.c + Octet to Integer OS2IP, Tom St Denis +*/ +#ifdef LTC_PKCS_1 + +/** + Read a binary string into an mp_int + @param n [out] The mp_int destination + @param in The binary string to read + @param inlen The length of the binary string + @return CRYPT_OK if successful +*/ +int pkcs_1_os2ip(void *n, unsigned char *in, unsigned long inlen) +{ + return mp_read_unsigned_bin(n, in, inlen); +} + +#endif /* LTC_PKCS_1 */ + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/pkcs1/pkcs_1_pss_decode.c b/src/ltc/pk/pkcs1/pkcs_1_pss_decode.c new file mode 100644 index 0000000..0fdf926 --- /dev/null +++ b/src/ltc/pk/pkcs1/pkcs_1_pss_decode.c @@ -0,0 +1,178 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pkcs_1_pss_decode.c + PKCS #1 PSS Signature Padding, Tom St Denis +*/ + +#ifdef LTC_PKCS_1 + +/** + PKCS #1 v2.00 PSS decode + @param msghash The hash to verify + @param msghashlen The length of the hash (octets) + @param sig The signature data (encoded data) + @param siglen The length of the signature data (octets) + @param saltlen The length of the salt used (octets) + @param hash_idx The index of the hash desired + @param modulus_bitlen The bit length of the RSA modulus + @param res [out] The result of the comparison, 1==valid, 0==invalid + @return CRYPT_OK if successful (even if the comparison failed) +*/ +int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, + const unsigned char *sig, unsigned long siglen, + unsigned long saltlen, int hash_idx, + unsigned long modulus_bitlen, int *res) +{ + unsigned char *DB, *mask, *salt, *hash; + unsigned long x, y, hLen, modulus_len; + int err; + hash_state md; + + LTC_ARGCHK(msghash != NULL); + LTC_ARGCHK(res != NULL); + + /* default to invalid */ + *res = 0; + + /* ensure hash is valid */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + + hLen = hash_descriptor[hash_idx].hashsize; + modulus_bitlen--; + 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); + salt = XMALLOC(modulus_len); + hash = XMALLOC(modulus_len); + if (DB == NULL || mask == NULL || salt == NULL || hash == NULL) { + if (DB != NULL) { + XFREE(DB); + } + if (mask != NULL) { + XFREE(mask); + } + if (salt != NULL) { + XFREE(salt); + } + if (hash != NULL) { + XFREE(hash); + } + return CRYPT_MEM; + } + + /* ensure the 0xBC byte */ + if (sig[siglen-1] != 0xBC) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + + /* copy out the DB */ + x = 0; + XMEMCPY(DB, sig + x, modulus_len - hLen - 1); + x += modulus_len - hLen - 1; + + /* copy out the hash */ + XMEMCPY(hash, sig + x, hLen); + /* x += hLen; */ + + /* check the MSB */ + if ((sig[0] & ~(0xFF >> ((modulus_len<<3) - (modulus_bitlen)))) != 0) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + + /* generate mask of length modulus_len - hLen - 1 from hash */ + if ((err = pkcs_1_mgf1(hash_idx, hash, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* xor against DB */ + for (y = 0; y < (modulus_len - hLen - 1); y++) { + DB[y] ^= mask[y]; + } + + /* now clear the first byte [make sure smaller than modulus] */ + DB[0] &= 0xFF >> ((modulus_len<<3) - (modulus_bitlen)); + + /* DB = PS || 0x01 || salt, PS == modulus_len - saltlen - hLen - 2 zero bytes */ + + /* check for zeroes and 0x01 */ + for (x = 0; x < modulus_len - saltlen - hLen - 2; x++) { + if (DB[x] != 0x00) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + } + + /* check for the 0x01 */ + if (DB[x++] != 0x01) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + + /* M = (eight) 0x00 || msghash || salt, mask = H(M) */ + if ((err = hash_descriptor[hash_idx].init(&md)) != CRYPT_OK) { + goto LBL_ERR; + } + zeromem(mask, 8); + if ((err = hash_descriptor[hash_idx].process(&md, mask, 8)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].process(&md, msghash, msghashlen)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].process(&md, DB+x, saltlen)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].done(&md, mask)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* mask == hash means valid signature */ + if (XMEM_NEQ(mask, hash, hLen) == 0) { + *res = 1; + } + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(DB, modulus_len); + zeromem(mask, modulus_len); + zeromem(salt, modulus_len); + zeromem(hash, modulus_len); +#endif + + XFREE(hash); + XFREE(salt); + XFREE(mask); + XFREE(DB); + + return err; +} + +#endif /* LTC_PKCS_1 */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/pkcs1/pkcs_1_pss_encode.c b/src/ltc/pk/pkcs1/pkcs_1_pss_encode.c new file mode 100644 index 0000000..7766c77 --- /dev/null +++ b/src/ltc/pk/pkcs1/pkcs_1_pss_encode.c @@ -0,0 +1,176 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file pkcs_1_pss_encode.c + PKCS #1 PSS Signature Padding, Tom St Denis +*/ + +#ifdef LTC_PKCS_1 + +/** + PKCS #1 v2.00 Signature Encoding + @param msghash The hash to encode + @param msghashlen The length of the hash (octets) + @param saltlen The length of the salt desired (octets) + @param prng An active PRNG context + @param prng_idx The index of the PRNG desired + @param hash_idx The index of the hash desired + @param modulus_bitlen The bit length of the RSA modulus + @param out [out] The destination of the encoding + @param outlen [in/out] The max size and resulting size of the encoded data + @return CRYPT_OK if successful +*/ +int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, + unsigned long saltlen, prng_state *prng, + int prng_idx, int hash_idx, + unsigned long modulus_bitlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned char *DB, *mask, *salt, *hash; + unsigned long x, y, hLen, modulus_len; + int err; + hash_state md; + + LTC_ARGCHK(msghash != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* ensure hash and PRNG are valid */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { + return err; + } + + hLen = hash_descriptor[hash_idx].hashsize; + modulus_bitlen--; + 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); + salt = XMALLOC(modulus_len); + hash = XMALLOC(modulus_len); + if (DB == NULL || mask == NULL || salt == NULL || hash == NULL) { + if (DB != NULL) { + XFREE(DB); + } + if (mask != NULL) { + XFREE(mask); + } + if (salt != NULL) { + XFREE(salt); + } + if (hash != NULL) { + XFREE(hash); + } + return CRYPT_MEM; + } + + + /* generate random salt */ + if (saltlen > 0) { + if (prng_descriptor[prng_idx].read(salt, saltlen, prng) != saltlen) { + err = CRYPT_ERROR_READPRNG; + goto LBL_ERR; + } + } + + /* M = (eight) 0x00 || msghash || salt, hash = H(M) */ + if ((err = hash_descriptor[hash_idx].init(&md)) != CRYPT_OK) { + goto LBL_ERR; + } + zeromem(DB, 8); + if ((err = hash_descriptor[hash_idx].process(&md, DB, 8)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].process(&md, msghash, msghashlen)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].process(&md, salt, saltlen)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].done(&md, hash)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* generate DB = PS || 0x01 || salt, PS == modulus_len - saltlen - hLen - 2 zero bytes */ + x = 0; + XMEMSET(DB + x, 0, modulus_len - saltlen - hLen - 2); + x += modulus_len - saltlen - hLen - 2; + DB[x++] = 0x01; + XMEMCPY(DB + x, salt, saltlen); + /* x += saltlen; */ + + /* generate mask of length modulus_len - hLen - 1 from hash */ + if ((err = pkcs_1_mgf1(hash_idx, hash, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* xor against DB */ + for (y = 0; y < (modulus_len - hLen - 1); y++) { + DB[y] ^= mask[y]; + } + + /* output is DB || hash || 0xBC */ + if (*outlen < modulus_len) { + *outlen = modulus_len; + err = CRYPT_BUFFER_OVERFLOW; + goto LBL_ERR; + } + + /* DB len = modulus_len - hLen - 1 */ + y = 0; + XMEMCPY(out + y, DB, modulus_len - hLen - 1); + y += modulus_len - hLen - 1; + + /* hash */ + XMEMCPY(out + y, hash, hLen); + y += hLen; + + /* 0xBC */ + out[y] = 0xBC; + + /* now clear the 8*modulus_len - modulus_bitlen most significant bits */ + out[0] &= 0xFF >> ((modulus_len<<3) - modulus_bitlen); + + /* store output size */ + *outlen = modulus_len; + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(DB, modulus_len); + zeromem(mask, modulus_len); + zeromem(salt, modulus_len); + zeromem(hash, modulus_len); +#endif + + XFREE(hash); + XFREE(salt); + XFREE(mask); + XFREE(DB); + + return err; +} + +#endif /* LTC_PKCS_1 */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/pkcs1/pkcs_1_v1_5_decode.c b/src/ltc/pk/pkcs1/pkcs_1_v1_5_decode.c new file mode 100644 index 0000000..34bb434 --- /dev/null +++ b/src/ltc/pk/pkcs1/pkcs_1_v1_5_decode.c @@ -0,0 +1,114 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** @file pkcs_1_v1_5_decode.c + * + * PKCS #1 v1.5 Padding. (Andreas Lange) + */ + +#ifdef LTC_PKCS_1 + +/** @brief PKCS #1 v1.5 decode. + * + * @param msg The encoded data to decode + * @param msglen The length of the encoded data (octets) + * @param block_type Block type to use in padding (\sa ltc_pkcs_1_v1_5_blocks) + * @param modulus_bitlen The bit length of the RSA modulus + * @param out [out] Destination of decoding + * @param outlen [in/out] The max size and resulting size of the decoding + * @param is_valid [out] Boolean whether the padding was valid + * + * @return CRYPT_OK if successful + */ +int pkcs_1_v1_5_decode(const unsigned char *msg, + unsigned long msglen, + int block_type, + unsigned long modulus_bitlen, + unsigned char *out, + unsigned long *outlen, + int *is_valid) +{ + unsigned long modulus_len, ps_len, i; + int result; + + /* default to invalid packet */ + *is_valid = 0; + + modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); + + /* test message size */ + + if ((msglen > modulus_len) || (modulus_len < 11)) { + return CRYPT_PK_INVALID_SIZE; + } + + result = CRYPT_OK; + + /* separate encoded message */ + + if ((msg[0] != 0x00) || (msg[1] != (unsigned char)block_type)) { + result = CRYPT_INVALID_PACKET; + } + + if (block_type == LTC_PKCS_1_EME) { + for (i = 2; i < modulus_len; i++) { + /* separator */ + if (msg[i] == 0x00) { break; } + } + ps_len = i++ - 2; + + if (i >= modulus_len) { + /* There was no octet with hexadecimal value 0x00 to separate ps from m. + */ + result = CRYPT_INVALID_PACKET; + } + } else { + for (i = 2; i < modulus_len - 1; i++) { + if (msg[i] != 0xFF) { break; } + } + + /* separator check */ + if (msg[i] != 0) { + /* There was no octet with hexadecimal value 0x00 to separate ps from m. */ + result = CRYPT_INVALID_PACKET; + } + + ps_len = i - 2; + } + + if (ps_len < 8) + { + /* The length of ps is less than 8 octets. + */ + result = CRYPT_INVALID_PACKET; + } + + if (*outlen < (msglen - (2 + ps_len + 1))) { + result = CRYPT_INVALID_PACKET; + } + + if (result == CRYPT_OK) { + *outlen = (msglen - (2 + ps_len + 1)); + XMEMCPY(out, &msg[2 + ps_len + 1], *outlen); + + /* valid packet */ + *is_valid = 1; + } + + return result; +} /* pkcs_1_v1_5_decode */ + +#endif /* #ifdef LTC_PKCS_1 */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/pkcs1/pkcs_1_v1_5_encode.c b/src/ltc/pk/pkcs1/pkcs_1_v1_5_encode.c new file mode 100644 index 0000000..ec932c3 --- /dev/null +++ b/src/ltc/pk/pkcs1/pkcs_1_v1_5_encode.c @@ -0,0 +1,111 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/*! \file pkcs_1_v1_5_encode.c + * + * PKCS #1 v1.5 Padding (Andreas Lange) + */ + +#ifdef LTC_PKCS_1 + +/*! \brief PKCS #1 v1.5 encode. + * + * \param msg The data to encode + * \param msglen The length of the data to encode (octets) + * \param block_type Block type to use in padding (\sa ltc_pkcs_1_v1_5_blocks) + * \param modulus_bitlen The bit length of the RSA modulus + * \param prng An active PRNG state (only for LTC_PKCS_1_EME) + * \param prng_idx The index of the PRNG desired (only for LTC_PKCS_1_EME) + * \param out [out] The destination for the encoded data + * \param outlen [in/out] The max size and resulting size of the encoded data + * + * \return CRYPT_OK if successful + */ +int pkcs_1_v1_5_encode(const unsigned char *msg, + unsigned long msglen, + int block_type, + unsigned long modulus_bitlen, + prng_state *prng, + int prng_idx, + unsigned char *out, + unsigned long *outlen) +{ + unsigned long modulus_len, ps_len, i; + unsigned char *ps; + int result; + + /* valid block_type? */ + if ((block_type != LTC_PKCS_1_EMSA) && + (block_type != LTC_PKCS_1_EME)) { + return CRYPT_PK_INVALID_PADDING; + } + + if (block_type == LTC_PKCS_1_EME) { /* encryption padding, we need a valid PRNG */ + if ((result = prng_is_valid(prng_idx)) != CRYPT_OK) { + return result; + } + } + + modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); + + /* test message size */ + if ((msglen + 11) > modulus_len) { + return CRYPT_PK_INVALID_SIZE; + } + + if (*outlen < modulus_len) { + *outlen = modulus_len; + result = CRYPT_BUFFER_OVERFLOW; + goto bail; + } + + /* generate an octets string PS */ + ps = &out[2]; + ps_len = modulus_len - msglen - 3; + + if (block_type == LTC_PKCS_1_EME) { + /* now choose a random ps */ + if (prng_descriptor[prng_idx].read(ps, ps_len, prng) != ps_len) { + result = CRYPT_ERROR_READPRNG; + goto bail; + } + + /* transform zero bytes (if any) to non-zero random bytes */ + for (i = 0; i < ps_len; i++) { + while (ps[i] == 0) { + if (prng_descriptor[prng_idx].read(&ps[i], 1, prng) != 1) { + result = CRYPT_ERROR_READPRNG; + goto bail; + } + } + } + } else { + XMEMSET(ps, 0xFF, ps_len); + } + + /* create string of length modulus_len */ + out[0] = 0x00; + out[1] = (unsigned char)block_type; /* block_type 1 or 2 */ + out[2 + ps_len] = 0x00; + XMEMCPY(&out[2 + ps_len + 1], msg, msglen); + *outlen = modulus_len; + + result = CRYPT_OK; +bail: + return result; +} /* pkcs_1_v1_5_encode */ + +#endif /* #ifdef LTC_PKCS_1 */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/rsa/rsa_decrypt_key.c b/src/ltc/pk/rsa/rsa_decrypt_key.c new file mode 100644 index 0000000..1f322ca --- /dev/null +++ b/src/ltc/pk/rsa/rsa_decrypt_key.c @@ -0,0 +1,105 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file rsa_decrypt_key.c + RSA PKCS #1 Decryption, Tom St Denis and Andreas Lange +*/ + +#ifdef LTC_MRSA + +/** + PKCS #1 decrypt then v1.5 or OAEP depad + @param in The ciphertext + @param inlen The length of the ciphertext (octets) + @param out [out] The plaintext + @param outlen [in/out] The max size and resulting size of the plaintext (octets) + @param lparam The system "lparam" value + @param lparamlen The length of the lparam value (octets) + @param hash_idx The index of the hash desired + @param padding Type of padding (LTC_PKCS_1_OAEP or LTC_PKCS_1_V1_5) + @param stat [out] Result of the decryption, 1==valid, 0==invalid + @param key The corresponding private RSA key + @return CRYPT_OK if succcessul (even if invalid) +*/ +int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const unsigned char *lparam, unsigned long lparamlen, + int hash_idx, int padding, + int *stat, rsa_key *key) +{ + unsigned long modulus_bitlen, modulus_bytelen, x; + int err; + unsigned char *tmp; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(stat != NULL); + + /* default to invalid */ + *stat = 0; + + /* valid padding? */ + + if ((padding != LTC_PKCS_1_V1_5) && + (padding != LTC_PKCS_1_OAEP)) { + return CRYPT_PK_INVALID_PADDING; + } + + if (padding == LTC_PKCS_1_OAEP) { + /* valid hash ? */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + } + + /* get modulus len in bits */ + modulus_bitlen = mp_count_bits( (key->N)); + + /* outlen must be at least the size of the modulus */ + modulus_bytelen = mp_unsigned_bin_size( (key->N)); + if (modulus_bytelen != inlen) { + return CRYPT_INVALID_PACKET; + } + + /* allocate ram */ + tmp = XMALLOC(inlen); + if (tmp == NULL) { + return CRYPT_MEM; + } + + /* rsa decode the packet */ + x = inlen; + if ((err = ltc_mp.rsa_me(in, inlen, tmp, &x, PK_PRIVATE, key)) != CRYPT_OK) { + XFREE(tmp); + return err; + } + + if (padding == LTC_PKCS_1_OAEP) { + /* now OAEP decode the packet */ + err = pkcs_1_oaep_decode(tmp, x, lparam, lparamlen, modulus_bitlen, hash_idx, + out, outlen, stat); + } else { + /* now PKCS #1 v1.5 depad the packet */ + err = pkcs_1_v1_5_decode(tmp, x, LTC_PKCS_1_EME, modulus_bitlen, out, outlen, stat); + } + + XFREE(tmp); + return err; +} + +#endif /* LTC_MRSA */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/rsa/rsa_encrypt_key.c b/src/ltc/pk/rsa/rsa_encrypt_key.c new file mode 100644 index 0000000..4d6c24b --- /dev/null +++ b/src/ltc/pk/rsa/rsa_encrypt_key.c @@ -0,0 +1,102 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file rsa_encrypt_key.c + RSA PKCS #1 encryption, Tom St Denis and Andreas Lange +*/ + +#ifdef LTC_MRSA + +/** + (PKCS #1 v2.0) OAEP pad then encrypt + @param in The plaintext + @param inlen The length of the plaintext (octets) + @param out [out] The ciphertext + @param outlen [in/out] The max size and resulting size of the ciphertext + @param lparam The system "lparam" for the encryption + @param lparamlen The length of lparam (octets) + @param prng An active PRNG + @param prng_idx The index of the desired prng + @param hash_idx The index of the desired hash + @param padding Type of padding (LTC_PKCS_1_OAEP or LTC_PKCS_1_V1_5) + @param key The RSA key to encrypt to + @return CRYPT_OK if successful +*/ +int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const unsigned char *lparam, unsigned long lparamlen, + prng_state *prng, int prng_idx, int hash_idx, int padding, rsa_key *key) +{ + unsigned long modulus_bitlen, modulus_bytelen, x; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* valid padding? */ + if ((padding != LTC_PKCS_1_V1_5) && + (padding != LTC_PKCS_1_OAEP)) { + return CRYPT_PK_INVALID_PADDING; + } + + /* valid prng? */ + if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { + return err; + } + + if (padding == LTC_PKCS_1_OAEP) { + /* valid hash? */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + } + + /* get modulus len in bits */ + modulus_bitlen = mp_count_bits( (key->N)); + + /* outlen must be at least the size of the modulus */ + modulus_bytelen = mp_unsigned_bin_size( (key->N)); + if (modulus_bytelen > *outlen) { + *outlen = modulus_bytelen; + return CRYPT_BUFFER_OVERFLOW; + } + + if (padding == LTC_PKCS_1_OAEP) { + /* OAEP pad the key */ + x = *outlen; + if ((err = pkcs_1_oaep_encode(in, inlen, lparam, + lparamlen, modulus_bitlen, prng, prng_idx, hash_idx, + out, &x)) != CRYPT_OK) { + return err; + } + } else { + /* PKCS #1 v1.5 pad the key */ + x = *outlen; + if ((err = pkcs_1_v1_5_encode(in, inlen, LTC_PKCS_1_EME, + modulus_bitlen, prng, prng_idx, + out, &x)) != CRYPT_OK) { + return err; + } + } + + /* rsa exptmod the OAEP or PKCS #1 v1.5 pad */ + return ltc_mp.rsa_me(out, x, out, outlen, PK_PUBLIC, key); +} + +#endif /* LTC_MRSA */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/rsa/rsa_export.c b/src/ltc/pk/rsa/rsa_export.c new file mode 100644 index 0000000..f869ff6 --- /dev/null +++ b/src/ltc/pk/rsa/rsa_export.c @@ -0,0 +1,99 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file rsa_export.c + Export RSA PKCS keys, Tom St Denis +*/ + +#ifdef LTC_MRSA + +/** + This will export either an RSAPublicKey or RSAPrivateKey [defined in PKCS #1 v2.1] + @param out [out] Destination of the packet + @param outlen [in/out] The max size and resulting size of the packet + @param type The type of exported key (PK_PRIVATE or PK_PUBLIC) + @param key The RSA key to export + @return CRYPT_OK if successful +*/ +int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key) +{ + unsigned long zero=0; + int err; + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* type valid? */ + if (!(key->type == PK_PRIVATE) && (type == PK_PRIVATE)) { + return CRYPT_PK_INVALID_TYPE; + } + + if (type == PK_PRIVATE) { + /* private key */ + /* output is + Version, n, e, d, p, q, d mod (p-1), d mod (q - 1), 1/q mod p + */ + return der_encode_sequence_multi(out, outlen, + LTC_ASN1_SHORT_INTEGER, 1UL, &zero, + LTC_ASN1_INTEGER, 1UL, key->N, + LTC_ASN1_INTEGER, 1UL, key->e, + LTC_ASN1_INTEGER, 1UL, key->d, + LTC_ASN1_INTEGER, 1UL, key->p, + LTC_ASN1_INTEGER, 1UL, key->q, + LTC_ASN1_INTEGER, 1UL, key->dP, + LTC_ASN1_INTEGER, 1UL, key->dQ, + LTC_ASN1_INTEGER, 1UL, key->qP, + LTC_ASN1_EOL, 0UL, NULL); + } else { + /* public key */ + unsigned long tmplen, *ptmplen; + unsigned char* tmp = NULL; + + if (type & PK_STD) { + tmplen = (mp_count_bits(key->N)/8)*2+8; + tmp = XMALLOC(tmplen); + ptmplen = &tmplen; + if (tmp == NULL) { + return CRYPT_MEM; + } + } + else { + tmp = out; + ptmplen = outlen; + } + + err = der_encode_sequence_multi(tmp, ptmplen, + LTC_ASN1_INTEGER, 1UL, key->N, + LTC_ASN1_INTEGER, 1UL, key->e, + LTC_ASN1_EOL, 0UL, NULL); + + if ((err != CRYPT_OK) || !(type & PK_STD)) { + goto finish; + } + + err = der_encode_subject_public_key_info(out, outlen, + PKA_RSA, tmp, tmplen, LTC_ASN1_NULL, NULL, 0); + +finish: + if (tmp != out) + XFREE(tmp); + return err; + + } +} + +#endif /* LTC_MRSA */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/rsa/rsa_exptmod.c b/src/ltc/pk/rsa/rsa_exptmod.c new file mode 100644 index 0000000..714bc52 --- /dev/null +++ b/src/ltc/pk/rsa/rsa_exptmod.c @@ -0,0 +1,183 @@ +/* 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://libtom.org + * + * Added RSA blinding --nmav + */ +#include "tomcrypt.h" + +/** + @file rsa_exptmod.c + RSA PKCS exptmod, Tom St Denis +*/ + +#ifdef LTC_MRSA + +/** + Compute an RSA modular exponentiation + @param in The input data to send into RSA + @param inlen The length of the input (octets) + @param out [out] The destination + @param outlen [in/out] The max size and resulting size of the output + @param which Which exponent to use, e.g. PK_PRIVATE or PK_PUBLIC + @param key The RSA key to use + @return CRYPT_OK if successful +*/ +int rsa_exptmod(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int which, + rsa_key *key) +{ + void *tmp, *tmpa, *tmpb; + #ifdef LTC_RSA_BLINDING + void *rnd, *rndi /* inverse of rnd */; + #endif + unsigned long x; + int err, has_crt_parameters; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* is the key of the right type for the operation? */ + if (which == PK_PRIVATE && (key->type != PK_PRIVATE)) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* must be a private or public operation */ + if (which != PK_PRIVATE && which != PK_PUBLIC) { + return CRYPT_PK_INVALID_TYPE; + } + + /* init and copy into tmp */ + if ((err = mp_init_multi(&tmp, &tmpa, &tmpb, +#ifdef LTC_RSA_BLINDING + &rnd, &rndi, +#endif /* LTC_RSA_BLINDING */ + NULL)) != CRYPT_OK) + { return err; } + if ((err = mp_read_unsigned_bin(tmp, (unsigned char *)in, (int)inlen)) != CRYPT_OK) + { goto error; } + + + /* sanity check on the input */ + if (mp_cmp(key->N, tmp) == LTC_MP_LT) { + err = CRYPT_PK_INVALID_SIZE; + goto error; + } + + /* are we using the private exponent and is the key optimized? */ + if (which == PK_PRIVATE) { + #ifdef LTC_RSA_BLINDING + /* do blinding */ + err = mp_rand(rnd, mp_get_digit_count(key->N)); + if (err != CRYPT_OK) { + goto error; + } + + /* rndi = 1/rnd mod N */ + err = mp_invmod(rnd, key->N, rndi); + if (err != CRYPT_OK) { + goto error; + } + + /* rnd = rnd^e */ + err = mp_exptmod( rnd, key->e, key->N, rnd); + if (err != CRYPT_OK) { + goto error; + } + + /* tmp = tmp*rnd mod N */ + err = mp_mulmod( tmp, rnd, key->N, tmp); + if (err != CRYPT_OK) { + goto error; + } + #endif /* LTC_RSA_BLINDING */ + + has_crt_parameters = (key->dP != NULL) && (mp_get_digit_count(key->dP) != 0) && + (key->dQ != NULL) && (mp_get_digit_count(key->dQ) != 0) && + (key->qP != NULL) && (mp_get_digit_count(key->qP) != 0); + + if (!has_crt_parameters) { + /* + * In case CRT optimization parameters are not provided, + * the private key is directly used to exptmod it + */ + if ((err = mp_exptmod(tmp, key->d, key->N, tmp)) != CRYPT_OK) { goto error; } + } else { + /* tmpa = tmp^dP mod p */ + if ((err = mp_exptmod(tmp, key->dP, key->p, tmpa)) != CRYPT_OK) { goto error; } + + /* tmpb = tmp^dQ mod q */ + if ((err = mp_exptmod(tmp, key->dQ, key->q, tmpb)) != CRYPT_OK) { goto error; } + + /* tmp = (tmpa - tmpb) * qInv (mod p) */ + if ((err = mp_sub(tmpa, tmpb, tmp)) != CRYPT_OK) { goto error; } + if ((err = mp_mulmod(tmp, key->qP, key->p, tmp)) != CRYPT_OK) { goto error; } + + /* tmp = tmpb + q * tmp */ + if ((err = mp_mul(tmp, key->q, tmp)) != CRYPT_OK) { goto error; } + if ((err = mp_add(tmp, tmpb, tmp)) != CRYPT_OK) { goto error; } + } + + #ifdef LTC_RSA_BLINDING + /* unblind */ + err = mp_mulmod( tmp, rndi, key->N, tmp); + if (err != CRYPT_OK) { + goto error; + } + #endif + + #ifdef LTC_RSA_CRT_HARDENING + if (has_crt_parameters) { + if ((err = mp_exptmod(tmp, key->e, key->N, tmpa)) != CRYPT_OK) { goto error; } + if ((err = mp_read_unsigned_bin(tmpb, (unsigned char *)in, (int)inlen)) != CRYPT_OK) { goto error; } + if (mp_cmp(tmpa, tmpb) != LTC_MP_EQ) { err = CRYPT_ERROR; goto error; } + } + #endif + } else { + /* exptmod it */ + if ((err = mp_exptmod(tmp, key->e, key->N, tmp)) != CRYPT_OK) { goto error; } + } + + /* read it back */ + x = (unsigned long)mp_unsigned_bin_size(key->N); + if (x > *outlen) { + *outlen = x; + err = CRYPT_BUFFER_OVERFLOW; + goto error; + } + + /* this should never happen ... */ + if (mp_unsigned_bin_size(tmp) > mp_unsigned_bin_size(key->N)) { + err = CRYPT_ERROR; + goto error; + } + *outlen = x; + + /* convert it */ + zeromem(out, x); + if ((err = mp_to_unsigned_bin(tmp, out+(x-mp_unsigned_bin_size(tmp)))) != CRYPT_OK) { goto error; } + + /* clean up and return */ + err = CRYPT_OK; +error: + mp_clear_multi( +#ifdef LTC_RSA_BLINDING + rndi, rnd, +#endif /* LTC_RSA_BLINDING */ + tmpb, tmpa, tmp, NULL); + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/rsa/rsa_free.c b/src/ltc/pk/rsa/rsa_free.c new file mode 100644 index 0000000..57da74c --- /dev/null +++ b/src/ltc/pk/rsa/rsa_free.c @@ -0,0 +1,34 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file rsa_free.c + Free an RSA key, Tom St Denis +*/ + +#ifdef LTC_MRSA + +/** + Free an RSA key from memory + @param key The RSA key to free +*/ +void rsa_free(rsa_key *key) +{ + LTC_ARGCHKVD(key != NULL); + mp_clear_multi(key->q, key->p, key->qP, key->dP, key->dQ, key->N, key->d, key->e, NULL); +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/rsa/rsa_get_size.c b/src/ltc/pk/rsa/rsa_get_size.c new file mode 100644 index 0000000..dfc82b0 --- /dev/null +++ b/src/ltc/pk/rsa/rsa_get_size.c @@ -0,0 +1,42 @@ +/* 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. + * + * http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file rsa_get_size.c + Retrieve the size of an RSA key, Steffen Jaeckel. +*/ + +#ifdef LTC_MRSA + +/** + Retrieve the size in bytes of an RSA key. + @param key The RSA key + @return The size in bytes of the RSA key or INT_MAX on error. +*/ +int rsa_get_size(rsa_key *key) +{ + int ret = INT_MAX; + LTC_ARGCHK(key != NULL); + + if (key) + { + ret = mp_unsigned_bin_size(key->N); + } /* if */ + + return ret; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/rsa/rsa_import.c b/src/ltc/pk/rsa/rsa_import.c new file mode 100644 index 0000000..efd5afb --- /dev/null +++ b/src/ltc/pk/rsa/rsa_import.c @@ -0,0 +1,130 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file rsa_import.c + Import a PKCS RSA key, Tom St Denis +*/ + +#ifdef LTC_MRSA + +/** + Import an RSAPublicKey or RSAPrivateKey [two-prime only, only support >= 1024-bit keys, defined in PKCS #1 v2.1] + @param in The packet to import from + @param inlen It's length (octets) + @param key [out] Destination for newly imported key + @return CRYPT_OK if successful, upon error allocated memory is freed +*/ +int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) +{ + int err; + void *zero; + unsigned char *tmpbuf=NULL; + unsigned long tmpbuf_len; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(ltc_mp.name != NULL); + + /* init key */ + if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, + &key->dP, &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) { + return err; + } + + /* see if the OpenSSL DER format RSA public key will work */ + tmpbuf_len = MAX_RSA_SIZE * 8; + tmpbuf = XCALLOC(1, tmpbuf_len); + if (tmpbuf == NULL) { + err = CRYPT_MEM; + goto LBL_ERR; + } + + err = der_decode_subject_public_key_info(in, inlen, + PKA_RSA, tmpbuf, &tmpbuf_len, + LTC_ASN1_NULL, NULL, 0); + + if (err == CRYPT_OK) { /* SubjectPublicKeyInfo format */ + + /* now it should be SEQUENCE { INTEGER, INTEGER } */ + if ((err = der_decode_sequence_multi(tmpbuf, tmpbuf_len, + LTC_ASN1_INTEGER, 1UL, key->N, + LTC_ASN1_INTEGER, 1UL, key->e, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto LBL_ERR; + } + key->type = PK_PUBLIC; + err = CRYPT_OK; + goto LBL_FREE; + } + + /* not SSL public key, try to match against PKCS #1 standards */ + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_INTEGER, 1UL, key->N, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto LBL_ERR; + } + + if (mp_cmp_d(key->N, 0) == LTC_MP_EQ) { + if ((err = mp_init(&zero)) != CRYPT_OK) { + goto LBL_ERR; + } + /* it's a private key */ + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_INTEGER, 1UL, zero, + LTC_ASN1_INTEGER, 1UL, key->N, + LTC_ASN1_INTEGER, 1UL, key->e, + LTC_ASN1_INTEGER, 1UL, key->d, + LTC_ASN1_INTEGER, 1UL, key->p, + LTC_ASN1_INTEGER, 1UL, key->q, + LTC_ASN1_INTEGER, 1UL, key->dP, + LTC_ASN1_INTEGER, 1UL, key->dQ, + LTC_ASN1_INTEGER, 1UL, key->qP, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + mp_clear(zero); + goto LBL_ERR; + } + mp_clear(zero); + key->type = PK_PRIVATE; + } else if (mp_cmp_d(key->N, 1) == LTC_MP_EQ) { + /* we don't support multi-prime RSA */ + err = CRYPT_PK_INVALID_TYPE; + goto LBL_ERR; + } else { + /* it's a public key and we lack e */ + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_INTEGER, 1UL, key->N, + LTC_ASN1_INTEGER, 1UL, key->e, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto LBL_ERR; + } + key->type = PK_PUBLIC; + } + err = CRYPT_OK; + goto LBL_FREE; + +LBL_ERR: + mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL); + +LBL_FREE: + if (tmpbuf != NULL) + XFREE(tmpbuf); + + return err; +} + +#endif /* LTC_MRSA */ + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/rsa/rsa_import_pkcs8.c b/src/ltc/pk/rsa/rsa_import_pkcs8.c new file mode 100644 index 0000000..2f2aa36 --- /dev/null +++ b/src/ltc/pk/rsa/rsa_import_pkcs8.c @@ -0,0 +1,151 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file rsa_import_pkcs8.c + Import a PKCS RSA key +*/ + +#ifdef LTC_MRSA + +/* Public-Key Cryptography Standards (PKCS) #8: + * Private-Key Information Syntax Specification Version 1.2 + * https://tools.ietf.org/html/rfc5208 + * + * PrivateKeyInfo ::= SEQUENCE { + * version Version, + * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, + * privateKey PrivateKey, + * attributes [0] IMPLICIT Attributes OPTIONAL } + * where: + * - Version ::= INTEGER + * - PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier + * - PrivateKey ::= OCTET STRING + * - Attributes ::= SET OF Attribute + * + * EncryptedPrivateKeyInfo ::= SEQUENCE { + * encryptionAlgorithm EncryptionAlgorithmIdentifier, + * encryptedData EncryptedData } + * where: + * - EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier + * - EncryptedData ::= OCTET STRING + */ + +/** + Import an RSAPublicKey or RSAPrivateKey in PKCS#8 format + @param in The packet to import from + @param inlen It's length (octets) + @param passwd The password for decrypting privkey (NOT SUPPORTED YET) + @param passwdlen Password's length (octets) + @param key [out] Destination for newly imported key + @return CRYPT_OK if successful, upon error allocated memory is freed +*/ +int rsa_import_pkcs8(const unsigned char *in, unsigned long inlen, + const void *passwd, unsigned long passwdlen, + rsa_key *key) +{ + int err; + void *zero, *iter; + unsigned char *buf1 = NULL, *buf2 = NULL; + unsigned long buf1len, buf2len; + unsigned long oid[16]; + oid_st rsaoid; + ltc_asn1_list alg_seq[2], top_seq[3]; + ltc_asn1_list alg_seq_e[2], key_seq_e[2], top_seq_e[2]; + unsigned char *decrypted = NULL; + unsigned long decryptedlen; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(ltc_mp.name != NULL); + + /* get RSA alg oid */ + err = pk_get_oid(PKA_RSA, &rsaoid); + if (err != CRYPT_OK) { goto LBL_NOFREE; } + + /* alloc buffers */ + buf1len = inlen; /* approx. */ + buf1 = XMALLOC(buf1len); + if (buf1 == NULL) { err = CRYPT_MEM; goto LBL_NOCLEAR; } + buf2len = inlen; /* approx. */ + buf2 = XMALLOC(buf2len); + if (buf2 == NULL) { err = CRYPT_MEM; goto LBL_FREE; } + + /* init key */ + err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, &zero, &iter, NULL); + if (err != CRYPT_OK) { goto LBL_NOCLEAR; } + + /* try to decode encrypted priv key */ + LTC_SET_ASN1(key_seq_e, 0, LTC_ASN1_OCTET_STRING, buf1, buf1len); + LTC_SET_ASN1(key_seq_e, 1, LTC_ASN1_INTEGER, iter, 1UL); + LTC_SET_ASN1(alg_seq_e, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, 16UL); + LTC_SET_ASN1(alg_seq_e, 1, LTC_ASN1_SEQUENCE, key_seq_e, 2UL); + LTC_SET_ASN1(top_seq_e, 0, LTC_ASN1_SEQUENCE, alg_seq_e, 2UL); + LTC_SET_ASN1(top_seq_e, 1, LTC_ASN1_OCTET_STRING, buf2, buf2len); + err=der_decode_sequence(in, inlen, top_seq_e, 2UL); + if (err == CRYPT_OK) { + LTC_UNUSED_PARAM(passwd); + LTC_UNUSED_PARAM(passwdlen); + /* XXX: TODO encrypted pkcs8 not implemented yet */ + /* fprintf(stderr, "decrypt: iter=%ld salt.len=%ld encdata.len=%ld\n", mp_get_int(iter), key_seq_e[0].size, top_seq_e[1].size); */ + err = CRYPT_PK_INVALID_TYPE; + goto LBL_ERR; + } + else { + decrypted = (unsigned char *)in; + decryptedlen = inlen; + } + + /* try to decode unencrypted priv key */ + LTC_SET_ASN1(alg_seq, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, 16UL); + LTC_SET_ASN1(alg_seq, 1, LTC_ASN1_NULL, NULL, 0UL); + LTC_SET_ASN1(top_seq, 0, LTC_ASN1_INTEGER, zero, 1UL); + LTC_SET_ASN1(top_seq, 1, LTC_ASN1_SEQUENCE, alg_seq, 2UL); + LTC_SET_ASN1(top_seq, 2, LTC_ASN1_OCTET_STRING, buf1, buf1len); + err=der_decode_sequence(decrypted, decryptedlen, top_seq, 3UL); + if (err != CRYPT_OK) { goto LBL_ERR; } + + /* check alg oid */ + if ((alg_seq[0].size != rsaoid.OIDlen) || + XMEMCMP(rsaoid.OID, alg_seq[0].data, rsaoid.OIDlen * sizeof(rsaoid.OID[0]))) { + err = CRYPT_PK_INVALID_TYPE; + goto LBL_ERR; + } + + err = der_decode_sequence_multi(buf1, top_seq[2].size, + LTC_ASN1_INTEGER, 1UL, zero, + LTC_ASN1_INTEGER, 1UL, key->N, + LTC_ASN1_INTEGER, 1UL, key->e, + LTC_ASN1_INTEGER, 1UL, key->d, + LTC_ASN1_INTEGER, 1UL, key->p, + LTC_ASN1_INTEGER, 1UL, key->q, + LTC_ASN1_INTEGER, 1UL, key->dP, + LTC_ASN1_INTEGER, 1UL, key->dQ, + LTC_ASN1_INTEGER, 1UL, key->qP, + LTC_ASN1_EOL, 0UL, NULL); + if (err != CRYPT_OK) { goto LBL_ERR; } + mp_clear_multi(zero, iter, NULL); + key->type = PK_PRIVATE; + err = CRYPT_OK; + goto LBL_FREE; + +LBL_ERR: + mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, zero, iter, NULL); +LBL_NOCLEAR: + XFREE(buf2); +LBL_FREE: + XFREE(buf1); +LBL_NOFREE: + return err; +} + +#endif /* LTC_MRSA */ diff --git a/src/ltc/pk/rsa/rsa_import_radix.c b/src/ltc/pk/rsa/rsa_import_radix.c new file mode 100644 index 0000000..d9d4ec7 --- /dev/null +++ b/src/ltc/pk/rsa/rsa_import_radix.c @@ -0,0 +1,64 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + Import RSA public or private key from raw numbers + @param radix the radix the numbers are represented in (2-64, 16 = hexadecimal) + @param N RSA's N in radix representation + @param e RSA's e in radix representation + @param d RSA's d in radix representation (only private key, NULL for public key) + @param p RSA's p in radix representation (only private key, NULL for public key) + @param q RSA's q in radix representation (only private key, NULL for public key) + @param dP RSA's dP in radix representation (only private key, NULL for public key) + @param dQ RSA's dQ in radix representation (only private key, NULL for public key) + @param qP RSA's qP in radix representation (only private key, NULL for public key) + @param key [out] the destination for the imported key + @return CRYPT_OK if successful, upon error allocated memory is freed +*/ + +#ifdef LTC_MRSA + +int rsa_import_radix(int radix, char *N, char *e, char *d, char *p, char *q, char *dP, char *dQ, char *qP, rsa_key *key) +{ + int err; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(N != NULL); + LTC_ARGCHK(e != NULL); + LTC_ARGCHK(ltc_mp.name != NULL); + + err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, NULL); + if (err != CRYPT_OK) return err; + + if ((err = mp_read_radix(key->N , N , radix)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = mp_read_radix(key->e , e , radix)) != CRYPT_OK) { goto LBL_ERR; } + if (d && p && q && dP && dQ && qP && strlen(d)>0 && strlen(p)>0 && + strlen(q)>0 && strlen(dP)>0 && strlen(dQ)>0 && strlen(qP)>0) { + if ((err = mp_read_radix(key->d , d , radix)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = mp_read_radix(key->p , p , radix)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = mp_read_radix(key->q , q , radix)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = mp_read_radix(key->dP, dP, radix)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = mp_read_radix(key->dQ, dQ, radix)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = mp_read_radix(key->qP, qP, radix)) != CRYPT_OK) { goto LBL_ERR; } + key->type = PK_PRIVATE; + } + else { + key->type = PK_PUBLIC; + } + return CRYPT_OK; + +LBL_ERR: + mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL); + return err; +} + +#endif /* LTC_MRSA */ diff --git a/src/ltc/pk/rsa/rsa_import_x509.c b/src/ltc/pk/rsa/rsa_import_x509.c new file mode 100644 index 0000000..45da7c7 --- /dev/null +++ b/src/ltc/pk/rsa/rsa_import_x509.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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file rsa_import.c + Import an RSA key from a X.509 certificate, Steffen Jaeckel +*/ + +#ifdef LTC_MRSA + +/** + Import an RSA key from a X.509 certificate + @param in The packet to import from + @param inlen It's length (octets) + @param key [out] Destination for newly imported key + @return CRYPT_OK if successful, upon error allocated memory is freed +*/ +int rsa_import_x509(const unsigned char *in, unsigned long inlen, rsa_key *key) +{ + int err; + unsigned char *tmpbuf; + unsigned long tmpbuf_len, tmp_inlen; + ltc_asn1_list *decoded_list = NULL, *l; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(ltc_mp.name != NULL); + + /* init key */ + if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, + &key->dP, &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) { + return err; + } + + tmpbuf_len = MAX_RSA_SIZE * 8; + tmpbuf = XCALLOC(1, tmpbuf_len); + if (tmpbuf == NULL) { + err = CRYPT_MEM; + goto LBL_ERR; + } + + tmp_inlen = inlen; + if ((err = der_decode_sequence_flexi(in, &tmp_inlen, &decoded_list)) == CRYPT_OK) { + l = decoded_list; + /* Move 2 levels up in the tree + SEQUENCE + SEQUENCE + ... + */ + if (l->type == LTC_ASN1_SEQUENCE && l->child) { + l = l->child; + if (l->type == LTC_ASN1_SEQUENCE && l->child) { + l = l->child; + + err = CRYPT_ERROR; + + /* Move forward in the tree until we find this combination + ... + SEQUENCE + SEQUENCE + OBJECT IDENTIFIER 1.2.840.113549.1.1.1 + NULL + BIT STRING + */ + do { + /* The additional check for l->data is there to make sure + * we won't try to decode a list that has been 'shrunk' + */ + if (l->type == LTC_ASN1_SEQUENCE && l->data && l->child && + l->child->type == LTC_ASN1_SEQUENCE && l->child->child && + l->child->child->type == LTC_ASN1_OBJECT_IDENTIFIER && l->child->next && + l->child->next->type == LTC_ASN1_BIT_STRING) { + err = der_decode_subject_public_key_info(l->data, l->size, + PKA_RSA, tmpbuf, &tmpbuf_len, + LTC_ASN1_NULL, NULL, 0); + if (err == CRYPT_OK) { + /* now it should be SEQUENCE { INTEGER, INTEGER } */ + if ((err = der_decode_sequence_multi(tmpbuf, tmpbuf_len, + LTC_ASN1_INTEGER, 1UL, key->N, + LTC_ASN1_INTEGER, 1UL, key->e, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto LBL_ERR; + } + key->type = PK_PUBLIC; + err = CRYPT_OK; + goto LBL_FREE; + } + } + l = l->next; + } while(l); + } + } + } + + +LBL_ERR: + rsa_free(key); + +LBL_FREE: + if (decoded_list) der_free_sequence_flexi(decoded_list); + if (tmpbuf != NULL) XFREE(tmpbuf); + + return err; +} + +#endif /* LTC_MRSA */ + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/rsa/rsa_make_key.c b/src/ltc/pk/rsa/rsa_make_key.c new file mode 100644 index 0000000..454d20b --- /dev/null +++ b/src/ltc/pk/rsa/rsa_make_key.c @@ -0,0 +1,112 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file rsa_make_key.c + RSA key generation, Tom St Denis +*/ + +#ifdef LTC_MRSA + +/** + Create an RSA key + @param prng An active PRNG state + @param wprng The index of the PRNG desired + @param size The size of the modulus (key size) desired (octets) + @param e The "e" value (public key). e==65537 is a good choice + @param key [out] Destination of a newly created private key pair + @return CRYPT_OK if successful, upon error all allocated ram is freed +*/ +int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key) +{ + void *p, *q, *tmp1, *tmp2, *tmp3; + int err; + + LTC_ARGCHK(ltc_mp.name != NULL); + LTC_ARGCHK(key != NULL); + + if ((size < (MIN_RSA_SIZE/8)) || (size > (MAX_RSA_SIZE/8))) { + return CRYPT_INVALID_KEYSIZE; + } + + if ((e < 3) || ((e & 1) == 0)) { + return CRYPT_INVALID_ARG; + } + + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != CRYPT_OK) { + return err; + } + + /* make primes p and q (optimization provided by Wayne Scott) */ + if ((err = mp_set_int(tmp3, e)) != CRYPT_OK) { goto cleanup; } /* tmp3 = e */ + + /* make prime "p" */ + do { + if ((err = rand_prime( p, size/2, prng, wprng)) != CRYPT_OK) { goto cleanup; } + if ((err = mp_sub_d( p, 1, tmp1)) != CRYPT_OK) { goto cleanup; } /* tmp1 = p-1 */ + if ((err = mp_gcd( tmp1, tmp3, tmp2)) != CRYPT_OK) { goto cleanup; } /* tmp2 = gcd(p-1, e) */ + } while (mp_cmp_d( tmp2, 1) != 0); /* while e divides p-1 */ + + /* make prime "q" */ + do { + if ((err = rand_prime( q, size/2, prng, wprng)) != CRYPT_OK) { goto cleanup; } + if ((err = mp_sub_d( q, 1, tmp1)) != CRYPT_OK) { goto cleanup; } /* tmp1 = q-1 */ + if ((err = mp_gcd( tmp1, tmp3, tmp2)) != CRYPT_OK) { goto cleanup; } /* tmp2 = gcd(q-1, e) */ + } while (mp_cmp_d( tmp2, 1) != 0); /* while e divides q-1 */ + + /* tmp1 = lcm(p-1, q-1) */ + if ((err = mp_sub_d( p, 1, tmp2)) != CRYPT_OK) { goto cleanup; } /* tmp2 = p-1 */ + /* tmp1 = q-1 (previous do/while loop) */ + if ((err = mp_lcm( tmp1, tmp2, tmp1)) != CRYPT_OK) { goto cleanup; } /* tmp1 = lcm(p-1, q-1) */ + + /* make key */ + if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) { + goto errkey; + } + + if ((err = mp_set_int( key->e, e)) != CRYPT_OK) { goto errkey; } /* key->e = e */ + if ((err = mp_invmod( key->e, tmp1, key->d)) != CRYPT_OK) { goto errkey; } /* key->d = 1/e mod lcm(p-1,q-1) */ + if ((err = mp_mul( p, q, key->N)) != CRYPT_OK) { goto errkey; } /* key->N = pq */ + + /* optimize for CRT now */ + /* find d mod q-1 and d mod p-1 */ + if ((err = mp_sub_d( p, 1, tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = q-1 */ + if ((err = mp_sub_d( q, 1, tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = p-1 */ + if ((err = mp_mod( key->d, tmp1, key->dP)) != CRYPT_OK) { goto errkey; } /* dP = d mod p-1 */ + if ((err = mp_mod( key->d, tmp2, key->dQ)) != CRYPT_OK) { goto errkey; } /* dQ = d mod q-1 */ + if ((err = mp_invmod( q, p, key->qP)) != CRYPT_OK) { goto errkey; } /* qP = 1/q mod p */ + + if ((err = mp_copy( p, key->p)) != CRYPT_OK) { goto errkey; } + if ((err = mp_copy( q, key->q)) != CRYPT_OK) { goto errkey; } + + /* set key type (in this case it's CRT optimized) */ + key->type = PK_PRIVATE; + + /* return ok and free temps */ + err = CRYPT_OK; + goto cleanup; +errkey: + mp_clear_multi(key->q, key->p, key->qP, key->dP, key->dQ, key->N, key->d, key->e, NULL); +cleanup: + mp_clear_multi(tmp3, tmp2, tmp1, q, p, NULL); + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/rsa/rsa_sign_hash.c b/src/ltc/pk/rsa/rsa_sign_hash.c new file mode 100644 index 0000000..46d5c9f --- /dev/null +++ b/src/ltc/pk/rsa/rsa_sign_hash.c @@ -0,0 +1,134 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file rsa_sign_hash.c + RSA PKCS #1 v1.5 and v2 PSS sign hash, Tom St Denis and Andreas Lange +*/ + +#ifdef LTC_MRSA + +/** + PKCS #1 pad then sign + @param in The hash to sign + @param inlen The length of the hash to sign (octets) + @param out [out] The signature + @param outlen [in/out] The max size and resulting size of the signature + @param padding Type of padding (LTC_PKCS_1_PSS or LTC_PKCS_1_V1_5) + @param prng An active PRNG state + @param prng_idx The index of the PRNG desired + @param hash_idx The index of the hash desired + @param saltlen The length of the salt desired (octets) + @param key The private RSA key to use + @return CRYPT_OK if successful +*/ +int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + int padding, + prng_state *prng, int prng_idx, + int hash_idx, unsigned long saltlen, + rsa_key *key) +{ + unsigned long modulus_bitlen, modulus_bytelen, x, y; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* valid padding? */ + if ((padding != LTC_PKCS_1_V1_5) && (padding != LTC_PKCS_1_PSS)) { + return CRYPT_PK_INVALID_PADDING; + } + + if (padding == LTC_PKCS_1_PSS) { + /* valid prng and hash ? */ + if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { + return err; + } + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + } + + /* get modulus len in bits */ + modulus_bitlen = mp_count_bits((key->N)); + + /* outlen must be at least the size of the modulus */ + modulus_bytelen = mp_unsigned_bin_size((key->N)); + if (modulus_bytelen > *outlen) { + *outlen = modulus_bytelen; + return CRYPT_BUFFER_OVERFLOW; + } + + if (padding == LTC_PKCS_1_PSS) { + /* PSS pad the key */ + x = *outlen; + if ((err = pkcs_1_pss_encode(in, inlen, saltlen, prng, prng_idx, + hash_idx, modulus_bitlen, out, &x)) != CRYPT_OK) { + return err; + } + } else { + /* PKCS #1 v1.5 pad the hash */ + unsigned char *tmpin; + ltc_asn1_list digestinfo[2], siginfo[2]; + + /* not all hashes have OIDs... so sad */ + if (hash_descriptor[hash_idx].OIDlen == 0) { + return CRYPT_INVALID_ARG; + } + + /* construct the SEQUENCE + SEQUENCE { + SEQUENCE {hashoid OID + blah NULL + } + hash OCTET STRING + } + */ + LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash_idx].OID, hash_descriptor[hash_idx].OIDlen); + LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0); + LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2); + LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, in, inlen); + + /* allocate memory for the encoding */ + y = mp_unsigned_bin_size(key->N); + tmpin = XMALLOC(y); + if (tmpin == NULL) { + return CRYPT_MEM; + } + + if ((err = der_encode_sequence(siginfo, 2, tmpin, &y)) != CRYPT_OK) { + XFREE(tmpin); + return err; + } + + x = *outlen; + if ((err = pkcs_1_v1_5_encode(tmpin, y, LTC_PKCS_1_EMSA, + modulus_bitlen, NULL, 0, + out, &x)) != CRYPT_OK) { + XFREE(tmpin); + return err; + } + XFREE(tmpin); + } + + /* RSA encode it */ + return ltc_mp.rsa_me(out, x, out, outlen, PK_PRIVATE, key); +} + +#endif /* LTC_MRSA */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/rsa/rsa_sign_saltlen_get.c b/src/ltc/pk/rsa/rsa_sign_saltlen_get.c new file mode 100644 index 0000000..9f5cadb --- /dev/null +++ b/src/ltc/pk/rsa/rsa_sign_saltlen_get.c @@ -0,0 +1,49 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * http://libtom.org + */ +#include "tomcrypt.h" + +/** + @file rsa_sign_saltlen_get.c + Retrieve the maximum size of the salt, Steffen Jaeckel. +*/ + +#ifdef LTC_MRSA + +/** + Retrieve the maximum possible size of the salt when creating a PKCS#1 PSS signature. + @param padding Type of padding (LTC_PKCS_1_PSS only) + @param hash_idx The index of the desired hash + @param key The RSA key + @return The maximum salt length in bytes or INT_MAX on error. +*/ +int rsa_sign_saltlen_get_max_ex(int padding, int hash_idx, rsa_key *key) +{ + int ret = INT_MAX; + LTC_ARGCHK(key != NULL); + + if ((hash_is_valid(hash_idx) == CRYPT_OK) && + (padding == LTC_PKCS_1_PSS)) + { + ret = rsa_get_size(key); + if (ret < INT_MAX) + { + ret -= (hash_descriptor[hash_idx].hashsize + 2); + } /* if */ + } /* if */ + + return ret; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/pk/rsa/rsa_verify_hash.c b/src/ltc/pk/rsa/rsa_verify_hash.c new file mode 100644 index 0000000..9a425cd --- /dev/null +++ b/src/ltc/pk/rsa/rsa_verify_hash.c @@ -0,0 +1,180 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file rsa_verify_hash.c + RSA PKCS #1 v1.5 or v2 PSS signature verification, Tom St Denis and Andreas Lange +*/ + +#ifdef LTC_MRSA + +/** + PKCS #1 de-sign then v1.5 or PSS depad + @param sig The signature data + @param siglen The length of the signature data (octets) + @param hash The hash of the message that was signed + @param hashlen The length of the hash of the message that was signed (octets) + @param padding Type of padding (LTC_PKCS_1_PSS or LTC_PKCS_1_V1_5) + @param hash_idx The index of the desired hash + @param saltlen The length of the salt used during signature + @param stat [out] The result of the signature comparison, 1==valid, 0==invalid + @param key The public RSA key corresponding to the key that performed the signature + @return CRYPT_OK on success (even if the signature is invalid) +*/ +int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int padding, + int hash_idx, unsigned long saltlen, + int *stat, rsa_key *key) +{ + unsigned long modulus_bitlen, modulus_bytelen, x; + int err; + unsigned char *tmpbuf; + + LTC_ARGCHK(hash != NULL); + LTC_ARGCHK(sig != NULL); + LTC_ARGCHK(stat != NULL); + LTC_ARGCHK(key != NULL); + + /* default to invalid */ + *stat = 0; + + /* valid padding? */ + + if ((padding != LTC_PKCS_1_V1_5) && + (padding != LTC_PKCS_1_PSS)) { + return CRYPT_PK_INVALID_PADDING; + } + + if (padding == LTC_PKCS_1_PSS) { + /* valid hash ? */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + } + + /* get modulus len in bits */ + modulus_bitlen = mp_count_bits( (key->N)); + + /* outlen must be at least the size of the modulus */ + modulus_bytelen = mp_unsigned_bin_size( (key->N)); + if (modulus_bytelen != siglen) { + return CRYPT_INVALID_PACKET; + } + + /* allocate temp buffer for decoded sig */ + tmpbuf = XMALLOC(siglen); + if (tmpbuf == NULL) { + return CRYPT_MEM; + } + + /* RSA decode it */ + x = siglen; + if ((err = ltc_mp.rsa_me(sig, siglen, tmpbuf, &x, PK_PUBLIC, key)) != CRYPT_OK) { + XFREE(tmpbuf); + return err; + } + + /* make sure the output is the right size */ + if (x != siglen) { + XFREE(tmpbuf); + return CRYPT_INVALID_PACKET; + } + + if (padding == LTC_PKCS_1_PSS) { + /* PSS decode and verify it */ + + if(modulus_bitlen%8 == 1){ + err = pkcs_1_pss_decode(hash, hashlen, tmpbuf+1, x-1, saltlen, hash_idx, modulus_bitlen, stat); + } + else{ + err = pkcs_1_pss_decode(hash, hashlen, tmpbuf, x, saltlen, hash_idx, modulus_bitlen, stat); + } + + } else { + /* PKCS #1 v1.5 decode it */ + unsigned char *out; + unsigned long outlen, loid[16], reallen; + int decoded; + ltc_asn1_list digestinfo[2], siginfo[2]; + + /* not all hashes have OIDs... so sad */ + if (hash_descriptor[hash_idx].OIDlen == 0) { + err = CRYPT_INVALID_ARG; + goto bail_2; + } + + /* allocate temp buffer for decoded hash */ + outlen = ((modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0)) - 3; + out = XMALLOC(outlen); + if (out == NULL) { + err = CRYPT_MEM; + goto bail_2; + } + + if ((err = pkcs_1_v1_5_decode(tmpbuf, x, LTC_PKCS_1_EMSA, modulus_bitlen, out, &outlen, &decoded)) != CRYPT_OK) { + XFREE(out); + goto bail_2; + } + + /* now we must decode out[0...outlen-1] using ASN.1, test the OID and then test the hash */ + /* construct the SEQUENCE + SEQUENCE { + SEQUENCE {hashoid OID + blah NULL + } + hash OCTET STRING + } + */ + LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, loid, sizeof(loid)/sizeof(loid[0])); + LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0); + LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2); + LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, tmpbuf, siglen); + + if ((err = der_decode_sequence(out, outlen, siginfo, 2)) != CRYPT_OK) { + XFREE(out); + goto bail_2; + } + + if ((err = der_length_sequence(siginfo, 2, &reallen)) != CRYPT_OK) { + XFREE(out); + goto bail_2; + } + + /* test OID */ + if ((reallen == outlen) && + (digestinfo[0].size == hash_descriptor[hash_idx].OIDlen) && + (XMEM_NEQ(digestinfo[0].data, hash_descriptor[hash_idx].OID, sizeof(unsigned long) * hash_descriptor[hash_idx].OIDlen) == 0) && + (siginfo[1].size == hashlen) && + (XMEM_NEQ(siginfo[1].data, hash, hashlen) == 0)) { + *stat = 1; + } + +#ifdef LTC_CLEAN_STACK + zeromem(out, outlen); +#endif + XFREE(out); + } + +bail_2: +#ifdef LTC_CLEAN_STACK + zeromem(tmpbuf, siglen); +#endif + XFREE(tmpbuf); + return err; +} + +#endif /* LTC_MRSA */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/prngs/chacha20.c b/src/ltc/prngs/chacha20.c new file mode 100644 index 0000000..faaf629 --- /dev/null +++ b/src/ltc/prngs/chacha20.c @@ -0,0 +1,242 @@ +/* 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. + */ + + /* the idea of re-keying loosely follows the approach used in: + * http://bxr.su/OpenBSD/lib/libc/crypt/arc4random.c + */ + +#include "tomcrypt.h" + +#ifdef LTC_CHACHA20_PRNG + +const struct ltc_prng_descriptor chacha20_prng_desc = +{ + "chacha20", + 40, + &chacha20_prng_start, + &chacha20_prng_add_entropy, + &chacha20_prng_ready, + &chacha20_prng_read, + &chacha20_prng_done, + &chacha20_prng_export, + &chacha20_prng_import, + &chacha20_prng_test +}; + +/** + Start the PRNG + @param prng[out] The PRNG state to initialize + @return CRYPT_OK if successful +*/ +int chacha20_prng_start(prng_state *prng) +{ + LTC_ARGCHK(prng != NULL); + prng->ready = 0; + XMEMSET(&prng->chacha.ent, 0, sizeof(prng->chacha.ent)); + prng->chacha.idx = 0; + LTC_MUTEX_INIT(&prng->lock) + return CRYPT_OK; +} + +/** + Add entropy to the PRNG state + @param in The data to add + @param inlen Length of the data to add + @param prng PRNG state to update + @return CRYPT_OK if successful +*/ +int chacha20_prng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng) +{ + unsigned char buf[40]; + unsigned long i; + int err; + + LTC_ARGCHK(prng != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen > 0); + + LTC_MUTEX_LOCK(&prng->lock); + if (prng->ready) { + /* chacha20_prng_ready() was already called, do "rekey" operation */ + if ((err = chacha_keystream(&prng->chacha.s, buf, sizeof(buf))) != CRYPT_OK) goto LBL_UNLOCK; + for(i = 0; i < inlen; i++) buf[i % sizeof(buf)] ^= in[i]; + /* key 32 bytes, 20 rounds */ + if ((err = chacha_setup(&prng->chacha.s, buf, 32, 20)) != CRYPT_OK) goto LBL_UNLOCK; + /* iv 8 bytes */ + if ((err = chacha_ivctr64(&prng->chacha.s, buf + 32, 8, 0)) != CRYPT_OK) goto LBL_UNLOCK; + /* clear KEY + IV */ + XMEMSET(buf, 0, sizeof(buf)); + } + else { + /* chacha20_prng_ready() was not called yet, add entropy to ent buffer */ + while (inlen--) prng->chacha.ent[prng->chacha.idx++ % sizeof(prng->chacha.ent)] ^= *in++; + } + err = CRYPT_OK; +LBL_UNLOCK: + LTC_MUTEX_UNLOCK(&prng->lock); + return err; +} + +/** + Make the PRNG ready to read from + @param prng The PRNG to make active + @return CRYPT_OK if successful +*/ +int chacha20_prng_ready(prng_state *prng) +{ + int err; + + LTC_ARGCHK(prng != NULL); + + LTC_MUTEX_LOCK(&prng->lock); + if (prng->ready) { err = CRYPT_OK; goto LBL_UNLOCK; } + /* key 32 bytes, 20 rounds */ + if ((err = chacha_setup(&prng->chacha.s, prng->chacha.ent, 32, 20)) != CRYPT_OK) goto LBL_UNLOCK; + /* iv 8 bytes */ + if ((err = chacha_ivctr64(&prng->chacha.s, prng->chacha.ent + 32, 8, 0)) != CRYPT_OK) goto LBL_UNLOCK; + XMEMSET(&prng->chacha.ent, 0, sizeof(prng->chacha.ent)); + prng->chacha.idx = 0; + prng->ready = 1; +LBL_UNLOCK: + LTC_MUTEX_UNLOCK(&prng->lock); + return err; +} + +/** + Read from the PRNG + @param out Destination + @param outlen Length of output + @param prng The active PRNG to read from + @return Number of octets read +*/ +unsigned long chacha20_prng_read(unsigned char *out, unsigned long outlen, prng_state *prng) +{ + if (outlen == 0 || prng == NULL || out == NULL) return 0; + LTC_MUTEX_LOCK(&prng->lock); + if (!prng->ready) { outlen = 0; goto LBL_UNLOCK; } + if (chacha_keystream(&prng->chacha.s, out, outlen) != CRYPT_OK) outlen = 0; +LBL_UNLOCK: + LTC_MUTEX_UNLOCK(&prng->lock); + return outlen; +} + +/** + Terminate the PRNG + @param prng The PRNG to terminate + @return CRYPT_OK if successful +*/ +int chacha20_prng_done(prng_state *prng) +{ + int err; + LTC_ARGCHK(prng != NULL); + LTC_MUTEX_LOCK(&prng->lock); + prng->ready = 0; + err = chacha_done(&prng->chacha.s); + LTC_MUTEX_UNLOCK(&prng->lock); + return err; +} + +/** + Export the PRNG state + @param out [out] Destination + @param outlen [in/out] Max size and resulting size of the state + @param prng The PRNG to export + @return CRYPT_OK if successful +*/ +int chacha20_prng_export(unsigned char *out, unsigned long *outlen, prng_state *prng) +{ + unsigned long len = chacha20_prng_desc.export_size; + + LTC_ARGCHK(prng != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + if (*outlen < len) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + if (chacha20_prng_read(out, len, prng) != len) { + return CRYPT_ERROR_READPRNG; + } + + *outlen = len; + return CRYPT_OK; +} + +/** + Import a PRNG state + @param in The PRNG state + @param inlen Size of the state + @param prng The PRNG to import + @return CRYPT_OK if successful +*/ +int chacha20_prng_import(const unsigned char *in, unsigned long inlen, prng_state *prng) +{ + int err; + + LTC_ARGCHK(prng != NULL); + LTC_ARGCHK(in != NULL); + if (inlen < (unsigned long)chacha20_prng_desc.export_size) return CRYPT_INVALID_ARG; + + if ((err = chacha20_prng_start(prng)) != CRYPT_OK) return err; + if ((err = chacha20_prng_add_entropy(in, inlen, prng)) != CRYPT_OK) return err; + return CRYPT_OK; +} + +/** + PRNG self-test + @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled +*/ +int chacha20_prng_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + prng_state st; + unsigned char en[] = { 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, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32 }; + unsigned char dmp[300]; + unsigned long dmplen = sizeof(dmp); + unsigned char out[500]; + unsigned char t1[] = { 0x59, 0xB2, 0x26, 0x95, 0x2B, 0x01, 0x8F, 0x05, 0xBE, 0xD8 }; + unsigned char t2[] = { 0x47, 0xC9, 0x0D, 0x03, 0xE4, 0x75, 0x34, 0x27, 0xBD, 0xDE }; + unsigned char t3[] = { 0xBC, 0xFA, 0xEF, 0x59, 0x37, 0x7F, 0x1A, 0x91, 0x1A, 0xA6 }; + int err; + + if ((err = chacha20_prng_start(&st)) != CRYPT_OK) return err; + /* add entropy to uninitialized prng */ + if ((err = chacha20_prng_add_entropy(en, sizeof(en), &st)) != CRYPT_OK) return err; + if ((err = chacha20_prng_ready(&st)) != CRYPT_OK) return err; + if (chacha20_prng_read(out, 10, &st) != 10) return CRYPT_ERROR_READPRNG; /* 10 bytes for testing */ + if (compare_testvector(out, 10, t1, sizeof(t1), "CHACHA-PRNG", 1)) return CRYPT_FAIL_TESTVECTOR; + if (chacha20_prng_read(out, 500, &st) != 500) return CRYPT_ERROR_READPRNG; /* skip 500 bytes */ + /* add entropy to already initialized prng */ + if ((err = chacha20_prng_add_entropy(en, sizeof(en), &st)) != CRYPT_OK) return err; + if (chacha20_prng_read(out, 500, &st) != 500) return CRYPT_ERROR_READPRNG; /* skip 500 bytes */ + if ((err = chacha20_prng_export(dmp, &dmplen, &st)) != CRYPT_OK) return err; + if (chacha20_prng_read(out, 500, &st) != 500) return CRYPT_ERROR_READPRNG; /* skip 500 bytes */ + if (chacha20_prng_read(out, 10, &st) != 10) return CRYPT_ERROR_READPRNG; /* 10 bytes for testing */ + if (compare_testvector(out, 10, t2, sizeof(t2), "CHACHA-PRNG", 2)) return CRYPT_FAIL_TESTVECTOR; + if ((err = chacha20_prng_done(&st)) != CRYPT_OK) return err; + if ((err = chacha20_prng_import(dmp, dmplen, &st)) != CRYPT_OK) return err; + if ((err = chacha20_prng_ready(&st)) != CRYPT_OK) return err; + if (chacha20_prng_read(out, 500, &st) != 500) return CRYPT_ERROR_READPRNG; /* skip 500 bytes */ + if (chacha20_prng_read(out, 10, &st) != 10) return CRYPT_ERROR_READPRNG; /* 10 bytes for testing */ + if (compare_testvector(out, 10, t3, sizeof(t3), "CHACHA-PRNG", 3)) return CRYPT_FAIL_TESTVECTOR; + if ((err = chacha20_prng_done(&st)) != CRYPT_OK) return err; + + return CRYPT_OK; +#endif +} + +#endif diff --git a/src/ltc/prngs/fortuna.c b/src/ltc/prngs/fortuna.c new file mode 100644 index 0000000..15f3c4c --- /dev/null +++ b/src/ltc/prngs/fortuna.c @@ -0,0 +1,449 @@ +/* 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. + */ +#include "tomcrypt.h" + +/** + @file fortuna.c + Fortuna PRNG, Tom St Denis +*/ + +/* Implementation of Fortuna by Tom St Denis + +We deviate slightly here for reasons of simplicity [and to fit in the API]. First all "sources" +in the AddEntropy function are fixed to 0. Second since no reliable timer is provided +we reseed automatically when len(pool0) >= 64 or every LTC_FORTUNA_WD calls to the read function */ + +#ifdef LTC_FORTUNA + +/* requries LTC_SHA256 and AES */ +#if !(defined(LTC_RIJNDAEL) && defined(LTC_SHA256)) + #error LTC_FORTUNA requires LTC_SHA256 and LTC_RIJNDAEL (AES) +#endif + +#ifndef LTC_FORTUNA_POOLS + #warning LTC_FORTUNA_POOLS was not previously defined (old headers?) + #define LTC_FORTUNA_POOLS 32 +#endif + +#if LTC_FORTUNA_POOLS < 4 || LTC_FORTUNA_POOLS > 32 + #error LTC_FORTUNA_POOLS must be in [4..32] +#endif + +const struct ltc_prng_descriptor fortuna_desc = { + "fortuna", + (32 * LTC_FORTUNA_POOLS), /* default: 1024 */ + &fortuna_start, + &fortuna_add_entropy, + &fortuna_ready, + &fortuna_read, + &fortuna_done, + &fortuna_export, + &fortuna_import, + &fortuna_test +}; + +/* update the IV */ +static void fortuna_update_iv(prng_state *prng) +{ + int x; + unsigned char *IV; + /* update IV */ + IV = prng->fortuna.IV; + for (x = 0; x < 16; x++) { + IV[x] = (IV[x] + 1) & 255; + if (IV[x] != 0) break; + } +} + +/* reseed the PRNG */ +static int fortuna_reseed(prng_state *prng) +{ + unsigned char tmp[MAXBLOCKSIZE]; + hash_state md; + int err, x; + + ++prng->fortuna.reset_cnt; + + /* new K == LTC_SHA256(K || s) where s == LTC_SHA256(P0) || LTC_SHA256(P1) ... */ + sha256_init(&md); + if ((err = sha256_process(&md, prng->fortuna.K, 32)) != CRYPT_OK) { + sha256_done(&md, tmp); + return err; + } + + for (x = 0; x < LTC_FORTUNA_POOLS; x++) { + if (x == 0 || ((prng->fortuna.reset_cnt >> (x-1)) & 1) == 0) { + /* terminate this hash */ + if ((err = sha256_done(&prng->fortuna.pool[x], tmp)) != CRYPT_OK) { + sha256_done(&md, tmp); + return err; + } + /* add it to the string */ + if ((err = sha256_process(&md, tmp, 32)) != CRYPT_OK) { + sha256_done(&md, tmp); + return err; + } + /* reset this pool */ + if ((err = sha256_init(&prng->fortuna.pool[x])) != CRYPT_OK) { + sha256_done(&md, tmp); + return err; + } + } else { + break; + } + } + + /* finish key */ + if ((err = sha256_done(&md, prng->fortuna.K)) != CRYPT_OK) { + return err; + } + if ((err = rijndael_setup(prng->fortuna.K, 32, 0, &prng->fortuna.skey)) != CRYPT_OK) { + return err; + } + fortuna_update_iv(prng); + + /* reset pool len */ + prng->fortuna.pool0_len = 0; + prng->fortuna.wd = 0; + + +#ifdef LTC_CLEAN_STACK + zeromem(&md, sizeof(md)); + zeromem(tmp, sizeof(tmp)); +#endif + + return CRYPT_OK; +} + +/** + Start the PRNG + @param prng [out] The PRNG state to initialize + @return CRYPT_OK if successful +*/ +int fortuna_start(prng_state *prng) +{ + int err, x, y; + unsigned char tmp[MAXBLOCKSIZE]; + + LTC_ARGCHK(prng != NULL); + prng->ready = 0; + + /* initialize the pools */ + for (x = 0; x < LTC_FORTUNA_POOLS; x++) { + if ((err = sha256_init(&prng->fortuna.pool[x])) != CRYPT_OK) { + for (y = 0; y < x; y++) { + sha256_done(&prng->fortuna.pool[y], tmp); + } + return err; + } + } + prng->fortuna.pool_idx = prng->fortuna.pool0_len = prng->fortuna.wd = 0; + prng->fortuna.reset_cnt = 0; + + /* reset bufs */ + zeromem(prng->fortuna.K, 32); + if ((err = rijndael_setup(prng->fortuna.K, 32, 0, &prng->fortuna.skey)) != CRYPT_OK) { + for (x = 0; x < LTC_FORTUNA_POOLS; x++) { + sha256_done(&prng->fortuna.pool[x], tmp); + } + return err; + } + zeromem(prng->fortuna.IV, 16); + + LTC_MUTEX_INIT(&prng->lock) + + return CRYPT_OK; +} + +/** + Add entropy to the PRNG state + @param in The data to add + @param inlen Length of the data to add + @param prng PRNG state to update + @return CRYPT_OK if successful +*/ +int fortuna_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng) +{ + unsigned char tmp[2]; + int err; + + LTC_ARGCHK(prng != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen > 0); + + /* ensure inlen <= 32 */ + if (inlen > 32) { + inlen = 32; + } + + /* add s || length(in) || in to pool[pool_idx] */ + tmp[0] = 0; + tmp[1] = (unsigned char)inlen; + + LTC_MUTEX_LOCK(&prng->lock); + if ((err = sha256_process(&prng->fortuna.pool[prng->fortuna.pool_idx], tmp, 2)) != CRYPT_OK) { + goto LBL_UNLOCK; + } + if ((err = sha256_process(&prng->fortuna.pool[prng->fortuna.pool_idx], in, inlen)) != CRYPT_OK) { + goto LBL_UNLOCK; + } + if (prng->fortuna.pool_idx == 0) { + prng->fortuna.pool0_len += inlen; + } + if (++(prng->fortuna.pool_idx) == LTC_FORTUNA_POOLS) { + prng->fortuna.pool_idx = 0; + } + err = CRYPT_OK; /* success */ + +LBL_UNLOCK: + LTC_MUTEX_UNLOCK(&prng->lock); + return err; +} + +/** + Make the PRNG ready to read from + @param prng The PRNG to make active + @return CRYPT_OK if successful +*/ +int fortuna_ready(prng_state *prng) +{ + int err; + LTC_ARGCHK(prng != NULL); + + LTC_MUTEX_LOCK(&prng->lock); + err = fortuna_reseed(prng); + prng->ready = (err == CRYPT_OK) ? 1 : 0; + + LTC_MUTEX_UNLOCK(&prng->lock); + return err; +} + +/** + Read from the PRNG + @param out Destination + @param outlen Length of output + @param prng The active PRNG to read from + @return Number of octets read +*/ +unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state *prng) +{ + unsigned char tmp[16]; + unsigned long tlen = 0; + + if (outlen == 0 || prng == NULL || out == NULL) return 0; + + LTC_MUTEX_LOCK(&prng->lock); + + if (!prng->ready) { + goto LBL_UNLOCK; + } + + /* do we have to reseed? */ + if (++prng->fortuna.wd == LTC_FORTUNA_WD || prng->fortuna.pool0_len >= 64) { + if (fortuna_reseed(prng) != CRYPT_OK) { + goto LBL_UNLOCK; + } + } + + /* now generate the blocks required */ + tlen = outlen; + + /* handle whole blocks without the extra XMEMCPY */ + while (outlen >= 16) { + /* encrypt the IV and store it */ + rijndael_ecb_encrypt(prng->fortuna.IV, out, &prng->fortuna.skey); + out += 16; + outlen -= 16; + fortuna_update_iv(prng); + } + + /* left over bytes? */ + if (outlen > 0) { + rijndael_ecb_encrypt(prng->fortuna.IV, tmp, &prng->fortuna.skey); + XMEMCPY(out, tmp, outlen); + fortuna_update_iv(prng); + } + + /* generate new key */ + rijndael_ecb_encrypt(prng->fortuna.IV, prng->fortuna.K , &prng->fortuna.skey); + fortuna_update_iv(prng); + + rijndael_ecb_encrypt(prng->fortuna.IV, prng->fortuna.K+16, &prng->fortuna.skey); + fortuna_update_iv(prng); + + if (rijndael_setup(prng->fortuna.K, 32, 0, &prng->fortuna.skey) != CRYPT_OK) { + tlen = 0; + } + +LBL_UNLOCK: +#ifdef LTC_CLEAN_STACK + zeromem(tmp, sizeof(tmp)); +#endif + LTC_MUTEX_UNLOCK(&prng->lock); + return tlen; +} + +/** + Terminate the PRNG + @param prng The PRNG to terminate + @return CRYPT_OK if successful +*/ +int fortuna_done(prng_state *prng) +{ + int err, x; + unsigned char tmp[32]; + + LTC_ARGCHK(prng != NULL); + + LTC_MUTEX_LOCK(&prng->lock); + prng->ready = 0; + + /* terminate all the hashes */ + for (x = 0; x < LTC_FORTUNA_POOLS; x++) { + if ((err = sha256_done(&(prng->fortuna.pool[x]), tmp)) != CRYPT_OK) { + goto LBL_UNLOCK; + } + } + /* call cipher done when we invent one ;-) */ + err = CRYPT_OK; /* success */ + +LBL_UNLOCK: +#ifdef LTC_CLEAN_STACK + zeromem(tmp, sizeof(tmp)); +#endif + LTC_MUTEX_UNLOCK(&prng->lock); + return err; +} + +/** + Export the PRNG state + @param out [out] Destination + @param outlen [in/out] Max size and resulting size of the state + @param prng The PRNG to export + @return CRYPT_OK if successful +*/ +int fortuna_export(unsigned char *out, unsigned long *outlen, prng_state *prng) +{ + int x, err; + hash_state *md; + unsigned long len = fortuna_desc.export_size; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(prng != NULL); + + LTC_MUTEX_LOCK(&prng->lock); + + if (!prng->ready) { + err = CRYPT_ERROR; + goto LBL_UNLOCK; + } + + /* we'll write bytes for s&g's */ + if (*outlen < len) { + *outlen = len; + err = CRYPT_BUFFER_OVERFLOW; + goto LBL_UNLOCK; + } + + md = XMALLOC(sizeof(hash_state)); + if (md == NULL) { + err = CRYPT_MEM; + goto LBL_UNLOCK; + } + + /* to emit the state we copy each pool, terminate it then hash it again so + * an attacker who sees the state can't determine the current state of the PRNG + */ + for (x = 0; x < LTC_FORTUNA_POOLS; x++) { + /* copy the PRNG */ + XMEMCPY(md, &(prng->fortuna.pool[x]), sizeof(*md)); + + /* terminate it */ + if ((err = sha256_done(md, out+x*32)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* now hash it */ + if ((err = sha256_init(md)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = sha256_process(md, out+x*32, 32)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = sha256_done(md, out+x*32)) != CRYPT_OK) { + goto LBL_ERR; + } + } + *outlen = len; + err = CRYPT_OK; + +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(*md)); +#endif + XFREE(md); +LBL_UNLOCK: + LTC_MUTEX_UNLOCK(&prng->lock); + return err; +} + +/** + Import a PRNG state + @param in The PRNG state + @param inlen Size of the state + @param prng The PRNG to import + @return CRYPT_OK if successful +*/ +int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prng) +{ + int err, x; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(prng != NULL); + + if (inlen < (unsigned long)fortuna_desc.export_size) { + return CRYPT_INVALID_ARG; + } + + if ((err = fortuna_start(prng)) != CRYPT_OK) { + return err; + } + for (x = 0; x < LTC_FORTUNA_POOLS; x++) { + if ((err = fortuna_add_entropy(in+x*32, 32, prng)) != CRYPT_OK) { + return err; + } + } + return CRYPT_OK; +} + +/** + PRNG self-test + @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled +*/ +int fortuna_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + int err; + + if ((err = sha256_test()) != CRYPT_OK) { + return err; + } + return rijndael_test(); +#endif +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/prngs/rc4.c b/src/ltc/prngs/rc4.c new file mode 100644 index 0000000..e7d3afc --- /dev/null +++ b/src/ltc/prngs/rc4.c @@ -0,0 +1,244 @@ +/* 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. + */ +#include "tomcrypt.h" + +/** + @file rc4.c + RC4 PRNG, Tom St Denis +*/ + +#ifdef LTC_RC4 + +const struct ltc_prng_descriptor rc4_desc = +{ + "rc4", + 32, + &rc4_start, + &rc4_add_entropy, + &rc4_ready, + &rc4_read, + &rc4_done, + &rc4_export, + &rc4_import, + &rc4_test +}; + +/** + Start the PRNG + @param prng [out] The PRNG state to initialize + @return CRYPT_OK if successful +*/ +int rc4_start(prng_state *prng) +{ + LTC_ARGCHK(prng != NULL); + prng->ready = 0; + /* set entropy (key) size to zero */ + prng->rc4.s.x = 0; + /* clear entropy (key) buffer */ + XMEMSET(&prng->rc4.s.buf, 0, sizeof(prng->rc4.s.buf)); + LTC_MUTEX_INIT(&prng->lock) + return CRYPT_OK; +} + +/** + Add entropy to the PRNG state + @param in The data to add + @param inlen Length of the data to add + @param prng PRNG state to update + @return CRYPT_OK if successful +*/ +int rc4_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng) +{ + unsigned char buf[256]; + unsigned long i; + int err; + + LTC_ARGCHK(prng != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen > 0); + + LTC_MUTEX_LOCK(&prng->lock); + if (prng->ready) { + /* rc4_ready() was already called, do "rekey" operation */ + if ((err = rc4_stream_keystream(&prng->rc4.s, buf, sizeof(buf))) != CRYPT_OK) goto LBL_UNLOCK; + for(i = 0; i < inlen; i++) buf[i % sizeof(buf)] ^= in[i]; + /* initialize RC4 */ + if ((err = rc4_stream_setup(&prng->rc4.s, buf, sizeof(buf))) != CRYPT_OK) goto LBL_UNLOCK; + /* drop first 3072 bytes - https://en.wikipedia.org/wiki/RC4#Fluhrer.2C_Mantin_and_Shamir_attack */ + for (i = 0; i < 12; i++) rc4_stream_keystream(&prng->rc4.s, buf, sizeof(buf)); + } + else { + /* rc4_ready() was not called yet, add entropy to the buffer */ + while (inlen--) prng->rc4.s.buf[prng->rc4.s.x++ % sizeof(prng->rc4.s.buf)] ^= *in++; + } + err = CRYPT_OK; +LBL_UNLOCK: + LTC_MUTEX_UNLOCK(&prng->lock); + return err; +} + +/** + Make the PRNG ready to read from + @param prng The PRNG to make active + @return CRYPT_OK if successful +*/ +int rc4_ready(prng_state *prng) +{ + unsigned char buf[256] = { 0 }; + unsigned long len; + int err, i; + + LTC_ARGCHK(prng != NULL); + + LTC_MUTEX_LOCK(&prng->lock); + if (prng->ready) { err = CRYPT_OK; goto LBL_UNLOCK; } + XMEMCPY(buf, prng->rc4.s.buf, sizeof(buf)); + /* initialize RC4 */ + len = MIN(prng->rc4.s.x, 256); /* TODO: we can perhaps always use all 256 bytes */ + if ((err = rc4_stream_setup(&prng->rc4.s, buf, len)) != CRYPT_OK) goto LBL_UNLOCK; + /* drop first 3072 bytes - https://en.wikipedia.org/wiki/RC4#Fluhrer.2C_Mantin_and_Shamir_attack */ + for (i = 0; i < 12; i++) rc4_stream_keystream(&prng->rc4.s, buf, sizeof(buf)); + prng->ready = 1; +LBL_UNLOCK: + LTC_MUTEX_UNLOCK(&prng->lock); + return err; +} + +/** + Read from the PRNG + @param out Destination + @param outlen Length of output + @param prng The active PRNG to read from + @return Number of octets read +*/ +unsigned long rc4_read(unsigned char *out, unsigned long outlen, prng_state *prng) +{ + if (outlen == 0 || prng == NULL || out == NULL) return 0; + LTC_MUTEX_LOCK(&prng->lock); + if (!prng->ready) { outlen = 0; goto LBL_UNLOCK; } + if (rc4_stream_keystream(&prng->rc4.s, out, outlen) != CRYPT_OK) outlen = 0; +LBL_UNLOCK: + LTC_MUTEX_UNLOCK(&prng->lock); + return outlen; +} + +/** + Terminate the PRNG + @param prng The PRNG to terminate + @return CRYPT_OK if successful +*/ +int rc4_done(prng_state *prng) +{ + int err; + LTC_ARGCHK(prng != NULL); + LTC_MUTEX_LOCK(&prng->lock); + prng->ready = 0; + err = rc4_stream_done(&prng->rc4.s); + LTC_MUTEX_UNLOCK(&prng->lock); + return err; +} + +/** + Export the PRNG state + @param out [out] Destination + @param outlen [in/out] Max size and resulting size of the state + @param prng The PRNG to export + @return CRYPT_OK if successful +*/ +int rc4_export(unsigned char *out, unsigned long *outlen, prng_state *prng) +{ + unsigned long len = rc4_desc.export_size; + + LTC_ARGCHK(prng != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + if (*outlen < len) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + if (rc4_read(out, len, prng) != len) { + return CRYPT_ERROR_READPRNG; + } + + *outlen = len; + return CRYPT_OK; +} + +/** + Import a PRNG state + @param in The PRNG state + @param inlen Size of the state + @param prng The PRNG to import + @return CRYPT_OK if successful +*/ +int rc4_import(const unsigned char *in, unsigned long inlen, prng_state *prng) +{ + int err; + + LTC_ARGCHK(prng != NULL); + LTC_ARGCHK(in != NULL); + if (inlen < (unsigned long)rc4_desc.export_size) return CRYPT_INVALID_ARG; + + if ((err = rc4_start(prng)) != CRYPT_OK) return err; + if ((err = rc4_add_entropy(in, inlen, prng)) != CRYPT_OK) return err; + return CRYPT_OK; +} + +/** + PRNG self-test + @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled +*/ +int rc4_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + prng_state st; + unsigned char en[] = { 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, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32 }; + unsigned char dmp[500]; + unsigned long dmplen = sizeof(dmp); + unsigned char out[1000]; + unsigned char t1[] = { 0xE0, 0x4D, 0x9A, 0xF6, 0xA8, 0x9D, 0x77, 0x53, 0xAE, 0x09 }; + unsigned char t2[] = { 0xEF, 0x80, 0xA2, 0xE6, 0x50, 0x91, 0xF3, 0x17, 0x4A, 0x8A }; + unsigned char t3[] = { 0x4B, 0xD6, 0x5C, 0x67, 0x99, 0x03, 0x56, 0x12, 0x80, 0x48 }; + int err; + + if ((err = rc4_start(&st)) != CRYPT_OK) return err; + /* add entropy to uninitialized prng */ + if ((err = rc4_add_entropy(en, sizeof(en), &st)) != CRYPT_OK) return err; + if ((err = rc4_ready(&st)) != CRYPT_OK) return err; + if (rc4_read(out, 10, &st) != 10) return CRYPT_ERROR_READPRNG; /* 10 bytes for testing */ + if (compare_testvector(out, 10, t1, sizeof(t1), "RC4-PRNG", 1)) return CRYPT_FAIL_TESTVECTOR; + if (rc4_read(out, 500, &st) != 500) return CRYPT_ERROR_READPRNG; /* skip 500 bytes */ + /* add entropy to already initialized prng */ + if ((err = rc4_add_entropy(en, sizeof(en), &st)) != CRYPT_OK) return err; + if (rc4_read(out, 500, &st) != 500) return CRYPT_ERROR_READPRNG; /* skip 500 bytes */ + if ((err = rc4_export(dmp, &dmplen, &st)) != CRYPT_OK) return err; + if (rc4_read(out, 500, &st) != 500) return CRYPT_ERROR_READPRNG; /* skip 500 bytes */ + if (rc4_read(out, 10, &st) != 10) return CRYPT_ERROR_READPRNG; /* 10 bytes for testing */ + if (compare_testvector(out, 10, t2, sizeof(t2), "RC4-PRNG", 2)) return CRYPT_FAIL_TESTVECTOR; + if ((err = rc4_done(&st)) != CRYPT_OK) return err; + if ((err = rc4_import(dmp, dmplen, &st)) != CRYPT_OK) return err; + if ((err = rc4_ready(&st)) != CRYPT_OK) return err; + if (rc4_read(out, 500, &st) != 500) return CRYPT_ERROR_READPRNG; /* skip 500 bytes */ + if (rc4_read(out, 10, &st) != 10) return CRYPT_ERROR_READPRNG; /* 10 bytes for testing */ + if (compare_testvector(out, 10, t3, sizeof(t3), "RC4-PRNG", 3)) return CRYPT_FAIL_TESTVECTOR; + if ((err = rc4_done(&st)) != CRYPT_OK) return err; + + return CRYPT_OK; +#endif +} + +#endif diff --git a/src/ltc/prngs/rng_get_bytes.c b/src/ltc/prngs/rng_get_bytes.c new file mode 100644 index 0000000..2c05d0d --- /dev/null +++ b/src/ltc/prngs/rng_get_bytes.c @@ -0,0 +1,159 @@ +/* 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. + */ +#include "tomcrypt.h" + +#ifdef LTC_RNG_GET_BYTES +/** + @file rng_get_bytes.c + portable way to get secure random bits to feed a PRNG (Tom St Denis) +*/ + +#ifdef LTC_DEVRANDOM +/* on *NIX read /dev/random */ +static unsigned long rng_nix(unsigned char *buf, unsigned long len, + void (*callback)(void)) +{ +#ifdef LTC_NO_FILE + LTC_UNUSED_PARAM(callback); + LTC_UNUSED_PARAM(buf); + LTC_UNUSED_PARAM(len); + return 0; +#else + FILE *f; + unsigned long x; + LTC_UNUSED_PARAM(callback); +#ifdef LTC_TRY_URANDOM_FIRST + f = fopen("/dev/urandom", "rb"); + if (f == NULL) +#endif /* LTC_TRY_URANDOM_FIRST */ + f = fopen("/dev/random", "rb"); + + if (f == NULL) { + return 0; + } + + /* disable buffering */ + if (setvbuf(f, NULL, _IONBF, 0) != 0) { + fclose(f); + return 0; + } + + x = (unsigned long)fread(buf, 1, (size_t)len, f); + fclose(f); + return x; +#endif /* LTC_NO_FILE */ +} + +#endif /* LTC_DEVRANDOM */ + +#if !defined(_WIN32_WCE) + +#define ANSI_RNG + +static unsigned long rng_ansic(unsigned char *buf, unsigned long len, + void (*callback)(void)) +{ + clock_t t1; + int l, acc, bits, a, b; + + l = len; + bits = 8; + acc = a = b = 0; + while (len--) { + if (callback != NULL) callback(); + while (bits--) { + do { + t1 = XCLOCK(); while (t1 == XCLOCK()) a ^= 1; + t1 = XCLOCK(); while (t1 == XCLOCK()) b ^= 1; + } while (a == b); + acc = (acc << 1) | a; + } + *buf++ = acc; + acc = 0; + bits = 8; + } + return l; +} + +#endif + +/* Try the Microsoft CSP */ +#if defined(_WIN32) || defined(_WIN32_WCE) +#ifndef _WIN32_WINNT + #define _WIN32_WINNT 0x0400 +#endif +#ifdef _WIN32_WCE + #define UNDER_CE + #define ARM +#endif + +#define WIN32_LEAN_AND_MEAN +#include +#include + +static unsigned long rng_win32(unsigned char *buf, unsigned long len, + void (*callback)(void)) +{ + HCRYPTPROV hProv = 0; + LTC_UNUSED_PARAM(callback); + if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, + (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) && + !CryptAcquireContext (&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET)) + return 0; + + if (CryptGenRandom(hProv, len, buf) == TRUE) { + CryptReleaseContext(hProv, 0); + return len; + } else { + CryptReleaseContext(hProv, 0); + return 0; + } +} + +#endif /* WIN32 */ + +/** + Read the system RNG + @param out Destination + @param outlen Length desired (octets) + @param callback Pointer to void function to act as "callback" when RNG is slow. This can be NULL + @return Number of octets read +*/ +unsigned long rng_get_bytes(unsigned char *out, unsigned long outlen, + void (*callback)(void)) +{ + unsigned long x; + + LTC_ARGCHK(out != NULL); + +#ifdef LTC_PRNG_ENABLE_LTC_RNG + if (ltc_rng) { + x = ltc_rng(out, outlen, callback); + if (x != 0) { + return x; + } + } +#endif + +#if defined(_WIN32) || defined(_WIN32_WCE) + x = rng_win32(out, outlen, callback); if (x != 0) { return x; } +#elif defined(LTC_DEVRANDOM) + x = rng_nix(out, outlen, callback); if (x != 0) { return x; } +#endif +#ifdef ANSI_RNG + x = rng_ansic(out, outlen, callback); if (x != 0) { return x; } +#endif + return 0; +} +#endif /* #ifdef LTC_RNG_GET_BYTES */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/prngs/rng_make_prng.c b/src/ltc/prngs/rng_make_prng.c new file mode 100644 index 0000000..fff92c7 --- /dev/null +++ b/src/ltc/prngs/rng_make_prng.c @@ -0,0 +1,69 @@ +/* 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. + */ +#include "tomcrypt.h" + +#ifdef LTC_RNG_MAKE_PRNG +/** + @file rng_make_prng.c + portable way to get secure random bits to feed a PRNG (Tom St Denis) +*/ + +/** + Create a PRNG from a RNG + @param bits Number of bits of entropy desired (64 ... 1024) + @param wprng Index of which PRNG to setup + @param prng [out] PRNG state to initialize + @param callback A pointer to a void function for when the RNG is slow, this can be NULL + @return CRYPT_OK if successful +*/ +int rng_make_prng(int bits, int wprng, prng_state *prng, + void (*callback)(void)) +{ + unsigned char buf[256]; + int err; + + LTC_ARGCHK(prng != NULL); + + /* check parameter */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + if (bits < 64 || bits > 1024) { + return CRYPT_INVALID_PRNGSIZE; + } + + if ((err = prng_descriptor[wprng].start(prng)) != CRYPT_OK) { + return err; + } + + bits = ((bits/8)+((bits&7)!=0?1:0)) * 2; + if (rng_get_bytes(buf, (unsigned long)bits, callback) != (unsigned long)bits) { + return CRYPT_ERROR_READPRNG; + } + + if ((err = prng_descriptor[wprng].add_entropy(buf, (unsigned long)bits, prng)) != CRYPT_OK) { + return err; + } + + if ((err = prng_descriptor[wprng].ready(prng)) != CRYPT_OK) { + return err; + } + + #ifdef LTC_CLEAN_STACK + zeromem(buf, sizeof(buf)); + #endif + return CRYPT_OK; +} +#endif /* #ifdef LTC_RNG_MAKE_PRNG */ + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/prngs/sober128.c b/src/ltc/prngs/sober128.c new file mode 100644 index 0000000..56f873c --- /dev/null +++ b/src/ltc/prngs/sober128.c @@ -0,0 +1,244 @@ +/* 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. + */ + +#include "tomcrypt.h" + +/** + @file sober128.c + Implementation of SOBER-128 by Tom St Denis. + Based on s128fast.c reference code supplied by Greg Rose of QUALCOMM. +*/ + +#ifdef LTC_SOBER128 + +const struct ltc_prng_descriptor sober128_desc = +{ + "sober128", + 40, + &sober128_start, + &sober128_add_entropy, + &sober128_ready, + &sober128_read, + &sober128_done, + &sober128_export, + &sober128_import, + &sober128_test +}; + +/** + Start the PRNG + @param prng [out] The PRNG state to initialize + @return CRYPT_OK if successful +*/ +int sober128_start(prng_state *prng) +{ + LTC_ARGCHK(prng != NULL); + prng->ready = 0; + XMEMSET(&prng->sober128.ent, 0, sizeof(prng->sober128.ent)); + prng->sober128.idx = 0; + LTC_MUTEX_INIT(&prng->lock) + return CRYPT_OK; +} + +/** + Add entropy to the PRNG state + @param in The data to add + @param inlen Length of the data to add + @param prng PRNG state to update + @return CRYPT_OK if successful +*/ +int sober128_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng) +{ + unsigned char buf[40]; + unsigned long i; + int err; + + LTC_ARGCHK(prng != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen > 0); + + LTC_MUTEX_LOCK(&prng->lock); + if (prng->ready) { + /* sober128_ready() was already called, do "rekey" operation */ + if ((err = sober128_stream_keystream(&prng->sober128.s, buf, sizeof(buf))) != CRYPT_OK) goto LBL_UNLOCK; + for(i = 0; i < inlen; i++) buf[i % sizeof(buf)] ^= in[i]; + /* key 32 bytes, 20 rounds */ + if ((err = sober128_stream_setup(&prng->sober128.s, buf, 32)) != CRYPT_OK) goto LBL_UNLOCK; + /* iv 8 bytes */ + if ((err = sober128_stream_setiv(&prng->sober128.s, buf + 32, 8)) != CRYPT_OK) goto LBL_UNLOCK; + /* clear KEY + IV */ + XMEMSET(buf, 0, sizeof(buf)); + } + else { + /* sober128_ready() was not called yet, add entropy to ent buffer */ + while (inlen--) prng->sober128.ent[prng->sober128.idx++ % sizeof(prng->sober128.ent)] ^= *in++; + } + err = CRYPT_OK; +LBL_UNLOCK: + LTC_MUTEX_UNLOCK(&prng->lock); + return err; +} + +/** + Make the PRNG ready to read from + @param prng The PRNG to make active + @return CRYPT_OK if successful +*/ +int sober128_ready(prng_state *prng) +{ + int err; + + LTC_ARGCHK(prng != NULL); + + LTC_MUTEX_LOCK(&prng->lock); + if (prng->ready) { err = CRYPT_OK; goto LBL_UNLOCK; } + /* key 32 bytes, 20 rounds */ + if ((err = sober128_stream_setup(&prng->sober128.s, prng->sober128.ent, 32)) != CRYPT_OK) goto LBL_UNLOCK; + /* iv 8 bytes */ + if ((err = sober128_stream_setiv(&prng->sober128.s, prng->sober128.ent + 32, 8)) != CRYPT_OK) goto LBL_UNLOCK; + XMEMSET(&prng->sober128.ent, 0, sizeof(prng->sober128.ent)); + prng->sober128.idx = 0; + prng->ready = 1; +LBL_UNLOCK: + LTC_MUTEX_UNLOCK(&prng->lock); + return err; +} + +/** + Read from the PRNG + @param out Destination + @param outlen Length of output + @param prng The active PRNG to read from + @return Number of octets read +*/ +unsigned long sober128_read(unsigned char *out, unsigned long outlen, prng_state *prng) +{ + if (outlen == 0 || prng == NULL || out == NULL) return 0; + LTC_MUTEX_LOCK(&prng->lock); + if (!prng->ready) { outlen = 0; goto LBL_UNLOCK; } + if (sober128_stream_keystream(&prng->sober128.s, out, outlen) != CRYPT_OK) outlen = 0; +LBL_UNLOCK: + LTC_MUTEX_UNLOCK(&prng->lock); + return outlen; +} + +/** + Terminate the PRNG + @param prng The PRNG to terminate + @return CRYPT_OK if successful +*/ +int sober128_done(prng_state *prng) +{ + int err; + LTC_ARGCHK(prng != NULL); + LTC_MUTEX_LOCK(&prng->lock); + prng->ready = 0; + err = sober128_stream_done(&prng->sober128.s); + LTC_MUTEX_UNLOCK(&prng->lock); + return err; +} + +/** + Export the PRNG state + @param out [out] Destination + @param outlen [in/out] Max size and resulting size of the state + @param prng The PRNG to export + @return CRYPT_OK if successful +*/ +int sober128_export(unsigned char *out, unsigned long *outlen, prng_state *prng) +{ + unsigned long len = sober128_desc.export_size; + + LTC_ARGCHK(prng != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + if (*outlen < len) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + if (sober128_read(out, len, prng) != len) { + return CRYPT_ERROR_READPRNG; + } + + *outlen = len; + return CRYPT_OK; +} + +/** + Import a PRNG state + @param in The PRNG state + @param inlen Size of the state + @param prng The PRNG to import + @return CRYPT_OK if successful +*/ +int sober128_import(const unsigned char *in, unsigned long inlen, prng_state *prng) +{ + int err; + + LTC_ARGCHK(prng != NULL); + LTC_ARGCHK(in != NULL); + if (inlen < (unsigned long)sober128_desc.export_size) return CRYPT_INVALID_ARG; + + if ((err = sober128_start(prng)) != CRYPT_OK) return err; + if ((err = sober128_add_entropy(in, sober128_desc.export_size, prng)) != CRYPT_OK) return err; + return CRYPT_OK; +} + +/** + PRNG self-test + @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled +*/ +int sober128_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + prng_state st; + unsigned char en[] = { 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, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32 }; + unsigned char dmp[300]; + unsigned long dmplen = sizeof(dmp); + unsigned char out[500]; + unsigned char t1[] = { 0x31, 0x82, 0xA7, 0xA5, 0x8B, 0xD7, 0xCB, 0x39, 0x86, 0x1A }; + unsigned char t2[] = { 0x6B, 0x43, 0x9E, 0xBC, 0xE7, 0x62, 0x9B, 0xE6, 0x9B, 0x83 }; + unsigned char t3[] = { 0x4A, 0x0E, 0x6C, 0xC1, 0xCF, 0xB4, 0x73, 0x49, 0x99, 0x05 }; + int err; + + if ((err = sober128_start(&st)) != CRYPT_OK) return err; + /* add entropy to uninitialized prng */ + if ((err = sober128_add_entropy(en, sizeof(en), &st)) != CRYPT_OK) return err; + if ((err = sober128_ready(&st)) != CRYPT_OK) return err; + if (sober128_read(out, 10, &st) != 10) return CRYPT_ERROR_READPRNG; /* 10 bytes for testing */ + if (compare_testvector(out, 10, t1, sizeof(t1), "SOBER128-PRNG", 1)) return CRYPT_FAIL_TESTVECTOR; + if (sober128_read(out, 500, &st) != 500) return CRYPT_ERROR_READPRNG; /* skip 500 bytes */ + /* add entropy to already initialized prng */ + if ((err = sober128_add_entropy(en, sizeof(en), &st)) != CRYPT_OK) return err; + if (sober128_read(out, 500, &st) != 500) return CRYPT_ERROR_READPRNG; /* skip 500 bytes */ + if ((err = sober128_export(dmp, &dmplen, &st)) != CRYPT_OK) return err; + if (sober128_read(out, 500, &st) != 500) return CRYPT_ERROR_READPRNG; /* skip 500 bytes */ + if (sober128_read(out, 10, &st) != 10) return CRYPT_ERROR_READPRNG; /* 10 bytes for testing */ + if (compare_testvector(out, 10, t2, sizeof(t2), "SOBER128-PRNG", 2)) return CRYPT_FAIL_TESTVECTOR; + if ((err = sober128_done(&st)) != CRYPT_OK) return err; + if ((err = sober128_import(dmp, dmplen, &st)) != CRYPT_OK) return err; + if ((err = sober128_ready(&st)) != CRYPT_OK) return err; + if (sober128_read(out, 500, &st) != 500) return CRYPT_ERROR_READPRNG; /* skip 500 bytes */ + if (sober128_read(out, 10, &st) != 10) return CRYPT_ERROR_READPRNG; /* 10 bytes for testing */ + if (compare_testvector(out, 10, t3, sizeof(t3), "SOBER128-PRNG", 3)) return CRYPT_FAIL_TESTVECTOR; + if ((err = sober128_done(&st)) != CRYPT_OK) return err; + + return CRYPT_OK; +#endif +} + +#endif diff --git a/src/ltc/prngs/sprng.c b/src/ltc/prngs/sprng.c new file mode 100644 index 0000000..7e1865f --- /dev/null +++ b/src/ltc/prngs/sprng.c @@ -0,0 +1,161 @@ +/* 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. + */ +#include "tomcrypt.h" + +/** + @file sprng.c + Secure PRNG, Tom St Denis +*/ + +/* A secure PRNG using the RNG functions. Basically this is a + * wrapper that allows you to use a secure RNG as a PRNG + * in the various other functions. + */ + +#ifdef LTC_SPRNG + +const struct ltc_prng_descriptor sprng_desc = +{ + "sprng", 0, + &sprng_start, + &sprng_add_entropy, + &sprng_ready, + &sprng_read, + &sprng_done, + &sprng_export, + &sprng_import, + &sprng_test +}; + +/** + Start the PRNG + @param prng [out] The PRNG state to initialize + @return CRYPT_OK if successful +*/ +int sprng_start(prng_state *prng) +{ + LTC_UNUSED_PARAM(prng); + return CRYPT_OK; +} + +/** + Add entropy to the PRNG state + @param in The data to add + @param inlen Length of the data to add + @param prng PRNG state to update + @return CRYPT_OK if successful +*/ +int sprng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng) +{ + LTC_UNUSED_PARAM(in); + LTC_UNUSED_PARAM(inlen); + LTC_UNUSED_PARAM(prng); + return CRYPT_OK; +} + +/** + Make the PRNG ready to read from + @param prng The PRNG to make active + @return CRYPT_OK if successful +*/ +int sprng_ready(prng_state *prng) +{ + LTC_UNUSED_PARAM(prng); + return CRYPT_OK; +} + +/** + Read from the PRNG + @param out Destination + @param outlen Length of output + @param prng The active PRNG to read from + @return Number of octets read +*/ +unsigned long sprng_read(unsigned char *out, unsigned long outlen, prng_state *prng) +{ + LTC_ARGCHK(out != NULL); + LTC_UNUSED_PARAM(prng); + return rng_get_bytes(out, outlen, NULL); +} + +/** + Terminate the PRNG + @param prng The PRNG to terminate + @return CRYPT_OK if successful +*/ +int sprng_done(prng_state *prng) +{ + LTC_UNUSED_PARAM(prng); + return CRYPT_OK; +} + +/** + Export the PRNG state + @param out [out] Destination + @param outlen [in/out] Max size and resulting size of the state + @param prng The PRNG to export + @return CRYPT_OK if successful +*/ +int sprng_export(unsigned char *out, unsigned long *outlen, prng_state *prng) +{ + LTC_ARGCHK(outlen != NULL); + LTC_UNUSED_PARAM(out); + LTC_UNUSED_PARAM(prng); + + *outlen = 0; + return CRYPT_OK; +} + +/** + Import a PRNG state + @param in The PRNG state + @param inlen Size of the state + @param prng The PRNG to import + @return CRYPT_OK if successful +*/ +int sprng_import(const unsigned char *in, unsigned long inlen, prng_state *prng) +{ + LTC_UNUSED_PARAM(in); + LTC_UNUSED_PARAM(inlen); + LTC_UNUSED_PARAM(prng); + return CRYPT_OK; +} + +/** + PRNG self-test + @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled +*/ +int sprng_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + prng_state st; + unsigned char en[] = { 0x01, 0x02, 0x03, 0x04 }; + unsigned char out[1000]; + int err; + + if ((err = sprng_start(&st)) != CRYPT_OK) return err; + if ((err = sprng_add_entropy(en, sizeof(en), &st)) != CRYPT_OK) return err; + if ((err = sprng_ready(&st)) != CRYPT_OK) return err; + if (sprng_read(out, 500, &st) != 500) return CRYPT_ERROR_READPRNG; /* skip 500 bytes */ + if ((err = sprng_done(&st)) != CRYPT_OK) return err; + + return CRYPT_OK; +#endif +} + +#endif + + + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/prngs/yarrow.c b/src/ltc/prngs/yarrow.c new file mode 100644 index 0000000..7275ac8 --- /dev/null +++ b/src/ltc/prngs/yarrow.c @@ -0,0 +1,351 @@ +/* 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. + */ +#include "tomcrypt.h" + +/** + @file yarrow.c + Yarrow PRNG, Tom St Denis +*/ + +#ifdef LTC_YARROW + +const struct ltc_prng_descriptor yarrow_desc = +{ + "yarrow", 64, + &yarrow_start, + &yarrow_add_entropy, + &yarrow_ready, + &yarrow_read, + &yarrow_done, + &yarrow_export, + &yarrow_import, + &yarrow_test +}; + +/** + Start the PRNG + @param prng [out] The PRNG state to initialize + @return CRYPT_OK if successful +*/ +int yarrow_start(prng_state *prng) +{ + int err; + + LTC_ARGCHK(prng != NULL); + prng->ready = 0; + + /* these are the default hash/cipher combo used */ +#ifdef LTC_RIJNDAEL +#if LTC_YARROW_AES==0 + prng->yarrow.cipher = register_cipher(&rijndael_enc_desc); +#elif LTC_YARROW_AES==1 + prng->yarrow.cipher = register_cipher(&aes_enc_desc); +#elif LTC_YARROW_AES==2 + prng->yarrow.cipher = register_cipher(&rijndael_desc); +#elif LTC_YARROW_AES==3 + prng->yarrow.cipher = register_cipher(&aes_desc); +#endif +#elif defined(LTC_BLOWFISH) + prng->yarrow.cipher = register_cipher(&blowfish_desc); +#elif defined(LTC_TWOFISH) + prng->yarrow.cipher = register_cipher(&twofish_desc); +#elif defined(LTC_RC6) + prng->yarrow.cipher = register_cipher(&rc6_desc); +#elif defined(LTC_RC5) + prng->yarrow.cipher = register_cipher(&rc5_desc); +#elif defined(LTC_SAFERP) + prng->yarrow.cipher = register_cipher(&saferp_desc); +#elif defined(LTC_RC2) + prng->yarrow.cipher = register_cipher(&rc2_desc); +#elif defined(LTC_NOEKEON) + prng->yarrow.cipher = register_cipher(&noekeon_desc); +#elif defined(LTC_ANUBIS) + prng->yarrow.cipher = register_cipher(&anubis_desc); +#elif defined(LTC_KSEED) + prng->yarrow.cipher = register_cipher(&kseed_desc); +#elif defined(LTC_KHAZAD) + prng->yarrow.cipher = register_cipher(&khazad_desc); +#elif defined(LTC_CAST5) + prng->yarrow.cipher = register_cipher(&cast5_desc); +#elif defined(LTC_XTEA) + prng->yarrow.cipher = register_cipher(&xtea_desc); +#elif defined(LTC_SAFER) + prng->yarrow.cipher = register_cipher(&safer_sk128_desc); +#elif defined(LTC_DES) + prng->yarrow.cipher = register_cipher(&des3_desc); +#else + #error LTC_YARROW needs at least one CIPHER +#endif + if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) { + return err; + } + +#ifdef LTC_SHA256 + prng->yarrow.hash = register_hash(&sha256_desc); +#elif defined(LTC_SHA512) + prng->yarrow.hash = register_hash(&sha512_desc); +#elif defined(LTC_TIGER) + prng->yarrow.hash = register_hash(&tiger_desc); +#elif defined(LTC_SHA1) + prng->yarrow.hash = register_hash(&sha1_desc); +#elif defined(LTC_RIPEMD320) + prng->yarrow.hash = register_hash(&rmd320_desc); +#elif defined(LTC_RIPEMD256) + prng->yarrow.hash = register_hash(&rmd256_desc); +#elif defined(LTC_RIPEMD160) + prng->yarrow.hash = register_hash(&rmd160_desc); +#elif defined(LTC_RIPEMD128) + prng->yarrow.hash = register_hash(&rmd128_desc); +#elif defined(LTC_MD5) + prng->yarrow.hash = register_hash(&md5_desc); +#elif defined(LTC_MD4) + prng->yarrow.hash = register_hash(&md4_desc); +#elif defined(LTC_MD2) + prng->yarrow.hash = register_hash(&md2_desc); +#elif defined(LTC_WHIRLPOOL) + prng->yarrow.hash = register_hash(&whirlpool_desc); +#else + #error LTC_YARROW needs at least one HASH +#endif + if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) { + return err; + } + + /* zero the memory used */ + zeromem(prng->yarrow.pool, sizeof(prng->yarrow.pool)); + LTC_MUTEX_INIT(&prng->lock) + + return CRYPT_OK; +} + +/** + Add entropy to the PRNG state + @param in The data to add + @param inlen Length of the data to add + @param prng PRNG state to update + @return CRYPT_OK if successful +*/ +int yarrow_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng) +{ + hash_state md; + int err; + + LTC_ARGCHK(prng != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen > 0); + + LTC_MUTEX_LOCK(&prng->lock); + + if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) { + goto LBL_UNLOCK; + } + + /* start the hash */ + if ((err = hash_descriptor[prng->yarrow.hash].init(&md)) != CRYPT_OK) { + goto LBL_UNLOCK; + } + + /* hash the current pool */ + if ((err = hash_descriptor[prng->yarrow.hash].process(&md, prng->yarrow.pool, + hash_descriptor[prng->yarrow.hash].hashsize)) != CRYPT_OK) { + goto LBL_UNLOCK; + } + + /* add the new entropy */ + if ((err = hash_descriptor[prng->yarrow.hash].process(&md, in, inlen)) != CRYPT_OK) { + goto LBL_UNLOCK; + } + + /* store result */ + err = hash_descriptor[prng->yarrow.hash].done(&md, prng->yarrow.pool); + +LBL_UNLOCK: + LTC_MUTEX_UNLOCK(&prng->lock); + return err; +} + +/** + Make the PRNG ready to read from + @param prng The PRNG to make active + @return CRYPT_OK if successful +*/ +int yarrow_ready(prng_state *prng) +{ + int ks, err; + + LTC_ARGCHK(prng != NULL); + + LTC_MUTEX_LOCK(&prng->lock); + + if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) { + goto LBL_UNLOCK; + } + + if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) { + goto LBL_UNLOCK; + } + + /* setup CTR mode using the "pool" as the key */ + ks = (int)hash_descriptor[prng->yarrow.hash].hashsize; + if ((err = cipher_descriptor[prng->yarrow.cipher].keysize(&ks)) != CRYPT_OK) { + goto LBL_UNLOCK; + } + + if ((err = ctr_start(prng->yarrow.cipher, /* what cipher to use */ + prng->yarrow.pool, /* IV */ + prng->yarrow.pool, ks, /* KEY and key size */ + 0, /* number of rounds */ + CTR_COUNTER_LITTLE_ENDIAN, /* little endian counter */ + &prng->yarrow.ctr)) != CRYPT_OK) { + goto LBL_UNLOCK; + } + prng->ready = 1; + +LBL_UNLOCK: + LTC_MUTEX_UNLOCK(&prng->lock); + return err; +} + +/** + Read from the PRNG + @param out Destination + @param outlen Length of output + @param prng The active PRNG to read from + @return Number of octets read +*/ +unsigned long yarrow_read(unsigned char *out, unsigned long outlen, prng_state *prng) +{ + if (outlen == 0 || prng == NULL || out == NULL) return 0; + + LTC_MUTEX_LOCK(&prng->lock); + + if (!prng->ready) { + outlen = 0; + goto LBL_UNLOCK; + } + + /* put out in predictable state first */ + zeromem(out, outlen); + + /* now randomize it */ + if (ctr_encrypt(out, out, outlen, &prng->yarrow.ctr) != CRYPT_OK) { + outlen = 0; + } + +LBL_UNLOCK: + LTC_MUTEX_UNLOCK(&prng->lock); + return outlen; +} + +/** + Terminate the PRNG + @param prng The PRNG to terminate + @return CRYPT_OK if successful +*/ +int yarrow_done(prng_state *prng) +{ + int err; + LTC_ARGCHK(prng != NULL); + + LTC_MUTEX_LOCK(&prng->lock); + prng->ready = 0; + + /* call cipher done when we invent one ;-) */ + + /* we invented one */ + err = ctr_done(&prng->yarrow.ctr); + + LTC_MUTEX_UNLOCK(&prng->lock); + return err; +} + +/** + Export the PRNG state + @param out [out] Destination + @param outlen [in/out] Max size and resulting size of the state + @param prng The PRNG to export + @return CRYPT_OK if successful +*/ +int yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng) +{ + unsigned long len = yarrow_desc.export_size; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(prng != NULL); + + if (*outlen < len) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + if (yarrow_read(out, len, prng) != len) { + return CRYPT_ERROR_READPRNG; + } + + *outlen = len; + return CRYPT_OK; +} + +/** + Import a PRNG state + @param in The PRNG state + @param inlen Size of the state + @param prng The PRNG to import + @return CRYPT_OK if successful +*/ +int yarrow_import(const unsigned char *in, unsigned long inlen, prng_state *prng) +{ + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(prng != NULL); + if (inlen < (unsigned long)yarrow_desc.export_size) return CRYPT_INVALID_ARG; + + if ((err = yarrow_start(prng)) != CRYPT_OK) return err; + if ((err = yarrow_add_entropy(in, inlen, prng)) != CRYPT_OK) return err; + return CRYPT_OK; +} + +/** + PRNG self-test + @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled +*/ +int yarrow_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + int err; + prng_state prng; + + if ((err = yarrow_start(&prng)) != CRYPT_OK) { + return err; + } + + /* now let's test the hash/cipher that was chosen */ + if (cipher_descriptor[prng.yarrow.cipher].test && + ((err = cipher_descriptor[prng.yarrow.cipher].test()) != CRYPT_OK)) { + return err; + } + if (hash_descriptor[prng.yarrow.hash].test && + ((err = hash_descriptor[prng.yarrow.hash].test()) != CRYPT_OK)) { + return err; + } + + return CRYPT_OK; +#endif +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltc/stream/chacha/chacha_crypt.c b/src/ltc/stream/chacha/chacha_crypt.c new file mode 100644 index 0000000..30b5da7 --- /dev/null +++ b/src/ltc/stream/chacha/chacha_crypt.c @@ -0,0 +1,95 @@ +/* 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. + */ + +/* The implementation is based on: + * chacha-ref.c version 20080118 + * Public domain from D. J. Bernstein + */ + +#include "tomcrypt.h" + +#ifdef LTC_CHACHA + +#define QUARTERROUND(a,b,c,d) \ + x[a] += x[b]; x[d] = ROL(x[d] ^ x[a], 16); \ + x[c] += x[d]; x[b] = ROL(x[b] ^ x[c], 12); \ + x[a] += x[b]; x[d] = ROL(x[d] ^ x[a], 8); \ + x[c] += x[d]; x[b] = ROL(x[b] ^ x[c], 7); + +static void _chacha_block(unsigned char *output, const ulong32 *input, int rounds) +{ + ulong32 x[16]; + int i; + XMEMCPY(x, input, sizeof(x)); + for (i = rounds; i > 0; i -= 2) { + QUARTERROUND(0, 4, 8,12) + QUARTERROUND(1, 5, 9,13) + QUARTERROUND(2, 6,10,14) + QUARTERROUND(3, 7,11,15) + QUARTERROUND(0, 5,10,15) + QUARTERROUND(1, 6,11,12) + QUARTERROUND(2, 7, 8,13) + QUARTERROUND(3, 4, 9,14) + } + for (i = 0; i < 16; ++i) { + x[i] += input[i]; + STORE32L(x[i], output + 4 * i); + } +} + +/** + Encrypt (or decrypt) bytes of ciphertext (or plaintext) with ChaCha + @param st The ChaCha state + @param in The plaintext (or ciphertext) + @param inlen The length of the input (octets) + @param out [out] The ciphertext (or plaintext), length inlen + @return CRYPT_OK if successful +*/ +int chacha_crypt(chacha_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out) +{ + unsigned char buf[64]; + unsigned long i, j; + + if (inlen == 0) return CRYPT_OK; /* nothing to do */ + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + + if (st->ksleft > 0) { + j = MIN(st->ksleft, inlen); + for (i = 0; i < j; ++i, st->ksleft--) out[i] = in[i] ^ st->kstream[64 - st->ksleft]; + inlen -= j; + if (inlen == 0) return CRYPT_OK; + out += j; + in += j; + } + for (;;) { + _chacha_block(buf, st->input, st->rounds); + if (st->ivlen == 8) { + /* IV-64bit, increment 64bit counter */ + if (0 == ++st->input[12] && 0 == ++st->input[13]) return CRYPT_OVERFLOW; + } + else { + /* IV-96bit, increment 32bit counter */ + if (0 == ++st->input[12]) return CRYPT_OVERFLOW; + } + if (inlen <= 64) { + for (i = 0; i < inlen; ++i) out[i] = in[i] ^ buf[i]; + st->ksleft = 64 - inlen; + for (i = inlen; i < 64; ++i) st->kstream[i] = buf[i]; + return CRYPT_OK; + } + for (i = 0; i < 64; ++i) out[i] = in[i] ^ buf[i]; + inlen -= 64; + out += 64; + in += 64; + } +} + +#endif diff --git a/src/ltc/stream/chacha/chacha_done.c b/src/ltc/stream/chacha/chacha_done.c new file mode 100644 index 0000000..4d6e278 --- /dev/null +++ b/src/ltc/stream/chacha/chacha_done.c @@ -0,0 +1,26 @@ +/* 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. + */ + +#include "tomcrypt.h" + +#ifdef LTC_CHACHA + +/** + Terminate and clear ChaCha state + @param st The ChaCha state + @return CRYPT_OK on success +*/ +int chacha_done(chacha_state *st) +{ + LTC_ARGCHK(st != NULL); + XMEMSET(st, 0, sizeof(chacha_state)); + return CRYPT_OK; +} + +#endif diff --git a/src/ltc/stream/chacha/chacha_ivctr32.c b/src/ltc/stream/chacha/chacha_ivctr32.c new file mode 100644 index 0000000..9884a1e --- /dev/null +++ b/src/ltc/stream/chacha/chacha_ivctr32.c @@ -0,0 +1,43 @@ +/* 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. + */ + +/* The implementation is based on: + * chacha-ref.c version 20080118 + * Public domain from D. J. Bernstein + */ + +#include "tomcrypt.h" + +#ifdef LTC_CHACHA + +/** + Set IV + counter data to the ChaCha state + @param st The ChaCha20 state + @param iv The IV data to add + @param inlen The length of the IV (must be 12) + @param counter 32bit (unsigned) initial counter value + @return CRYPT_OK on success + */ +int chacha_ivctr32(chacha_state *st, const unsigned char *iv, unsigned long ivlen, ulong32 counter) +{ + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(iv != NULL); + /* 96bit IV + 32bit counter */ + LTC_ARGCHK(ivlen == 12); + + st->input[12] = counter; + LOAD32L(st->input[13], iv + 0); + LOAD32L(st->input[14], iv + 4); + LOAD32L(st->input[15], iv + 8); + st->ksleft = 0; + st->ivlen = ivlen; + return CRYPT_OK; +} + +#endif diff --git a/src/ltc/stream/chacha/chacha_ivctr64.c b/src/ltc/stream/chacha/chacha_ivctr64.c new file mode 100644 index 0000000..82d39fb --- /dev/null +++ b/src/ltc/stream/chacha/chacha_ivctr64.c @@ -0,0 +1,43 @@ +/* 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. + */ + +/* The implementation is based on: + * chacha-ref.c version 20080118 + * Public domain from D. J. Bernstein + */ + +#include "tomcrypt.h" + +#ifdef LTC_CHACHA + +/** + Set IV + counter data to the ChaCha state + @param st The ChaCha20 state + @param iv The IV data to add + @param inlen The length of the IV (must be 8) + @param counter 64bit (unsigned) initial counter value + @return CRYPT_OK on success + */ +int chacha_ivctr64(chacha_state *st, const unsigned char *iv, unsigned long ivlen, ulong64 counter) +{ + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(iv != NULL); + /* 64bit IV + 64bit counter */ + LTC_ARGCHK(ivlen == 8); + + st->input[12] = (ulong32)(counter & 0xFFFFFFFF); + st->input[13] = (ulong32)(counter >> 32); + LOAD32L(st->input[14], iv + 0); + LOAD32L(st->input[15], iv + 4); + st->ksleft = 0; + st->ivlen = ivlen; + return CRYPT_OK; +} + +#endif diff --git a/src/ltc/stream/chacha/chacha_keystream.c b/src/ltc/stream/chacha/chacha_keystream.c new file mode 100644 index 0000000..b45323f --- /dev/null +++ b/src/ltc/stream/chacha/chacha_keystream.c @@ -0,0 +1,34 @@ +/* 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. + */ + +/* The implementation is based on: + * chacha-ref.c version 20080118 + * Public domain from D. J. Bernstein + */ + +#include "tomcrypt.h" + +#ifdef LTC_CHACHA + +/** + Generate a stream of random bytes via ChaCha + @param st The ChaCha20 state + @param out [out] The output buffer + @param outlen The output length + @return CRYPT_OK on success + */ +int chacha_keystream(chacha_state *st, unsigned char *out, unsigned long outlen) +{ + if (outlen == 0) return CRYPT_OK; /* nothing to do */ + LTC_ARGCHK(out != NULL); + XMEMSET(out, 0, outlen); + return chacha_crypt(st, out, outlen, out); +} + +#endif diff --git a/src/ltc/stream/chacha/chacha_setup.c b/src/ltc/stream/chacha/chacha_setup.c new file mode 100644 index 0000000..69a1483 --- /dev/null +++ b/src/ltc/stream/chacha/chacha_setup.c @@ -0,0 +1,61 @@ +/* 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. + */ + +/* The implementation is based on: + * chacha-ref.c version 20080118 + * Public domain from D. J. Bernstein + */ + +#include "tomcrypt.h" + +#ifdef LTC_CHACHA + +static const char * const sigma = "expand 32-byte k"; +static const char * const tau = "expand 16-byte k"; + +/** + Initialize an ChaCha context (only the key) + @param st [out] The destination of the ChaCha state + @param key The secret key + @param keylen The length of the secret key (octets) + @param rounds Number of rounds (e.g. 20 for ChaCha20) + @return CRYPT_OK if successful +*/ +int chacha_setup(chacha_state *st, const unsigned char *key, unsigned long keylen, int rounds) +{ + const char *constants; + + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(keylen == 32 || keylen == 16); + + LOAD32L(st->input[4], key + 0); + LOAD32L(st->input[5], key + 4); + LOAD32L(st->input[6], key + 8); + LOAD32L(st->input[7], key + 12); + if (keylen == 32) { /* 256bit */ + key += 16; + constants = sigma; + } else { /* 128bit */ + constants = tau; + } + LOAD32L(st->input[8], key + 0); + LOAD32L(st->input[9], key + 4); + LOAD32L(st->input[10], key + 8); + LOAD32L(st->input[11], key + 12); + LOAD32L(st->input[0], constants + 0); + LOAD32L(st->input[1], constants + 4); + LOAD32L(st->input[2], constants + 8); + LOAD32L(st->input[3], constants + 12); + st->rounds = rounds; /* e.g. 20 for chacha20 */ + st->ivlen = 0; /* will be set later by chacha_ivctr(32|64) */ + return CRYPT_OK; +} + +#endif diff --git a/src/ltc/stream/rc4/rc4.c b/src/ltc/stream/rc4/rc4.c new file mode 100644 index 0000000..ec174a0 --- /dev/null +++ b/src/ltc/stream/rc4/rc4.c @@ -0,0 +1,107 @@ +/* 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. + */ + +#include "tomcrypt.h" + +#ifdef LTC_RC4_STREAM + +/** + Initialize an RC4 context (only the key) + @param st [out] The destination of the RC4 state + @param key The secret key + @param keylen The length of the secret key (8 - 256 bytes) + @return CRYPT_OK if successful +*/ +int rc4_stream_setup(rc4_state *st, const unsigned char *key, unsigned long keylen) +{ + unsigned char tmp, *s; + int x, y; + unsigned long j; + + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(keylen >= 5); /* 40-2048 bits */ + + s = st->buf; + for (x = 0; x < 256; x++) { + s[x] = x; + } + + for (j = x = y = 0; x < 256; x++) { + y = (y + s[x] + key[j++]) & 255; + if (j == keylen) { + j = 0; + } + tmp = s[x]; s[x] = s[y]; s[y] = tmp; + } + st->x = 0; + st->y = 0; + + return CRYPT_OK; +} + +/** + Encrypt (or decrypt) bytes of ciphertext (or plaintext) with RC4 + @param st The RC4 state + @param in The plaintext (or ciphertext) + @param inlen The length of the input (octets) + @param out [out] The ciphertext (or plaintext), length inlen + @return CRYPT_OK if successful +*/ +int rc4_stream_crypt(rc4_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out) +{ + unsigned char x, y, *s, tmp; + + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + + x = st->x; + y = st->y; + s = st->buf; + while (inlen--) { + x = (x + 1) & 255; + y = (y + s[x]) & 255; + tmp = s[x]; s[x] = s[y]; s[y] = tmp; + tmp = (s[x] + s[y]) & 255; + *out++ = *in++ ^ s[tmp]; + } + st->x = x; + st->y = y; + return CRYPT_OK; +} + +/** + Generate a stream of random bytes via RC4 + @param st The RC420 state + @param out [out] The output buffer + @param outlen The output length + @return CRYPT_OK on success + */ +int rc4_stream_keystream(rc4_state *st, unsigned char *out, unsigned long outlen) +{ + if (outlen == 0) return CRYPT_OK; /* nothing to do */ + LTC_ARGCHK(out != NULL); + XMEMSET(out, 0, outlen); + return rc4_stream_crypt(st, out, outlen, out); +} + +/** + Terminate and clear RC4 state + @param st The RC4 state + @return CRYPT_OK on success +*/ +int rc4_stream_done(rc4_state *st) +{ + LTC_ARGCHK(st != NULL); + XMEMSET(st, 0, sizeof(rc4_state)); + return CRYPT_OK; +} + +#endif diff --git a/src/ltc/stream/sober128/sober128.c b/src/ltc/stream/sober128/sober128.c new file mode 100644 index 0000000..b192d9a --- /dev/null +++ b/src/ltc/stream/sober128/sober128.c @@ -0,0 +1,344 @@ +/* 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://libtom.org + */ +#include "tomcrypt.h" + +/** + @file sober128.c + Implementation of SOBER-128 by Tom St Denis. + Based on s128fast.c reference code supplied by Greg Rose of QUALCOMM. +*/ + +#ifdef LTC_SOBER128 + +#define __LTC_SOBER128TAB_C__ +#include "sober128tab.c" + +/* don't change these... */ +#define N 17 +#define FOLD N /* how many iterations of folding to do */ +#define INITKONST 0x6996c53a /* value of KONST to use during key loading */ +#define KEYP 15 /* where to insert key words */ +#define FOLDP 4 /* where to insert non-linear feedback */ + +#define B(x,i) ((unsigned char)(((x) >> (8*i)) & 0xFF)) + +static ulong32 BYTE2WORD(unsigned char *b) +{ + ulong32 t; + LOAD32L(t, b); + return t; +} + +static void XORWORD(ulong32 w, const unsigned char *in, unsigned char *out) +{ + ulong32 t; + LOAD32L(t, in); + t ^= w; + STORE32L(t, out); +} + +/* give correct offset for the current position of the register, + * where logically R[0] is at position "zero". + */ +#define OFF(zero, i) (((zero)+(i)) % N) + +/* step the LFSR */ +/* After stepping, "zero" moves right one place */ +#define STEP(R,z) \ + R[OFF(z,0)] = R[OFF(z,15)] ^ R[OFF(z,4)] ^ (R[OFF(z,0)] << 8) ^ Multab[(R[OFF(z,0)] >> 24) & 0xFF]; + +static void cycle(ulong32 *R) +{ + ulong32 t; + int i; + + STEP(R,0); + t = R[0]; + for (i = 1; i < N; ++i) { + R[i-1] = R[i]; + } + R[N-1] = t; +} + +/* Return a non-linear function of some parts of the register. + */ +#define NLFUNC(c,z) \ +{ \ + t = c->R[OFF(z,0)] + c->R[OFF(z,16)]; \ + t ^= Sbox[(t >> 24) & 0xFF]; \ + t = RORc(t, 8); \ + t = ((t + c->R[OFF(z,1)]) ^ c->konst) + c->R[OFF(z,6)]; \ + t ^= Sbox[(t >> 24) & 0xFF]; \ + t = t + c->R[OFF(z,13)]; \ +} + +static ulong32 nltap(sober128_state *c) +{ + ulong32 t; + NLFUNC(c, 0); + return t; +} + +/* Save the current register state + */ +static void s128_savestate(sober128_state *c) +{ + int i; + for (i = 0; i < N; ++i) { + c->initR[i] = c->R[i]; + } +} + +/* initialise to previously saved register state + */ +static void s128_reloadstate(sober128_state *c) +{ + int i; + + for (i = 0; i < N; ++i) { + c->R[i] = c->initR[i]; + } +} + +/* Initialise "konst" + */ +static void s128_genkonst(sober128_state *c) +{ + ulong32 newkonst; + + do { + cycle(c->R); + newkonst = nltap(c); + } while ((newkonst & 0xFF000000) == 0); + c->konst = newkonst; +} + +/* Load key material into the register + */ +#define ADDKEY(k) \ + c->R[KEYP] += (k); + +#define XORNL(nl) \ + c->R[FOLDP] ^= (nl); + +/* nonlinear diffusion of register for key */ +#define DROUND(z) STEP(c->R,z); NLFUNC(c,(z+1)); c->R[OFF((z+1),FOLDP)] ^= t; +static void s128_diffuse(sober128_state *c) +{ + ulong32 t; + /* relies on FOLD == N == 17! */ + DROUND(0); + DROUND(1); + DROUND(2); + DROUND(3); + DROUND(4); + DROUND(5); + DROUND(6); + DROUND(7); + DROUND(8); + DROUND(9); + DROUND(10); + DROUND(11); + DROUND(12); + DROUND(13); + DROUND(14); + DROUND(15); + DROUND(16); +} + +/** + Initialize an Sober128 context (only the key) + @param c [out] The destination of the Sober128 state + @param key The secret key + @param keylen The length of the secret key (octets) + @return CRYPT_OK if successful +*/ +int sober128_stream_setup(sober128_state *c, const unsigned char *key, unsigned long keylen) +{ + ulong32 i, k; + + LTC_ARGCHK(c != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(keylen > 0); + + /* keylen must be multiple of 4 bytes */ + if ((keylen & 3) != 0) { + return CRYPT_INVALID_KEYSIZE; + } + + /* Register initialised to Fibonacci numbers */ + c->R[0] = 1; + c->R[1] = 1; + for (i = 2; i < N; ++i) { + c->R[i] = c->R[i-1] + c->R[i-2]; + } + c->konst = INITKONST; + + for (i = 0; i < keylen; i += 4) { + k = BYTE2WORD((unsigned char *)&key[i]); + ADDKEY(k); + cycle(c->R); + XORNL(nltap(c)); + } + + /* also fold in the length of the key */ + ADDKEY(keylen); + + /* now diffuse */ + s128_diffuse(c); + s128_genkonst(c); + s128_savestate(c); + c->nbuf = 0; + + return CRYPT_OK; +} + +/** + Set IV to the Sober128 state + @param c The Sober12820 state + @param iv The IV data to add + @param inlen The length of the IV (must be 12) + @return CRYPT_OK on success + */ +int sober128_stream_setiv(sober128_state *c, const unsigned char *iv, unsigned long ivlen) +{ + ulong32 i, k; + + LTC_ARGCHK(c != NULL); + LTC_ARGCHK(iv != NULL); + LTC_ARGCHK(ivlen > 0); + + /* ok we are adding an IV then... */ + s128_reloadstate(c); + + /* ivlen must be multiple of 4 bytes */ + if ((ivlen & 3) != 0) { + return CRYPT_INVALID_KEYSIZE; + } + + for (i = 0; i < ivlen; i += 4) { + k = BYTE2WORD((unsigned char *)&iv[i]); + ADDKEY(k); + cycle(c->R); + XORNL(nltap(c)); + } + + /* also fold in the length of the key */ + ADDKEY(ivlen); + + /* now diffuse */ + s128_diffuse(c); + c->nbuf = 0; + + return CRYPT_OK; +} + +/* XOR pseudo-random bytes into buffer + */ +#define SROUND(z) STEP(c->R,z); NLFUNC(c,(z+1)); XORWORD(t, in+(z*4), out+(z*4)); + +/** + Encrypt (or decrypt) bytes of ciphertext (or plaintext) with Sober128 + @param c The Sober128 state + @param in The plaintext (or ciphertext) + @param inlen The length of the input (octets) + @param out [out] The ciphertext (or plaintext), length inlen + @return CRYPT_OK if successful +*/ +int sober128_stream_crypt(sober128_state *c, const unsigned char *in, unsigned long inlen, unsigned char *out) +{ + ulong32 t; + + if (inlen == 0) return CRYPT_OK; /* nothing to do */ + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(c != NULL); + + /* handle any previously buffered bytes */ + while (c->nbuf != 0 && inlen != 0) { + *out++ = *in++ ^ (c->sbuf & 0xFF); + c->sbuf >>= 8; + c->nbuf -= 8; + --inlen; + } + +#ifndef LTC_SMALL_CODE + /* do lots at a time, if there's enough to do */ + while (inlen >= N*4) { + SROUND(0); + SROUND(1); + SROUND(2); + SROUND(3); + SROUND(4); + SROUND(5); + SROUND(6); + SROUND(7); + SROUND(8); + SROUND(9); + SROUND(10); + SROUND(11); + SROUND(12); + SROUND(13); + SROUND(14); + SROUND(15); + SROUND(16); + out += 4*N; + in += 4*N; + inlen -= 4*N; + } +#endif + + /* do small or odd size buffers the slow way */ + while (4 <= inlen) { + cycle(c->R); + t = nltap(c); + XORWORD(t, in, out); + out += 4; + in += 4; + inlen -= 4; + } + + /* handle any trailing bytes */ + if (inlen != 0) { + cycle(c->R); + c->sbuf = nltap(c); + c->nbuf = 32; + while (c->nbuf != 0 && inlen != 0) { + *out++ = *in++ ^ (c->sbuf & 0xFF); + c->sbuf >>= 8; + c->nbuf -= 8; + --inlen; + } + } + + return CRYPT_OK; +} + +int sober128_stream_keystream(sober128_state *c, unsigned char *out, unsigned long outlen) +{ + if (outlen == 0) return CRYPT_OK; /* nothing to do */ + LTC_ARGCHK(out != NULL); + XMEMSET(out, 0, outlen); + return sober128_stream_crypt(c, out, outlen, out); +} + +/** + Terminate and clear Sober128 state + @param c The Sober128 state + @return CRYPT_OK on success +*/ +int sober128_stream_done(sober128_state *c) +{ + LTC_ARGCHK(c != NULL); + XMEMSET(c, 0, sizeof(sober128_state)); + return CRYPT_OK; +} + +#endif diff --git a/src/ltc/stream/sober128/sober128tab.c b/src/ltc/stream/sober128/sober128tab.c new file mode 100644 index 0000000..74e4f88 --- /dev/null +++ b/src/ltc/stream/sober128/sober128tab.c @@ -0,0 +1,167 @@ +/** + @file sober128tab.c + SOBER-128 Tables +*/ + +#ifdef __LTC_SOBER128TAB_C__ + +/* $ID$ */ +/* @(#)TuringMultab.h 1.3 (QUALCOMM) 02/09/03 */ +/* Multiplication table for Turing using 0xD02B4367 */ +static const ulong32 Multab[256] = { + 0x00000000, 0xD02B4367, 0xED5686CE, 0x3D7DC5A9, + 0x97AC41D1, 0x478702B6, 0x7AFAC71F, 0xAAD18478, + 0x631582EF, 0xB33EC188, 0x8E430421, 0x5E684746, + 0xF4B9C33E, 0x24928059, 0x19EF45F0, 0xC9C40697, + 0xC62A4993, 0x16010AF4, 0x2B7CCF5D, 0xFB578C3A, + 0x51860842, 0x81AD4B25, 0xBCD08E8C, 0x6CFBCDEB, + 0xA53FCB7C, 0x7514881B, 0x48694DB2, 0x98420ED5, + 0x32938AAD, 0xE2B8C9CA, 0xDFC50C63, 0x0FEE4F04, + 0xC154926B, 0x117FD10C, 0x2C0214A5, 0xFC2957C2, + 0x56F8D3BA, 0x86D390DD, 0xBBAE5574, 0x6B851613, + 0xA2411084, 0x726A53E3, 0x4F17964A, 0x9F3CD52D, + 0x35ED5155, 0xE5C61232, 0xD8BBD79B, 0x089094FC, + 0x077EDBF8, 0xD755989F, 0xEA285D36, 0x3A031E51, + 0x90D29A29, 0x40F9D94E, 0x7D841CE7, 0xADAF5F80, + 0x646B5917, 0xB4401A70, 0x893DDFD9, 0x59169CBE, + 0xF3C718C6, 0x23EC5BA1, 0x1E919E08, 0xCEBADD6F, + 0xCFA869D6, 0x1F832AB1, 0x22FEEF18, 0xF2D5AC7F, + 0x58042807, 0x882F6B60, 0xB552AEC9, 0x6579EDAE, + 0xACBDEB39, 0x7C96A85E, 0x41EB6DF7, 0x91C02E90, + 0x3B11AAE8, 0xEB3AE98F, 0xD6472C26, 0x066C6F41, + 0x09822045, 0xD9A96322, 0xE4D4A68B, 0x34FFE5EC, + 0x9E2E6194, 0x4E0522F3, 0x7378E75A, 0xA353A43D, + 0x6A97A2AA, 0xBABCE1CD, 0x87C12464, 0x57EA6703, + 0xFD3BE37B, 0x2D10A01C, 0x106D65B5, 0xC04626D2, + 0x0EFCFBBD, 0xDED7B8DA, 0xE3AA7D73, 0x33813E14, + 0x9950BA6C, 0x497BF90B, 0x74063CA2, 0xA42D7FC5, + 0x6DE97952, 0xBDC23A35, 0x80BFFF9C, 0x5094BCFB, + 0xFA453883, 0x2A6E7BE4, 0x1713BE4D, 0xC738FD2A, + 0xC8D6B22E, 0x18FDF149, 0x258034E0, 0xF5AB7787, + 0x5F7AF3FF, 0x8F51B098, 0xB22C7531, 0x62073656, + 0xABC330C1, 0x7BE873A6, 0x4695B60F, 0x96BEF568, + 0x3C6F7110, 0xEC443277, 0xD139F7DE, 0x0112B4B9, + 0xD31DD2E1, 0x03369186, 0x3E4B542F, 0xEE601748, + 0x44B19330, 0x949AD057, 0xA9E715FE, 0x79CC5699, + 0xB008500E, 0x60231369, 0x5D5ED6C0, 0x8D7595A7, + 0x27A411DF, 0xF78F52B8, 0xCAF29711, 0x1AD9D476, + 0x15379B72, 0xC51CD815, 0xF8611DBC, 0x284A5EDB, + 0x829BDAA3, 0x52B099C4, 0x6FCD5C6D, 0xBFE61F0A, + 0x7622199D, 0xA6095AFA, 0x9B749F53, 0x4B5FDC34, + 0xE18E584C, 0x31A51B2B, 0x0CD8DE82, 0xDCF39DE5, + 0x1249408A, 0xC26203ED, 0xFF1FC644, 0x2F348523, + 0x85E5015B, 0x55CE423C, 0x68B38795, 0xB898C4F2, + 0x715CC265, 0xA1778102, 0x9C0A44AB, 0x4C2107CC, + 0xE6F083B4, 0x36DBC0D3, 0x0BA6057A, 0xDB8D461D, + 0xD4630919, 0x04484A7E, 0x39358FD7, 0xE91ECCB0, + 0x43CF48C8, 0x93E40BAF, 0xAE99CE06, 0x7EB28D61, + 0xB7768BF6, 0x675DC891, 0x5A200D38, 0x8A0B4E5F, + 0x20DACA27, 0xF0F18940, 0xCD8C4CE9, 0x1DA70F8E, + 0x1CB5BB37, 0xCC9EF850, 0xF1E33DF9, 0x21C87E9E, + 0x8B19FAE6, 0x5B32B981, 0x664F7C28, 0xB6643F4F, + 0x7FA039D8, 0xAF8B7ABF, 0x92F6BF16, 0x42DDFC71, + 0xE80C7809, 0x38273B6E, 0x055AFEC7, 0xD571BDA0, + 0xDA9FF2A4, 0x0AB4B1C3, 0x37C9746A, 0xE7E2370D, + 0x4D33B375, 0x9D18F012, 0xA06535BB, 0x704E76DC, + 0xB98A704B, 0x69A1332C, 0x54DCF685, 0x84F7B5E2, + 0x2E26319A, 0xFE0D72FD, 0xC370B754, 0x135BF433, + 0xDDE1295C, 0x0DCA6A3B, 0x30B7AF92, 0xE09CECF5, + 0x4A4D688D, 0x9A662BEA, 0xA71BEE43, 0x7730AD24, + 0xBEF4ABB3, 0x6EDFE8D4, 0x53A22D7D, 0x83896E1A, + 0x2958EA62, 0xF973A905, 0xC40E6CAC, 0x14252FCB, + 0x1BCB60CF, 0xCBE023A8, 0xF69DE601, 0x26B6A566, + 0x8C67211E, 0x5C4C6279, 0x6131A7D0, 0xB11AE4B7, + 0x78DEE220, 0xA8F5A147, 0x958864EE, 0x45A32789, + 0xEF72A3F1, 0x3F59E096, 0x0224253F, 0xD20F6658, +}; + +/* $ID$ */ +/* Sbox for SOBER-128 */ +/* + * This is really the combination of two SBoxes; the least significant + * 24 bits comes from: + * 8->32 Sbox generated by Millan et. al. at Queensland University of + * Technology. See: E. Dawson, W. Millan, L. Burnett, G. Carter, + * "On the Design of 8*32 S-boxes". Unpublished report, by the + * Information Systems Research Centre, + * Queensland University of Technology, 1999. + * + * The most significant 8 bits are the Skipjack "F table", which can be + * found at http://csrc.nist.gov/CryptoToolkit/skipjack/skipjack.pdf . + * In this optimised table, though, the intent is to XOR the word from + * the table selected by the high byte with the input word. Thus, the + * high byte is actually the Skipjack F-table entry XORED with its + * table index. + */ +static const ulong32 Sbox[256] = { + 0xa3aa1887, 0xd65e435c, 0x0b65c042, 0x800e6ef4, + 0xfc57ee20, 0x4d84fed3, 0xf066c502, 0xf354e8ae, + 0xbb2ee9d9, 0x281f38d4, 0x1f829b5d, 0x735cdf3c, + 0x95864249, 0xbc2e3963, 0xa1f4429f, 0xf6432c35, + 0xf7f40325, 0x3cc0dd70, 0x5f973ded, 0x9902dc5e, + 0xda175b42, 0x590012bf, 0xdc94d78c, 0x39aab26b, + 0x4ac11b9a, 0x8c168146, 0xc3ea8ec5, 0x058ac28f, + 0x52ed5c0f, 0x25b4101c, 0x5a2db082, 0x370929e1, + 0x2a1843de, 0xfe8299fc, 0x202fbc4b, 0x833915dd, + 0x33a803fa, 0xd446b2de, 0x46233342, 0x4fcee7c3, + 0x3ad607ef, 0x9e97ebab, 0x507f859b, 0xe81f2e2f, + 0xc55b71da, 0xd7e2269a, 0x1339c3d1, 0x7ca56b36, + 0xa6c9def2, 0xb5c9fc5f, 0x5927b3a3, 0x89a56ddf, + 0xc625b510, 0x560f85a7, 0xace82e71, 0x2ecb8816, + 0x44951e2a, 0x97f5f6af, 0xdfcbc2b3, 0xce4ff55d, + 0xcb6b6214, 0x2b0b83e3, 0x549ea6f5, 0x9de041af, + 0x792f1f17, 0xf73b99ee, 0x39a65ec0, 0x4c7016c6, + 0x857709a4, 0xd6326e01, 0xc7b280d9, 0x5cfb1418, + 0xa6aff227, 0xfd548203, 0x506b9d96, 0xa117a8c0, + 0x9cd5bf6e, 0xdcee7888, 0x61fcfe64, 0xf7a193cd, + 0x050d0184, 0xe8ae4930, 0x88014f36, 0xd6a87088, + 0x6bad6c2a, 0x1422c678, 0xe9204de7, 0xb7c2e759, + 0x0200248e, 0x013b446b, 0xda0d9fc2, 0x0414a895, + 0x3a6cc3a1, 0x56fef170, 0x86c19155, 0xcf7b8a66, + 0x551b5e69, 0xb4a8623e, 0xa2bdfa35, 0xc4f068cc, + 0x573a6acd, 0x6355e936, 0x03602db9, 0x0edf13c1, + 0x2d0bb16d, 0x6980b83c, 0xfeb23763, 0x3dd8a911, + 0x01b6bc13, 0xf55579d7, 0xf55c2fa8, 0x19f4196e, + 0xe7db5476, 0x8d64a866, 0xc06e16ad, 0xb17fc515, + 0xc46feb3c, 0x8bc8a306, 0xad6799d9, 0x571a9133, + 0x992466dd, 0x92eb5dcd, 0xac118f50, 0x9fafb226, + 0xa1b9cef3, 0x3ab36189, 0x347a19b1, 0x62c73084, + 0xc27ded5c, 0x6c8bc58f, 0x1cdde421, 0xed1e47fb, + 0xcdcc715e, 0xb9c0ff99, 0x4b122f0f, 0xc4d25184, + 0xaf7a5e6c, 0x5bbf18bc, 0x8dd7c6e0, 0x5fb7e420, + 0x521f523f, 0x4ad9b8a2, 0xe9da1a6b, 0x97888c02, + 0x19d1e354, 0x5aba7d79, 0xa2cc7753, 0x8c2d9655, + 0x19829da1, 0x531590a7, 0x19c1c149, 0x3d537f1c, + 0x50779b69, 0xed71f2b7, 0x463c58fa, 0x52dc4418, + 0xc18c8c76, 0xc120d9f0, 0xafa80d4d, 0x3b74c473, + 0xd09410e9, 0x290e4211, 0xc3c8082b, 0x8f6b334a, + 0x3bf68ed2, 0xa843cc1b, 0x8d3c0ff3, 0x20e564a0, + 0xf8f55a4f, 0x2b40f8e7, 0xfea7f15f, 0xcf00fe21, + 0x8a6d37d6, 0xd0d506f1, 0xade00973, 0xefbbde36, + 0x84670fa8, 0xfa31ab9e, 0xaedab618, 0xc01f52f5, + 0x6558eb4f, 0x71b9e343, 0x4b8d77dd, 0x8cb93da6, + 0x740fd52d, 0x425412f8, 0xc5a63360, 0x10e53ad0, + 0x5a700f1c, 0x8324ed0b, 0xe53dc1ec, 0x1a366795, + 0x6d549d15, 0xc5ce46d7, 0xe17abe76, 0x5f48e0a0, + 0xd0f07c02, 0x941249b7, 0xe49ed6ba, 0x37a47f78, + 0xe1cfffbd, 0xb007ca84, 0xbb65f4da, 0xb59f35da, + 0x33d2aa44, 0x417452ac, 0xc0d674a7, 0x2d61a46a, + 0xdc63152a, 0x3e12b7aa, 0x6e615927, 0xa14fb118, + 0xa151758d, 0xba81687b, 0xe152f0b3, 0x764254ed, + 0x34c77271, 0x0a31acab, 0x54f94aec, 0xb9e994cd, + 0x574d9e81, 0x5b623730, 0xce8a21e8, 0x37917f0b, + 0xe8a9b5d6, 0x9697adf8, 0xf3d30431, 0x5dcac921, + 0x76b35d46, 0xaa430a36, 0xc2194022, 0x22bca65e, + 0xdaec70ba, 0xdfaea8cc, 0x777bae8b, 0x242924d5, + 0x1f098a5a, 0x4b396b81, 0x55de2522, 0x435c1cb8, + 0xaeb8fe1d, 0x9db3c697, 0x5b164f83, 0xe0c16376, + 0xa319224c, 0xd0203b35, 0x433ac0fe, 0x1466a19a, + 0x45f0b24f, 0x51fda998, 0xc0d52d71, 0xfa0896a8, + 0xf9e6053f, 0xa4b0d300, 0xd499cbcc, 0xb95e3d40, +}; + +#endif /* __LTC_SOBER128TAB_C__ */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_error.c b/src/ltm/bn_error.c new file mode 100644 index 0000000..3abf1a7 --- /dev/null +++ b/src/ltm/bn_error.c @@ -0,0 +1,47 @@ +#include +#ifdef BN_ERROR_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, tstdenis82@gmail.com, http://libtom.org + */ + +static const struct { + int code; + const char *msg; +} msgs[] = { + { MP_OKAY, "Successful" }, + { MP_MEM, "Out of heap" }, + { MP_VAL, "Value out of range" } +}; + +/* return a char * string for a given code */ +const char *mp_error_to_string(int code) +{ + int x; + + /* scan the lookup table for the given message */ + for (x = 0; x < (int)(sizeof(msgs) / sizeof(msgs[0])); x++) { + if (msgs[x].code == code) { + return msgs[x].msg; + } + } + + /* generic reply for invalid code */ + return "Invalid error code"; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_fast_mp_invmod.c b/src/ltm/bn_fast_mp_invmod.c new file mode 100644 index 0000000..aa41098 --- /dev/null +++ b/src/ltm/bn_fast_mp_invmod.c @@ -0,0 +1,148 @@ +#include +#ifdef BN_FAST_MP_INVMOD_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* computes the modular inverse via binary extended euclidean algorithm, + * that is c = 1/a mod b + * + * 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) +{ + mp_int x, y, u, v, B, D; + int res, neg; + + /* 2. [modified] b must be odd */ + if (mp_iseven (b) == MP_YES) { + return MP_VAL; + } + + /* init all our temps */ + if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) { + return res; + } + + /* x == modulus, y == value to invert */ + if ((res = mp_copy (b, &x)) != MP_OKAY) { + goto LBL_ERR; + } + + /* we need y = |a| */ + if ((res = mp_mod (a, b, &y)) != MP_OKAY) { + goto LBL_ERR; + } + + /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ + if ((res = mp_copy (&x, &u)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_copy (&y, &v)) != MP_OKAY) { + goto LBL_ERR; + } + mp_set (&D, 1); + +top: + /* 4. while u is even do */ + while (mp_iseven (&u) == MP_YES) { + /* 4.1 u = u/2 */ + if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { + goto LBL_ERR; + } + /* 4.2 if B is odd then */ + if (mp_isodd (&B) == MP_YES) { + if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } + /* B = B/2 */ + if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* 5. while v is even do */ + while (mp_iseven (&v) == MP_YES) { + /* 5.1 v = v/2 */ + if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { + goto LBL_ERR; + } + /* 5.2 if D is odd then */ + if (mp_isodd (&D) == MP_YES) { + /* D = (D-x)/2 */ + if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + /* D = D/2 */ + if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* 6. if u >= v then */ + if (mp_cmp (&u, &v) != MP_LT) { + /* u = u - v, B = B - D */ + if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } else { + /* v - v - u, D = D - B */ + if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* if not zero goto step 4 */ + if (mp_iszero (&u) == MP_NO) { + goto top; + } + + /* now a = C, b = D, gcd == g*v */ + + /* if v != 1 then there is no inverse */ + if (mp_cmp_d (&v, 1) != MP_EQ) { + res = MP_VAL; + goto LBL_ERR; + } + + /* b is now the inverse */ + neg = a->sign; + while (D.sign == MP_NEG) { + if ((res = mp_add (&D, b, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + mp_exch (&D, c); + c->sign = neg; + res = MP_OKAY; + +LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL); + return res; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_fast_mp_montgomery_reduce.c b/src/ltm/bn_fast_mp_montgomery_reduce.c new file mode 100644 index 0000000..a63839d --- /dev/null +++ b/src/ltm/bn_fast_mp_montgomery_reduce.c @@ -0,0 +1,172 @@ +#include +#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* computes xR**-1 == x (mod N) via Montgomery Reduction + * + * This is an optimized implementation of montgomery_reduce + * which uses the comba method to quickly calculate the columns of the + * reduction. + * + * 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 ix, res, olduse; + mp_word W[MP_WARRAY]; + + /* get old used count */ + olduse = x->used; + + /* grow a as required */ + if (x->alloc < (n->used + 1)) { + if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) { + return res; + } + } + + /* first we have to get the digits of the input into + * an array of double precision words W[...] + */ + { + mp_word *_W; + mp_digit *tmpx; + + /* alias for the W[] array */ + _W = W; + + /* alias for the digits of x*/ + tmpx = x->dp; + + /* copy the digits of a into W[0..a->used-1] */ + for (ix = 0; ix < x->used; ix++) { + *_W++ = *tmpx++; + } + + /* zero the high words of W[a->used..m->used*2] */ + for (; ix < ((n->used * 2) + 1); ix++) { + *_W++ = 0; + } + } + + /* now we proceed to zero successive digits + * from the least significant upwards + */ + for (ix = 0; ix < n->used; ix++) { + /* mu = ai * m' mod b + * + * We avoid a double precision multiplication (which isn't required) + * by casting the value down to a mp_digit. Note this requires + * that W[ix-1] have the carry cleared (see after the inner loop) + */ + mp_digit mu; + mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK); + + /* a = a + mu * m * b**i + * + * This is computed in place and on the fly. The multiplication + * by b**i is handled by offseting which columns the results + * are added to. + * + * Note the comba method normally doesn't handle carries in the + * inner loop In this case we fix the carry from the previous + * column since the Montgomery reduction requires digits of the + * result (so far) [see above] to work. This is + * handled by fixing up one carry after the inner loop. The + * carry fixups are done in order so after these loops the + * first m->used words of W[] have the carries fixed + */ + { + int iy; + mp_digit *tmpn; + mp_word *_W; + + /* alias for the digits of the modulus */ + tmpn = n->dp; + + /* Alias for the columns set by an offset of ix */ + _W = W + ix; + + /* inner loop */ + for (iy = 0; iy < n->used; iy++) { + *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++); + } + } + + /* now fix carry for next digit, W[ix+1] */ + W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT); + } + + /* now we have to propagate the carries and + * shift the words downward [all those least + * significant digits we zeroed]. + */ + { + mp_digit *tmpx; + mp_word *_W, *_W1; + + /* nox fix rest of carries */ + + /* alias for current word */ + _W1 = W + ix; + + /* alias for next word, where the carry goes */ + _W = W + ++ix; + + for (; ix <= ((n->used * 2) + 1); ix++) { + *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT); + } + + /* copy out, A = A/b**n + * + * The result is A/b**n but instead of converting from an + * array of mp_word to mp_digit than calling mp_rshd + * we just copy them in the right order + */ + + /* alias for destination word */ + tmpx = x->dp; + + /* alias for shifted double precision result */ + _W = W + n->used; + + for (ix = 0; ix < (n->used + 1); ix++) { + *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK)); + } + + /* zero oldused digits, if the input a was larger than + * m->used+1 we'll have to clear the digits + */ + for (; ix < olduse; ix++) { + *tmpx++ = 0; + } + } + + /* set the max used and clamp */ + x->used = n->used + 1; + mp_clamp (x); + + /* if A >= m then A = A - m */ + if (mp_cmp_mag (x, n) != MP_LT) { + return s_mp_sub (x, n, x); + } + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_fast_s_mp_mul_digs.c b/src/ltm/bn_fast_s_mp_mul_digs.c new file mode 100644 index 0000000..acd13b4 --- /dev/null +++ b/src/ltm/bn_fast_s_mp_mul_digs.c @@ -0,0 +1,107 @@ +#include +#ifdef BN_FAST_S_MP_MUL_DIGS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * 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, tstdenis82@gmail.com, http://libtom.org + */ + +/* Fast (comba) multiplier + * + * This is the fast column-array [comba] multiplier. It is + * designed to compute the columns of the product first + * then handle the carries afterwards. This has the effect + * of making the nested loops that compute the columns very + * simple and schedulable on super-scalar processors. + * + * This has been modified to produce a variable number of + * digits of output so if say only a half-product is required + * you don't have to compute the upper half (a feature + * required for fast Barrett reduction). + * + * 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 olduse, res, pa, ix, iz; + mp_digit W[MP_WARRAY]; + mp_word _W; + + /* grow the destination as required */ + if (c->alloc < digs) { + if ((res = mp_grow (c, digs)) != MP_OKAY) { + return res; + } + } + + /* number of output digits to produce */ + pa = MIN(digs, a->used + b->used); + + /* clear the carry */ + _W = 0; + for (ix = 0; ix < pa; ix++) { + int tx, ty; + int iy; + mp_digit *tmpx, *tmpy; + + /* get offsets into the two bignums */ + ty = MIN(b->used-1, ix); + tx = ix - ty; + + /* setup temp aliases */ + tmpx = a->dp + tx; + tmpy = b->dp + ty; + + /* this is the number of times the loop will iterrate, essentially + while (tx++ < a->used && ty-- >= 0) { ... } + */ + iy = MIN(a->used-tx, ty+1); + + /* execute loop */ + for (iz = 0; iz < iy; ++iz) { + _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); + + } + + /* store term */ + W[ix] = ((mp_digit)_W) & MP_MASK; + + /* make next carry */ + _W = _W >> ((mp_word)DIGIT_BIT); + } + + /* setup dest */ + olduse = c->used; + c->used = pa; + + { + mp_digit *tmpc; + tmpc = c->dp; + for (ix = 0; ix < (pa + 1); ix++) { + /* now extract the previous digit [below the carry] */ + *tmpc++ = W[ix]; + } + + /* clear unused digits [that existed in the old copy of c] */ + for (; ix < olduse; ix++) { + *tmpc++ = 0; + } + } + mp_clamp (c); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_fast_s_mp_mul_high_digs.c b/src/ltm/bn_fast_s_mp_mul_high_digs.c new file mode 100644 index 0000000..b96cf60 --- /dev/null +++ b/src/ltm/bn_fast_s_mp_mul_high_digs.c @@ -0,0 +1,98 @@ +#include +#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * 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, tstdenis82@gmail.com, http://libtom.org + */ + +/* this is a modified version of fast_s_mul_digs that only produces + * output digits *above* digs. See the comments for fast_s_mul_digs + * to see how it works. + * + * This is used in the Barrett reduction since for one of the multiplications + * only the higher digits were needed. This essentially halves the work. + * + * 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 olduse, res, pa, ix, iz; + mp_digit W[MP_WARRAY]; + mp_word _W; + + /* grow the destination as required */ + pa = a->used + b->used; + if (c->alloc < pa) { + if ((res = mp_grow (c, pa)) != MP_OKAY) { + return res; + } + } + + /* number of output digits to produce */ + pa = a->used + b->used; + _W = 0; + for (ix = digs; ix < pa; ix++) { + int tx, ty, iy; + mp_digit *tmpx, *tmpy; + + /* get offsets into the two bignums */ + ty = MIN(b->used-1, ix); + tx = ix - ty; + + /* setup temp aliases */ + tmpx = a->dp + tx; + tmpy = b->dp + ty; + + /* this is the number of times the loop will iterrate, essentially its + while (tx++ < a->used && ty-- >= 0) { ... } + */ + iy = MIN(a->used-tx, ty+1); + + /* execute loop */ + for (iz = 0; iz < iy; iz++) { + _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); + } + + /* store term */ + W[ix] = ((mp_digit)_W) & MP_MASK; + + /* make next carry */ + _W = _W >> ((mp_word)DIGIT_BIT); + } + + /* setup dest */ + olduse = c->used; + c->used = pa; + + { + mp_digit *tmpc; + + tmpc = c->dp + digs; + for (ix = digs; ix < pa; ix++) { + /* now extract the previous digit [below the carry] */ + *tmpc++ = W[ix]; + } + + /* clear unused digits [that existed in the old copy of c] */ + for (; ix < olduse; ix++) { + *tmpc++ = 0; + } + } + mp_clamp (c); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_fast_s_mp_sqr.c b/src/ltm/bn_fast_s_mp_sqr.c new file mode 100644 index 0000000..775c76f --- /dev/null +++ b/src/ltm/bn_fast_s_mp_sqr.c @@ -0,0 +1,114 @@ +#include +#ifdef BN_FAST_S_MP_SQR_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* the jist of squaring... + * you do like mult except the offset of the tmpx [one that + * starts closer to zero] can't equal the offset of tmpy. + * So basically you set up iy like before then you min it with + * (ty-tx) so that it never happens. You double all those + * you add in the inner loop + +After that loop you do the squares and add them in. +*/ + +int fast_s_mp_sqr (mp_int * a, mp_int * b) +{ + int olduse, res, pa, ix, iz; + mp_digit W[MP_WARRAY], *tmpx; + mp_word W1; + + /* grow the destination as required */ + pa = a->used + a->used; + if (b->alloc < pa) { + if ((res = mp_grow (b, pa)) != MP_OKAY) { + return res; + } + } + + /* number of output digits to produce */ + W1 = 0; + for (ix = 0; ix < pa; ix++) { + int tx, ty, iy; + mp_word _W; + mp_digit *tmpy; + + /* clear counter */ + _W = 0; + + /* get offsets into the two bignums */ + ty = MIN(a->used-1, ix); + tx = ix - ty; + + /* setup temp aliases */ + tmpx = a->dp + tx; + tmpy = a->dp + ty; + + /* this is the number of times the loop will iterrate, essentially + while (tx++ < a->used && ty-- >= 0) { ... } + */ + iy = MIN(a->used-tx, ty+1); + + /* now for squaring tx can never equal ty + * we halve the distance since they approach at a rate of 2x + * and we have to round because odd cases need to be executed + */ + iy = MIN(iy, ((ty-tx)+1)>>1); + + /* execute loop */ + for (iz = 0; iz < iy; iz++) { + _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); + } + + /* double the inner product and add carry */ + _W = _W + _W + W1; + + /* even columns have the square term in them */ + if ((ix&1) == 0) { + _W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]); + } + + /* store it */ + W[ix] = (mp_digit)(_W & MP_MASK); + + /* make next carry */ + W1 = _W >> ((mp_word)DIGIT_BIT); + } + + /* setup dest */ + olduse = b->used; + b->used = a->used+a->used; + + { + mp_digit *tmpb; + tmpb = b->dp; + for (ix = 0; ix < pa; ix++) { + *tmpb++ = W[ix] & MP_MASK; + } + + /* clear unused digits [that existed in the old copy of c] */ + for (; ix < olduse; ix++) { + *tmpb++ = 0; + } + } + mp_clamp (b); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_2expt.c b/src/ltm/bn_mp_2expt.c new file mode 100644 index 0000000..2845814 --- /dev/null +++ b/src/ltm/bn_mp_2expt.c @@ -0,0 +1,48 @@ +#include +#ifdef BN_MP_2EXPT_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* computes a = 2**b + * + * Simple algorithm which zeroes the int, grows it then just sets one bit + * as required. + */ +int +mp_2expt (mp_int * a, int b) +{ + int res; + + /* zero a as per default */ + mp_zero (a); + + /* grow a to accomodate the single bit */ + if ((res = mp_grow (a, (b / DIGIT_BIT) + 1)) != MP_OKAY) { + return res; + } + + /* set the used count of where the bit will go */ + a->used = (b / DIGIT_BIT) + 1; + + /* put the single bit in its place */ + a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT); + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_abs.c b/src/ltm/bn_mp_abs.c new file mode 100644 index 0000000..cc9c3db --- /dev/null +++ b/src/ltm/bn_mp_abs.c @@ -0,0 +1,43 @@ +#include +#ifdef BN_MP_ABS_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* b = |a| + * + * Simple function copies the input and fixes the sign to positive + */ +int +mp_abs (mp_int * a, mp_int * b) +{ + int res; + + /* copy a to b */ + if (a != b) { + if ((res = mp_copy (a, b)) != MP_OKAY) { + return res; + } + } + + /* force the sign of b to positive */ + b->sign = MP_ZPOS; + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_add.c b/src/ltm/bn_mp_add.c new file mode 100644 index 0000000..236fc75 --- /dev/null +++ b/src/ltm/bn_mp_add.c @@ -0,0 +1,53 @@ +#include +#ifdef BN_MP_ADD_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* high level addition (handles signs) */ +int mp_add (mp_int * a, mp_int * b, mp_int * c) +{ + int sa, sb, res; + + /* get sign of both inputs */ + sa = a->sign; + sb = b->sign; + + /* handle two cases, not four */ + if (sa == sb) { + /* both positive or both negative */ + /* add their magnitudes, copy the sign */ + c->sign = sa; + res = s_mp_add (a, b, c); + } else { + /* one positive, the other negative */ + /* subtract the one with the greater magnitude from */ + /* the one of the lesser magnitude. The result gets */ + /* the sign of the one with the greater magnitude. */ + if (mp_cmp_mag (a, b) == MP_LT) { + c->sign = sb; + res = s_mp_sub (b, a, c); + } else { + c->sign = sa; + res = s_mp_sub (a, b, c); + } + } + return res; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_add_d.c b/src/ltm/bn_mp_add_d.c new file mode 100644 index 0000000..4d4e1df --- /dev/null +++ b/src/ltm/bn_mp_add_d.c @@ -0,0 +1,112 @@ +#include +#ifdef BN_MP_ADD_D_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* single digit addition */ +int +mp_add_d (mp_int * a, mp_digit b, mp_int * c) +{ + int res, ix, oldused; + mp_digit *tmpa, *tmpc, mu; + + /* grow c as required */ + if (c->alloc < (a->used + 1)) { + if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { + return res; + } + } + + /* if a is negative and |a| >= b, call c = |a| - b */ + if ((a->sign == MP_NEG) && ((a->used > 1) || (a->dp[0] >= b))) { + /* temporarily fix sign of a */ + a->sign = MP_ZPOS; + + /* c = |a| - b */ + res = mp_sub_d(a, b, c); + + /* fix sign */ + a->sign = c->sign = MP_NEG; + + /* clamp */ + mp_clamp(c); + + return res; + } + + /* old number of used digits in c */ + oldused = c->used; + + /* sign always positive */ + c->sign = MP_ZPOS; + + /* source alias */ + tmpa = a->dp; + + /* destination alias */ + tmpc = c->dp; + + /* if a is positive */ + if (a->sign == MP_ZPOS) { + /* add digit, after this we're propagating + * the carry. + */ + *tmpc = *tmpa++ + b; + mu = *tmpc >> DIGIT_BIT; + *tmpc++ &= MP_MASK; + + /* now handle rest of the digits */ + for (ix = 1; ix < a->used; ix++) { + *tmpc = *tmpa++ + mu; + mu = *tmpc >> DIGIT_BIT; + *tmpc++ &= MP_MASK; + } + /* set final carry */ + ix++; + *tmpc++ = mu; + + /* setup size */ + c->used = a->used + 1; + } else { + /* a was negative and |a| < b */ + c->used = 1; + + /* the result is a single digit */ + if (a->used == 1) { + *tmpc++ = b - a->dp[0]; + } else { + *tmpc++ = b; + } + + /* setup count so the clearing of oldused + * can fall through correctly + */ + ix = 1; + } + + /* now zero to oldused */ + while (ix++ < oldused) { + *tmpc++ = 0; + } + mp_clamp(c); + + return MP_OKAY; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_addmod.c b/src/ltm/bn_mp_addmod.c new file mode 100644 index 0000000..825c928 --- /dev/null +++ b/src/ltm/bn_mp_addmod.c @@ -0,0 +1,41 @@ +#include +#ifdef BN_MP_ADDMOD_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* d = a + b (mod c) */ +int +mp_addmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + int res; + mp_int t; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_add (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + res = mp_mod (&t, c, d); + mp_clear (&t); + return res; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_and.c b/src/ltm/bn_mp_and.c new file mode 100644 index 0000000..3b6b03e --- /dev/null +++ b/src/ltm/bn_mp_and.c @@ -0,0 +1,57 @@ +#include +#ifdef BN_MP_AND_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* AND two ints together */ +int +mp_and (mp_int * a, mp_int * b, mp_int * c) +{ + int res, ix, px; + mp_int t, *x; + + if (a->used > b->used) { + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + px = b->used; + x = b; + } else { + if ((res = mp_init_copy (&t, b)) != MP_OKAY) { + return res; + } + px = a->used; + x = a; + } + + for (ix = 0; ix < px; ix++) { + t.dp[ix] &= x->dp[ix]; + } + + /* zero digits above the last from the smallest mp_int */ + for (; ix < t.used; ix++) { + t.dp[ix] = 0; + } + + mp_clamp (&t); + mp_exch (c, &t); + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_clamp.c b/src/ltm/bn_mp_clamp.c new file mode 100644 index 0000000..d4fb70d --- /dev/null +++ b/src/ltm/bn_mp_clamp.c @@ -0,0 +1,44 @@ +#include +#ifdef BN_MP_CLAMP_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* trim unused digits + * + * This is used to ensure that leading zero digits are + * trimed and the leading "used" digit will be non-zero + * Typically very fast. Also fixes the sign if there + * are no more leading digits + */ +void +mp_clamp (mp_int * a) +{ + /* decrease used while the most significant digit is + * zero. + */ + while ((a->used > 0) && (a->dp[a->used - 1] == 0)) { + --(a->used); + } + + /* reset the sign flag if used == 0 */ + if (a->used == 0) { + a->sign = MP_ZPOS; + } +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_clear.c b/src/ltm/bn_mp_clear.c new file mode 100644 index 0000000..17ef9d5 --- /dev/null +++ b/src/ltm/bn_mp_clear.c @@ -0,0 +1,44 @@ +#include +#ifdef BN_MP_CLEAR_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* clear one (frees) */ +void +mp_clear (mp_int * a) +{ + int i; + + /* only do anything if a hasn't been freed previously */ + if (a->dp != NULL) { + /* first zero the digits */ + for (i = 0; i < a->used; i++) { + a->dp[i] = 0; + } + + /* free ram */ + XFREE(a->dp); + + /* reset members to make debugging easier */ + a->dp = NULL; + a->alloc = a->used = 0; + a->sign = MP_ZPOS; + } +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_clear_multi.c b/src/ltm/bn_mp_clear_multi.c new file mode 100644 index 0000000..441a200 --- /dev/null +++ b/src/ltm/bn_mp_clear_multi.c @@ -0,0 +1,34 @@ +#include +#ifdef BN_MP_CLEAR_MULTI_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, tstdenis82@gmail.com, http://libtom.org + */ +#include + +void mp_clear_multi(mp_int *mp, ...) +{ + mp_int* next_mp = mp; + va_list args; + va_start(args, mp); + while (next_mp != NULL) { + mp_clear(next_mp); + next_mp = va_arg(args, mp_int*); + } + va_end(args); +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_cmp.c b/src/ltm/bn_mp_cmp.c new file mode 100644 index 0000000..74a98fe --- /dev/null +++ b/src/ltm/bn_mp_cmp.c @@ -0,0 +1,43 @@ +#include +#ifdef BN_MP_CMP_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* compare two ints (signed)*/ +int +mp_cmp (mp_int * a, mp_int * b) +{ + /* compare based on sign */ + if (a->sign != b->sign) { + if (a->sign == MP_NEG) { + return MP_LT; + } else { + return MP_GT; + } + } + + /* compare digits */ + if (a->sign == MP_NEG) { + /* if negative compare opposite direction */ + return mp_cmp_mag(b, a); + } else { + return mp_cmp_mag(a, b); + } +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_cmp_d.c b/src/ltm/bn_mp_cmp_d.c new file mode 100644 index 0000000..28a53ce --- /dev/null +++ b/src/ltm/bn_mp_cmp_d.c @@ -0,0 +1,44 @@ +#include +#ifdef BN_MP_CMP_D_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* compare a digit */ +int mp_cmp_d(mp_int * a, mp_digit b) +{ + /* compare based on sign */ + if (a->sign == MP_NEG) { + return MP_LT; + } + + /* compare based on magnitude */ + if (a->used > 1) { + return MP_GT; + } + + /* compare the only digit of a to b */ + if (a->dp[0] > b) { + return MP_GT; + } else if (a->dp[0] < b) { + return MP_LT; + } else { + return MP_EQ; + } +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_cmp_mag.c b/src/ltm/bn_mp_cmp_mag.c new file mode 100644 index 0000000..f72830f --- /dev/null +++ b/src/ltm/bn_mp_cmp_mag.c @@ -0,0 +1,55 @@ +#include +#ifdef BN_MP_CMP_MAG_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* compare maginitude of two ints (unsigned) */ +int mp_cmp_mag (mp_int * a, mp_int * b) +{ + int n; + mp_digit *tmpa, *tmpb; + + /* compare based on # of non-zero digits */ + if (a->used > b->used) { + return MP_GT; + } + + if (a->used < b->used) { + return MP_LT; + } + + /* alias for a */ + tmpa = a->dp + (a->used - 1); + + /* alias for b */ + tmpb = b->dp + (a->used - 1); + + /* compare based on digits */ + for (n = 0; n < a->used; ++n, --tmpa, --tmpb) { + if (*tmpa > *tmpb) { + return MP_GT; + } + + if (*tmpa < *tmpb) { + return MP_LT; + } + } + return MP_EQ; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_cnt_lsb.c b/src/ltm/bn_mp_cnt_lsb.c new file mode 100644 index 0000000..9d7eef8 --- /dev/null +++ b/src/ltm/bn_mp_cnt_lsb.c @@ -0,0 +1,53 @@ +#include +#ifdef BN_MP_CNT_LSB_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, tstdenis82@gmail.com, http://libtom.org + */ + +static const int lnz[16] = { + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 +}; + +/* Counts the number of lsbs which are zero before the first zero bit */ +int mp_cnt_lsb(mp_int *a) +{ + int x; + mp_digit q, qq; + + /* easy out */ + if (mp_iszero(a) == MP_YES) { + return 0; + } + + /* scan lower digits until non-zero */ + for (x = 0; (x < a->used) && (a->dp[x] == 0); x++) {} + q = a->dp[x]; + x *= DIGIT_BIT; + + /* now scan this digit until a 1 is found */ + if ((q & 1) == 0) { + do { + qq = q & 15; + x += lnz[qq]; + q >>= 4; + } while (qq == 0); + } + return x; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_copy.c b/src/ltm/bn_mp_copy.c new file mode 100644 index 0000000..69e9464 --- /dev/null +++ b/src/ltm/bn_mp_copy.c @@ -0,0 +1,68 @@ +#include +#ifdef BN_MP_COPY_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* copy, b = a */ +int +mp_copy (mp_int * a, mp_int * b) +{ + int res, n; + + /* if dst == src do nothing */ + if (a == b) { + return MP_OKAY; + } + + /* grow dest */ + if (b->alloc < a->used) { + if ((res = mp_grow (b, a->used)) != MP_OKAY) { + return res; + } + } + + /* zero b and copy the parameters over */ + { + mp_digit *tmpa, *tmpb; + + /* pointer aliases */ + + /* source */ + tmpa = a->dp; + + /* destination */ + tmpb = b->dp; + + /* copy all the digits */ + for (n = 0; n < a->used; n++) { + *tmpb++ = *tmpa++; + } + + /* clear high digits */ + for (; n < b->used; n++) { + *tmpb++ = 0; + } + } + + /* copy used count and sign */ + b->used = a->used; + b->sign = a->sign; + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_count_bits.c b/src/ltm/bn_mp_count_bits.c new file mode 100644 index 0000000..74b59b6 --- /dev/null +++ b/src/ltm/bn_mp_count_bits.c @@ -0,0 +1,45 @@ +#include +#ifdef BN_MP_COUNT_BITS_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* returns the number of bits in an int */ +int +mp_count_bits (mp_int * a) +{ + int r; + mp_digit q; + + /* shortcut */ + if (a->used == 0) { + return 0; + } + + /* get number of digits and add that */ + r = (a->used - 1) * DIGIT_BIT; + + /* take the last digit and count the bits in it */ + q = a->dp[a->used - 1]; + while (q > ((mp_digit) 0)) { + ++r; + q >>= ((mp_digit) 1); + } + return r; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_div.c b/src/ltm/bn_mp_div.c new file mode 100644 index 0000000..3ca5d7f --- /dev/null +++ b/src/ltm/bn_mp_div.c @@ -0,0 +1,295 @@ +#include +#ifdef BN_MP_DIV_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, tstdenis82@gmail.com, http://libtom.org + */ + +#ifdef BN_MP_DIV_SMALL + +/* slower bit-bang division... also smaller */ +int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + mp_int ta, tb, tq, q; + int res, n, n2; + + /* is divisor zero ? */ + if (mp_iszero (b) == MP_YES) { + return MP_VAL; + } + + /* if a < b then q=0, r = a */ + if (mp_cmp_mag (a, b) == MP_LT) { + if (d != NULL) { + res = mp_copy (a, d); + } else { + res = MP_OKAY; + } + if (c != NULL) { + mp_zero (c); + } + return res; + } + + /* init our temps */ + if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL)) != MP_OKAY) { + return res; + } + + + mp_set(&tq, 1); + n = mp_count_bits(a) - mp_count_bits(b); + if (((res = mp_abs(a, &ta)) != MP_OKAY) || + ((res = mp_abs(b, &tb)) != MP_OKAY) || + ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) || + ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) { + goto LBL_ERR; + } + + while (n-- >= 0) { + if (mp_cmp(&tb, &ta) != MP_GT) { + if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) || + ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) { + goto LBL_ERR; + } + } + if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) || + ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) { + goto LBL_ERR; + } + } + + /* now q == quotient and ta == remainder */ + n = a->sign; + n2 = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; + if (c != NULL) { + mp_exch(c, &q); + c->sign = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2; + } + if (d != NULL) { + mp_exch(d, &ta); + d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n; + } +LBL_ERR: + mp_clear_multi(&ta, &tb, &tq, &q, NULL); + return res; +} + +#else + +/* integer signed division. + * c*b + d == a [e.g. a/b, c=quotient, d=remainder] + * HAC pp.598 Algorithm 14.20 + * + * Note that the description in HAC is horribly + * incomplete. For example, it doesn't consider + * the case where digits are removed from 'x' in + * the inner loop. It also doesn't consider the + * case that y has fewer than three digits, etc.. + * + * The overall algorithm is as described as + * 14.20 from HAC but fixed to treat these cases. +*/ +int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + mp_int q, x, y, t1, t2; + int res, n, t, i, norm, neg; + + /* is divisor zero ? */ + if (mp_iszero (b) == MP_YES) { + return MP_VAL; + } + + /* if a < b then q=0, r = a */ + if (mp_cmp_mag (a, b) == MP_LT) { + if (d != NULL) { + res = mp_copy (a, d); + } else { + res = MP_OKAY; + } + if (c != NULL) { + mp_zero (c); + } + return res; + } + + if ((res = mp_init_size (&q, a->used + 2)) != MP_OKAY) { + return res; + } + q.used = a->used + 2; + + if ((res = mp_init (&t1)) != MP_OKAY) { + goto LBL_Q; + } + + if ((res = mp_init (&t2)) != MP_OKAY) { + goto LBL_T1; + } + + if ((res = mp_init_copy (&x, a)) != MP_OKAY) { + goto LBL_T2; + } + + if ((res = mp_init_copy (&y, b)) != MP_OKAY) { + goto LBL_X; + } + + /* fix the sign */ + neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; + x.sign = y.sign = MP_ZPOS; + + /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */ + norm = mp_count_bits(&y) % DIGIT_BIT; + if (norm < (int)(DIGIT_BIT-1)) { + norm = (DIGIT_BIT-1) - norm; + if ((res = mp_mul_2d (&x, norm, &x)) != MP_OKAY) { + goto LBL_Y; + } + if ((res = mp_mul_2d (&y, norm, &y)) != MP_OKAY) { + goto LBL_Y; + } + } else { + norm = 0; + } + + /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */ + n = x.used - 1; + t = y.used - 1; + + /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */ + if ((res = mp_lshd (&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */ + goto LBL_Y; + } + + while (mp_cmp (&x, &y) != MP_LT) { + ++(q.dp[n - t]); + if ((res = mp_sub (&x, &y, &x)) != MP_OKAY) { + goto LBL_Y; + } + } + + /* reset y by shifting it back down */ + mp_rshd (&y, n - t); + + /* step 3. for i from n down to (t + 1) */ + for (i = n; i >= (t + 1); i--) { + if (i > x.used) { + continue; + } + + /* step 3.1 if xi == yt then set q{i-t-1} to b-1, + * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */ + if (x.dp[i] == y.dp[t]) { + q.dp[(i - t) - 1] = ((((mp_digit)1) << DIGIT_BIT) - 1); + } else { + mp_word tmp; + tmp = ((mp_word) x.dp[i]) << ((mp_word) DIGIT_BIT); + tmp |= ((mp_word) x.dp[i - 1]); + tmp /= ((mp_word) y.dp[t]); + if (tmp > (mp_word) MP_MASK) { + tmp = MP_MASK; + } + q.dp[(i - t) - 1] = (mp_digit) (tmp & (mp_word) (MP_MASK)); + } + + /* while (q{i-t-1} * (yt * b + y{t-1})) > + xi * b**2 + xi-1 * b + xi-2 + + do q{i-t-1} -= 1; + */ + q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] + 1) & MP_MASK; + do { + q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] - 1) & MP_MASK; + + /* find left hand */ + mp_zero (&t1); + t1.dp[0] = ((t - 1) < 0) ? 0 : y.dp[t - 1]; + t1.dp[1] = y.dp[t]; + t1.used = 2; + if ((res = mp_mul_d (&t1, q.dp[(i - t) - 1], &t1)) != MP_OKAY) { + goto LBL_Y; + } + + /* find right hand */ + t2.dp[0] = ((i - 2) < 0) ? 0 : x.dp[i - 2]; + t2.dp[1] = ((i - 1) < 0) ? 0 : x.dp[i - 1]; + t2.dp[2] = x.dp[i]; + t2.used = 3; + } while (mp_cmp_mag(&t1, &t2) == MP_GT); + + /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */ + if ((res = mp_mul_d (&y, q.dp[(i - t) - 1], &t1)) != MP_OKAY) { + goto LBL_Y; + } + + if ((res = mp_lshd (&t1, (i - t) - 1)) != MP_OKAY) { + goto LBL_Y; + } + + if ((res = mp_sub (&x, &t1, &x)) != MP_OKAY) { + goto LBL_Y; + } + + /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */ + if (x.sign == MP_NEG) { + if ((res = mp_copy (&y, &t1)) != MP_OKAY) { + goto LBL_Y; + } + if ((res = mp_lshd (&t1, (i - t) - 1)) != MP_OKAY) { + goto LBL_Y; + } + if ((res = mp_add (&x, &t1, &x)) != MP_OKAY) { + goto LBL_Y; + } + + q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] - 1UL) & MP_MASK; + } + } + + /* now q is the quotient and x is the remainder + * [which we have to normalize] + */ + + /* get sign before writing to c */ + x.sign = (x.used == 0) ? MP_ZPOS : a->sign; + + if (c != NULL) { + mp_clamp (&q); + mp_exch (&q, c); + c->sign = neg; + } + + if (d != NULL) { + if ((res = mp_div_2d (&x, norm, &x, NULL)) != MP_OKAY) { + goto LBL_Y; + } + mp_exch (&x, d); + } + + res = MP_OKAY; + +LBL_Y:mp_clear (&y); +LBL_X:mp_clear (&x); +LBL_T2:mp_clear (&t2); +LBL_T1:mp_clear (&t1); +LBL_Q:mp_clear (&q); + return res; +} + +#endif + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_div_2.c b/src/ltm/bn_mp_div_2.c new file mode 100644 index 0000000..d2a213f --- /dev/null +++ b/src/ltm/bn_mp_div_2.c @@ -0,0 +1,68 @@ +#include +#ifdef BN_MP_DIV_2_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* b = a/2 */ +int mp_div_2(mp_int * a, mp_int * b) +{ + int x, res, oldused; + + /* copy */ + if (b->alloc < a->used) { + if ((res = mp_grow (b, a->used)) != MP_OKAY) { + return res; + } + } + + oldused = b->used; + b->used = a->used; + { + mp_digit r, rr, *tmpa, *tmpb; + + /* source alias */ + tmpa = a->dp + b->used - 1; + + /* dest alias */ + tmpb = b->dp + b->used - 1; + + /* carry */ + r = 0; + for (x = b->used - 1; x >= 0; x--) { + /* get the carry for the next iteration */ + rr = *tmpa & 1; + + /* shift the current digit, add in carry and store */ + *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1)); + + /* forward carry to next iteration */ + r = rr; + } + + /* zero excess digits */ + tmpb = b->dp + b->used; + for (x = b->used; x < oldused; x++) { + *tmpb++ = 0; + } + } + b->sign = a->sign; + mp_clamp (b); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_div_2d.c b/src/ltm/bn_mp_div_2d.c new file mode 100644 index 0000000..5b9fb48 --- /dev/null +++ b/src/ltm/bn_mp_div_2d.c @@ -0,0 +1,97 @@ +#include +#ifdef BN_MP_DIV_2D_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* shift right by a certain bit count (store quotient in c, optional remainder in d) */ +int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d) +{ + mp_digit D, r, rr; + int x, res; + mp_int t; + + + /* if the shift count is <= 0 then we do no work */ + if (b <= 0) { + res = mp_copy (a, c); + if (d != NULL) { + mp_zero (d); + } + return res; + } + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + /* get the remainder */ + if (d != NULL) { + if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + } + + /* copy */ + if ((res = mp_copy (a, c)) != MP_OKAY) { + mp_clear (&t); + return res; + } + + /* shift by as many digits in the bit count */ + if (b >= (int)DIGIT_BIT) { + mp_rshd (c, b / DIGIT_BIT); + } + + /* shift any bit count < DIGIT_BIT */ + D = (mp_digit) (b % DIGIT_BIT); + if (D != 0) { + mp_digit *tmpc, mask, shift; + + /* mask */ + mask = (((mp_digit)1) << D) - 1; + + /* shift for lsb */ + shift = DIGIT_BIT - D; + + /* alias */ + tmpc = c->dp + (c->used - 1); + + /* carry */ + r = 0; + for (x = c->used - 1; x >= 0; x--) { + /* get the lower bits of this word in a temp */ + rr = *tmpc & mask; + + /* shift the current word and mix in the carry bits from the previous word */ + *tmpc = (*tmpc >> D) | (r << shift); + --tmpc; + + /* set the carry to the carry bits of the current word found above */ + r = rr; + } + } + mp_clamp (c); + if (d != NULL) { + mp_exch (&t, d); + } + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_div_3.c b/src/ltm/bn_mp_div_3.c new file mode 100644 index 0000000..c2b76fb --- /dev/null +++ b/src/ltm/bn_mp_div_3.c @@ -0,0 +1,79 @@ +#include +#ifdef BN_MP_DIV_3_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* divide by three (based on routine from MPI and the GMP manual) */ +int +mp_div_3 (mp_int * a, mp_int *c, mp_digit * d) +{ + mp_int q; + mp_word w, t; + mp_digit b; + int res, ix; + + /* b = 2**DIGIT_BIT / 3 */ + b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3); + + if ((res = mp_init_size(&q, a->used)) != MP_OKAY) { + return res; + } + + q.used = a->used; + q.sign = a->sign; + w = 0; + for (ix = a->used - 1; ix >= 0; ix--) { + w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); + + if (w >= 3) { + /* multiply w by [1/3] */ + t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT); + + /* now subtract 3 * [w/3] from w, to get the remainder */ + w -= t+t+t; + + /* fixup the remainder as required since + * the optimization is not exact. + */ + while (w >= 3) { + t += 1; + w -= 3; + } + } else { + t = 0; + } + q.dp[ix] = (mp_digit)t; + } + + /* [optional] store the remainder */ + if (d != NULL) { + *d = (mp_digit)w; + } + + /* [optional] store the quotient */ + if (c != NULL) { + mp_clamp(&q); + mp_exch(&q, c); + } + mp_clear(&q); + + return res; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_div_d.c b/src/ltm/bn_mp_div_d.c new file mode 100644 index 0000000..4df1d36 --- /dev/null +++ b/src/ltm/bn_mp_div_d.c @@ -0,0 +1,115 @@ +#include +#ifdef BN_MP_DIV_D_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, tstdenis82@gmail.com, http://libtom.org + */ + +static int s_is_power_of_two(mp_digit b, int *p) +{ + int x; + + /* fast return if no power of two */ + if ((b == 0) || ((b & (b-1)) != 0)) { + return 0; + } + + for (x = 0; x < DIGIT_BIT; x++) { + if (b == (((mp_digit)1)<dp[0] & ((((mp_digit)1)<used)) != MP_OKAY) { + return res; + } + + q.used = a->used; + q.sign = a->sign; + w = 0; + for (ix = a->used - 1; ix >= 0; ix--) { + w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); + + if (w >= b) { + t = (mp_digit)(w / b); + w -= ((mp_word)t) * ((mp_word)b); + } else { + t = 0; + } + q.dp[ix] = (mp_digit)t; + } + + if (d != NULL) { + *d = (mp_digit)w; + } + + if (c != NULL) { + mp_clamp(&q); + mp_exch(&q, c); + } + mp_clear(&q); + + return res; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_dr_is_modulus.c b/src/ltm/bn_mp_dr_is_modulus.c new file mode 100644 index 0000000..599d929 --- /dev/null +++ b/src/ltm/bn_mp_dr_is_modulus.c @@ -0,0 +1,43 @@ +#include +#ifdef BN_MP_DR_IS_MODULUS_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* determines if a number is a valid DR modulus */ +int mp_dr_is_modulus(mp_int *a) +{ + int ix; + + /* must be at least two digits */ + if (a->used < 2) { + return 0; + } + + /* must be of the form b**k - a [a <= b] so all + * but the first digit must be equal to -1 (mod b). + */ + for (ix = 1; ix < a->used; ix++) { + if (a->dp[ix] != MP_MASK) { + return 0; + } + } + return 1; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_dr_reduce.c b/src/ltm/bn_mp_dr_reduce.c new file mode 100644 index 0000000..2273c79 --- /dev/null +++ b/src/ltm/bn_mp_dr_reduce.c @@ -0,0 +1,96 @@ +#include +#ifdef BN_MP_DR_REDUCE_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* reduce "x" in place modulo "n" using the Diminished Radix algorithm. + * + * Based on algorithm from the paper + * + * "Generating Efficient Primes for Discrete Log Cryptosystems" + * Chae Hoon Lim, Pil Joong Lee, + * POSTECH Information Research Laboratories + * + * The modulus must be of a special format [see manual] + * + * Has been modified to use algorithm 7.10 from the LTM book instead + * + * Input x must be in the range 0 <= x <= (n-1)**2 + */ +int +mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k) +{ + int err, i, m; + mp_word r; + mp_digit mu, *tmpx1, *tmpx2; + + /* m = digits in modulus */ + m = n->used; + + /* ensure that "x" has at least 2m digits */ + if (x->alloc < (m + m)) { + if ((err = mp_grow (x, m + m)) != MP_OKAY) { + return err; + } + } + +/* top of loop, this is where the code resumes if + * another reduction pass is required. + */ +top: + /* aliases for digits */ + /* alias for lower half of x */ + tmpx1 = x->dp; + + /* alias for upper half of x, or x/B**m */ + tmpx2 = x->dp + m; + + /* set carry to zero */ + mu = 0; + + /* compute (x mod B**m) + k * [x/B**m] inline and inplace */ + for (i = 0; i < m; i++) { + r = (((mp_word)*tmpx2++) * (mp_word)k) + *tmpx1 + mu; + *tmpx1++ = (mp_digit)(r & MP_MASK); + mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT)); + } + + /* set final carry */ + *tmpx1++ = mu; + + /* zero words above m */ + for (i = m + 1; i < x->used; i++) { + *tmpx1++ = 0; + } + + /* clamp, sub and return */ + mp_clamp (x); + + /* if x >= n then subtract and reduce again + * Each successive "recursion" makes the input smaller and smaller. + */ + if (mp_cmp_mag (x, n) != MP_LT) { + if ((err = s_mp_sub(x, n, x)) != MP_OKAY) { + return err; + } + goto top; + } + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_dr_setup.c b/src/ltm/bn_mp_dr_setup.c new file mode 100644 index 0000000..1bccb2b --- /dev/null +++ b/src/ltm/bn_mp_dr_setup.c @@ -0,0 +1,32 @@ +#include +#ifdef BN_MP_DR_SETUP_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* determines the setup value */ +void mp_dr_setup(mp_int *a, mp_digit *d) +{ + /* the casts are required if DIGIT_BIT is one less than + * the number of bits in a mp_digit [e.g. DIGIT_BIT==31] + */ + *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) - + ((mp_word)a->dp[0])); +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_exch.c b/src/ltm/bn_mp_exch.c new file mode 100644 index 0000000..634193b --- /dev/null +++ b/src/ltm/bn_mp_exch.c @@ -0,0 +1,34 @@ +#include +#ifdef BN_MP_EXCH_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* swap the elements of two integers, for cases where you can't simply swap the + * mp_int pointers around + */ +void +mp_exch (mp_int * a, mp_int * b) +{ + mp_int t; + + t = *a; + *a = *b; + *b = t; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_export.c b/src/ltm/bn_mp_export.c new file mode 100644 index 0000000..9e7f7c4 --- /dev/null +++ b/src/ltm/bn_mp_export.c @@ -0,0 +1,88 @@ +#include +#ifdef BN_MP_EXPORT_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* based on gmp's mpz_export. + * see http://gmplib.org/manual/Integer-Import-and-Export.html + */ +int mp_export(void* rop, size_t* countp, int order, size_t size, + int endian, size_t nails, mp_int* op) { + int result; + size_t odd_nails, nail_bytes, i, j, bits, count; + unsigned char odd_nail_mask; + + mp_int t; + + if ((result = mp_init_copy(&t, op)) != MP_OKAY) { + return result; + } + + if (endian == 0) { + union { + unsigned int i; + char c[4]; + } lint; + lint.i = 0x01020304; + + endian = (lint.c[0] == 4) ? -1 : 1; + } + + odd_nails = (nails % 8); + odd_nail_mask = 0xff; + for (i = 0; i < odd_nails; ++i) { + odd_nail_mask ^= (1 << (7 - i)); + } + nail_bytes = nails / 8; + + bits = mp_count_bits(&t); + count = (bits / ((size * 8) - nails)) + (((bits % ((size * 8) - nails)) != 0) ? 1 : 0); + + for (i = 0; i < count; ++i) { + for (j = 0; j < size; ++j) { + unsigned char* byte = ( + (unsigned char*)rop + + (((order == -1) ? i : ((count - 1) - i)) * size) + + ((endian == -1) ? j : ((size - 1) - j)) + ); + + if (j >= (size - nail_bytes)) { + *byte = 0; + continue; + } + + *byte = (unsigned char)((j == ((size - nail_bytes) - 1)) ? (t.dp[0] & odd_nail_mask) : (t.dp[0] & 0xFF)); + + if ((result = mp_div_2d(&t, (int)((j == ((size - nail_bytes) - 1)) ? (8 - odd_nails) : 8), &t, NULL)) != MP_OKAY) { + mp_clear(&t); + return result; + } + } + } + + mp_clear(&t); + + if (countp != NULL) { + *countp = count; + } + + return MP_OKAY; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_expt_d.c b/src/ltm/bn_mp_expt_d.c new file mode 100644 index 0000000..61c5a1d --- /dev/null +++ b/src/ltm/bn_mp_expt_d.c @@ -0,0 +1,28 @@ +#include +#ifdef BN_MP_EXPT_D_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* wrapper function for mp_expt_d_ex() */ +int mp_expt_d (mp_int * a, mp_digit b, mp_int * c) +{ + return mp_expt_d_ex(a, b, c, 0); +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_expt_d_ex.c b/src/ltm/bn_mp_expt_d_ex.c new file mode 100644 index 0000000..649d224 --- /dev/null +++ b/src/ltm/bn_mp_expt_d_ex.c @@ -0,0 +1,83 @@ +#include +#ifdef BN_MP_EXPT_D_EX_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tstdenis82@gmail.com, http://libtom.org + */ + +/* calculate c = a**b using a square-multiply algorithm */ +int mp_expt_d_ex (mp_int * a, mp_digit b, mp_int * c, int fast) +{ + int res; + unsigned int x; + + mp_int g; + + if ((res = mp_init_copy (&g, a)) != MP_OKAY) { + return res; + } + + /* set initial result */ + mp_set (c, 1); + + if (fast != 0) { + while (b > 0) { + /* if the bit is set multiply */ + if ((b & 1) != 0) { + if ((res = mp_mul (c, &g, c)) != MP_OKAY) { + mp_clear (&g); + return res; + } + } + + /* square */ + if (b > 1) { + if ((res = mp_sqr (&g, &g)) != MP_OKAY) { + mp_clear (&g); + return res; + } + } + + /* shift to next bit */ + b >>= 1; + } + } + else { + for (x = 0; x < DIGIT_BIT; x++) { + /* square */ + if ((res = mp_sqr (c, c)) != MP_OKAY) { + mp_clear (&g); + return res; + } + + /* if the bit is set multiply */ + if ((b & (mp_digit) (((mp_digit)1) << (DIGIT_BIT - 1))) != 0) { + if ((res = mp_mul (c, &g, c)) != MP_OKAY) { + mp_clear (&g); + return res; + } + } + + /* shift to next bit */ + b <<= 1; + } + } /* if ... else */ + + mp_clear (&g); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_exptmod.c b/src/ltm/bn_mp_exptmod.c new file mode 100644 index 0000000..0973e44 --- /dev/null +++ b/src/ltm/bn_mp_exptmod.c @@ -0,0 +1,112 @@ +#include +#ifdef BN_MP_EXPTMOD_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, tstdenis82@gmail.com, http://libtom.org + */ + + +/* this is a shell function that calls either the normal or Montgomery + * exptmod functions. Originally the call to the montgomery code was + * embedded in the normal function but that wasted alot of stack space + * for nothing (since 99% of the time the Montgomery code would be called) + */ +int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) +{ + int dr; + + /* modulus P must be positive */ + if (P->sign == MP_NEG) { + return MP_VAL; + } + + /* if exponent X is negative we have to recurse */ + if (X->sign == MP_NEG) { +#ifdef BN_MP_INVMOD_C + mp_int tmpG, tmpX; + int err; + + /* first compute 1/G mod P */ + if ((err = mp_init(&tmpG)) != MP_OKAY) { + return err; + } + if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) { + mp_clear(&tmpG); + return err; + } + + /* now get |X| */ + if ((err = mp_init(&tmpX)) != MP_OKAY) { + mp_clear(&tmpG); + return err; + } + if ((err = mp_abs(X, &tmpX)) != MP_OKAY) { + mp_clear_multi(&tmpG, &tmpX, NULL); + return err; + } + + /* and now compute (1/G)**|X| instead of G**X [X < 0] */ + err = mp_exptmod(&tmpG, &tmpX, P, Y); + mp_clear_multi(&tmpG, &tmpX, NULL); + return err; +#else + /* no invmod */ + return MP_VAL; +#endif + } + +/* modified diminished radix reduction */ +#if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && defined(BN_S_MP_EXPTMOD_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 unrestricted DR modulus? */ + if (dr == 0) { + dr = mp_reduce_is_2k(P) << 1; + } +#endif + + /* if the modulus is odd or dr != 0 use the montgomery method */ +#ifdef BN_MP_EXPTMOD_FAST_C + if ((mp_isodd (P) == MP_YES) || (dr != 0)) { + return mp_exptmod_fast (G, X, P, Y, dr); + } else { +#endif +#ifdef BN_S_MP_EXPTMOD_C + /* otherwise use the generic Barrett reduction technique */ + return s_mp_exptmod (G, X, P, Y, 0); +#else + /* no exptmod for evens */ + return MP_VAL; +#endif +#ifdef BN_MP_EXPTMOD_FAST_C + } +#endif +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_exptmod_fast.c b/src/ltm/bn_mp_exptmod_fast.c new file mode 100644 index 0000000..8d280bd --- /dev/null +++ b/src/ltm/bn_mp_exptmod_fast.c @@ -0,0 +1,321 @@ +#include +#ifdef BN_MP_EXPTMOD_FAST_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85 + * + * Uses a left-to-right k-ary sliding window to compute the modular exponentiation. + * The value of k changes based on the size of the exponent. + * + * Uses Montgomery or Diminished Radix reduction [whichever appropriate] + */ + +#ifdef MP_LOW_MEM + #define TAB_SIZE 32 +#else + #define TAB_SIZE 256 +#endif + +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; + int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; + + /* use a pointer to the reduction algorithm. This allows us to use + * one of many reduction algorithms without modding the guts of + * the code with if statements everywhere. + */ + int (*redux)(mp_int*,mp_int*,mp_digit); + + /* find window size */ + x = mp_count_bits (X); + if (x <= 7) { + winsize = 2; + } else if (x <= 36) { + winsize = 3; + } else if (x <= 140) { + winsize = 4; + } else if (x <= 450) { + winsize = 5; + } else if (x <= 1303) { + winsize = 6; + } else if (x <= 3529) { + winsize = 7; + } else { + winsize = 8; + } + +#ifdef MP_LOW_MEM + if (winsize > 5) { + winsize = 5; + } +#endif + + /* init M array */ + /* init first cell */ + if ((err = mp_init(&M[1])) != MP_OKAY) { + return err; + } + + /* now init the second half of the array */ + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + if ((err = mp_init(&M[x])) != MP_OKAY) { + for (y = 1<<(winsize-1); y < x; y++) { + mp_clear (&M[y]); + } + mp_clear(&M[1]); + return err; + } + } + + /* determine and setup reduction code */ + if (redmode == 0) { +#ifdef BN_MP_MONTGOMERY_SETUP_C + /* now setup montgomery */ + if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) { + goto LBL_M; + } +#else + err = MP_VAL; + goto LBL_M; +#endif + + /* automatically pick the comba one if available (saves quite a few calls/ifs) */ +#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C + if ((((P->used * 2) + 1) < MP_WARRAY) && + (P->used < (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) { + redux = fast_mp_montgomery_reduce; + } else +#endif + { +#ifdef BN_MP_MONTGOMERY_REDUCE_C + /* use slower baseline Montgomery method */ + redux = mp_montgomery_reduce; +#else + err = MP_VAL; + goto LBL_M; +#endif + } + } else if (redmode == 1) { +#if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C) + /* setup DR reduction for moduli of the form B**k - b */ + mp_dr_setup(P, &mp); + redux = mp_dr_reduce; +#else + err = MP_VAL; + goto LBL_M; +#endif + } else { +#if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C) + /* setup DR reduction for moduli of the form 2**k - b */ + if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) { + goto LBL_M; + } + redux = mp_reduce_2k; +#else + err = MP_VAL; + goto LBL_M; +#endif + } + + /* setup result */ + if ((err = mp_init (&res)) != MP_OKAY) { + goto LBL_M; + } + + /* create M table + * + + * + * The first half of the table is not computed though accept for M[0] and M[1] + */ + + if (redmode == 0) { +#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C + /* now we need R mod m */ + if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) { + goto LBL_RES; + } +#else + err = MP_VAL; + goto LBL_RES; +#endif + + /* now set M[1] to G * R mod m */ + if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) { + goto LBL_RES; + } + } else { + mp_set(&res, 1); + if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) { + goto LBL_RES; + } + } + + /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */ + if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { + goto LBL_RES; + } + + for (x = 0; x < (winsize - 1); x++) { + if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* create upper table */ + for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { + if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&M[x], P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* set initial mode and bit cnt */ + mode = 0; + bitcnt = 1; + buf = 0; + digidx = X->used - 1; + bitcpy = 0; + bitbuf = 0; + + for (;;) { + /* grab next digit as required */ + if (--bitcnt == 0) { + /* if digidx == -1 we are out of digits so break */ + if (digidx == -1) { + break; + } + /* read next digit and reset bitcnt */ + buf = X->dp[digidx--]; + bitcnt = (int)DIGIT_BIT; + } + + /* grab the next msb from the exponent */ + y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1; + buf <<= (mp_digit)1; + + /* if the bit is zero and mode == 0 then we ignore it + * These represent the leading zero bits before the first 1 bit + * in the exponent. Technically this opt is not required but it + * does lower the # of trivial squaring/reductions used + */ + if ((mode == 0) && (y == 0)) { + continue; + } + + /* if the bit is zero and mode == 1 then we square */ + if ((mode == 1) && (y == 0)) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + continue; + } + + /* else we add it to the window */ + bitbuf |= (y << (winsize - ++bitcpy)); + mode = 2; + + if (bitcpy == winsize) { + /* ok window is filled so square as required and multiply */ + /* square first */ + for (x = 0; x < winsize; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* then multiply */ + if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + + /* empty window and reset */ + bitcpy = 0; + bitbuf = 0; + mode = 1; + } + } + + /* if bits remain then square/multiply */ + if ((mode == 2) && (bitcpy > 0)) { + /* square then multiply if the bit is set */ + for (x = 0; x < bitcpy; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + + /* get next bit of the window */ + bitbuf <<= 1; + if ((bitbuf & (1 << winsize)) != 0) { + /* then multiply */ + if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + } + } + + if (redmode == 0) { + /* fixup result if Montgomery reduction is used + * recall that any value in a Montgomery system is + * actually multiplied by R mod n. So we have + * to reduce one more time to cancel out the factor + * of R. + */ + if ((err = redux(&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* swap res with Y */ + mp_exch (&res, Y); + err = MP_OKAY; +LBL_RES:mp_clear (&res); +LBL_M: + mp_clear(&M[1]); + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + mp_clear (&M[x]); + } + return err; +} +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_exteuclid.c b/src/ltm/bn_mp_exteuclid.c new file mode 100644 index 0000000..fbbd92c --- /dev/null +++ b/src/ltm/bn_mp_exteuclid.c @@ -0,0 +1,82 @@ +#include +#ifdef BN_MP_EXTEUCLID_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* Extended euclidean algorithm of (a, b) produces + a*u1 + b*u2 = u3 + */ +int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3) +{ + mp_int u1,u2,u3,v1,v2,v3,t1,t2,t3,q,tmp; + int err; + + if ((err = mp_init_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) { + return err; + } + + /* initialize, (u1,u2,u3) = (1,0,a) */ + mp_set(&u1, 1); + if ((err = mp_copy(a, &u3)) != MP_OKAY) { goto _ERR; } + + /* initialize, (v1,v2,v3) = (0,1,b) */ + mp_set(&v2, 1); + if ((err = mp_copy(b, &v3)) != MP_OKAY) { goto _ERR; } + + /* loop while v3 != 0 */ + while (mp_iszero(&v3) == MP_NO) { + /* q = u3/v3 */ + if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) { goto _ERR; } + + /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */ + if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY) { goto _ERR; } + if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY) { goto _ERR; } + if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY) { goto _ERR; } + if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY) { goto _ERR; } + if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY) { goto _ERR; } + if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY) { goto _ERR; } + + /* (u1,u2,u3) = (v1,v2,v3) */ + if ((err = mp_copy(&v1, &u1)) != MP_OKAY) { goto _ERR; } + if ((err = mp_copy(&v2, &u2)) != MP_OKAY) { goto _ERR; } + if ((err = mp_copy(&v3, &u3)) != MP_OKAY) { goto _ERR; } + + /* (v1,v2,v3) = (t1,t2,t3) */ + if ((err = mp_copy(&t1, &v1)) != MP_OKAY) { goto _ERR; } + if ((err = mp_copy(&t2, &v2)) != MP_OKAY) { goto _ERR; } + if ((err = mp_copy(&t3, &v3)) != MP_OKAY) { goto _ERR; } + } + + /* make sure U3 >= 0 */ + if (u3.sign == MP_NEG) { + if ((err = mp_neg(&u1, &u1)) != MP_OKAY) { goto _ERR; } + if ((err = mp_neg(&u2, &u2)) != MP_OKAY) { goto _ERR; } + if ((err = mp_neg(&u3, &u3)) != MP_OKAY) { goto _ERR; } + } + + /* copy result out */ + if (U1 != NULL) { mp_exch(U1, &u1); } + if (U2 != NULL) { mp_exch(U2, &u2); } + if (U3 != NULL) { mp_exch(U3, &u3); } + + err = MP_OKAY; +_ERR: mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL); + return err; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_fread.c b/src/ltm/bn_mp_fread.c new file mode 100644 index 0000000..a4fa8c9 --- /dev/null +++ b/src/ltm/bn_mp_fread.c @@ -0,0 +1,67 @@ +#include +#ifdef BN_MP_FREAD_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* read a bigint from a file stream in ASCII */ +int mp_fread(mp_int *a, int radix, FILE *stream) +{ + int err, ch, neg, y; + + /* clear a */ + mp_zero(a); + + /* if first digit is - then set negative */ + ch = fgetc(stream); + if (ch == '-') { + neg = MP_NEG; + ch = fgetc(stream); + } else { + neg = MP_ZPOS; + } + + for (;;) { + /* find y in the radix map */ + for (y = 0; y < radix; y++) { + if (mp_s_rmap[y] == ch) { + break; + } + } + if (y == radix) { + break; + } + + /* shift up and add */ + if ((err = mp_mul_d(a, radix, a)) != MP_OKAY) { + return err; + } + if ((err = mp_add_d(a, y, a)) != MP_OKAY) { + return err; + } + + ch = fgetc(stream); + } + if (mp_cmp_d(a, 0) != MP_EQ) { + a->sign = neg; + } + + return MP_OKAY; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_fwrite.c b/src/ltm/bn_mp_fwrite.c new file mode 100644 index 0000000..90f1fc5 --- /dev/null +++ b/src/ltm/bn_mp_fwrite.c @@ -0,0 +1,52 @@ +#include +#ifdef BN_MP_FWRITE_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, tstdenis82@gmail.com, http://libtom.org + */ + +int mp_fwrite(mp_int *a, int radix, FILE *stream) +{ + char *buf; + int err, len, x; + + if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) { + return err; + } + + buf = OPT_CAST(char) XMALLOC (len); + if (buf == NULL) { + return MP_MEM; + } + + if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) { + XFREE (buf); + return err; + } + + for (x = 0; x < len; x++) { + if (fputc(buf[x], stream) == EOF) { + XFREE (buf); + return MP_VAL; + } + } + + XFREE (buf); + return MP_OKAY; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_gcd.c b/src/ltm/bn_mp_gcd.c new file mode 100644 index 0000000..16acfd9 --- /dev/null +++ b/src/ltm/bn_mp_gcd.c @@ -0,0 +1,105 @@ +#include +#ifdef BN_MP_GCD_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* Greatest Common Divisor using the binary method */ +int mp_gcd (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int u, v; + int k, u_lsb, v_lsb, res; + + /* either zero than gcd is the largest */ + if (mp_iszero (a) == MP_YES) { + return mp_abs (b, c); + } + if (mp_iszero (b) == MP_YES) { + return mp_abs (a, c); + } + + /* get copies of a and b we can modify */ + if ((res = mp_init_copy (&u, a)) != MP_OKAY) { + return res; + } + + if ((res = mp_init_copy (&v, b)) != MP_OKAY) { + goto LBL_U; + } + + /* must be positive for the remainder of the algorithm */ + u.sign = v.sign = MP_ZPOS; + + /* B1. Find the common power of two for u and v */ + u_lsb = mp_cnt_lsb(&u); + v_lsb = mp_cnt_lsb(&v); + k = MIN(u_lsb, v_lsb); + + if (k > 0) { + /* divide the power of two out */ + if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) { + goto LBL_V; + } + + if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) { + goto LBL_V; + } + } + + /* divide any remaining factors of two out */ + if (u_lsb != k) { + if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) { + goto LBL_V; + } + } + + if (v_lsb != k) { + if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) { + goto LBL_V; + } + } + + while (mp_iszero(&v) == MP_NO) { + /* make sure v is the largest */ + if (mp_cmp_mag(&u, &v) == MP_GT) { + /* swap u and v to make sure v is >= u */ + mp_exch(&u, &v); + } + + /* subtract smallest from largest */ + if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) { + goto LBL_V; + } + + /* Divide out all factors of two */ + if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) { + goto LBL_V; + } + } + + /* multiply by 2**k which we divided out at the beginning */ + if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) { + goto LBL_V; + } + c->sign = MP_ZPOS; + res = MP_OKAY; +LBL_V:mp_clear (&u); +LBL_U:mp_clear (&v); + return res; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_get_int.c b/src/ltm/bn_mp_get_int.c new file mode 100644 index 0000000..3912c27 --- /dev/null +++ b/src/ltm/bn_mp_get_int.c @@ -0,0 +1,45 @@ +#include +#ifdef BN_MP_GET_INT_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* get the lower 32-bits of an mp_int */ +unsigned long mp_get_int(mp_int * a) +{ + int i; + mp_uint64 res; + + if (a->used == 0) { + return 0; + } + + /* get number of digits of the lsb we have to read */ + i = MIN(a->used,(int)(((sizeof(unsigned long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1; + + /* get most significant digit of result */ + res = DIGIT(a,i); + + while (--i >= 0) { + res = (res << DIGIT_BIT) | DIGIT(a,i); + } + + /* force result to 32-bits always so it is consistent on non 32-bit platforms */ + return (unsigned long)(res & 0xFFFFFFFFUL); +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_get_long.c b/src/ltm/bn_mp_get_long.c new file mode 100644 index 0000000..7c3d0fe --- /dev/null +++ b/src/ltm/bn_mp_get_long.c @@ -0,0 +1,41 @@ +#include +#ifdef BN_MP_GET_LONG_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* get the lower unsigned long of an mp_int, platform dependent */ +unsigned long mp_get_long(mp_int * a) +{ + int i; + unsigned long res; + + if (a->used == 0) { + return 0; + } + + /* get number of digits of the lsb we have to read */ + i = MIN(a->used,(int)(((sizeof(unsigned long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1; + + /* get most significant digit of result */ + res = DIGIT(a,i); + +#if (ULONG_MAX != 0xffffffffuL) || (DIGIT_BIT < 32) + while (--i >= 0) { + res = (res << DIGIT_BIT) | DIGIT(a,i); + } +#endif + return res; +} +#endif diff --git a/src/ltm/bn_mp_get_long_long.c b/src/ltm/bn_mp_get_long_long.c new file mode 100644 index 0000000..4b959e6 --- /dev/null +++ b/src/ltm/bn_mp_get_long_long.c @@ -0,0 +1,41 @@ +#include +#ifdef BN_MP_GET_LONG_LONG_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* get the lower unsigned long long of an mp_int, platform dependent */ +unsigned long long mp_get_long_long (mp_int * a) +{ + int i; + unsigned long long res; + + if (a->used == 0) { + return 0; + } + + /* get number of digits of the lsb we have to read */ + i = MIN(a->used,(int)(((sizeof(unsigned long long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1; + + /* get most significant digit of result */ + res = DIGIT(a,i); + +#if DIGIT_BIT < 64 + while (--i >= 0) { + res = (res << DIGIT_BIT) | DIGIT(a,i); + } +#endif + return res; +} +#endif diff --git a/src/ltm/bn_mp_grow.c b/src/ltm/bn_mp_grow.c new file mode 100644 index 0000000..cbdcfed --- /dev/null +++ b/src/ltm/bn_mp_grow.c @@ -0,0 +1,57 @@ +#include +#ifdef BN_MP_GROW_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* grow as required */ +int mp_grow (mp_int * a, int size) +{ + int i; + mp_digit *tmp; + + /* if the alloc size is smaller alloc more ram */ + if (a->alloc < size) { + /* ensure there are always at least MP_PREC digits extra on top */ + size += (MP_PREC * 2) - (size % MP_PREC); + + /* reallocate the array a->dp + * + * We store the return in a temporary variable + * in case the operation failed we don't want + * to overwrite the dp member of a. + */ + tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size); + if (tmp == NULL) { + /* reallocation failed but "a" is still valid [can be freed] */ + return MP_MEM; + } + + /* reallocation succeeded so set a->dp */ + a->dp = tmp; + + /* zero excess digits */ + i = a->alloc; + a->alloc = size; + for (; i < a->alloc; i++) { + a->dp[i] = 0; + } + } + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_import.c b/src/ltm/bn_mp_import.c new file mode 100644 index 0000000..bc31651 --- /dev/null +++ b/src/ltm/bn_mp_import.c @@ -0,0 +1,73 @@ +#include +#ifdef BN_MP_IMPORT_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* based on gmp's mpz_import. + * see http://gmplib.org/manual/Integer-Import-and-Export.html + */ +int mp_import(mp_int* rop, size_t count, int order, size_t size, + int endian, size_t nails, const void* op) { + int result; + size_t odd_nails, nail_bytes, i, j; + unsigned char odd_nail_mask; + + mp_zero(rop); + + if (endian == 0) { + union { + unsigned int i; + char c[4]; + } lint; + lint.i = 0x01020304; + + endian = (lint.c[0] == 4) ? -1 : 1; + } + + odd_nails = (nails % 8); + odd_nail_mask = 0xff; + for (i = 0; i < odd_nails; ++i) { + odd_nail_mask ^= (1 << (7 - i)); + } + nail_bytes = nails / 8; + + for (i = 0; i < count; ++i) { + for (j = 0; j < (size - nail_bytes); ++j) { + unsigned char byte = *( + (unsigned char*)op + + (((order == 1) ? i : ((count - 1) - i)) * size) + + ((endian == 1) ? (j + nail_bytes) : (((size - 1) - j) - nail_bytes)) + ); + + if ( + (result = mp_mul_2d(rop, (int)((j == 0) ? (8 - odd_nails) : 8), rop)) != MP_OKAY) { + return result; + } + + rop->dp[0] |= (j == 0) ? (byte & odd_nail_mask) : byte; + rop->used += 1; + } + } + + mp_clamp(rop); + + return MP_OKAY; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_init.c b/src/ltm/bn_mp_init.c new file mode 100644 index 0000000..7a57730 --- /dev/null +++ b/src/ltm/bn_mp_init.c @@ -0,0 +1,46 @@ +#include +#ifdef BN_MP_INIT_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* init a new mp_int */ +int mp_init (mp_int * a) +{ + int i; + + /* allocate memory required and clear it */ + a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC); + if (a->dp == NULL) { + return MP_MEM; + } + + /* set the digits to zero */ + for (i = 0; i < MP_PREC; i++) { + a->dp[i] = 0; + } + + /* set the used to zero, allocated digits to the default precision + * and sign to positive */ + a->used = 0; + a->alloc = MP_PREC; + a->sign = MP_ZPOS; + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_init_copy.c b/src/ltm/bn_mp_init_copy.c new file mode 100644 index 0000000..9e15f36 --- /dev/null +++ b/src/ltm/bn_mp_init_copy.c @@ -0,0 +1,32 @@ +#include +#ifdef BN_MP_INIT_COPY_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* creates "a" then copies b into it */ +int mp_init_copy (mp_int * a, mp_int * b) +{ + int res; + + if ((res = mp_init_size (a, b->used)) != MP_OKAY) { + return res; + } + return mp_copy (b, a); +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_init_multi.c b/src/ltm/bn_mp_init_multi.c new file mode 100644 index 0000000..52220a3 --- /dev/null +++ b/src/ltm/bn_mp_init_multi.c @@ -0,0 +1,59 @@ +#include +#ifdef BN_MP_INIT_MULTI_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, tstdenis82@gmail.com, http://libtom.org + */ +#include + +int mp_init_multi(mp_int *mp, ...) +{ + mp_err res = MP_OKAY; /* Assume ok until proven otherwise */ + int n = 0; /* Number of ok inits */ + mp_int* cur_arg = mp; + va_list args; + + va_start(args, mp); /* init args to next argument from caller */ + while (cur_arg != NULL) { + if (mp_init(cur_arg) != MP_OKAY) { + /* Oops - error! Back-track and mp_clear what we already + succeeded in init-ing, then return error. + */ + va_list clean_args; + + /* end the current list */ + va_end(args); + + /* now start cleaning up */ + cur_arg = mp; + va_start(clean_args, mp); + while (n-- != 0) { + mp_clear(cur_arg); + cur_arg = va_arg(clean_args, mp_int*); + } + va_end(clean_args); + res = MP_MEM; + break; + } + n++; + cur_arg = va_arg(args, mp_int*); + } + va_end(args); + return res; /* Assumed ok, if error flagged above. */ +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_init_set.c b/src/ltm/bn_mp_init_set.c new file mode 100644 index 0000000..c337e50 --- /dev/null +++ b/src/ltm/bn_mp_init_set.c @@ -0,0 +1,32 @@ +#include +#ifdef BN_MP_INIT_SET_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* initialize and set a digit */ +int mp_init_set (mp_int * a, mp_digit b) +{ + int err; + if ((err = mp_init(a)) != MP_OKAY) { + return err; + } + mp_set(a, b); + return err; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_init_set_int.c b/src/ltm/bn_mp_init_set_int.c new file mode 100644 index 0000000..c88f14e --- /dev/null +++ b/src/ltm/bn_mp_init_set_int.c @@ -0,0 +1,31 @@ +#include +#ifdef BN_MP_INIT_SET_INT_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* initialize and set a digit */ +int mp_init_set_int (mp_int * a, unsigned long b) +{ + int err; + if ((err = mp_init(a)) != MP_OKAY) { + return err; + } + return mp_set_int(a, b); +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_init_size.c b/src/ltm/bn_mp_init_size.c new file mode 100644 index 0000000..e1d1b51 --- /dev/null +++ b/src/ltm/bn_mp_init_size.c @@ -0,0 +1,48 @@ +#include +#ifdef BN_MP_INIT_SIZE_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* init an mp_init for a given size */ +int mp_init_size (mp_int * a, int size) +{ + int x; + + /* pad size so there are always extra digits */ + size += (MP_PREC * 2) - (size % MP_PREC); + + /* alloc mem */ + a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size); + if (a->dp == NULL) { + return MP_MEM; + } + + /* set the members */ + a->used = 0; + a->alloc = size; + a->sign = MP_ZPOS; + + /* zero the digits */ + for (x = 0; x < size; x++) { + a->dp[x] = 0; + } + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_invmod.c b/src/ltm/bn_mp_invmod.c new file mode 100644 index 0000000..22df566 --- /dev/null +++ b/src/ltm/bn_mp_invmod.c @@ -0,0 +1,43 @@ +#include +#ifdef BN_MP_INVMOD_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* hac 14.61, pp608 */ +int mp_invmod (mp_int * a, mp_int * b, mp_int * c) +{ + /* b cannot be negative */ + if ((b->sign == MP_NEG) || (mp_iszero(b) == MP_YES)) { + return MP_VAL; + } + +#ifdef BN_FAST_MP_INVMOD_C + /* if the modulus is odd and >1 we can use a faster routine instead */ + if ((mp_isodd (b) == MP_YES) && (mp_cmp_d (b, 1) != MP_EQ)) { + return fast_mp_invmod (a, b, c); + } +#endif + +#ifdef BN_MP_INVMOD_SLOW_C + return mp_invmod_slow(a, b, c); +#else + return MP_VAL; +#endif +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_invmod_slow.c b/src/ltm/bn_mp_invmod_slow.c new file mode 100644 index 0000000..a21f947 --- /dev/null +++ b/src/ltm/bn_mp_invmod_slow.c @@ -0,0 +1,175 @@ +#include +#ifdef BN_MP_INVMOD_SLOW_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tstdenis82@gmail.com, http://libtom.org + */ + +/* hac 14.61, pp608 */ +int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int x, y, u, v, A, B, C, D; + int res; + + /* b cannot be negative */ + if ((b->sign == MP_NEG) || (mp_iszero(b) == MP_YES)) { + return MP_VAL; + } + + /* init temps */ + if ((res = mp_init_multi(&x, &y, &u, &v, + &A, &B, &C, &D, NULL)) != MP_OKAY) { + return res; + } + + /* x = a, y = b */ + if ((res = mp_mod(a, b, &x)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_copy (b, &y)) != MP_OKAY) { + goto LBL_ERR; + } + + /* 2. [modified] if x,y are both even then return an error! */ + if ((mp_iseven (&x) == MP_YES) && (mp_iseven (&y) == MP_YES)) { + res = MP_VAL; + goto LBL_ERR; + } + + /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ + if ((res = mp_copy (&x, &u)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_copy (&y, &v)) != MP_OKAY) { + goto LBL_ERR; + } + mp_set (&A, 1); + mp_set (&D, 1); + +top: + /* 4. while u is even do */ + while (mp_iseven (&u) == MP_YES) { + /* 4.1 u = u/2 */ + if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { + goto LBL_ERR; + } + /* 4.2 if A or B is odd then */ + if ((mp_isodd (&A) == MP_YES) || (mp_isodd (&B) == MP_YES)) { + /* A = (A+y)/2, B = (B-x)/2 */ + if ((res = mp_add (&A, &y, &A)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } + /* A = A/2, B = B/2 */ + if ((res = mp_div_2 (&A, &A)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* 5. while v is even do */ + while (mp_iseven (&v) == MP_YES) { + /* 5.1 v = v/2 */ + if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { + goto LBL_ERR; + } + /* 5.2 if C or D is odd then */ + if ((mp_isodd (&C) == MP_YES) || (mp_isodd (&D) == MP_YES)) { + /* C = (C+y)/2, D = (D-x)/2 */ + if ((res = mp_add (&C, &y, &C)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + /* C = C/2, D = D/2 */ + if ((res = mp_div_2 (&C, &C)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* 6. if u >= v then */ + if (mp_cmp (&u, &v) != MP_LT) { + /* u = u - v, A = A - C, B = B - D */ + if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } else { + /* v - v - u, C = C - A, D = D - B */ + if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* if not zero goto step 4 */ + if (mp_iszero (&u) == MP_NO) + goto top; + + /* now a = C, b = D, gcd == g*v */ + + /* if v != 1 then there is no inverse */ + if (mp_cmp_d (&v, 1) != MP_EQ) { + res = MP_VAL; + goto LBL_ERR; + } + + /* if its too low */ + while (mp_cmp_d(&C, 0) == MP_LT) { + if ((res = mp_add(&C, b, &C)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* too big */ + while (mp_cmp_mag(&C, b) != MP_LT) { + if ((res = mp_sub(&C, b, &C)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* C is now the inverse */ + mp_exch (&C, c); + res = MP_OKAY; +LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL); + return res; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_is_square.c b/src/ltm/bn_mp_is_square.c new file mode 100644 index 0000000..9f065ef --- /dev/null +++ b/src/ltm/bn_mp_is_square.c @@ -0,0 +1,109 @@ +#include +#ifdef BN_MP_IS_SQUARE_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* Check if remainders are possible squares - fast exclude non-squares */ +static const char rem_128[128] = { + 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 +}; + +static const char rem_105[105] = { + 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1 +}; + +/* Store non-zero to ret if arg is square, and zero if not */ +int mp_is_square(mp_int *arg,int *ret) +{ + int res; + mp_digit c; + mp_int t; + unsigned long r; + + /* Default to Non-square :) */ + *ret = MP_NO; + + if (arg->sign == MP_NEG) { + return MP_VAL; + } + + /* digits used? (TSD) */ + if (arg->used == 0) { + return MP_OKAY; + } + + /* First check mod 128 (suppose that DIGIT_BIT is at least 7) */ + if (rem_128[127 & DIGIT(arg,0)] == 1) { + return MP_OKAY; + } + + /* Next check mod 105 (3*5*7) */ + if ((res = mp_mod_d(arg,105,&c)) != MP_OKAY) { + return res; + } + if (rem_105[c] == 1) { + return MP_OKAY; + } + + + if ((res = mp_init_set_int(&t,11L*13L*17L*19L*23L*29L*31L)) != MP_OKAY) { + return res; + } + if ((res = mp_mod(arg,&t,&t)) != MP_OKAY) { + goto ERR; + } + r = mp_get_int(&t); + /* Check for other prime modules, note it's not an ERROR but we must + * free "t" so the easiest way is to goto ERR. We know that res + * is already equal to MP_OKAY from the mp_mod call + */ + if (((1L<<(r%11)) & 0x5C4L) != 0L) goto ERR; + if (((1L<<(r%13)) & 0x9E4L) != 0L) goto ERR; + if (((1L<<(r%17)) & 0x5CE8L) != 0L) goto ERR; + if (((1L<<(r%19)) & 0x4F50CL) != 0L) goto ERR; + if (((1L<<(r%23)) & 0x7ACCA0L) != 0L) goto ERR; + if (((1L<<(r%29)) & 0xC2EDD0CL) != 0L) goto ERR; + if (((1L<<(r%31)) & 0x6DE2B848L) != 0L) goto ERR; + + /* Final check - is sqr(sqrt(arg)) == arg ? */ + if ((res = mp_sqrt(arg,&t)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sqr(&t,&t)) != MP_OKAY) { + goto ERR; + } + + *ret = (mp_cmp_mag(&t,arg) == MP_EQ) ? MP_YES : MP_NO; +ERR:mp_clear(&t); + return res; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_jacobi.c b/src/ltm/bn_mp_jacobi.c new file mode 100644 index 0000000..3c114e3 --- /dev/null +++ b/src/ltm/bn_mp_jacobi.c @@ -0,0 +1,117 @@ +#include +#ifdef BN_MP_JACOBI_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* computes the jacobi c = (a | n) (or Legendre if n is prime) + * HAC pp. 73 Algorithm 2.149 + * HAC is wrong here, as the special case of (0 | 1) is not + * handled correctly. + */ +int mp_jacobi (mp_int * a, mp_int * n, int *c) +{ + mp_int a1, p1; + int k, s, r, res; + mp_digit residue; + + /* if a < 0 return MP_VAL */ + if (mp_isneg(a) == MP_YES) { + return MP_VAL; + } + + /* if n <= 0 return MP_VAL */ + if (mp_cmp_d(n, 0) != MP_GT) { + return MP_VAL; + } + + /* step 1. handle case of a == 0 */ + if (mp_iszero (a) == MP_YES) { + /* special case of a == 0 and n == 1 */ + if (mp_cmp_d (n, 1) == MP_EQ) { + *c = 1; + } else { + *c = 0; + } + return MP_OKAY; + } + + /* step 2. if a == 1, return 1 */ + if (mp_cmp_d (a, 1) == MP_EQ) { + *c = 1; + return MP_OKAY; + } + + /* default */ + s = 0; + + /* step 3. write a = a1 * 2**k */ + if ((res = mp_init_copy (&a1, a)) != MP_OKAY) { + return res; + } + + if ((res = mp_init (&p1)) != MP_OKAY) { + goto LBL_A1; + } + + /* divide out larger power of two */ + k = mp_cnt_lsb(&a1); + if ((res = mp_div_2d(&a1, k, &a1, NULL)) != MP_OKAY) { + goto LBL_P1; + } + + /* step 4. if e is even set s=1 */ + if ((k & 1) == 0) { + s = 1; + } else { + /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */ + residue = n->dp[0] & 7; + + if ((residue == 1) || (residue == 7)) { + s = 1; + } else if ((residue == 3) || (residue == 5)) { + s = -1; + } + } + + /* step 5. if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */ + if ( ((n->dp[0] & 3) == 3) && ((a1.dp[0] & 3) == 3)) { + s = -s; + } + + /* if a1 == 1 we're done */ + if (mp_cmp_d (&a1, 1) == MP_EQ) { + *c = s; + } else { + /* n1 = n mod a1 */ + if ((res = mp_mod (n, &a1, &p1)) != MP_OKAY) { + goto LBL_P1; + } + if ((res = mp_jacobi (&p1, &a1, &r)) != MP_OKAY) { + goto LBL_P1; + } + *c = s * r; + } + + /* done */ + res = MP_OKAY; +LBL_P1:mp_clear (&p1); +LBL_A1:mp_clear (&a1); + return res; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_karatsuba_mul.c b/src/ltm/bn_mp_karatsuba_mul.c new file mode 100644 index 0000000..d65e37e --- /dev/null +++ b/src/ltm/bn_mp_karatsuba_mul.c @@ -0,0 +1,167 @@ +#include +#ifdef BN_MP_KARATSUBA_MUL_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* c = |a| * |b| using Karatsuba Multiplication using + * three half size multiplications + * + * Let B represent the radix [e.g. 2**DIGIT_BIT] and + * let n represent half of the number of digits in + * the min(a,b) + * + * a = a1 * B**n + a0 + * b = b1 * B**n + b0 + * + * Then, a * b => + a1b1 * B**2n + ((a1 + a0)(b1 + b0) - (a0b0 + a1b1)) * B + a0b0 + * + * Note that a1b1 and a0b0 are used twice and only need to be + * computed once. So in total three half size (half # of + * digit) multiplications are performed, a0b0, a1b1 and + * (a1+b1)(a0+b0) + * + * Note that a multiplication of half the digits requires + * 1/4th the number of single precision multiplications so in + * total after one call 25% of the single precision multiplications + * are saved. Note also that the call to mp_mul can end up back + * in this function if the a0, a1, b0, or b1 are above the threshold. + * This is known as divide-and-conquer and leads to the famous + * O(N**lg(3)) or O(N**1.584) work which is asymptopically lower than + * the standard O(N**2) that the baseline/comba methods use. + * Generally though the overhead of this method doesn't pay off + * until a certain size (N ~ 80) is reached. + */ +int mp_karatsuba_mul (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int x0, x1, y0, y1, t1, x0y0, x1y1; + int B, err; + + /* default the return code to an error */ + err = MP_MEM; + + /* min # of digits */ + B = MIN (a->used, b->used); + + /* now divide in two */ + B = B >> 1; + + /* init copy all the temps */ + if (mp_init_size (&x0, B) != MP_OKAY) + goto ERR; + if (mp_init_size (&x1, a->used - B) != MP_OKAY) + goto X0; + if (mp_init_size (&y0, B) != MP_OKAY) + goto X1; + if (mp_init_size (&y1, b->used - B) != MP_OKAY) + goto Y0; + + /* init temps */ + if (mp_init_size (&t1, B * 2) != MP_OKAY) + goto Y1; + if (mp_init_size (&x0y0, B * 2) != MP_OKAY) + goto T1; + if (mp_init_size (&x1y1, B * 2) != MP_OKAY) + goto X0Y0; + + /* now shift the digits */ + x0.used = y0.used = B; + x1.used = a->used - B; + y1.used = b->used - B; + + { + int x; + mp_digit *tmpa, *tmpb, *tmpx, *tmpy; + + /* we copy the digits directly instead of using higher level functions + * since we also need to shift the digits + */ + tmpa = a->dp; + tmpb = b->dp; + + tmpx = x0.dp; + tmpy = y0.dp; + for (x = 0; x < B; x++) { + *tmpx++ = *tmpa++; + *tmpy++ = *tmpb++; + } + + tmpx = x1.dp; + for (x = B; x < a->used; x++) { + *tmpx++ = *tmpa++; + } + + tmpy = y1.dp; + for (x = B; x < b->used; x++) { + *tmpy++ = *tmpb++; + } + } + + /* only need to clamp the lower words since by definition the + * upper words x1/y1 must have a known number of digits + */ + mp_clamp (&x0); + mp_clamp (&y0); + + /* now calc the products x0y0 and x1y1 */ + /* after this x0 is no longer required, free temp [x0==t2]! */ + if (mp_mul (&x0, &y0, &x0y0) != MP_OKAY) + goto X1Y1; /* x0y0 = x0*y0 */ + if (mp_mul (&x1, &y1, &x1y1) != MP_OKAY) + goto X1Y1; /* x1y1 = x1*y1 */ + + /* now calc x1+x0 and y1+y0 */ + if (s_mp_add (&x1, &x0, &t1) != MP_OKAY) + goto X1Y1; /* t1 = x1 - x0 */ + if (s_mp_add (&y1, &y0, &x0) != MP_OKAY) + goto X1Y1; /* t2 = y1 - y0 */ + if (mp_mul (&t1, &x0, &t1) != MP_OKAY) + goto X1Y1; /* t1 = (x1 + x0) * (y1 + y0) */ + + /* add x0y0 */ + if (mp_add (&x0y0, &x1y1, &x0) != MP_OKAY) + goto X1Y1; /* t2 = x0y0 + x1y1 */ + if (s_mp_sub (&t1, &x0, &t1) != MP_OKAY) + goto X1Y1; /* t1 = (x1+x0)*(y1+y0) - (x1y1 + x0y0) */ + + /* shift by B */ + if (mp_lshd (&t1, B) != MP_OKAY) + goto X1Y1; /* t1 = (x0y0 + x1y1 - (x1-x0)*(y1-y0))< +#ifdef BN_MP_KARATSUBA_SQR_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* Karatsuba squaring, computes b = a*a using three + * half size squarings + * + * See comments of karatsuba_mul for details. It + * is essentially the same algorithm but merely + * tuned to perform recursive squarings. + */ +int mp_karatsuba_sqr (mp_int * a, mp_int * b) +{ + mp_int x0, x1, t1, t2, x0x0, x1x1; + int B, err; + + err = MP_MEM; + + /* min # of digits */ + B = a->used; + + /* now divide in two */ + B = B >> 1; + + /* init copy all the temps */ + if (mp_init_size (&x0, B) != MP_OKAY) + goto ERR; + if (mp_init_size (&x1, a->used - B) != MP_OKAY) + goto X0; + + /* init temps */ + if (mp_init_size (&t1, a->used * 2) != MP_OKAY) + goto X1; + if (mp_init_size (&t2, a->used * 2) != MP_OKAY) + goto T1; + if (mp_init_size (&x0x0, B * 2) != MP_OKAY) + goto T2; + if (mp_init_size (&x1x1, (a->used - B) * 2) != MP_OKAY) + goto X0X0; + + { + int x; + mp_digit *dst, *src; + + src = a->dp; + + /* now shift the digits */ + dst = x0.dp; + for (x = 0; x < B; x++) { + *dst++ = *src++; + } + + dst = x1.dp; + for (x = B; x < a->used; x++) { + *dst++ = *src++; + } + } + + x0.used = B; + x1.used = a->used - B; + + mp_clamp (&x0); + + /* now calc the products x0*x0 and x1*x1 */ + if (mp_sqr (&x0, &x0x0) != MP_OKAY) + goto X1X1; /* x0x0 = x0*x0 */ + if (mp_sqr (&x1, &x1x1) != MP_OKAY) + goto X1X1; /* x1x1 = x1*x1 */ + + /* now calc (x1+x0)**2 */ + if (s_mp_add (&x1, &x0, &t1) != MP_OKAY) + goto X1X1; /* t1 = x1 - x0 */ + if (mp_sqr (&t1, &t1) != MP_OKAY) + goto X1X1; /* t1 = (x1 - x0) * (x1 - x0) */ + + /* add x0y0 */ + if (s_mp_add (&x0x0, &x1x1, &t2) != MP_OKAY) + goto X1X1; /* t2 = x0x0 + x1x1 */ + if (s_mp_sub (&t1, &t2, &t1) != MP_OKAY) + goto X1X1; /* t1 = (x1+x0)**2 - (x0x0 + x1x1) */ + + /* shift by B */ + if (mp_lshd (&t1, B) != MP_OKAY) + goto X1X1; /* t1 = (x0x0 + x1x1 - (x1-x0)*(x1-x0))< +#ifdef BN_MP_LCM_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* computes least common multiple as |a*b|/(a, b) */ +int mp_lcm (mp_int * a, mp_int * b, mp_int * c) +{ + int res; + mp_int t1, t2; + + + if ((res = mp_init_multi (&t1, &t2, NULL)) != MP_OKAY) { + return res; + } + + /* t1 = get the GCD of the two inputs */ + if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) { + goto LBL_T; + } + + /* divide the smallest by the GCD */ + if (mp_cmp_mag(a, b) == MP_LT) { + /* store quotient in t2 such that t2 * b is the LCM */ + if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) { + goto LBL_T; + } + res = mp_mul(b, &t2, c); + } else { + /* store quotient in t2 such that t2 * a is the LCM */ + if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) { + goto LBL_T; + } + res = mp_mul(a, &t2, c); + } + + /* fix the sign to positive */ + c->sign = MP_ZPOS; + +LBL_T: + mp_clear_multi (&t1, &t2, NULL); + return res; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_lshd.c b/src/ltm/bn_mp_lshd.c new file mode 100644 index 0000000..f6f800f --- /dev/null +++ b/src/ltm/bn_mp_lshd.c @@ -0,0 +1,67 @@ +#include +#ifdef BN_MP_LSHD_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* shift left a certain amount of digits */ +int mp_lshd (mp_int * a, int b) +{ + int x, res; + + /* if its less than zero return */ + if (b <= 0) { + return MP_OKAY; + } + + /* grow to fit the new digits */ + if (a->alloc < (a->used + b)) { + if ((res = mp_grow (a, a->used + b)) != MP_OKAY) { + return res; + } + } + + { + mp_digit *top, *bottom; + + /* increment the used by the shift amount then copy upwards */ + a->used += b; + + /* top */ + top = a->dp + a->used - 1; + + /* base */ + bottom = (a->dp + a->used - 1) - b; + + /* much like mp_rshd this is implemented using a sliding window + * except the window goes the otherway around. Copying from + * the bottom to the top. see bn_mp_rshd.c for more info. + */ + for (x = a->used - 1; x >= b; x--) { + *top-- = *bottom--; + } + + /* zero the lower digits */ + top = a->dp; + for (x = 0; x < b; x++) { + *top++ = 0; + } + } + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_mod.c b/src/ltm/bn_mp_mod.c new file mode 100644 index 0000000..b67467d --- /dev/null +++ b/src/ltm/bn_mp_mod.c @@ -0,0 +1,48 @@ +#include +#ifdef BN_MP_MOD_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* c = a mod b, 0 <= c < b if b > 0, b < c <= 0 if b < 0 */ +int +mp_mod (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int t; + int res; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + + if ((mp_iszero(&t) != MP_NO) || (t.sign == b->sign)) { + res = MP_OKAY; + mp_exch (&t, c); + } else { + res = mp_add (b, &t, c); + } + + mp_clear (&t); + return res; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_mod_2d.c b/src/ltm/bn_mp_mod_2d.c new file mode 100644 index 0000000..926f810 --- /dev/null +++ b/src/ltm/bn_mp_mod_2d.c @@ -0,0 +1,55 @@ +#include +#ifdef BN_MP_MOD_2D_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* calc a value mod 2**b */ +int +mp_mod_2d (mp_int * a, int b, mp_int * c) +{ + int x, res; + + /* if b is <= 0 then zero the int */ + if (b <= 0) { + mp_zero (c); + return MP_OKAY; + } + + /* if the modulus is larger than the value than return */ + if (b >= (int) (a->used * DIGIT_BIT)) { + res = mp_copy (a, c); + return res; + } + + /* copy */ + if ((res = mp_copy (a, c)) != MP_OKAY) { + return res; + } + + /* zero digits above the last digit of the modulus */ + for (x = (b / DIGIT_BIT) + (((b % DIGIT_BIT) == 0) ? 0 : 1); x < c->used; x++) { + c->dp[x] = 0; + } + /* clear the digit that is not completely outside/inside the modulus */ + c->dp[b / DIGIT_BIT] &= + (mp_digit) ((((mp_digit) 1) << (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1)); + mp_clamp (c); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_mod_d.c b/src/ltm/bn_mp_mod_d.c new file mode 100644 index 0000000..d8722f0 --- /dev/null +++ b/src/ltm/bn_mp_mod_d.c @@ -0,0 +1,27 @@ +#include +#ifdef BN_MP_MOD_D_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, tstdenis82@gmail.com, http://libtom.org + */ + +int +mp_mod_d (mp_int * a, mp_digit b, mp_digit * c) +{ + return mp_div_d(a, b, NULL, c); +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_montgomery_calc_normalization.c b/src/ltm/bn_mp_montgomery_calc_normalization.c new file mode 100644 index 0000000..ea87cbd --- /dev/null +++ b/src/ltm/bn_mp_montgomery_calc_normalization.c @@ -0,0 +1,59 @@ +#include +#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* + * shifts with subtractions when the result is greater than b. + * + * The method is slightly modified to shift B unconditionally upto just under + * the leading bit of b. This saves alot of multiple precision shifting. + */ +int mp_montgomery_calc_normalization (mp_int * a, mp_int * b) +{ + int x, bits, res; + + /* 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; + } + } else { + mp_set(a, 1); + bits = 1; + } + + + /* now compute C = A * B mod b */ + for (x = bits - 1; x < (int)DIGIT_BIT; x++) { + if ((res = mp_mul_2 (a, a)) != MP_OKAY) { + return res; + } + if (mp_cmp_mag (a, b) != MP_LT) { + if ((res = s_mp_sub (a, b, a)) != MP_OKAY) { + return res; + } + } + } + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_montgomery_reduce.c b/src/ltm/bn_mp_montgomery_reduce.c new file mode 100644 index 0000000..af2cc58 --- /dev/null +++ b/src/ltm/bn_mp_montgomery_reduce.c @@ -0,0 +1,118 @@ +#include +#ifdef BN_MP_MONTGOMERY_REDUCE_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* computes xR**-1 == x (mod N) via Montgomery Reduction */ +int +mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) +{ + int ix, res, digs; + mp_digit mu; + + /* can the fast reduction [comba] method be used? + * + * Note that unlike in mul you're safely allowed *less* + * than the available columns [255 per default] since carries + * are fixed up in the inner loop. + */ + digs = (n->used * 2) + 1; + if ((digs < MP_WARRAY) && + (n->used < + (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) { + return fast_mp_montgomery_reduce (x, n, rho); + } + + /* grow the input as required */ + if (x->alloc < digs) { + if ((res = mp_grow (x, digs)) != MP_OKAY) { + return res; + } + } + x->used = digs; + + for (ix = 0; ix < n->used; ix++) { + /* mu = ai * rho mod b + * + * The value of rho must be precalculated via + * montgomery_setup() such that + * it equals -1/n0 mod b this allows the + * following inner loop to reduce the + * input one digit at a time + */ + mu = (mp_digit) (((mp_word)x->dp[ix] * (mp_word)rho) & MP_MASK); + + /* a = a + mu * m * b**i */ + { + int iy; + mp_digit *tmpn, *tmpx, u; + mp_word r; + + /* alias for digits of the modulus */ + tmpn = n->dp; + + /* alias for the digits of x [the input] */ + tmpx = x->dp + ix; + + /* set the carry to zero */ + u = 0; + + /* Multiply and add in place */ + for (iy = 0; iy < n->used; iy++) { + /* compute product and sum */ + r = ((mp_word)mu * (mp_word)*tmpn++) + + (mp_word) u + (mp_word) *tmpx; + + /* get carry */ + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + + /* fix digit */ + *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK)); + } + /* At this point the ix'th digit of x should be zero */ + + + /* propagate carries upwards as required*/ + while (u != 0) { + *tmpx += u; + u = *tmpx >> DIGIT_BIT; + *tmpx++ &= MP_MASK; + } + } + } + + /* at this point the n.used'th least + * significant digits of x are all zero + * which means we can shift x to the + * right by n.used digits and the + * residue is unchanged. + */ + + /* x = x/b**n.used */ + mp_clamp(x); + mp_rshd (x, n->used); + + /* if x >= n then x = x - n */ + if (mp_cmp_mag (x, n) != MP_LT) { + return s_mp_sub (x, n, x); + } + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_montgomery_setup.c b/src/ltm/bn_mp_montgomery_setup.c new file mode 100644 index 0000000..264a2bd --- /dev/null +++ b/src/ltm/bn_mp_montgomery_setup.c @@ -0,0 +1,59 @@ +#include +#ifdef BN_MP_MONTGOMERY_SETUP_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* setups the montgomery reduction stuff */ +int +mp_montgomery_setup (mp_int * n, mp_digit * rho) +{ + mp_digit x, b; + +/* fast inversion mod 2**k + * + * Based on the fact that + * + * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n) + * => 2*X*A - X*X*A*A = 1 + * => 2*(1) - (1) = 1 + */ + b = n->dp[0]; + + if ((b & 1) == 0) { + return MP_VAL; + } + + x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ + x *= 2 - (b * x); /* here x*a==1 mod 2**8 */ +#if !defined(MP_8BIT) + x *= 2 - (b * x); /* here x*a==1 mod 2**16 */ +#endif +#if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT)) + x *= 2 - (b * x); /* here x*a==1 mod 2**32 */ +#endif +#ifdef MP_64BIT + x *= 2 - (b * x); /* here x*a==1 mod 2**64 */ +#endif + + /* rho = -1/m mod b */ + *rho = (mp_digit)(((mp_word)1 << ((mp_word) DIGIT_BIT)) - x) & MP_MASK; + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_mul.c b/src/ltm/bn_mp_mul.c new file mode 100644 index 0000000..ea53d5e --- /dev/null +++ b/src/ltm/bn_mp_mul.c @@ -0,0 +1,67 @@ +#include +#ifdef BN_MP_MUL_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* high level multiplication (handles sign) */ +int mp_mul (mp_int * a, mp_int * b, mp_int * c) +{ + int res, neg; + neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; + + /* use Toom-Cook? */ +#ifdef BN_MP_TOOM_MUL_C + if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) { + res = mp_toom_mul(a, b, c); + } else +#endif +#ifdef BN_MP_KARATSUBA_MUL_C + /* use Karatsuba? */ + if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) { + res = mp_karatsuba_mul (a, b, c); + } else +#endif + { + /* can we use the fast multiplier? + * + * The fast multiplier can be used if the output will + * have less than MP_WARRAY digits and the number of + * digits won't affect carry propagation + */ + int digs = a->used + b->used + 1; + +#ifdef BN_FAST_S_MP_MUL_DIGS_C + if ((digs < MP_WARRAY) && + (MIN(a->used, b->used) <= + (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) { + res = fast_s_mp_mul_digs (a, b, c, digs); + } else +#endif + { +#ifdef BN_S_MP_MUL_DIGS_C + res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */ +#else + res = MP_VAL; +#endif + } + } + c->sign = (c->used > 0) ? neg : MP_ZPOS; + return res; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_mul_2.c b/src/ltm/bn_mp_mul_2.c new file mode 100644 index 0000000..9c72c7f --- /dev/null +++ b/src/ltm/bn_mp_mul_2.c @@ -0,0 +1,82 @@ +#include +#ifdef BN_MP_MUL_2_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* b = a*2 */ +int mp_mul_2(mp_int * a, mp_int * b) +{ + int x, res, oldused; + + /* grow to accomodate result */ + if (b->alloc < (a->used + 1)) { + if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) { + return res; + } + } + + oldused = b->used; + b->used = a->used; + + { + mp_digit r, rr, *tmpa, *tmpb; + + /* alias for source */ + tmpa = a->dp; + + /* alias for dest */ + tmpb = b->dp; + + /* carry */ + r = 0; + for (x = 0; x < a->used; x++) { + + /* get what will be the *next* carry bit from the + * MSB of the current digit + */ + rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1)); + + /* now shift up this digit, add in the carry [from the previous] */ + *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK; + + /* copy the carry that would be from the source + * digit into the next iteration + */ + r = rr; + } + + /* new leading digit? */ + if (r != 0) { + /* add a MSB which is always 1 at this point */ + *tmpb = 1; + ++(b->used); + } + + /* now zero any excess digits on the destination + * that we didn't write to + */ + tmpb = b->dp + b->used; + for (x = b->used; x < oldused; x++) { + *tmpb++ = 0; + } + } + b->sign = a->sign; + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_mul_2d.c b/src/ltm/bn_mp_mul_2d.c new file mode 100644 index 0000000..9967e46 --- /dev/null +++ b/src/ltm/bn_mp_mul_2d.c @@ -0,0 +1,85 @@ +#include +#ifdef BN_MP_MUL_2D_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* shift left by a certain bit count */ +int mp_mul_2d (mp_int * a, int b, mp_int * c) +{ + mp_digit d; + int res; + + /* copy */ + if (a != c) { + if ((res = mp_copy (a, c)) != MP_OKAY) { + return res; + } + } + + if (c->alloc < (int)(c->used + (b / DIGIT_BIT) + 1)) { + if ((res = mp_grow (c, c->used + (b / DIGIT_BIT) + 1)) != MP_OKAY) { + return res; + } + } + + /* shift by as many digits in the bit count */ + if (b >= (int)DIGIT_BIT) { + if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) { + return res; + } + } + + /* shift any bit count < DIGIT_BIT */ + d = (mp_digit) (b % DIGIT_BIT); + if (d != 0) { + mp_digit *tmpc, shift, mask, r, rr; + int x; + + /* bitmask for carries */ + mask = (((mp_digit)1) << d) - 1; + + /* shift for msbs */ + shift = DIGIT_BIT - d; + + /* alias */ + tmpc = c->dp; + + /* carry */ + r = 0; + for (x = 0; x < c->used; x++) { + /* get the higher bits of the current word */ + rr = (*tmpc >> shift) & mask; + + /* shift the current word and OR in the carry */ + *tmpc = ((*tmpc << d) | r) & MP_MASK; + ++tmpc; + + /* set the carry to the carry bits of the current word */ + r = rr; + } + + /* set final carry */ + if (r != 0) { + c->dp[(c->used)++] = r; + } + } + mp_clamp (c); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_mul_d.c b/src/ltm/bn_mp_mul_d.c new file mode 100644 index 0000000..e77da5d --- /dev/null +++ b/src/ltm/bn_mp_mul_d.c @@ -0,0 +1,79 @@ +#include +#ifdef BN_MP_MUL_D_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* multiply by a digit */ +int +mp_mul_d (mp_int * a, mp_digit b, mp_int * c) +{ + mp_digit u, *tmpa, *tmpc; + mp_word r; + int ix, res, olduse; + + /* make sure c is big enough to hold a*b */ + if (c->alloc < (a->used + 1)) { + if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) { + return res; + } + } + + /* get the original destinations used count */ + olduse = c->used; + + /* set the sign */ + c->sign = a->sign; + + /* alias for a->dp [source] */ + tmpa = a->dp; + + /* alias for c->dp [dest] */ + tmpc = c->dp; + + /* zero carry */ + u = 0; + + /* compute columns */ + for (ix = 0; ix < a->used; ix++) { + /* compute product and carry sum for this term */ + r = (mp_word)u + ((mp_word)*tmpa++ * (mp_word)b); + + /* mask off higher bits to get a single digit */ + *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* send carry into next iteration */ + u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); + } + + /* store final carry [if any] and increment ix offset */ + *tmpc++ = u; + ++ix; + + /* now zero digits above the top */ + while (ix++ < olduse) { + *tmpc++ = 0; + } + + /* set used count */ + c->used = a->used + 1; + mp_clamp(c); + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_mulmod.c b/src/ltm/bn_mp_mulmod.c new file mode 100644 index 0000000..5ea88ef --- /dev/null +++ b/src/ltm/bn_mp_mulmod.c @@ -0,0 +1,40 @@ +#include +#ifdef BN_MP_MULMOD_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* d = a * b (mod c) */ +int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + int res; + mp_int t; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_mul (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + res = mp_mod (&t, c, d); + mp_clear (&t); + return res; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_n_root.c b/src/ltm/bn_mp_n_root.c new file mode 100644 index 0000000..a14ee67 --- /dev/null +++ b/src/ltm/bn_mp_n_root.c @@ -0,0 +1,30 @@ +#include +#ifdef BN_MP_N_ROOT_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* wrapper function for mp_n_root_ex() + * computes c = (a)**(1/b) such that (c)**b <= a and (c+1)**b > a + */ +int mp_n_root (mp_int * a, mp_digit b, mp_int * c) +{ + return mp_n_root_ex(a, b, c, 0); +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_n_root_ex.c b/src/ltm/bn_mp_n_root_ex.c new file mode 100644 index 0000000..79d1dfb --- /dev/null +++ b/src/ltm/bn_mp_n_root_ex.c @@ -0,0 +1,132 @@ +#include +#ifdef BN_MP_N_ROOT_EX_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tstdenis82@gmail.com, http://libtom.org + */ + +/* find the n'th root of an integer + * + * Result found such that (c)**b <= a and (c+1)**b > a + * + * This algorithm uses Newton's approximation + * x[i+1] = x[i] - f(x[i])/f'(x[i]) + * which will find the root in log(N) time where + * each step involves a fair bit. This is not meant to + * find huge roots [square and cube, etc]. + */ +int mp_n_root_ex (mp_int * a, mp_digit b, mp_int * c, int fast) +{ + mp_int t1, t2, t3; + int res, neg; + + /* input must be positive if b is even */ + if (((b & 1) == 0) && (a->sign == MP_NEG)) { + return MP_VAL; + } + + if ((res = mp_init (&t1)) != MP_OKAY) { + return res; + } + + if ((res = mp_init (&t2)) != MP_OKAY) { + goto LBL_T1; + } + + if ((res = mp_init (&t3)) != MP_OKAY) { + goto LBL_T2; + } + + /* if a is negative fudge the sign but keep track */ + neg = a->sign; + a->sign = MP_ZPOS; + + /* t2 = 2 */ + mp_set (&t2, 2); + + do { + /* t1 = t2 */ + if ((res = mp_copy (&t2, &t1)) != MP_OKAY) { + goto LBL_T3; + } + + /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */ + + /* t3 = t1**(b-1) */ + if ((res = mp_expt_d_ex (&t1, b - 1, &t3, fast)) != MP_OKAY) { + goto LBL_T3; + } + + /* numerator */ + /* t2 = t1**b */ + if ((res = mp_mul (&t3, &t1, &t2)) != MP_OKAY) { + goto LBL_T3; + } + + /* t2 = t1**b - a */ + if ((res = mp_sub (&t2, a, &t2)) != MP_OKAY) { + goto LBL_T3; + } + + /* denominator */ + /* t3 = t1**(b-1) * b */ + if ((res = mp_mul_d (&t3, b, &t3)) != MP_OKAY) { + goto LBL_T3; + } + + /* t3 = (t1**b - a)/(b * t1**(b-1)) */ + if ((res = mp_div (&t2, &t3, &t3, NULL)) != MP_OKAY) { + goto LBL_T3; + } + + if ((res = mp_sub (&t1, &t3, &t2)) != MP_OKAY) { + goto LBL_T3; + } + } while (mp_cmp (&t1, &t2) != MP_EQ); + + /* result can be off by a few so check */ + for (;;) { + if ((res = mp_expt_d_ex (&t1, b, &t2, fast)) != MP_OKAY) { + goto LBL_T3; + } + + if (mp_cmp (&t2, a) == MP_GT) { + if ((res = mp_sub_d (&t1, 1, &t1)) != MP_OKAY) { + goto LBL_T3; + } + } else { + break; + } + } + + /* reset the sign of a first */ + a->sign = neg; + + /* set the result */ + mp_exch (&t1, c); + + /* set the sign of the result */ + c->sign = neg; + + res = MP_OKAY; + +LBL_T3:mp_clear (&t3); +LBL_T2:mp_clear (&t2); +LBL_T1:mp_clear (&t1); + return res; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_neg.c b/src/ltm/bn_mp_neg.c new file mode 100644 index 0000000..ea32e46 --- /dev/null +++ b/src/ltm/bn_mp_neg.c @@ -0,0 +1,40 @@ +#include +#ifdef BN_MP_NEG_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* b = -a */ +int mp_neg (mp_int * a, mp_int * b) +{ + int 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 + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_or.c b/src/ltm/bn_mp_or.c new file mode 100644 index 0000000..b7f2e4f --- /dev/null +++ b/src/ltm/bn_mp_or.c @@ -0,0 +1,50 @@ +#include +#ifdef BN_MP_OR_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* OR two ints together */ +int mp_or (mp_int * a, mp_int * b, mp_int * c) +{ + int res, ix, px; + mp_int t, *x; + + if (a->used > b->used) { + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + px = b->used; + x = b; + } else { + if ((res = mp_init_copy (&t, b)) != MP_OKAY) { + return res; + } + px = a->used; + x = a; + } + + for (ix = 0; ix < px; ix++) { + t.dp[ix] |= x->dp[ix]; + } + mp_clamp (&t); + mp_exch (c, &t); + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_prime_fermat.c b/src/ltm/bn_mp_prime_fermat.c new file mode 100644 index 0000000..9dc9e85 --- /dev/null +++ b/src/ltm/bn_mp_prime_fermat.c @@ -0,0 +1,62 @@ +#include +#ifdef BN_MP_PRIME_FERMAT_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* performs one Fermat test. + * + * If "a" were prime then b**a == b (mod a) since the order of + * the multiplicative sub-group would be phi(a) = a-1. That means + * it would be the same as b**(a mod (a-1)) == b**1 == b (mod a). + * + * Sets result to 1 if the congruence holds, or zero otherwise. + */ +int mp_prime_fermat (mp_int * a, mp_int * b, int *result) +{ + mp_int t; + int err; + + /* default to composite */ + *result = MP_NO; + + /* ensure b > 1 */ + if (mp_cmp_d(b, 1) != MP_GT) { + return MP_VAL; + } + + /* init t */ + if ((err = mp_init (&t)) != MP_OKAY) { + return err; + } + + /* compute t = b**a mod a */ + if ((err = mp_exptmod (b, a, a, &t)) != MP_OKAY) { + goto LBL_T; + } + + /* is it equal to b? */ + if (mp_cmp (&t, b) == MP_EQ) { + *result = MP_YES; + } + + err = MP_OKAY; +LBL_T:mp_clear (&t); + return err; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_prime_is_divisible.c b/src/ltm/bn_mp_prime_is_divisible.c new file mode 100644 index 0000000..5854f08 --- /dev/null +++ b/src/ltm/bn_mp_prime_is_divisible.c @@ -0,0 +1,50 @@ +#include +#ifdef BN_MP_PRIME_IS_DIVISIBLE_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* determines if an integers is divisible by one + * of the first PRIME_SIZE primes or not + * + * sets result to 0 if not, 1 if yes + */ +int mp_prime_is_divisible (mp_int * a, int *result) +{ + int err, ix; + mp_digit res; + + /* default to not */ + *result = MP_NO; + + for (ix = 0; ix < PRIME_SIZE; ix++) { + /* what is a mod LBL_prime_tab[ix] */ + if ((err = mp_mod_d (a, ltm_prime_tab[ix], &res)) != MP_OKAY) { + return err; + } + + /* is the residue zero? */ + if (res == 0) { + *result = MP_YES; + return MP_OKAY; + } + } + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_prime_is_prime.c b/src/ltm/bn_mp_prime_is_prime.c new file mode 100644 index 0000000..be5ebe4 --- /dev/null +++ b/src/ltm/bn_mp_prime_is_prime.c @@ -0,0 +1,83 @@ +#include +#ifdef BN_MP_PRIME_IS_PRIME_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* performs a variable number of rounds of Miller-Rabin + * + * Probability of error after t rounds is no more than + + * + * Sets result to 1 if probably prime, 0 otherwise + */ +int mp_prime_is_prime (mp_int * a, int t, int *result) +{ + mp_int b; + int ix, err, res; + + /* default to no */ + *result = MP_NO; + + /* valid value of t? */ + if ((t <= 0) || (t > PRIME_SIZE)) { + return MP_VAL; + } + + /* is the input equal to one of the primes in the table? */ + for (ix = 0; ix < PRIME_SIZE; ix++) { + if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) { + *result = 1; + return MP_OKAY; + } + } + + /* first perform trial division */ + if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) { + return err; + } + + /* return if it was trivially divisible */ + if (res == MP_YES) { + return MP_OKAY; + } + + /* now perform the miller-rabin rounds */ + if ((err = mp_init (&b)) != MP_OKAY) { + return err; + } + + for (ix = 0; ix < t; ix++) { + /* set the prime */ + mp_set (&b, ltm_prime_tab[ix]); + + if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) { + goto LBL_B; + } + + if (res == MP_NO) { + goto LBL_B; + } + } + + /* passed the test */ + *result = MP_YES; +LBL_B:mp_clear (&b); + return err; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_prime_miller_rabin.c b/src/ltm/bn_mp_prime_miller_rabin.c new file mode 100644 index 0000000..7b5c8d2 --- /dev/null +++ b/src/ltm/bn_mp_prime_miller_rabin.c @@ -0,0 +1,103 @@ +#include +#ifdef BN_MP_PRIME_MILLER_RABIN_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* Miller-Rabin test of "a" to the base of "b" as described in + * HAC pp. 139 Algorithm 4.24 + * + * Sets result to 0 if definitely composite or 1 if probably prime. + * Randomly the chance of error is no more than 1/4 and often + * very much lower. + */ +int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result) +{ + mp_int n1, y, r; + int s, j, err; + + /* default */ + *result = MP_NO; + + /* ensure b > 1 */ + if (mp_cmp_d(b, 1) != MP_GT) { + return MP_VAL; + } + + /* get n1 = a - 1 */ + if ((err = mp_init_copy (&n1, a)) != MP_OKAY) { + return err; + } + if ((err = mp_sub_d (&n1, 1, &n1)) != MP_OKAY) { + goto LBL_N1; + } + + /* set 2**s * r = n1 */ + if ((err = mp_init_copy (&r, &n1)) != MP_OKAY) { + goto LBL_N1; + } + + /* count the number of least significant bits + * which are zero + */ + s = mp_cnt_lsb(&r); + + /* now divide n - 1 by 2**s */ + if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) { + goto LBL_R; + } + + /* compute y = b**r mod a */ + if ((err = mp_init (&y)) != MP_OKAY) { + goto LBL_R; + } + if ((err = mp_exptmod (b, &r, a, &y)) != MP_OKAY) { + goto LBL_Y; + } + + /* if y != 1 and y != n1 do */ + if ((mp_cmp_d (&y, 1) != MP_EQ) && (mp_cmp (&y, &n1) != MP_EQ)) { + j = 1; + /* while j <= s-1 and y != n1 */ + while ((j <= (s - 1)) && (mp_cmp (&y, &n1) != MP_EQ)) { + if ((err = mp_sqrmod (&y, a, &y)) != MP_OKAY) { + goto LBL_Y; + } + + /* if y == 1 then composite */ + if (mp_cmp_d (&y, 1) == MP_EQ) { + goto LBL_Y; + } + + ++j; + } + + /* if y != n1 then composite */ + if (mp_cmp (&y, &n1) != MP_EQ) { + goto LBL_Y; + } + } + + /* probably prime now */ + *result = MP_YES; +LBL_Y:mp_clear (&y); +LBL_R:mp_clear (&r); +LBL_N1:mp_clear (&n1); + return err; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_prime_next_prime.c b/src/ltm/bn_mp_prime_next_prime.c new file mode 100644 index 0000000..9951dc3 --- /dev/null +++ b/src/ltm/bn_mp_prime_next_prime.c @@ -0,0 +1,170 @@ +#include +#ifdef BN_MP_PRIME_NEXT_PRIME_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* finds the next prime after the number "a" using "t" trials + * of Miller-Rabin. + * + * bbs_style = 1 means the prime must be congruent to 3 mod 4 + */ +int mp_prime_next_prime(mp_int *a, int t, int bbs_style) +{ + int err, res = MP_NO, x, y; + mp_digit res_tab[PRIME_SIZE], step, kstep; + mp_int b; + + /* ensure t is valid */ + if ((t <= 0) || (t > PRIME_SIZE)) { + return MP_VAL; + } + + /* force positive */ + a->sign = MP_ZPOS; + + /* simple algo if a is less than the largest prime in the table */ + if (mp_cmp_d(a, ltm_prime_tab[PRIME_SIZE-1]) == MP_LT) { + /* find which prime it is bigger than */ + for (x = PRIME_SIZE - 2; x >= 0; x--) { + if (mp_cmp_d(a, ltm_prime_tab[x]) != MP_LT) { + if (bbs_style == 1) { + /* ok we found a prime smaller or + * equal [so the next is larger] + * + * however, the prime must be + * congruent to 3 mod 4 + */ + if ((ltm_prime_tab[x + 1] & 3) != 3) { + /* scan upwards for a prime congruent to 3 mod 4 */ + for (y = x + 1; y < PRIME_SIZE; y++) { + if ((ltm_prime_tab[y] & 3) == 3) { + mp_set(a, ltm_prime_tab[y]); + return MP_OKAY; + } + } + } + } else { + mp_set(a, ltm_prime_tab[x + 1]); + return MP_OKAY; + } + } + } + /* at this point a maybe 1 */ + if (mp_cmp_d(a, 1) == MP_EQ) { + mp_set(a, 2); + return MP_OKAY; + } + /* fall through to the sieve */ + } + + /* generate a prime congruent to 3 mod 4 or 1/3 mod 4? */ + if (bbs_style == 1) { + kstep = 4; + } else { + kstep = 2; + } + + /* at this point we will use a combination of a sieve and Miller-Rabin */ + + if (bbs_style == 1) { + /* if a mod 4 != 3 subtract the correct value to make it so */ + if ((a->dp[0] & 3) != 3) { + if ((err = mp_sub_d(a, (a->dp[0] & 3) + 1, a)) != MP_OKAY) { return err; }; + } + } else { + if (mp_iseven(a) == MP_YES) { + /* force odd */ + if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { + return err; + } + } + } + + /* generate the restable */ + for (x = 1; x < PRIME_SIZE; x++) { + if ((err = mp_mod_d(a, ltm_prime_tab[x], res_tab + x)) != MP_OKAY) { + return err; + } + } + + /* init temp used for Miller-Rabin Testing */ + if ((err = mp_init(&b)) != MP_OKAY) { + return err; + } + + for (;;) { + /* skip to the next non-trivially divisible candidate */ + step = 0; + do { + /* y == 1 if any residue was zero [e.g. cannot be prime] */ + y = 0; + + /* increase step to next candidate */ + step += kstep; + + /* compute the new residue without using division */ + for (x = 1; x < PRIME_SIZE; x++) { + /* add the step to each residue */ + res_tab[x] += kstep; + + /* subtract the modulus [instead of using division] */ + if (res_tab[x] >= ltm_prime_tab[x]) { + res_tab[x] -= ltm_prime_tab[x]; + } + + /* set flag if zero */ + if (res_tab[x] == 0) { + y = 1; + } + } + } while ((y == 1) && (step < ((((mp_digit)1) << DIGIT_BIT) - kstep))); + + /* add the step */ + if ((err = mp_add_d(a, step, a)) != MP_OKAY) { + goto LBL_ERR; + } + + /* if didn't pass sieve and step == MAX then skip test */ + if ((y == 1) && (step >= ((((mp_digit)1) << DIGIT_BIT) - kstep))) { + continue; + } + + /* is this prime? */ + for (x = 0; x < t; x++) { + mp_set(&b, ltm_prime_tab[x]); + if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) { + goto LBL_ERR; + } + if (res == MP_NO) { + break; + } + } + + if (res == MP_YES) { + break; + } + } + + err = MP_OKAY; +LBL_ERR: + mp_clear(&b); + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_prime_rabin_miller_trials.c b/src/ltm/bn_mp_prime_rabin_miller_trials.c new file mode 100644 index 0000000..bca4229 --- /dev/null +++ b/src/ltm/bn_mp_prime_rabin_miller_trials.c @@ -0,0 +1,52 @@ +#include +#ifdef BN_MP_PRIME_RABIN_MILLER_TRIALS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * 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, tstdenis82@gmail.com, http://libtom.org + */ + + +static const struct { + int k, t; +} sizes[] = { +{ 128, 28 }, +{ 256, 16 }, +{ 384, 10 }, +{ 512, 7 }, +{ 640, 6 }, +{ 768, 5 }, +{ 896, 4 }, +{ 1024, 4 } +}; + +/* returns # of RM trials required for a given bit size */ +int mp_prime_rabin_miller_trials(int size) +{ + int x; + + for (x = 0; x < (int)(sizeof(sizes)/(sizeof(sizes[0]))); x++) { + if (sizes[x].k == size) { + return sizes[x].t; + } else if (sizes[x].k > size) { + return (x == 0) ? sizes[0].t : sizes[x - 1].t; + } + } + return sizes[x-1].t + 1; +} + + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_prime_random_ex.c b/src/ltm/bn_mp_prime_random_ex.c new file mode 100644 index 0000000..1efc4fc --- /dev/null +++ b/src/ltm/bn_mp_prime_random_ex.c @@ -0,0 +1,124 @@ +#include +#ifdef BN_MP_PRIME_RANDOM_EX_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tstdenis82@gmail.com, http://libtom.org + */ + +/* makes a truly random prime of a given size (bits), + * + * Flags are as follows: + * + * LTM_PRIME_BBS - make prime congruent to 3 mod 4 + * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS) + * LTM_PRIME_2MSB_ON - make the 2nd highest bit one + * + * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can + * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself + * so it can be NULL + * + */ + +/* This is possibly the mother of all prime generation functions, muahahahahaha! */ +int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat) +{ + unsigned char *tmp, maskAND, maskOR_msb, maskOR_lsb; + int res, err, bsize, maskOR_msb_offset; + + /* sanity check the input */ + if ((size <= 1) || (t <= 0)) { + return MP_VAL; + } + + /* LTM_PRIME_SAFE implies LTM_PRIME_BBS */ + if ((flags & LTM_PRIME_SAFE) != 0) { + flags |= LTM_PRIME_BBS; + } + + /* calc the byte size */ + bsize = (size>>3) + ((size&7)?1:0); + + /* we need a buffer of bsize bytes */ + tmp = OPT_CAST(unsigned char) XMALLOC(bsize); + if (tmp == NULL) { + return MP_MEM; + } + + /* calc the maskAND value for the MSbyte*/ + maskAND = ((size&7) == 0) ? 0xFF : (0xFF >> (8 - (size & 7))); + + /* calc the maskOR_msb */ + maskOR_msb = 0; + maskOR_msb_offset = ((size & 7) == 1) ? 1 : 0; + if ((flags & LTM_PRIME_2MSB_ON) != 0) { + maskOR_msb |= 0x80 >> ((9 - size) & 7); + } + + /* get the maskOR_lsb */ + maskOR_lsb = 1; + if ((flags & LTM_PRIME_BBS) != 0) { + maskOR_lsb |= 3; + } + + do { + /* read the bytes */ + if (cb(tmp, bsize, dat) != bsize) { + err = MP_VAL; + goto error; + } + + /* work over the MSbyte */ + tmp[0] &= maskAND; + tmp[0] |= 1 << ((size - 1) & 7); + + /* mix in the maskORs */ + tmp[maskOR_msb_offset] |= maskOR_msb; + tmp[bsize-1] |= maskOR_lsb; + + /* read it in */ + if ((err = mp_read_unsigned_bin(a, tmp, bsize)) != MP_OKAY) { goto error; } + + /* is it prime? */ + if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; } + if (res == MP_NO) { + continue; + } + + if ((flags & LTM_PRIME_SAFE) != 0) { + /* see if (a-1)/2 is prime */ + if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { goto error; } + if ((err = mp_div_2(a, a)) != MP_OKAY) { goto error; } + + /* is it prime? */ + if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; } + } + } while (res == MP_NO); + + if ((flags & LTM_PRIME_SAFE) != 0) { + /* restore a to the original value */ + if ((err = mp_mul_2(a, a)) != MP_OKAY) { goto error; } + if ((err = mp_add_d(a, 1, a)) != MP_OKAY) { goto error; } + } + + err = MP_OKAY; +error: + XFREE(tmp); + return err; +} + + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_radix_size.c b/src/ltm/bn_mp_radix_size.c new file mode 100644 index 0000000..e5d7772 --- /dev/null +++ b/src/ltm/bn_mp_radix_size.c @@ -0,0 +1,78 @@ +#include +#ifdef BN_MP_RADIX_SIZE_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* returns size of ASCII reprensentation */ +int mp_radix_size (mp_int * a, int radix, int *size) +{ + int res, digs; + mp_int t; + mp_digit d; + + *size = 0; + + /* make sure the radix is in range */ + if ((radix < 2) || (radix > 64)) { + return MP_VAL; + } + + if (mp_iszero(a) == MP_YES) { + *size = 2; + return MP_OKAY; + } + + /* special case for binary */ + if (radix == 2) { + *size = mp_count_bits (a) + ((a->sign == MP_NEG) ? 1 : 0) + 1; + return MP_OKAY; + } + + /* digs is the digit count */ + digs = 0; + + /* if it's negative add one for the sign */ + if (a->sign == MP_NEG) { + ++digs; + } + + /* 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) == MP_NO) { + if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { + mp_clear (&t); + return res; + } + ++digs; + } + mp_clear (&t); + + /* return digs + 1, the 1 is for the NULL byte that would be required. */ + *size = digs + 1; + return MP_OKAY; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_radix_smap.c b/src/ltm/bn_mp_radix_smap.c new file mode 100644 index 0000000..d1c75ad --- /dev/null +++ b/src/ltm/bn_mp_radix_smap.c @@ -0,0 +1,24 @@ +#include +#ifdef BN_MP_RADIX_SMAP_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* chars used in radix conversions */ +const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_rand.c b/src/ltm/bn_mp_rand.c new file mode 100644 index 0000000..4c9610d --- /dev/null +++ b/src/ltm/bn_mp_rand.c @@ -0,0 +1,55 @@ +#include +#ifdef BN_MP_RAND_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* makes a pseudo-random int of a given size */ +int +mp_rand (mp_int * a, int digits) +{ + int res; + mp_digit d; + + mp_zero (a); + if (digits <= 0) { + return MP_OKAY; + } + + /* first place a random non-zero digit */ + do { + d = ((mp_digit) abs (MP_GEN_RANDOM())) & MP_MASK; + } while (d == 0); + + if ((res = mp_add_d (a, d, a)) != MP_OKAY) { + return res; + } + + while (--digits > 0) { + if ((res = mp_lshd (a, 1)) != MP_OKAY) { + return res; + } + + if ((res = mp_add_d (a, ((mp_digit) abs (MP_GEN_RANDOM())), a)) != MP_OKAY) { + return res; + } + } + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_read_radix.c b/src/ltm/bn_mp_read_radix.c new file mode 100644 index 0000000..5c9eb5e --- /dev/null +++ b/src/ltm/bn_mp_read_radix.c @@ -0,0 +1,85 @@ +#include +#ifdef BN_MP_READ_RADIX_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* read a string [ASCII] in a given radix */ +int mp_read_radix (mp_int * a, const char *str, int radix) +{ + int y, res, neg; + char ch; + + /* zero the digit bignum */ + mp_zero(a); + + /* make sure the radix is ok */ + if ((radix < 2) || (radix > 64)) { + return MP_VAL; + } + + /* if the leading digit is a + * minus set the sign to negative. + */ + if (*str == '-') { + ++str; + neg = MP_NEG; + } else { + neg = MP_ZPOS; + } + + /* set the integer to the default of zero */ + mp_zero (a); + + /* process each digit of the string */ + while (*str != '\0') { + /* if the radix <= 36 the conversion is case insensitive + * this allows numbers like 1AB and 1ab to represent the same value + * [e.g. in hex] + */ + ch = (radix <= 36) ? (char)toupper((int)*str) : *str; + for (y = 0; y < 64; y++) { + if (ch == mp_s_rmap[y]) { + break; + } + } + + /* if the char was found in the map + * and is less than the given radix add it + * to the number, otherwise exit the loop. + */ + if (y < radix) { + if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) { + return res; + } + if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) { + return res; + } + } else { + break; + } + ++str; + } + + /* set the sign only if a != 0 */ + if (mp_iszero(a) != MP_YES) { + a->sign = neg; + } + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_read_signed_bin.c b/src/ltm/bn_mp_read_signed_bin.c new file mode 100644 index 0000000..a4d4760 --- /dev/null +++ b/src/ltm/bn_mp_read_signed_bin.c @@ -0,0 +1,41 @@ +#include +#ifdef BN_MP_READ_SIGNED_BIN_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* read signed bin, big endian, first byte is 0==positive or 1==negative */ +int mp_read_signed_bin (mp_int * a, const unsigned char *b, int c) +{ + int res; + + /* read magnitude */ + if ((res = mp_read_unsigned_bin (a, b + 1, c - 1)) != MP_OKAY) { + return res; + } + + /* first byte is 0 for positive, non-zero for negative */ + if (b[0] == 0) { + a->sign = MP_ZPOS; + } else { + a->sign = MP_NEG; + } + + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_read_unsigned_bin.c b/src/ltm/bn_mp_read_unsigned_bin.c new file mode 100644 index 0000000..e8e5df8 --- /dev/null +++ b/src/ltm/bn_mp_read_unsigned_bin.c @@ -0,0 +1,55 @@ +#include +#ifdef BN_MP_READ_UNSIGNED_BIN_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* reads a unsigned char array, assumes the msb is stored first [big endian] */ +int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c) +{ + int res; + + /* make sure there are at least two digits */ + if (a->alloc < 2) { + if ((res = mp_grow(a, 2)) != MP_OKAY) { + return res; + } + } + + /* zero the int */ + mp_zero (a); + + /* read the bytes in */ + while (c-- > 0) { + if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) { + return res; + } + +#ifndef MP_8BIT + a->dp[0] |= *b++; + a->used += 1; +#else + a->dp[0] = (*b & MP_MASK); + a->dp[1] |= ((*b++ >> 7U) & 1); + a->used += 2; +#endif + } + mp_clamp (a); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_reduce.c b/src/ltm/bn_mp_reduce.c new file mode 100644 index 0000000..e2c3a58 --- /dev/null +++ b/src/ltm/bn_mp_reduce.c @@ -0,0 +1,100 @@ +#include +#ifdef BN_MP_REDUCE_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, tstdenis82@gmail.com, http://libtom.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) +{ + mp_int q; + int res, um = m->used; + + /* q = x */ + if ((res = mp_init_copy (&q, x)) != MP_OKAY) { + return res; + } + + /* q1 = x / b**(k-1) */ + mp_rshd (&q, um - 1); + + /* according to HAC this optimization is ok */ + if (((mp_digit) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) { + if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) { + goto CLEANUP; + } + } else { +#ifdef BN_S_MP_MUL_HIGH_DIGS_C + 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)) != MP_OKAY) { + goto CLEANUP; + } +#else + { + res = MP_VAL; + goto CLEANUP; + } +#endif + } + + /* q3 = q2 / b**(k+1) */ + mp_rshd (&q, um + 1); + + /* x = x mod b**(k+1), quick (no division) */ + if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) { + goto CLEANUP; + } + + /* q = q * m mod b**(k+1), quick (no division) */ + if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) { + goto CLEANUP; + } + + /* x = x - q */ + if ((res = mp_sub (x, &q, x)) != MP_OKAY) { + goto CLEANUP; + } + + /* If x < 0, add b**(k+1) to it */ + if (mp_cmp_d (x, 0) == MP_LT) { + mp_set (&q, 1); + if ((res = mp_lshd (&q, um + 1)) != MP_OKAY) + goto CLEANUP; + if ((res = mp_add (x, &q, x)) != MP_OKAY) + goto CLEANUP; + } + + /* Back off if it's too big */ + while (mp_cmp (x, m) != MP_LT) { + if ((res = s_mp_sub (x, m, x)) != MP_OKAY) { + goto CLEANUP; + } + } + +CLEANUP: + mp_clear (&q); + + return res; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_reduce_2k.c b/src/ltm/bn_mp_reduce_2k.c new file mode 100644 index 0000000..2876a75 --- /dev/null +++ b/src/ltm/bn_mp_reduce_2k.c @@ -0,0 +1,63 @@ +#include +#ifdef BN_MP_REDUCE_2K_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, tstdenis82@gmail.com, http://libtom.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) +{ + 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; + } + + if (d != 1) { + /* q = q * d */ + if ((res = mp_mul_d(&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) { + if ((res = s_mp_sub(a, n, a)) != MP_OKAY) { + goto ERR; + } + goto top; + } + +ERR: + mp_clear(&q); + return res; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_reduce_2k_l.c b/src/ltm/bn_mp_reduce_2k_l.c new file mode 100644 index 0000000..3225214 --- /dev/null +++ b/src/ltm/bn_mp_reduce_2k_l.c @@ -0,0 +1,64 @@ +#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, tstdenis82@gmail.com, http://libtom.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) { + if ((res = s_mp_sub(a, n, a)) != MP_OKAY) { + goto ERR; + } + goto top; + } + +ERR: + mp_clear(&q); + return res; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_reduce_2k_setup.c b/src/ltm/bn_mp_reduce_2k_setup.c new file mode 100644 index 0000000..545051e --- /dev/null +++ b/src/ltm/bn_mp_reduce_2k_setup.c @@ -0,0 +1,47 @@ +#include +#ifdef BN_MP_REDUCE_2K_SETUP_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* determines the setup value */ +int mp_reduce_2k_setup(mp_int *a, mp_digit *d) +{ + int res, p; + mp_int tmp; + + if ((res = mp_init(&tmp)) != MP_OKAY) { + return res; + } + + p = mp_count_bits(a); + if ((res = mp_2expt(&tmp, p)) != MP_OKAY) { + mp_clear(&tmp); + return res; + } + + if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) { + mp_clear(&tmp); + return res; + } + + *d = tmp.dp[0]; + mp_clear(&tmp); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_reduce_2k_setup_l.c b/src/ltm/bn_mp_reduce_2k_setup_l.c new file mode 100644 index 0000000..59132dd --- /dev/null +++ b/src/ltm/bn_mp_reduce_2k_setup_l.c @@ -0,0 +1,44 @@ +#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, tstdenis82@gmail.com, http://libtom.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 + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_reduce_is_2k.c b/src/ltm/bn_mp_reduce_is_2k.c new file mode 100644 index 0000000..784947b --- /dev/null +++ b/src/ltm/bn_mp_reduce_is_2k.c @@ -0,0 +1,52 @@ +#include +#ifdef BN_MP_REDUCE_IS_2K_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* determines if mp_reduce_2k can be used */ +int mp_reduce_is_2k(mp_int *a) +{ + int ix, iy, iw; + mp_digit iz; + + if (a->used == 0) { + return MP_NO; + } else if (a->used == 1) { + return MP_YES; + } else if (a->used > 1) { + iy = mp_count_bits(a); + iz = 1; + iw = 1; + + /* 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 MP_NO; + } + iz <<= 1; + if (iz > (mp_digit)MP_MASK) { + ++iw; + iz = 1; + } + } + } + return MP_YES; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_reduce_is_2k_l.c b/src/ltm/bn_mp_reduce_is_2k_l.c new file mode 100644 index 0000000..c193f39 --- /dev/null +++ b/src/ltm/bn_mp_reduce_is_2k_l.c @@ -0,0 +1,44 @@ +#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, tstdenis82@gmail.com, http://libtom.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 + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_reduce_setup.c b/src/ltm/bn_mp_reduce_setup.c new file mode 100644 index 0000000..f97eed5 --- /dev/null +++ b/src/ltm/bn_mp_reduce_setup.c @@ -0,0 +1,34 @@ +#include +#ifdef BN_MP_REDUCE_SETUP_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* pre-calculate the value required for Barrett reduction + * For a given modulus "b" it calulates the value required in "a" + */ +int mp_reduce_setup (mp_int * a, mp_int * b) +{ + int res; + + if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) { + return res; + } + return mp_div (a, b, a, NULL); +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_rshd.c b/src/ltm/bn_mp_rshd.c new file mode 100644 index 0000000..77b0f6c --- /dev/null +++ b/src/ltm/bn_mp_rshd.c @@ -0,0 +1,72 @@ +#include +#ifdef BN_MP_RSHD_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* shift right a certain amount of digits */ +void mp_rshd (mp_int * a, int b) +{ + int x; + + /* if b <= 0 then ignore it */ + if (b <= 0) { + return; + } + + /* if b > used then simply zero it and return */ + if (a->used <= b) { + mp_zero (a); + return; + } + + { + mp_digit *bottom, *top; + + /* shift the digits down */ + + /* bottom */ + bottom = a->dp; + + /* top [offset into digits] */ + top = a->dp + b; + + /* this is implemented as a sliding window where + * the window is b-digits long and digits from + * the top of the window are copied to the bottom + * + * e.g. + + b-2 | b-1 | b0 | b1 | b2 | ... | bb | ----> + /\ | ----> + \-------------------/ ----> + */ + for (x = 0; x < (a->used - b); x++) { + *bottom++ = *top++; + } + + /* zero the top digits */ + for (; x < a->used; x++) { + *bottom++ = 0; + } + } + + /* remove excess digits */ + a->used -= b; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_set.c b/src/ltm/bn_mp_set.c new file mode 100644 index 0000000..cac48ea --- /dev/null +++ b/src/ltm/bn_mp_set.c @@ -0,0 +1,29 @@ +#include +#ifdef BN_MP_SET_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* set to a digit */ +void mp_set (mp_int * a, mp_digit b) +{ + mp_zero (a); + a->dp[0] = b & MP_MASK; + a->used = (a->dp[0] != 0) ? 1 : 0; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_set_int.c b/src/ltm/bn_mp_set_int.c new file mode 100644 index 0000000..5aa59d5 --- /dev/null +++ b/src/ltm/bn_mp_set_int.c @@ -0,0 +1,48 @@ +#include +#ifdef BN_MP_SET_INT_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* set a 32-bit const */ +int mp_set_int (mp_int * a, unsigned long b) +{ + int x, res; + + mp_zero (a); + + /* set four bits at a time */ + for (x = 0; x < 8; x++) { + /* shift the number up four bits */ + if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) { + return res; + } + + /* OR in the top four bits of the source */ + a->dp[0] |= (b >> 28) & 15; + + /* shift the source up to the next four bits */ + b <<= 4; + + /* ensure that digits are not clamped off */ + a->used += 1; + } + mp_clamp (a); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_set_long.c b/src/ltm/bn_mp_set_long.c new file mode 100644 index 0000000..281fce7 --- /dev/null +++ b/src/ltm/bn_mp_set_long.c @@ -0,0 +1,24 @@ +#include +#ifdef BN_MP_SET_LONG_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* set a platform dependent unsigned long int */ +MP_SET_XLONG(mp_set_long, unsigned long) +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_set_long_long.c b/src/ltm/bn_mp_set_long_long.c new file mode 100644 index 0000000..3c4b01a --- /dev/null +++ b/src/ltm/bn_mp_set_long_long.c @@ -0,0 +1,24 @@ +#include +#ifdef BN_MP_SET_LONG_LONG_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* set a platform dependent unsigned long long int */ +MP_SET_XLONG(mp_set_long_long, unsigned long long) +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_shrink.c b/src/ltm/bn_mp_shrink.c new file mode 100644 index 0000000..1ad2ede --- /dev/null +++ b/src/ltm/bn_mp_shrink.c @@ -0,0 +1,41 @@ +#include +#ifdef BN_MP_SHRINK_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* shrink a bignum */ +int mp_shrink (mp_int * a) +{ + mp_digit *tmp; + int used = 1; + + if(a->used > 0) { + used = a->used; + } + + if (a->alloc != used) { + if ((tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * used)) == NULL) { + return MP_MEM; + } + a->dp = tmp; + a->alloc = used; + } + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_signed_bin_size.c b/src/ltm/bn_mp_signed_bin_size.c new file mode 100644 index 0000000..0e760a6 --- /dev/null +++ b/src/ltm/bn_mp_signed_bin_size.c @@ -0,0 +1,27 @@ +#include +#ifdef BN_MP_SIGNED_BIN_SIZE_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* get the size for an signed equivalent */ +int mp_signed_bin_size (mp_int * a) +{ + return 1 + mp_unsigned_bin_size (a); +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_sqr.c b/src/ltm/bn_mp_sqr.c new file mode 100644 index 0000000..ad2099b --- /dev/null +++ b/src/ltm/bn_mp_sqr.c @@ -0,0 +1,60 @@ +#include +#ifdef BN_MP_SQR_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* computes b = a*a */ +int +mp_sqr (mp_int * a, mp_int * b) +{ + int res; + +#ifdef BN_MP_TOOM_SQR_C + /* use Toom-Cook? */ + if (a->used >= TOOM_SQR_CUTOFF) { + res = mp_toom_sqr(a, b); + /* Karatsuba? */ + } else +#endif +#ifdef BN_MP_KARATSUBA_SQR_C + if (a->used >= KARATSUBA_SQR_CUTOFF) { + res = mp_karatsuba_sqr (a, b); + } else +#endif + { +#ifdef BN_FAST_S_MP_SQR_C + /* can we use the fast comba multiplier? */ + if ((((a->used * 2) + 1) < MP_WARRAY) && + (a->used < + (1 << (((sizeof(mp_word) * CHAR_BIT) - (2 * DIGIT_BIT)) - 1)))) { + res = fast_s_mp_sqr (a, b); + } else +#endif + { +#ifdef BN_S_MP_SQR_C + res = s_mp_sqr (a, b); +#else + res = MP_VAL; +#endif + } + } + b->sign = MP_ZPOS; + return res; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_sqrmod.c b/src/ltm/bn_mp_sqrmod.c new file mode 100644 index 0000000..2f9463d --- /dev/null +++ b/src/ltm/bn_mp_sqrmod.c @@ -0,0 +1,41 @@ +#include +#ifdef BN_MP_SQRMOD_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* c = a * a (mod b) */ +int +mp_sqrmod (mp_int * a, mp_int * b, mp_int * c) +{ + int res; + mp_int t; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_sqr (a, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + res = mp_mod (&t, b, c); + mp_clear (&t); + return res; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_sqrt.c b/src/ltm/bn_mp_sqrt.c new file mode 100644 index 0000000..4a52f5e --- /dev/null +++ b/src/ltm/bn_mp_sqrt.c @@ -0,0 +1,81 @@ +#include +#ifdef BN_MP_SQRT_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* this function is less generic than mp_n_root, simpler and faster */ +int mp_sqrt(mp_int *arg, mp_int *ret) +{ + int res; + mp_int t1,t2; + + /* must be positive */ + if (arg->sign == MP_NEG) { + return MP_VAL; + } + + /* easy out */ + if (mp_iszero(arg) == MP_YES) { + mp_zero(ret); + return MP_OKAY; + } + + if ((res = mp_init_copy(&t1, arg)) != MP_OKAY) { + return res; + } + + if ((res = mp_init(&t2)) != MP_OKAY) { + goto E2; + } + + /* First approx. (not very bad for large arg) */ + mp_rshd (&t1,t1.used/2); + + /* t1 > 0 */ + if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) { + goto E1; + } + if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) { + goto E1; + } + if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) { + goto E1; + } + /* And now t1 > sqrt(arg) */ + do { + if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) { + goto E1; + } + if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) { + goto E1; + } + if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) { + goto E1; + } + /* t1 >= sqrt(arg) >= t2 at this point */ + } while (mp_cmp_mag(&t1,&t2) == MP_GT); + + mp_exch(&t1,ret); + +E1: mp_clear(&t2); +E2: mp_clear(&t1); + return res; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_sqrtmod_prime.c b/src/ltm/bn_mp_sqrtmod_prime.c new file mode 100644 index 0000000..968729e --- /dev/null +++ b/src/ltm/bn_mp_sqrtmod_prime.c @@ -0,0 +1,124 @@ +#include +#ifdef BN_MP_SQRTMOD_PRIME_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 is free for all purposes without any express + * guarantee it works. + */ + +/* Tonelli-Shanks algorithm + * https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm + * https://gmplib.org/list-archives/gmp-discuss/2013-April/005300.html + * + */ + +int mp_sqrtmod_prime(mp_int *n, mp_int *prime, mp_int *ret) +{ + int res, legendre; + mp_int t1, C, Q, S, Z, M, T, R, two; + mp_digit i; + + /* first handle the simple cases */ + if (mp_cmp_d(n, 0) == MP_EQ) { + mp_zero(ret); + return MP_OKAY; + } + if (mp_cmp_d(prime, 2) == MP_EQ) return MP_VAL; /* prime must be odd */ + if ((res = mp_jacobi(n, prime, &legendre)) != MP_OKAY) return res; + if (legendre == -1) return MP_VAL; /* quadratic non-residue mod prime */ + + if ((res = mp_init_multi(&t1, &C, &Q, &S, &Z, &M, &T, &R, &two, NULL)) != MP_OKAY) { + return res; + } + + /* SPECIAL CASE: if prime mod 4 == 3 + * compute directly: res = n^(prime+1)/4 mod prime + * Handbook of Applied Cryptography algorithm 3.36 + */ + if ((res = mp_mod_d(prime, 4, &i)) != MP_OKAY) goto cleanup; + if (i == 3) { + if ((res = mp_add_d(prime, 1, &t1)) != MP_OKAY) goto cleanup; + if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup; + if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup; + if ((res = mp_exptmod(n, &t1, prime, ret)) != MP_OKAY) goto cleanup; + res = MP_OKAY; + goto cleanup; + } + + /* NOW: Tonelli-Shanks algorithm */ + + /* factor out powers of 2 from prime-1, defining Q and S as: prime-1 = Q*2^S */ + if ((res = mp_copy(prime, &Q)) != MP_OKAY) goto cleanup; + if ((res = mp_sub_d(&Q, 1, &Q)) != MP_OKAY) goto cleanup; + /* Q = prime - 1 */ + mp_zero(&S); + /* S = 0 */ + while (mp_iseven(&Q) != MP_NO) { + if ((res = mp_div_2(&Q, &Q)) != MP_OKAY) goto cleanup; + /* Q = Q / 2 */ + if ((res = mp_add_d(&S, 1, &S)) != MP_OKAY) goto cleanup; + /* S = S + 1 */ + } + + /* find a Z such that the Legendre symbol (Z|prime) == -1 */ + if ((res = mp_set_int(&Z, 2)) != MP_OKAY) goto cleanup; + /* Z = 2 */ + while(1) { + if ((res = mp_jacobi(&Z, prime, &legendre)) != MP_OKAY) goto cleanup; + if (legendre == -1) break; + if ((res = mp_add_d(&Z, 1, &Z)) != MP_OKAY) goto cleanup; + /* Z = Z + 1 */ + } + + if ((res = mp_exptmod(&Z, &Q, prime, &C)) != MP_OKAY) goto cleanup; + /* C = Z ^ Q mod prime */ + if ((res = mp_add_d(&Q, 1, &t1)) != MP_OKAY) goto cleanup; + if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup; + /* t1 = (Q + 1) / 2 */ + if ((res = mp_exptmod(n, &t1, prime, &R)) != MP_OKAY) goto cleanup; + /* R = n ^ ((Q + 1) / 2) mod prime */ + if ((res = mp_exptmod(n, &Q, prime, &T)) != MP_OKAY) goto cleanup; + /* T = n ^ Q mod prime */ + if ((res = mp_copy(&S, &M)) != MP_OKAY) goto cleanup; + /* M = S */ + if ((res = mp_set_int(&two, 2)) != MP_OKAY) goto cleanup; + + res = MP_VAL; + while (1) { + if ((res = mp_copy(&T, &t1)) != MP_OKAY) goto cleanup; + i = 0; + while (1) { + if (mp_cmp_d(&t1, 1) == MP_EQ) break; + if ((res = mp_exptmod(&t1, &two, prime, &t1)) != MP_OKAY) goto cleanup; + i++; + } + if (i == 0) { + if ((res = mp_copy(&R, ret)) != MP_OKAY) goto cleanup; + res = MP_OKAY; + goto cleanup; + } + if ((res = mp_sub_d(&M, i, &t1)) != MP_OKAY) goto cleanup; + if ((res = mp_sub_d(&t1, 1, &t1)) != MP_OKAY) goto cleanup; + if ((res = mp_exptmod(&two, &t1, prime, &t1)) != MP_OKAY) goto cleanup; + /* t1 = 2 ^ (M - i - 1) */ + if ((res = mp_exptmod(&C, &t1, prime, &t1)) != MP_OKAY) goto cleanup; + /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */ + if ((res = mp_sqrmod(&t1, prime, &C)) != MP_OKAY) goto cleanup; + /* C = (t1 * t1) mod prime */ + if ((res = mp_mulmod(&R, &t1, prime, &R)) != MP_OKAY) goto cleanup; + /* R = (R * t1) mod prime */ + if ((res = mp_mulmod(&T, &C, prime, &T)) != MP_OKAY) goto cleanup; + /* T = (T * C) mod prime */ + mp_set(&M, i); + /* M = i */ + } + +cleanup: + mp_clear_multi(&t1, &C, &Q, &S, &Z, &M, &T, &R, &two, NULL); + return res; +} + +#endif diff --git a/src/ltm/bn_mp_sub.c b/src/ltm/bn_mp_sub.c new file mode 100644 index 0000000..0d616c2 --- /dev/null +++ b/src/ltm/bn_mp_sub.c @@ -0,0 +1,59 @@ +#include +#ifdef BN_MP_SUB_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* high level subtraction (handles signs) */ +int +mp_sub (mp_int * a, mp_int * b, mp_int * c) +{ + int sa, sb, res; + + sa = a->sign; + sb = b->sign; + + if (sa != sb) { + /* subtract a negative from a positive, OR */ + /* subtract a positive from a negative. */ + /* In either case, ADD their magnitudes, */ + /* and use the sign of the first number. */ + c->sign = sa; + res = s_mp_add (a, b, c); + } else { + /* subtract a positive from a positive, OR */ + /* subtract a negative from a negative. */ + /* First, take the difference between their */ + /* magnitudes, then... */ + if (mp_cmp_mag (a, b) != MP_LT) { + /* Copy the sign from the first */ + c->sign = sa; + /* The first has a larger or equal magnitude */ + res = s_mp_sub (a, b, c); + } else { + /* The result has the *opposite* sign from */ + /* the first number. */ + c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS; + /* The second has a larger magnitude */ + res = s_mp_sub (b, a, c); + } + } + return res; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_sub_d.c b/src/ltm/bn_mp_sub_d.c new file mode 100644 index 0000000..f5a932f --- /dev/null +++ b/src/ltm/bn_mp_sub_d.c @@ -0,0 +1,93 @@ +#include +#ifdef BN_MP_SUB_D_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* single digit subtraction */ +int +mp_sub_d (mp_int * a, mp_digit b, mp_int * c) +{ + mp_digit *tmpa, *tmpc, mu; + int res, ix, oldused; + + /* grow c as required */ + if (c->alloc < (a->used + 1)) { + if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { + return res; + } + } + + /* if a is negative just do an unsigned + * addition [with fudged signs] + */ + if (a->sign == MP_NEG) { + a->sign = MP_ZPOS; + res = mp_add_d(a, b, c); + a->sign = c->sign = MP_NEG; + + /* clamp */ + mp_clamp(c); + + return res; + } + + /* setup regs */ + oldused = c->used; + tmpa = a->dp; + tmpc = c->dp; + + /* if a <= b simply fix the single digit */ + if (((a->used == 1) && (a->dp[0] <= b)) || (a->used == 0)) { + if (a->used == 1) { + *tmpc++ = b - *tmpa; + } else { + *tmpc++ = b; + } + ix = 1; + + /* negative/1digit */ + c->sign = MP_NEG; + c->used = 1; + } else { + /* positive/size */ + c->sign = MP_ZPOS; + c->used = a->used; + + /* subtract first digit */ + *tmpc = *tmpa++ - b; + mu = *tmpc >> ((sizeof(mp_digit) * CHAR_BIT) - 1); + *tmpc++ &= MP_MASK; + + /* handle rest of the digits */ + for (ix = 1; ix < a->used; ix++) { + *tmpc = *tmpa++ - mu; + mu = *tmpc >> ((sizeof(mp_digit) * CHAR_BIT) - 1); + *tmpc++ &= MP_MASK; + } + } + + /* zero excess digits */ + while (ix++ < oldused) { + *tmpc++ = 0; + } + mp_clamp(c); + return MP_OKAY; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_submod.c b/src/ltm/bn_mp_submod.c new file mode 100644 index 0000000..87e0889 --- /dev/null +++ b/src/ltm/bn_mp_submod.c @@ -0,0 +1,42 @@ +#include +#ifdef BN_MP_SUBMOD_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* d = a - b (mod c) */ +int +mp_submod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + int res; + mp_int t; + + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_sub (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + res = mp_mod (&t, c, d); + mp_clear (&t); + return res; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_to_signed_bin.c b/src/ltm/bn_mp_to_signed_bin.c new file mode 100644 index 0000000..e9289ea --- /dev/null +++ b/src/ltm/bn_mp_to_signed_bin.c @@ -0,0 +1,33 @@ +#include +#ifdef BN_MP_TO_SIGNED_BIN_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* store in signed [big endian] format */ +int mp_to_signed_bin (mp_int * a, unsigned char *b) +{ + int res; + + if ((res = mp_to_unsigned_bin (a, b + 1)) != MP_OKAY) { + return res; + } + b[0] = (a->sign == MP_ZPOS) ? (unsigned char)0 : (unsigned char)1; + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_to_signed_bin_n.c b/src/ltm/bn_mp_to_signed_bin_n.c new file mode 100644 index 0000000..d4fe6e6 --- /dev/null +++ b/src/ltm/bn_mp_to_signed_bin_n.c @@ -0,0 +1,31 @@ +#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, tstdenis82@gmail.com, http://libtom.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 + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_to_unsigned_bin.c b/src/ltm/bn_mp_to_unsigned_bin.c new file mode 100644 index 0000000..d3ef46f --- /dev/null +++ b/src/ltm/bn_mp_to_unsigned_bin.c @@ -0,0 +1,48 @@ +#include +#ifdef BN_MP_TO_UNSIGNED_BIN_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* store in unsigned [big endian] format */ +int mp_to_unsigned_bin (mp_int * a, unsigned char *b) +{ + int x, res; + mp_int t; + + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + + x = 0; + while (mp_iszero (&t) == MP_NO) { +#ifndef MP_8BIT + b[x++] = (unsigned char) (t.dp[0] & 255); +#else + b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7)); +#endif + if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) { + mp_clear (&t); + return res; + } + } + bn_reverse (b, x); + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_to_unsigned_bin_n.c b/src/ltm/bn_mp_to_unsigned_bin_n.c new file mode 100644 index 0000000..2da13cc --- /dev/null +++ b/src/ltm/bn_mp_to_unsigned_bin_n.c @@ -0,0 +1,31 @@ +#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, tstdenis82@gmail.com, http://libtom.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 + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_toom_mul.c b/src/ltm/bn_mp_toom_mul.c new file mode 100644 index 0000000..4731f8f --- /dev/null +++ b/src/ltm/bn_mp_toom_mul.c @@ -0,0 +1,286 @@ +#include +#ifdef BN_MP_TOOM_MUL_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, tstdenis82@gmail.com, http://libtom.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...). +*/ +int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c) +{ + mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2; + int res, B; + + /* init temps */ + if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, + &a0, &a1, &a2, &b0, &b1, + &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) { + return res; + } + + /* B */ + B = MIN(a->used, b->used) / 3; + + /* a = a2 * B**2 + a1 * B + a0 */ + if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_copy(a, &a1)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a1, B); + if ((res = mp_mod_2d(&a1, DIGIT_BIT * B, &a1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_copy(a, &a2)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a2, B*2); + + /* b = b2 * B**2 + b1 * B + b0 */ + if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_copy(b, &b1)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&b1, B); + (void)mp_mod_2d(&b1, DIGIT_BIT * B, &b1); + + if ((res = mp_copy(b, &b2)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&b2, B*2); + + /* w0 = a0*b0 */ + if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) { + goto ERR; + } + + /* w4 = a2 * b2 */ + if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) { + goto ERR; + } + + /* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */ + if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) { + goto ERR; + } + + /* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */ + if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) { + goto ERR; + } + + + /* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */ + if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) { + goto ERR; + } + + /* now solve the matrix + + 0 0 0 0 1 + 1 2 4 8 16 + 1 1 1 1 1 + 16 8 4 2 1 + 1 0 0 0 0 + + using 12 subtractions, 4 shifts, + 2 small divisions and 1 small multiplication + */ + + /* r1 - r4 */ + if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r0 */ + if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/2 */ + if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3/2 */ + if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { + goto ERR; + } + /* r2 - r0 - r4 */ + if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1 - 8r0 */ + if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - 8r4 */ + if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { + goto ERR; + } + /* 3r2 - r1 - r3 */ + if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/3 */ + if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { + goto ERR; + } + /* r3/3 */ + if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { + goto ERR; + } + + /* at this point shift W[n] by B*n */ + if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) { + goto ERR; + } + +ERR: + mp_clear_multi(&w0, &w1, &w2, &w3, &w4, + &a0, &a1, &a2, &b0, &b1, + &b2, &tmp1, &tmp2, NULL); + return res; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_toom_sqr.c b/src/ltm/bn_mp_toom_sqr.c new file mode 100644 index 0000000..69b69d4 --- /dev/null +++ b/src/ltm/bn_mp_toom_sqr.c @@ -0,0 +1,228 @@ +#include +#ifdef BN_MP_TOOM_SQR_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* squaring using Toom-Cook 3-way algorithm */ +int +mp_toom_sqr(mp_int *a, mp_int *b) +{ + mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2; + int res, B; + + /* init temps */ + if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) { + return res; + } + + /* B */ + B = a->used / 3; + + /* a = a2 * B**2 + a1 * B + a0 */ + if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_copy(a, &a1)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a1, B); + if ((res = mp_mod_2d(&a1, DIGIT_BIT * B, &a1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_copy(a, &a2)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a2, B*2); + + /* w0 = a0*a0 */ + if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) { + goto ERR; + } + + /* w4 = a2 * a2 */ + if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) { + goto ERR; + } + + /* w1 = (a2 + 2(a1 + 2a0))**2 */ + if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) { + goto ERR; + } + + /* w3 = (a0 + 2(a1 + 2a2))**2 */ + if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) { + goto ERR; + } + + + /* w2 = (a2 + a1 + a0)**2 */ + if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) { + goto ERR; + } + + /* now solve the matrix + + 0 0 0 0 1 + 1 2 4 8 16 + 1 1 1 1 1 + 16 8 4 2 1 + 1 0 0 0 0 + + using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication. + */ + + /* r1 - r4 */ + if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r0 */ + if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/2 */ + if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3/2 */ + if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { + goto ERR; + } + /* r2 - r0 - r4 */ + if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1 - 8r0 */ + if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - 8r4 */ + if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { + goto ERR; + } + /* 3r2 - r1 - r3 */ + if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/3 */ + if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { + goto ERR; + } + /* r3/3 */ + if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { + goto ERR; + } + + /* at this point shift W[n] by B*n */ + if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) { + goto ERR; + } + +ERR: + mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL); + return res; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_toradix.c b/src/ltm/bn_mp_toradix.c new file mode 100644 index 0000000..f04352d --- /dev/null +++ b/src/ltm/bn_mp_toradix.c @@ -0,0 +1,75 @@ +#include +#ifdef BN_MP_TORADIX_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* stores a bignum as a ASCII string in a given radix (2..64) */ +int mp_toradix (mp_int * a, char *str, int radix) +{ + int res, digs; + mp_int t; + mp_digit d; + char *_s = str; + + /* check range of the radix */ + if ((radix < 2) || (radix > 64)) { + return MP_VAL; + } + + /* quick out if its zero */ + if (mp_iszero(a) == MP_YES) { + *str++ = '0'; + *str = '\0'; + return MP_OKAY; + } + + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + + /* if it is negative output a - */ + if (t.sign == MP_NEG) { + ++_s; + *str++ = '-'; + t.sign = MP_ZPOS; + } + + digs = 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; + } + *str++ = mp_s_rmap[d]; + ++digs; + } + + /* reverse the digits of the string. In this case _s points + * to the first digit [exluding the sign] of the number] + */ + bn_reverse ((unsigned char *)_s, digs); + + /* append a NULL so the string is properly terminated */ + *str = '\0'; + + mp_clear (&t); + return MP_OKAY; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_toradix_n.c b/src/ltm/bn_mp_toradix_n.c new file mode 100644 index 0000000..19b61d7 --- /dev/null +++ b/src/ltm/bn_mp_toradix_n.c @@ -0,0 +1,88 @@ +#include +#ifdef BN_MP_TORADIX_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* stores a bignum as a ASCII string in a given radix (2..64) + * + * Stores upto maxlen-1 chars and always a NULL byte + */ +int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen) +{ + int res, digs; + mp_int t; + mp_digit d; + char *_s = str; + + /* check range of the maxlen, radix */ + if ((maxlen < 2) || (radix < 2) || (radix > 64)) { + return MP_VAL; + } + + /* quick out if its zero */ + if (mp_iszero(a) == MP_YES) { + *str++ = '0'; + *str = '\0'; + return MP_OKAY; + } + + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + + /* if it is negative output a - */ + if (t.sign == MP_NEG) { + /* we have to reverse our digits later... but not the - sign!! */ + ++_s; + + /* store the flag and mark the number as positive */ + *str++ = '-'; + t.sign = MP_ZPOS; + + /* subtract a char */ + --maxlen; + } + + digs = 0; + while (mp_iszero (&t) == MP_NO) { + if (--maxlen < 1) { + /* no more room */ + break; + } + if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { + mp_clear (&t); + return res; + } + *str++ = mp_s_rmap[d]; + ++digs; + } + + /* reverse the digits of the string. In this case _s points + * to the first digit [exluding the sign] of the number + */ + bn_reverse ((unsigned char *)_s, digs); + + /* append a NULL so the string is properly terminated */ + *str = '\0'; + + mp_clear (&t); + return MP_OKAY; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_unsigned_bin_size.c b/src/ltm/bn_mp_unsigned_bin_size.c new file mode 100644 index 0000000..0312625 --- /dev/null +++ b/src/ltm/bn_mp_unsigned_bin_size.c @@ -0,0 +1,28 @@ +#include +#ifdef BN_MP_UNSIGNED_BIN_SIZE_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* get the size for an unsigned equivalent */ +int mp_unsigned_bin_size (mp_int * a) +{ + int size = mp_count_bits (a); + return (size / 8) + (((size & 7) != 0) ? 1 : 0); +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_xor.c b/src/ltm/bn_mp_xor.c new file mode 100644 index 0000000..3c2ba9e --- /dev/null +++ b/src/ltm/bn_mp_xor.c @@ -0,0 +1,51 @@ +#include +#ifdef BN_MP_XOR_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* XOR two ints together */ +int +mp_xor (mp_int * a, mp_int * b, mp_int * c) +{ + int res, ix, px; + mp_int t, *x; + + if (a->used > b->used) { + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + px = b->used; + x = b; + } else { + if ((res = mp_init_copy (&t, b)) != MP_OKAY) { + return res; + } + px = a->used; + x = a; + } + + for (ix = 0; ix < px; ix++) { + t.dp[ix] ^= x->dp[ix]; + } + mp_clamp (&t); + mp_exch (c, &t); + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_mp_zero.c b/src/ltm/bn_mp_zero.c new file mode 100644 index 0000000..21365ed --- /dev/null +++ b/src/ltm/bn_mp_zero.c @@ -0,0 +1,36 @@ +#include +#ifdef BN_MP_ZERO_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* set to zero */ +void mp_zero (mp_int * a) +{ + int n; + mp_digit *tmp; + + a->sign = MP_ZPOS; + a->used = 0; + + tmp = a->dp; + for (n = 0; n < a->alloc; n++) { + *tmp++ = 0; + } +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_prime_tab.c b/src/ltm/bn_prime_tab.c new file mode 100644 index 0000000..ae727a4 --- /dev/null +++ b/src/ltm/bn_prime_tab.c @@ -0,0 +1,61 @@ +#include +#ifdef BN_PRIME_TAB_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tstdenis82@gmail.com, http://libtom.org + */ +const mp_digit ltm_prime_tab[] = { + 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, + 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035, + 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059, + 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, +#ifndef MP_8BIT + 0x0083, + 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD, + 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF, + 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107, + 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137, + + 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167, + 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199, + 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9, + 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7, + 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239, + 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265, + 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293, + 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF, + + 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301, + 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B, + 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371, + 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD, + 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5, + 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419, + 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449, + 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B, + + 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7, + 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503, + 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529, + 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F, + 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3, + 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7, + 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623, + 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653 +#endif +}; +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_reverse.c b/src/ltm/bn_reverse.c new file mode 100644 index 0000000..fc6eb2d --- /dev/null +++ b/src/ltm/bn_reverse.c @@ -0,0 +1,39 @@ +#include +#ifdef BN_REVERSE_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* reverse an array, used for radix code */ +void +bn_reverse (unsigned char *s, int len) +{ + int ix, iy; + unsigned char t; + + ix = 0; + iy = len - 1; + while (ix < iy) { + t = s[ix]; + s[ix] = s[iy]; + s[iy] = t; + ++ix; + --iy; + } +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_s_mp_add.c b/src/ltm/bn_s_mp_add.c new file mode 100644 index 0000000..c2ad649 --- /dev/null +++ b/src/ltm/bn_s_mp_add.c @@ -0,0 +1,109 @@ +#include +#ifdef BN_S_MP_ADD_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* low level addition, based on HAC pp.594, Algorithm 14.7 */ +int +s_mp_add (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int *x; + int olduse, res, min, max; + + /* find sizes, we let |a| <= |b| which means we have to sort + * them. "x" will point to the input with the most digits + */ + if (a->used > b->used) { + min = b->used; + max = a->used; + x = a; + } else { + min = a->used; + max = b->used; + x = b; + } + + /* init result */ + if (c->alloc < (max + 1)) { + if ((res = mp_grow (c, max + 1)) != MP_OKAY) { + return res; + } + } + + /* get old used digit count and set new one */ + olduse = c->used; + c->used = max + 1; + + { + mp_digit u, *tmpa, *tmpb, *tmpc; + int i; + + /* alias for digit pointers */ + + /* first input */ + tmpa = a->dp; + + /* second input */ + tmpb = b->dp; + + /* destination */ + tmpc = c->dp; + + /* zero the carry */ + u = 0; + for (i = 0; i < min; i++) { + /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */ + *tmpc = *tmpa++ + *tmpb++ + u; + + /* U = carry bit of T[i] */ + u = *tmpc >> ((mp_digit)DIGIT_BIT); + + /* take away carry bit from T[i] */ + *tmpc++ &= MP_MASK; + } + + /* now copy higher words if any, that is in A+B + * if A or B has more digits add those in + */ + if (min != max) { + for (; i < max; i++) { + /* T[i] = X[i] + U */ + *tmpc = x->dp[i] + u; + + /* U = carry bit of T[i] */ + u = *tmpc >> ((mp_digit)DIGIT_BIT); + + /* take away carry bit from T[i] */ + *tmpc++ &= MP_MASK; + } + } + + /* add carry */ + *tmpc++ = u; + + /* clear digits above oldused */ + for (i = c->used; i < olduse; i++) { + *tmpc++ = 0; + } + } + + mp_clamp (c); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_s_mp_exptmod.c b/src/ltm/bn_s_mp_exptmod.c new file mode 100644 index 0000000..63e1b1e --- /dev/null +++ b/src/ltm/bn_s_mp_exptmod.c @@ -0,0 +1,252 @@ +#include +#ifdef BN_S_MP_EXPTMOD_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, tstdenis82@gmail.com, http://libtom.org + */ +#ifdef MP_LOW_MEM + #define TAB_SIZE 32 +#else + #define TAB_SIZE 256 +#endif + +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); + if (x <= 7) { + winsize = 2; + } else if (x <= 36) { + winsize = 3; + } else if (x <= 140) { + winsize = 4; + } else if (x <= 450) { + winsize = 5; + } else if (x <= 1303) { + winsize = 6; + } else if (x <= 3529) { + winsize = 7; + } else { + winsize = 8; + } + +#ifdef MP_LOW_MEM + if (winsize > 5) { + winsize = 5; + } +#endif + + /* init M array */ + /* init first cell */ + if ((err = mp_init(&M[1])) != MP_OKAY) { + return err; + } + + /* now init the second half of the array */ + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + if ((err = mp_init(&M[x])) != MP_OKAY) { + for (y = 1<<(winsize-1); y < x; y++) { + mp_clear (&M[y]); + } + mp_clear(&M[1]); + return err; + } + } + + /* create mu, used for Barrett reduction */ + if ((err = mp_init (&mu)) != MP_OKAY) { + goto LBL_M; + } + + 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 + * + * The M table contains powers of the base, + * e.g. M[x] = G**x mod P + * + * The first half of the table is not + * computed though accept for M[0] and M[1] + */ + if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) { + goto LBL_MU; + } + + /* compute the value at M[1<<(winsize-1)] by squaring + * M[1] (winsize-1) times + */ + if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { + goto LBL_MU; + } + + 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; + } + + /* reduce modulo P */ + if ((err = redux (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) { + goto LBL_MU; + } + } + + /* create upper table, that is M[x] = M[x-1] * M[1] (mod P) + * for x = (2**(winsize - 1) + 1) to (2**winsize - 1) + */ + for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { + if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { + goto LBL_MU; + } + if ((err = redux (&M[x], P, &mu)) != MP_OKAY) { + goto LBL_MU; + } + } + + /* setup result */ + if ((err = mp_init (&res)) != MP_OKAY) { + goto LBL_MU; + } + mp_set (&res, 1); + + /* set initial mode and bit cnt */ + mode = 0; + bitcnt = 1; + buf = 0; + digidx = X->used - 1; + bitcpy = 0; + bitbuf = 0; + + for (;;) { + /* grab next digit as required */ + if (--bitcnt == 0) { + /* if digidx == -1 we are out of digits */ + if (digidx == -1) { + break; + } + /* read next digit and reset the bitcnt */ + buf = X->dp[digidx--]; + bitcnt = (int) DIGIT_BIT; + } + + /* grab the next msb from the exponent */ + y = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1; + buf <<= (mp_digit)1; + + /* if the bit is zero and mode == 0 then we ignore it + * These represent the leading zero bits before the first 1 bit + * in the exponent. Technically this opt is not required but it + * does lower the # of trivial squaring/reductions used + */ + if ((mode == 0) && (y == 0)) { + continue; + } + + /* if the bit is zero and mode == 1 then we square */ + if ((mode == 1) && (y == 0)) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + continue; + } + + /* else we add it to the window */ + bitbuf |= (y << (winsize - ++bitcpy)); + mode = 2; + + if (bitcpy == winsize) { + /* ok window is filled so square as required and multiply */ + /* square first */ + for (x = 0; x < winsize; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* then multiply */ + if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + + /* empty window and reset */ + bitcpy = 0; + bitbuf = 0; + mode = 1; + } + } + + /* if bits remain then square/multiply */ + if ((mode == 2) && (bitcpy > 0)) { + /* square then multiply if the bit is set */ + for (x = 0; x < bitcpy; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + + bitbuf <<= 1; + if ((bitbuf & (1 << winsize)) != 0) { + /* then multiply */ + if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + } + } + } + + mp_exch (&res, Y); + err = MP_OKAY; +LBL_RES:mp_clear (&res); +LBL_MU:mp_clear (&mu); +LBL_M: + mp_clear(&M[1]); + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + mp_clear (&M[x]); + } + return err; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_s_mp_mul_digs.c b/src/ltm/bn_s_mp_mul_digs.c new file mode 100644 index 0000000..bd8553d --- /dev/null +++ b/src/ltm/bn_s_mp_mul_digs.c @@ -0,0 +1,90 @@ +#include +#ifdef BN_S_MP_MUL_DIGS_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, tstdenis82@gmail.com, http://libtom.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) +{ + mp_int t; + int res, pa, pb, ix, iy; + mp_digit u; + mp_word r; + mp_digit tmpx, *tmpt, *tmpy; + + /* can we use the fast multiplier? */ + if (((digs) < MP_WARRAY) && + (MIN (a->used, b->used) < + (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) { + return fast_s_mp_mul_digs (a, b, c, digs); + } + + if ((res = mp_init_size (&t, digs)) != MP_OKAY) { + return res; + } + t.used = digs; + + /* compute the digits of the product directly */ + pa = a->used; + for (ix = 0; ix < pa; ix++) { + /* set the carry to zero */ + u = 0; + + /* limit ourselves to making digs digits of output */ + pb = MIN (b->used, digs - ix); + + /* setup some aliases */ + /* copy of the digit from a used within the nested loop */ + tmpx = a->dp[ix]; + + /* an alias for the destination shifted ix places */ + tmpt = t.dp + ix; + + /* an alias for the digits of b */ + tmpy = b->dp; + + /* compute the columns of the output and propagate the carry */ + for (iy = 0; iy < pb; iy++) { + /* compute the column as a mp_word */ + r = (mp_word)*tmpt + + ((mp_word)tmpx * (mp_word)*tmpy++) + + (mp_word)u; + + /* the new column is the lower part of the result */ + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* get the carry word from the result */ + u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); + } + /* set carry if it is placed below digs */ + if ((ix + iy) < digs) { + *tmpt = u; + } + } + + mp_clamp (&t); + mp_exch (&t, c); + + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_s_mp_mul_high_digs.c b/src/ltm/bn_s_mp_mul_high_digs.c new file mode 100644 index 0000000..153cea4 --- /dev/null +++ b/src/ltm/bn_s_mp_mul_high_digs.c @@ -0,0 +1,81 @@ +#include +#ifdef BN_S_MP_MUL_HIGH_DIGS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * 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, tstdenis82@gmail.com, http://libtom.org + */ + +/* multiplies |a| * |b| and does not compute the lower digs digits + * [meant to get the higher part of the product] + */ +int +s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + mp_int t; + int res, pa, pb, ix, iy; + mp_digit u; + mp_word r; + mp_digit tmpx, *tmpt, *tmpy; + + /* can we use the fast multiplier? */ +#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C + if (((a->used + b->used + 1) < MP_WARRAY) + && (MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) { + return fast_s_mp_mul_high_digs (a, b, c, digs); + } +#endif + + if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) { + return res; + } + t.used = a->used + b->used + 1; + + pa = a->used; + pb = b->used; + for (ix = 0; ix < pa; ix++) { + /* clear the carry */ + u = 0; + + /* left hand side of A[ix] * B[iy] */ + tmpx = a->dp[ix]; + + /* alias to the address of where the digits will be stored */ + tmpt = &(t.dp[digs]); + + /* alias for where to read the right hand side from */ + tmpy = b->dp + (digs - ix); + + for (iy = digs - ix; iy < pb; iy++) { + /* calculate the double precision result */ + r = (mp_word)*tmpt + + ((mp_word)tmpx * (mp_word)*tmpy++) + + (mp_word)u; + + /* get the lower part */ + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* carry the carry */ + u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); + } + *tmpt = u; + } + mp_clamp (&t); + mp_exch (&t, c); + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_s_mp_sqr.c b/src/ltm/bn_s_mp_sqr.c new file mode 100644 index 0000000..68c95bc --- /dev/null +++ b/src/ltm/bn_s_mp_sqr.c @@ -0,0 +1,84 @@ +#include +#ifdef BN_S_MP_SQR_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */ +int s_mp_sqr (mp_int * a, mp_int * b) +{ + mp_int t; + int res, ix, iy, pa; + mp_word r; + mp_digit u, tmpx, *tmpt; + + pa = a->used; + if ((res = mp_init_size (&t, (2 * pa) + 1)) != MP_OKAY) { + return res; + } + + /* default used is maximum possible size */ + t.used = (2 * pa) + 1; + + for (ix = 0; ix < pa; ix++) { + /* first calculate the digit at 2*ix */ + /* calculate double precision result */ + r = (mp_word)t.dp[2*ix] + + ((mp_word)a->dp[ix] * (mp_word)a->dp[ix]); + + /* store lower part in result */ + t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* get the carry */ + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + + /* left hand side of A[ix] * A[iy] */ + tmpx = a->dp[ix]; + + /* alias for where to store the results */ + tmpt = t.dp + ((2 * ix) + 1); + + for (iy = ix + 1; iy < pa; iy++) { + /* first calculate the product */ + r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]); + + /* now calculate the double precision result, note we use + * addition instead of *2 since it's easier to optimize + */ + r = ((mp_word) *tmpt) + r + r + ((mp_word) u); + + /* store lower part */ + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* get carry */ + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + } + /* propagate upwards */ + while (u != ((mp_digit) 0)) { + r = ((mp_word) *tmpt) + ((mp_word) u); + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + } + } + + mp_clamp (&t); + mp_exch (&t, b); + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bn_s_mp_sub.c b/src/ltm/bn_s_mp_sub.c new file mode 100644 index 0000000..c0ea556 --- /dev/null +++ b/src/ltm/bn_s_mp_sub.c @@ -0,0 +1,89 @@ +#include +#ifdef BN_S_MP_SUB_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */ +int +s_mp_sub (mp_int * a, mp_int * b, mp_int * c) +{ + int olduse, res, min, max; + + /* find sizes */ + min = b->used; + max = a->used; + + /* init result */ + if (c->alloc < max) { + if ((res = mp_grow (c, max)) != MP_OKAY) { + return res; + } + } + olduse = c->used; + c->used = max; + + { + mp_digit u, *tmpa, *tmpb, *tmpc; + int i; + + /* alias for digit pointers */ + tmpa = a->dp; + tmpb = b->dp; + tmpc = c->dp; + + /* set carry to zero */ + u = 0; + for (i = 0; i < min; i++) { + /* T[i] = A[i] - B[i] - U */ + *tmpc = (*tmpa++ - *tmpb++) - u; + + /* U = carry bit of T[i] + * Note this saves performing an AND operation since + * if a carry does occur it will propagate all the way to the + * MSB. As a result a single shift is enough to get the carry + */ + u = *tmpc >> ((mp_digit)((CHAR_BIT * sizeof(mp_digit)) - 1)); + + /* Clear carry from T[i] */ + *tmpc++ &= MP_MASK; + } + + /* now copy higher words if any, e.g. if A has more digits than B */ + for (; i < max; i++) { + /* T[i] = A[i] - U */ + *tmpc = *tmpa++ - u; + + /* U = carry bit of T[i] */ + u = *tmpc >> ((mp_digit)((CHAR_BIT * sizeof(mp_digit)) - 1)); + + /* Clear carry from T[i] */ + *tmpc++ &= MP_MASK; + } + + /* clear digits above used (since we may not have grown result above) */ + for (i = c->used; i < olduse; i++) { + *tmpc++ = 0; + } + } + + mp_clamp (c); + return MP_OKAY; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/bncore.c b/src/ltm/bncore.c new file mode 100644 index 0000000..9552714 --- /dev/null +++ b/src/ltm/bncore.c @@ -0,0 +1,36 @@ +#include +#ifdef BNCORE_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, tstdenis82@gmail.com, http://libtom.org + */ + +/* Known optimal configurations + + CPU /Compiler /MUL CUTOFF/SQR CUTOFF +------------------------------------------------------------- + Intel P4 Northwood /GCC v3.4.1 / 88/ 128/LTM 0.32 ;-) + AMD Athlon64 /GCC v3.4.4 / 80/ 120/LTM 0.35 + +*/ + +int KARATSUBA_MUL_CUTOFF = 80, /* Min. number of digits before Karatsuba multiplication is used. */ + KARATSUBA_SQR_CUTOFF = 120, /* Min. number of digits before Karatsuba squaring is used. */ + + TOOM_MUL_CUTOFF = 350, /* no optimal values of these are known yet so set em high */ + TOOM_SQR_CUTOFF = 400; +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/tommath.h b/src/ltm/tommath.h new file mode 100644 index 0000000..e7ffb8f --- /dev/null +++ b/src/ltm/tommath.h @@ -0,0 +1,578 @@ +/* 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, tstdenis82@gmail.com, http://math.libtomcrypt.com + */ +#ifndef BN_H_ +#define BN_H_ + +#include +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* unsigned int types */ +typedef unsigned char mp_uint8; +typedef unsigned short mp_uint16; +typedef unsigned int mp_uint32; +#ifdef _MSC_VER +#undef BN_MP_SET_LONG_LONG_C +#undef BN_MP_GET_LONG_LONG_C +typedef unsigned __int64 mp_uint64; +#else +typedef unsigned long long mp_uint64; +#endif + +/* detect 64-bit mode if possible */ +#if defined(__x86_64__) + #if !(defined(MP_32BIT) || defined(MP_16BIT) || defined(MP_8BIT)) + #if defined(__GNUC__) + typedef unsigned long mp_uint128 __attribute__ ((mode(TI))); + #define MP_64BIT + #elif defined(_MSC_VER) + typedef unsigned __int128 mp_uint128; + #define MP_64BIT + #endif + #endif +#endif + +/* some default configurations. + * + * A "mp_digit" must be able to hold DIGIT_BIT + 1 bits + * A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits + * + * At the very least a mp_digit must be able to hold 7 bits + * [any size beyond that is ok provided it doesn't overflow the data type] + */ +#ifdef MP_8BIT + typedef mp_uint8 mp_digit; + typedef mp_uint16 mp_word; +#define MP_SIZEOF_MP_DIGIT 1 +#ifdef DIGIT_BIT +#error You must not define DIGIT_BIT when using MP_8BIT +#endif +#elif defined(MP_16BIT) + typedef mp_uint16 mp_digit; + typedef mp_uint32 mp_word; +#define MP_SIZEOF_MP_DIGIT 2 +#ifdef DIGIT_BIT +#error You must not define DIGIT_BIT when using MP_16BIT +#endif +#elif defined(MP_64BIT) + typedef mp_uint64 mp_digit; + typedef mp_uint128 mp_word; + #define DIGIT_BIT 60 +#else + /* this is the default case, 28-bit digits */ + + /* this is to make porting into LibTomCrypt easier :-) */ + typedef mp_uint32 mp_digit; + typedef mp_uint64 mp_word; + +#ifdef MP_31BIT + /* this is an extension that uses 31-bit digits */ + #define DIGIT_BIT 31 +#else + /* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */ + #define DIGIT_BIT 28 + #define MP_28BIT +#endif +#endif + +/* otherwise the bits per digit is calculated automatically from the size of a mp_digit */ +#ifndef DIGIT_BIT + #define DIGIT_BIT (((CHAR_BIT * MP_SIZEOF_MP_DIGIT) - 1)) /* bits per digit */ + typedef mp_uint32 mp_min_u32; +#else + typedef mp_digit mp_min_u32; +#endif + +/* platforms that can use a better rand function */ +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) + #define MP_USE_ALT_RAND 1 +#endif + +/* use arc4random on platforms that support it */ +#ifdef MP_USE_ALT_RAND + #define MP_GEN_RANDOM() arc4random() + #define MP_GEN_RANDOM_MAX 0xffffffff +#else + #define MP_GEN_RANDOM() rand() + #define MP_GEN_RANDOM_MAX RAND_MAX +#endif + +#define MP_DIGIT_BIT DIGIT_BIT +#define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1)) +#define MP_DIGIT_MAX MP_MASK + +/* equalities */ +#define MP_LT -1 /* less than */ +#define MP_EQ 0 /* equal to */ +#define MP_GT 1 /* greater than */ + +#define MP_ZPOS 0 /* positive integer */ +#define MP_NEG 1 /* negative */ + +#define MP_OKAY 0 /* ok result */ +#define MP_MEM -2 /* out of mem */ +#define MP_VAL -3 /* invalid input */ +#define MP_RANGE MP_VAL + +#define MP_YES 1 /* yes response */ +#define MP_NO 0 /* no response */ + +/* 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_ON 0x0008 /* force 2nd MSB to 1 */ + +typedef int mp_err; + +/* you'll have to tune these... */ +extern int KARATSUBA_MUL_CUTOFF, + KARATSUBA_SQR_CUTOFF, + TOOM_MUL_CUTOFF, + TOOM_SQR_CUTOFF; + +/* define this to use lower memory usage routines (exptmods mostly) */ +/* #define MP_LOW_MEM */ + +/* default precision */ +#ifndef MP_PREC + #ifndef MP_LOW_MEM + #define MP_PREC 32 /* default digits of precision */ + #else + #define MP_PREC 8 /* default digits of precision */ + #endif +#endif + +/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */ +#define MP_WARRAY (1 << (((sizeof(mp_word) * CHAR_BIT) - (2 * DIGIT_BIT)) + 1)) + +/* the infamous mp_int structure */ +typedef struct { + int used, alloc, sign; + mp_digit *dp; +} mp_int; + +/* callback for mp_prime_random, should fill dst with random bytes and return how many read [upto len] */ +typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat); + + +#define USED(m) ((m)->used) +#define DIGIT(m,k) ((m)->dp[(k)]) +#define SIGN(m) ((m)->sign) + +/* error code to char* string */ +const char *mp_error_to_string(int code); + +/* ---> init and deinit bignum functions <--- */ +/* init a bignum */ +int mp_init(mp_int *a); + +/* free a bignum */ +void mp_clear(mp_int *a); + +/* init a null terminated series of arguments */ +int mp_init_multi(mp_int *mp, ...); + +/* clear a null terminated series of arguments */ +void mp_clear_multi(mp_int *mp, ...); + +/* exchange two ints */ +void mp_exch(mp_int *a, mp_int *b); + +/* shrink ram required for a bignum */ +int mp_shrink(mp_int *a); + +/* grow an int to a given size */ +int mp_grow(mp_int *a, int size); + +/* init to a given number of digits */ +int mp_init_size(mp_int *a, int size); + +/* ---> Basic Manipulations <--- */ +#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO) +#define mp_iseven(a) ((((a)->used > 0) && (((a)->dp[0] & 1u) == 0u)) ? MP_YES : MP_NO) +#define mp_isodd(a) ((((a)->used > 0) && (((a)->dp[0] & 1u) == 1u)) ? MP_YES : MP_NO) +#define mp_isneg(a) (((a)->sign != MP_ZPOS) ? MP_YES : MP_NO) + +/* set to zero */ +void mp_zero(mp_int *a); + +/* set to a digit */ +void mp_set(mp_int *a, mp_digit b); + +/* set a 32-bit const */ +int mp_set_int(mp_int *a, unsigned long b); + +/* set a platform dependent unsigned long value */ +int mp_set_long(mp_int *a, unsigned long b); + +#ifdef BN_MP_SET_LONG_LONG_C +/* set a platform dependent unsigned long long value */ +int mp_set_long_long(mp_int *a, unsigned long long b); +#endif + +/* get a 32-bit value */ +unsigned long mp_get_int(mp_int * a); + +/* get a platform dependent unsigned long value */ +unsigned long mp_get_long(mp_int * a); + +#ifdef BN_MP_GET_LONG_LONG_C +/* get a platform dependent unsigned long long value */ +unsigned long long mp_get_long_long(mp_int * a); +#endif + +/* initialize and set a digit */ +int mp_init_set (mp_int * a, mp_digit b); + +/* initialize and set 32-bit value */ +int mp_init_set_int (mp_int * a, unsigned long b); + +/* copy, b = a */ +int mp_copy(mp_int *a, mp_int *b); + +/* inits and copies, a = b */ +int mp_init_copy(mp_int *a, mp_int *b); + +/* trim unused digits */ +void mp_clamp(mp_int *a); + +/* import binary data */ +int mp_import(mp_int* rop, size_t count, int order, size_t size, int endian, size_t nails, const void* op); + +/* export binary data */ +int mp_export(void* rop, size_t* countp, int order, size_t size, int endian, size_t nails, mp_int* op); + +/* ---> digit manipulation <--- */ + +/* right shift by "b" digits */ +void mp_rshd(mp_int *a, int b); + +/* left shift by "b" digits */ +int mp_lshd(mp_int *a, int b); + +/* c = a / 2**b, implemented as c = a >> b */ +int mp_div_2d(mp_int *a, int b, mp_int *c, mp_int *d); + +/* b = a/2 */ +int mp_div_2(mp_int *a, mp_int *b); + +/* c = a * 2**b, implemented as c = a << b */ +int mp_mul_2d(mp_int *a, int b, mp_int *c); + +/* b = a*2 */ +int mp_mul_2(mp_int *a, mp_int *b); + +/* c = a mod 2**b */ +int mp_mod_2d(mp_int *a, int b, mp_int *c); + +/* computes a = 2**b */ +int mp_2expt(mp_int *a, int b); + +/* Counts the number of lsbs which are zero before the first zero bit */ +int mp_cnt_lsb(mp_int *a); + +/* I Love Earth! */ + +/* makes a pseudo-random int of a given size */ +int mp_rand(mp_int *a, int digits); + +/* ---> binary operations <--- */ +/* c = a XOR b */ +int mp_xor(mp_int *a, mp_int *b, mp_int *c); + +/* c = a OR b */ +int mp_or(mp_int *a, mp_int *b, mp_int *c); + +/* c = a AND b */ +int mp_and(mp_int *a, mp_int *b, mp_int *c); + +/* ---> Basic arithmetic <--- */ + +/* b = -a */ +int mp_neg(mp_int *a, mp_int *b); + +/* b = |a| */ +int mp_abs(mp_int *a, mp_int *b); + +/* compare a to b */ +int mp_cmp(mp_int *a, mp_int *b); + +/* compare |a| to |b| */ +int mp_cmp_mag(mp_int *a, mp_int *b); + +/* c = a + b */ +int mp_add(mp_int *a, mp_int *b, mp_int *c); + +/* c = a - b */ +int mp_sub(mp_int *a, mp_int *b, mp_int *c); + +/* c = a * b */ +int mp_mul(mp_int *a, mp_int *b, mp_int *c); + +/* b = a*a */ +int mp_sqr(mp_int *a, mp_int *b); + +/* a/b => cb + d == a */ +int mp_div(mp_int *a, mp_int *b, mp_int *c, mp_int *d); + +/* c = a mod b, 0 <= c < b */ +int mp_mod(mp_int *a, mp_int *b, mp_int *c); + +/* ---> single digit functions <--- */ + +/* compare against a single digit */ +int mp_cmp_d(mp_int *a, mp_digit b); + +/* c = a + b */ +int mp_add_d(mp_int *a, mp_digit b, mp_int *c); + +/* c = a - b */ +int mp_sub_d(mp_int *a, mp_digit b, mp_int *c); + +/* c = a * b */ +int mp_mul_d(mp_int *a, mp_digit b, mp_int *c); + +/* a/b => cb + d == a */ +int mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d); + +/* a/3 => 3c + d == a */ +int mp_div_3(mp_int *a, mp_int *c, mp_digit *d); + +/* c = a**b */ +int mp_expt_d(mp_int *a, mp_digit b, mp_int *c); +int mp_expt_d_ex (mp_int * a, mp_digit b, mp_int * c, int fast); + +/* c = a mod b, 0 <= c < b */ +int mp_mod_d(mp_int *a, mp_digit b, mp_digit *c); + +/* ---> number theory <--- */ + +/* d = a + b (mod c) */ +int mp_addmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); + +/* d = a - b (mod c) */ +int mp_submod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); + +/* d = a * b (mod c) */ +int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); + +/* c = a * a (mod b) */ +int mp_sqrmod(mp_int *a, mp_int *b, mp_int *c); + +/* c = 1/a (mod b) */ +int mp_invmod(mp_int *a, mp_int *b, mp_int *c); + +/* c = (a, b) */ +int mp_gcd(mp_int *a, mp_int *b, mp_int *c); + +/* produces value such that U1*a + U2*b = U3 */ +int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3); + +/* c = [a, b] or (a*b)/(a, b) */ +int mp_lcm(mp_int *a, mp_int *b, mp_int *c); + +/* finds one of the b'th root of a, such that |c|**b <= |a| + * + * returns error if a < 0 and b is even + */ +int mp_n_root(mp_int *a, mp_digit b, mp_int *c); +int mp_n_root_ex (mp_int * a, mp_digit b, mp_int * c, int fast); + +/* special sqrt algo */ +int mp_sqrt(mp_int *arg, mp_int *ret); + +/* special sqrt (mod prime) */ +int mp_sqrtmod_prime(mp_int *arg, mp_int *prime, mp_int *ret); + +/* is number a square? */ +int mp_is_square(mp_int *arg, int *ret); + +/* computes the jacobi c = (a | n) (or Legendre if b is prime) */ +int mp_jacobi(mp_int *a, mp_int *n, int *c); + +/* used to setup the Barrett reduction for a given modulus b */ +int mp_reduce_setup(mp_int *a, mp_int *b); + +/* Barrett Reduction, computes a (mod b) with a precomputed value c + * + * Assumes that 0 < a <= b*b, note if 0 > a > -(b*b) then you can merely + * compute the reduction as -1 * mp_reduce(mp_abs(a)) [pseudo code]. + */ +int mp_reduce(mp_int *a, mp_int *b, mp_int *c); + +/* setups the montgomery reduction */ +int mp_montgomery_setup(mp_int *a, mp_digit *mp); + +/* computes a = B**n mod b without division or multiplication useful for + * normalizing numbers in a Montgomery system. + */ +int mp_montgomery_calc_normalization(mp_int *a, mp_int *b); + +/* computes x/R == x (mod N) via Montgomery Reduction */ +int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp); + +/* returns 1 if a is a valid DR modulus */ +int mp_dr_is_modulus(mp_int *a); + +/* sets the value of "d" required for mp_dr_reduce */ +void mp_dr_setup(mp_int *a, mp_digit *d); + +/* reduces a modulo b using the Diminished Radix method */ +int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp); + +/* returns true if a can be reduced with mp_reduce_2k */ +int mp_reduce_is_2k(mp_int *a); + +/* determines k value for 2k reduction */ +int mp_reduce_2k_setup(mp_int *a, mp_digit *d); + +/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */ +int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit 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); + +/* ---> Primes <--- */ + +/* number of primes */ +#ifdef MP_8BIT + #define PRIME_SIZE 31 +#else + #define PRIME_SIZE 256 +#endif + +/* table of first PRIME_SIZE primes */ +extern const mp_digit ltm_prime_tab[PRIME_SIZE]; + +/* result=1 if a is divisible by one of the first PRIME_SIZE primes */ +int mp_prime_is_divisible(mp_int *a, int *result); + +/* performs one Fermat test of "a" using base "b". + * Sets result to 0 if composite or 1 if probable prime + */ +int mp_prime_fermat(mp_int *a, mp_int *b, int *result); + +/* performs one Miller-Rabin test of "a" using base "b". + * Sets result to 0 if composite or 1 if probable prime + */ +int mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result); + +/* This gives [for a given bit size] the number of trials required + * such that Miller-Rabin gives a prob of failure lower than 2^-96 + */ +int mp_prime_rabin_miller_trials(int size); + +/* performs t rounds of Miller-Rabin on "a" using the first + * t prime bases. Also performs an initial sieve of trial + * division. Determines if "a" is prime with probability + * of error no more than (1/4)**t. + * + * Sets result to 1 if probably prime, 0 otherwise + */ +int mp_prime_is_prime(mp_int *a, int t, int *result); + +/* finds the next prime after the number "a" using "t" trials + * of Miller-Rabin. + * + * bbs_style = 1 means the prime must be congruent to 3 mod 4 + */ +int mp_prime_next_prime(mp_int *a, int t, int bbs_style); + +/* makes a truly random prime of a given size (bytes), + * call with bbs = 1 if you want it to be congruent to 3 mod 4 + * + * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can + * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself + * so it can be NULL + * + * The prime generated will be larger than 2^(8*size). + */ +#define mp_prime_random(a, t, size, bbs, cb, dat) mp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?LTM_PRIME_BBS:0, cb, dat) + +/* makes a truly random prime of a given size (bits), + * + * Flags are as follows: + * + * LTM_PRIME_BBS - make prime congruent to 3 mod 4 + * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS) + * LTM_PRIME_2MSB_ON - make the 2nd highest bit one + * + * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can + * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself + * so it can be NULL + * + */ +int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat); + +/* ---> radix conversion <--- */ +int mp_count_bits(mp_int *a); + +int mp_unsigned_bin_size(mp_int *a); +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, 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, 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); + +#ifndef LTM_NO_FILE +int mp_fread(mp_int *a, int radix, FILE *stream); +int mp_fwrite(mp_int *a, int radix, FILE *stream); +#endif + +#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len)) +#define mp_raw_size(mp) mp_signed_bin_size(mp) +#define mp_toraw(mp, str) mp_to_signed_bin((mp), (str)) +#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len)) +#define mp_mag_size(mp) mp_unsigned_bin_size(mp) +#define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str)) + +#define mp_tobinary(M, S) mp_toradix((M), (S), 2) +#define mp_tooctal(M, S) mp_toradix((M), (S), 8) +#define mp_todecimal(M, S) mp_toradix((M), (S), 10) +#define mp_tohex(M, S) mp_toradix((M), (S), 16) + +#ifdef __cplusplus + } +#endif + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/tommath_class.h b/src/ltm/tommath_class.h new file mode 100644 index 0000000..2085521 --- /dev/null +++ b/src/ltm/tommath_class.h @@ -0,0 +1,1057 @@ +#if !(defined(LTM1) && defined(LTM2) && defined(LTM3)) +#if defined(LTM2) +#define LTM3 +#endif +#if defined(LTM1) +#define LTM2 +#endif +#define LTM1 + +#if defined(LTM_ALL) +#define BN_ERROR_C +#define BN_FAST_MP_INVMOD_C +#define BN_FAST_MP_MONTGOMERY_REDUCE_C +#define BN_FAST_S_MP_MUL_DIGS_C +#define BN_FAST_S_MP_MUL_HIGH_DIGS_C +#define BN_FAST_S_MP_SQR_C +#define BN_MP_2EXPT_C +#define BN_MP_ABS_C +#define BN_MP_ADD_C +#define BN_MP_ADD_D_C +#define BN_MP_ADDMOD_C +#define BN_MP_AND_C +#define BN_MP_CLAMP_C +#define BN_MP_CLEAR_C +#define BN_MP_CLEAR_MULTI_C +#define BN_MP_CMP_C +#define BN_MP_CMP_D_C +#define BN_MP_CMP_MAG_C +#define BN_MP_CNT_LSB_C +#define BN_MP_COPY_C +#define BN_MP_COUNT_BITS_C +#define BN_MP_DIV_C +#define BN_MP_DIV_2_C +#define BN_MP_DIV_2D_C +#define BN_MP_DIV_3_C +#define BN_MP_DIV_D_C +#define BN_MP_DR_IS_MODULUS_C +#define BN_MP_DR_REDUCE_C +#define BN_MP_DR_SETUP_C +#define BN_MP_EXCH_C +#define BN_MP_EXPORT_C +#define BN_MP_EXPT_D_C +#define BN_MP_EXPT_D_EX_C +#define BN_MP_EXPTMOD_C +#define BN_MP_EXPTMOD_FAST_C +#define BN_MP_EXTEUCLID_C +#define BN_MP_FREAD_C +#define BN_MP_FWRITE_C +#define BN_MP_GCD_C +#define BN_MP_GET_INT_C +#define BN_MP_GET_LONG_C +#define BN_MP_GET_LONG_LONG_C +#define BN_MP_GROW_C +#define BN_MP_IMPORT_C +#define BN_MP_INIT_C +#define BN_MP_INIT_COPY_C +#define BN_MP_INIT_MULTI_C +#define BN_MP_INIT_SET_C +#define BN_MP_INIT_SET_INT_C +#define BN_MP_INIT_SIZE_C +#define BN_MP_INVMOD_C +#define BN_MP_INVMOD_SLOW_C +#define BN_MP_IS_SQUARE_C +#define BN_MP_JACOBI_C +#define BN_MP_KARATSUBA_MUL_C +#define BN_MP_KARATSUBA_SQR_C +#define BN_MP_LCM_C +#define BN_MP_LSHD_C +#define BN_MP_MOD_C +#define BN_MP_MOD_2D_C +#define BN_MP_MOD_D_C +#define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C +#define BN_MP_MONTGOMERY_REDUCE_C +#define BN_MP_MONTGOMERY_SETUP_C +#define BN_MP_MUL_C +#define BN_MP_MUL_2_C +#define BN_MP_MUL_2D_C +#define BN_MP_MUL_D_C +#define BN_MP_MULMOD_C +#define BN_MP_N_ROOT_C +#define BN_MP_N_ROOT_EX_C +#define BN_MP_NEG_C +#define BN_MP_OR_C +#define BN_MP_PRIME_FERMAT_C +#define BN_MP_PRIME_IS_DIVISIBLE_C +#define BN_MP_PRIME_IS_PRIME_C +#define BN_MP_PRIME_MILLER_RABIN_C +#define BN_MP_PRIME_NEXT_PRIME_C +#define BN_MP_PRIME_RABIN_MILLER_TRIALS_C +#define BN_MP_PRIME_RANDOM_EX_C +#define BN_MP_RADIX_SIZE_C +#define BN_MP_RADIX_SMAP_C +#define BN_MP_RAND_C +#define BN_MP_READ_RADIX_C +#define BN_MP_READ_SIGNED_BIN_C +#define BN_MP_READ_UNSIGNED_BIN_C +#define BN_MP_REDUCE_C +#define BN_MP_REDUCE_2K_C +#define BN_MP_REDUCE_2K_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 +#define BN_MP_SET_INT_C +#define BN_MP_SET_LONG_C +#define BN_MP_SET_LONG_LONG_C +#define BN_MP_SHRINK_C +#define BN_MP_SIGNED_BIN_SIZE_C +#define BN_MP_SQR_C +#define BN_MP_SQRMOD_C +#define BN_MP_SQRT_C +#define BN_MP_SQRTMOD_PRIME_C +#define BN_MP_SUB_C +#define BN_MP_SUB_D_C +#define BN_MP_SUBMOD_C +#define BN_MP_TO_SIGNED_BIN_C +#define BN_MP_TO_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 +#define BN_MP_TORADIX_N_C +#define BN_MP_UNSIGNED_BIN_SIZE_C +#define BN_MP_XOR_C +#define BN_MP_ZERO_C +#define BN_PRIME_TAB_C +#define BN_REVERSE_C +#define BN_S_MP_ADD_C +#define BN_S_MP_EXPTMOD_C +#define BN_S_MP_MUL_DIGS_C +#define BN_S_MP_MUL_HIGH_DIGS_C +#define BN_S_MP_SQR_C +#define BN_S_MP_SUB_C +#define BNCORE_C +#endif + +#if defined(BN_ERROR_C) + #define BN_MP_ERROR_TO_STRING_C +#endif + +#if defined(BN_FAST_MP_INVMOD_C) + #define BN_MP_ISEVEN_C + #define BN_MP_INIT_MULTI_C + #define BN_MP_COPY_C + #define BN_MP_MOD_C + #define BN_MP_SET_C + #define BN_MP_DIV_2_C + #define BN_MP_ISODD_C + #define BN_MP_SUB_C + #define BN_MP_CMP_C + #define BN_MP_ISZERO_C + #define BN_MP_CMP_D_C + #define BN_MP_ADD_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_FAST_MP_MONTGOMERY_REDUCE_C) + #define BN_MP_GROW_C + #define BN_MP_RSHD_C + #define BN_MP_CLAMP_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_FAST_S_MP_MUL_DIGS_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_FAST_S_MP_SQR_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_2EXPT_C) + #define BN_MP_ZERO_C + #define BN_MP_GROW_C +#endif + +#if defined(BN_MP_ABS_C) + #define BN_MP_COPY_C +#endif + +#if defined(BN_MP_ADD_C) + #define BN_S_MP_ADD_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_ADD_D_C) + #define BN_MP_GROW_C + #define BN_MP_SUB_D_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_ADDMOD_C) + #define BN_MP_INIT_C + #define BN_MP_ADD_C + #define BN_MP_CLEAR_C + #define BN_MP_MOD_C +#endif + +#if defined(BN_MP_AND_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_CLAMP_C) +#endif + +#if defined(BN_MP_CLEAR_C) +#endif + +#if defined(BN_MP_CLEAR_MULTI_C) + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_CMP_C) + #define BN_MP_CMP_MAG_C +#endif + +#if defined(BN_MP_CMP_D_C) +#endif + +#if defined(BN_MP_CMP_MAG_C) +#endif + +#if defined(BN_MP_CNT_LSB_C) + #define BN_MP_ISZERO_C +#endif + +#if defined(BN_MP_COPY_C) + #define BN_MP_GROW_C +#endif + +#if defined(BN_MP_COUNT_BITS_C) +#endif + +#if defined(BN_MP_DIV_C) + #define BN_MP_ISZERO_C + #define BN_MP_CMP_MAG_C + #define BN_MP_COPY_C + #define BN_MP_ZERO_C + #define BN_MP_INIT_MULTI_C + #define BN_MP_SET_C + #define BN_MP_COUNT_BITS_C + #define BN_MP_ABS_C + #define BN_MP_MUL_2D_C + #define BN_MP_CMP_C + #define BN_MP_SUB_C + #define BN_MP_ADD_C + #define BN_MP_DIV_2D_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_MULTI_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_INIT_C + #define BN_MP_INIT_COPY_C + #define BN_MP_LSHD_C + #define BN_MP_RSHD_C + #define BN_MP_MUL_D_C + #define BN_MP_CLAMP_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_DIV_2_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_DIV_2D_C) + #define BN_MP_COPY_C + #define BN_MP_ZERO_C + #define BN_MP_INIT_C + #define BN_MP_MOD_2D_C + #define BN_MP_CLEAR_C + #define BN_MP_RSHD_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C +#endif + +#if defined(BN_MP_DIV_3_C) + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_DIV_D_C) + #define BN_MP_ISZERO_C + #define BN_MP_COPY_C + #define BN_MP_DIV_2D_C + #define BN_MP_DIV_3_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_DR_IS_MODULUS_C) +#endif + +#if defined(BN_MP_DR_REDUCE_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_DR_SETUP_C) +#endif + +#if defined(BN_MP_EXCH_C) +#endif + +#if defined(BN_MP_EXPORT_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_COUNT_BITS_C + #define BN_MP_DIV_2D_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_EXPT_D_C) + #define BN_MP_EXPT_D_EX_C +#endif + +#if defined(BN_MP_EXPT_D_EX_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_SET_C + #define BN_MP_MUL_C + #define BN_MP_CLEAR_C + #define BN_MP_SQR_C +#endif + +#if defined(BN_MP_EXPTMOD_C) + #define BN_MP_INIT_C + #define BN_MP_INVMOD_C + #define BN_MP_CLEAR_C + #define BN_MP_ABS_C + #define BN_MP_CLEAR_MULTI_C + #define BN_MP_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 +#endif + +#if defined(BN_MP_EXPTMOD_FAST_C) + #define BN_MP_COUNT_BITS_C + #define BN_MP_INIT_C + #define BN_MP_CLEAR_C + #define BN_MP_MONTGOMERY_SETUP_C + #define BN_FAST_MP_MONTGOMERY_REDUCE_C + #define BN_MP_MONTGOMERY_REDUCE_C + #define BN_MP_DR_SETUP_C + #define BN_MP_DR_REDUCE_C + #define BN_MP_REDUCE_2K_SETUP_C + #define BN_MP_REDUCE_2K_C + #define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C + #define BN_MP_MULMOD_C + #define BN_MP_SET_C + #define BN_MP_MOD_C + #define BN_MP_COPY_C + #define BN_MP_SQR_C + #define BN_MP_MUL_C + #define BN_MP_EXCH_C +#endif + +#if defined(BN_MP_EXTEUCLID_C) + #define BN_MP_INIT_MULTI_C + #define BN_MP_SET_C + #define BN_MP_COPY_C + #define BN_MP_ISZERO_C + #define BN_MP_DIV_C + #define BN_MP_MUL_C + #define BN_MP_SUB_C + #define BN_MP_NEG_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_FREAD_C) + #define BN_MP_ZERO_C + #define BN_MP_S_RMAP_C + #define BN_MP_MUL_D_C + #define BN_MP_ADD_D_C + #define BN_MP_CMP_D_C +#endif + +#if defined(BN_MP_FWRITE_C) + #define BN_MP_RADIX_SIZE_C + #define BN_MP_TORADIX_C +#endif + +#if defined(BN_MP_GCD_C) + #define BN_MP_ISZERO_C + #define BN_MP_ABS_C + #define BN_MP_INIT_COPY_C + #define BN_MP_CNT_LSB_C + #define BN_MP_DIV_2D_C + #define BN_MP_CMP_MAG_C + #define BN_MP_EXCH_C + #define BN_S_MP_SUB_C + #define BN_MP_MUL_2D_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_GET_INT_C) +#endif + +#if defined(BN_MP_GET_LONG_C) +#endif + +#if defined(BN_MP_GET_LONG_LONG_C) +#endif + +#if defined(BN_MP_GROW_C) +#endif + +#if defined(BN_MP_IMPORT_C) + #define BN_MP_ZERO_C + #define BN_MP_MUL_2D_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_INIT_C) +#endif + +#if defined(BN_MP_INIT_COPY_C) + #define BN_MP_INIT_SIZE_C + #define BN_MP_COPY_C +#endif + +#if defined(BN_MP_INIT_MULTI_C) + #define BN_MP_ERR_C + #define BN_MP_INIT_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_INIT_SET_C) + #define BN_MP_INIT_C + #define BN_MP_SET_C +#endif + +#if defined(BN_MP_INIT_SET_INT_C) + #define BN_MP_INIT_C + #define BN_MP_SET_INT_C +#endif + +#if defined(BN_MP_INIT_SIZE_C) + #define BN_MP_INIT_C +#endif + +#if defined(BN_MP_INVMOD_C) + #define BN_MP_ISZERO_C + #define BN_MP_ISODD_C + #define BN_FAST_MP_INVMOD_C + #define BN_MP_INVMOD_SLOW_C +#endif + +#if defined(BN_MP_INVMOD_SLOW_C) + #define BN_MP_ISZERO_C + #define BN_MP_INIT_MULTI_C + #define BN_MP_MOD_C + #define BN_MP_COPY_C + #define BN_MP_ISEVEN_C + #define BN_MP_SET_C + #define BN_MP_DIV_2_C + #define BN_MP_ISODD_C + #define BN_MP_ADD_C + #define BN_MP_SUB_C + #define BN_MP_CMP_C + #define BN_MP_CMP_D_C + #define BN_MP_CMP_MAG_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_IS_SQUARE_C) + #define BN_MP_MOD_D_C + #define BN_MP_INIT_SET_INT_C + #define BN_MP_MOD_C + #define BN_MP_GET_INT_C + #define BN_MP_SQRT_C + #define BN_MP_SQR_C + #define BN_MP_CMP_MAG_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_JACOBI_C) + #define BN_MP_CMP_D_C + #define BN_MP_ISZERO_C + #define BN_MP_INIT_COPY_C + #define BN_MP_CNT_LSB_C + #define BN_MP_DIV_2D_C + #define BN_MP_MOD_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_KARATSUBA_MUL_C) + #define BN_MP_MUL_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_S_MP_ADD_C + #define BN_MP_ADD_C + #define BN_S_MP_SUB_C + #define BN_MP_LSHD_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_KARATSUBA_SQR_C) + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_SQR_C + #define BN_S_MP_ADD_C + #define BN_S_MP_SUB_C + #define BN_MP_LSHD_C + #define BN_MP_ADD_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_LCM_C) + #define BN_MP_INIT_MULTI_C + #define BN_MP_GCD_C + #define BN_MP_CMP_MAG_C + #define BN_MP_DIV_C + #define BN_MP_MUL_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_LSHD_C) + #define BN_MP_GROW_C + #define BN_MP_RSHD_C +#endif + +#if defined(BN_MP_MOD_C) + #define BN_MP_INIT_C + #define BN_MP_DIV_C + #define BN_MP_CLEAR_C + #define BN_MP_ISZERO_C + #define BN_MP_EXCH_C + #define BN_MP_ADD_C +#endif + +#if defined(BN_MP_MOD_2D_C) + #define BN_MP_ZERO_C + #define BN_MP_COPY_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_MOD_D_C) + #define BN_MP_DIV_D_C +#endif + +#if defined(BN_MP_MONTGOMERY_CALC_NORMALIZATION_C) + #define BN_MP_COUNT_BITS_C + #define BN_MP_2EXPT_C + #define BN_MP_SET_C + #define BN_MP_MUL_2_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_MONTGOMERY_REDUCE_C) + #define BN_FAST_MP_MONTGOMERY_REDUCE_C + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C + #define BN_MP_RSHD_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_MONTGOMERY_SETUP_C) +#endif + +#if defined(BN_MP_MUL_C) + #define BN_MP_TOOM_MUL_C + #define BN_MP_KARATSUBA_MUL_C + #define BN_FAST_S_MP_MUL_DIGS_C + #define BN_S_MP_MUL_C + #define BN_S_MP_MUL_DIGS_C +#endif + +#if defined(BN_MP_MUL_2_C) + #define BN_MP_GROW_C +#endif + +#if defined(BN_MP_MUL_2D_C) + #define BN_MP_COPY_C + #define BN_MP_GROW_C + #define BN_MP_LSHD_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_MUL_D_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_MULMOD_C) + #define BN_MP_INIT_C + #define BN_MP_MUL_C + #define BN_MP_CLEAR_C + #define BN_MP_MOD_C +#endif + +#if defined(BN_MP_N_ROOT_C) + #define BN_MP_N_ROOT_EX_C +#endif + +#if defined(BN_MP_N_ROOT_EX_C) + #define BN_MP_INIT_C + #define BN_MP_SET_C + #define BN_MP_COPY_C + #define BN_MP_EXPT_D_EX_C + #define BN_MP_MUL_C + #define BN_MP_SUB_C + #define BN_MP_MUL_D_C + #define BN_MP_DIV_C + #define BN_MP_CMP_C + #define BN_MP_SUB_D_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_NEG_C) + #define BN_MP_COPY_C + #define BN_MP_ISZERO_C +#endif + +#if defined(BN_MP_OR_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_FERMAT_C) + #define BN_MP_CMP_D_C + #define BN_MP_INIT_C + #define BN_MP_EXPTMOD_C + #define BN_MP_CMP_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_IS_DIVISIBLE_C) + #define BN_MP_MOD_D_C +#endif + +#if defined(BN_MP_PRIME_IS_PRIME_C) + #define BN_MP_CMP_D_C + #define BN_MP_PRIME_IS_DIVISIBLE_C + #define BN_MP_INIT_C + #define BN_MP_SET_C + #define BN_MP_PRIME_MILLER_RABIN_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_MILLER_RABIN_C) + #define BN_MP_CMP_D_C + #define BN_MP_INIT_COPY_C + #define BN_MP_SUB_D_C + #define BN_MP_CNT_LSB_C + #define BN_MP_DIV_2D_C + #define BN_MP_EXPTMOD_C + #define BN_MP_CMP_C + #define BN_MP_SQRMOD_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_NEXT_PRIME_C) + #define BN_MP_CMP_D_C + #define BN_MP_SET_C + #define BN_MP_SUB_D_C + #define BN_MP_ISEVEN_C + #define BN_MP_MOD_D_C + #define BN_MP_INIT_C + #define BN_MP_ADD_D_C + #define BN_MP_PRIME_MILLER_RABIN_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_RABIN_MILLER_TRIALS_C) +#endif + +#if defined(BN_MP_PRIME_RANDOM_EX_C) + #define BN_MP_READ_UNSIGNED_BIN_C + #define BN_MP_PRIME_IS_PRIME_C + #define BN_MP_SUB_D_C + #define BN_MP_DIV_2_C + #define BN_MP_MUL_2_C + #define BN_MP_ADD_D_C +#endif + +#if defined(BN_MP_RADIX_SIZE_C) + #define BN_MP_ISZERO_C + #define BN_MP_COUNT_BITS_C + #define BN_MP_INIT_COPY_C + #define BN_MP_DIV_D_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_RADIX_SMAP_C) + #define BN_MP_S_RMAP_C +#endif + +#if defined(BN_MP_RAND_C) + #define BN_MP_ZERO_C + #define BN_MP_ADD_D_C + #define BN_MP_LSHD_C +#endif + +#if defined(BN_MP_READ_RADIX_C) + #define BN_MP_ZERO_C + #define BN_MP_S_RMAP_C + #define BN_MP_MUL_D_C + #define BN_MP_ADD_D_C + #define BN_MP_ISZERO_C +#endif + +#if defined(BN_MP_READ_SIGNED_BIN_C) + #define BN_MP_READ_UNSIGNED_BIN_C +#endif + +#if defined(BN_MP_READ_UNSIGNED_BIN_C) + #define BN_MP_GROW_C + #define BN_MP_ZERO_C + #define BN_MP_MUL_2D_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_REDUCE_C) + #define BN_MP_REDUCE_SETUP_C + #define BN_MP_INIT_COPY_C + #define BN_MP_RSHD_C + #define BN_MP_MUL_C + #define BN_S_MP_MUL_HIGH_DIGS_C + #define BN_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 + #define BN_MP_CMP_D_C + #define BN_MP_SET_C + #define BN_MP_LSHD_C + #define BN_MP_ADD_C + #define BN_MP_CMP_C + #define BN_S_MP_SUB_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_REDUCE_2K_C) + #define BN_MP_INIT_C + #define BN_MP_COUNT_BITS_C + #define BN_MP_DIV_2D_C + #define BN_MP_MUL_D_C + #define BN_S_MP_ADD_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_REDUCE_2K_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 + #define BN_MP_2EXPT_C + #define BN_MP_CLEAR_C + #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 +#endif + +#if defined(BN_MP_RSHD_C) + #define BN_MP_ZERO_C +#endif + +#if defined(BN_MP_SET_C) + #define BN_MP_ZERO_C +#endif + +#if defined(BN_MP_SET_INT_C) + #define BN_MP_ZERO_C + #define BN_MP_MUL_2D_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_SET_LONG_C) +#endif + +#if defined(BN_MP_SET_LONG_LONG_C) +#endif + +#if defined(BN_MP_SHRINK_C) +#endif + +#if defined(BN_MP_SIGNED_BIN_SIZE_C) + #define BN_MP_UNSIGNED_BIN_SIZE_C +#endif + +#if defined(BN_MP_SQR_C) + #define BN_MP_TOOM_SQR_C + #define BN_MP_KARATSUBA_SQR_C + #define BN_FAST_S_MP_SQR_C + #define BN_S_MP_SQR_C +#endif + +#if defined(BN_MP_SQRMOD_C) + #define BN_MP_INIT_C + #define BN_MP_SQR_C + #define BN_MP_CLEAR_C + #define BN_MP_MOD_C +#endif + +#if defined(BN_MP_SQRT_C) + #define BN_MP_N_ROOT_C + #define BN_MP_ISZERO_C + #define BN_MP_ZERO_C + #define BN_MP_INIT_COPY_C + #define BN_MP_RSHD_C + #define BN_MP_DIV_C + #define BN_MP_ADD_C + #define BN_MP_DIV_2_C + #define BN_MP_CMP_MAG_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_SQRTMOD_PRIME_C) + #define BN_MP_CMP_D_C + #define BN_MP_ZERO_C + #define BN_MP_JACOBI_C + #define BN_MP_INIT_MULTI_C + #define BN_MP_MOD_D_C + #define BN_MP_ADD_D_C + #define BN_MP_DIV_2_C + #define BN_MP_EXPTMOD_C + #define BN_MP_COPY_C + #define BN_MP_SUB_D_C + #define BN_MP_ISEVEN_C + #define BN_MP_SET_INT_C + #define BN_MP_SQRMOD_C + #define BN_MP_MULMOD_C + #define BN_MP_SET_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_SUB_C) + #define BN_S_MP_ADD_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_SUB_D_C) + #define BN_MP_GROW_C + #define BN_MP_ADD_D_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_SUBMOD_C) + #define BN_MP_INIT_C + #define BN_MP_SUB_C + #define BN_MP_CLEAR_C + #define BN_MP_MOD_C +#endif + +#if defined(BN_MP_TO_SIGNED_BIN_C) + #define BN_MP_TO_UNSIGNED_BIN_C +#endif + +#if defined(BN_MP_TO_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 + #define BN_MP_DIV_2D_C + #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 + #define BN_MP_COPY_C + #define BN_MP_RSHD_C + #define BN_MP_MUL_C + #define BN_MP_MUL_2_C + #define BN_MP_ADD_C + #define BN_MP_SUB_C + #define BN_MP_DIV_2_C + #define BN_MP_MUL_2D_C + #define BN_MP_MUL_D_C + #define BN_MP_DIV_3_C + #define BN_MP_LSHD_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_TOOM_SQR_C) + #define BN_MP_INIT_MULTI_C + #define BN_MP_MOD_2D_C + #define BN_MP_COPY_C + #define BN_MP_RSHD_C + #define BN_MP_SQR_C + #define BN_MP_MUL_2_C + #define BN_MP_ADD_C + #define BN_MP_SUB_C + #define BN_MP_DIV_2_C + #define BN_MP_MUL_2D_C + #define BN_MP_MUL_D_C + #define BN_MP_DIV_3_C + #define BN_MP_LSHD_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_TORADIX_C) + #define BN_MP_ISZERO_C + #define BN_MP_INIT_COPY_C + #define BN_MP_DIV_D_C + #define BN_MP_CLEAR_C + #define BN_MP_S_RMAP_C +#endif + +#if defined(BN_MP_TORADIX_N_C) + #define BN_MP_ISZERO_C + #define BN_MP_INIT_COPY_C + #define BN_MP_DIV_D_C + #define BN_MP_CLEAR_C + #define BN_MP_S_RMAP_C +#endif + +#if defined(BN_MP_UNSIGNED_BIN_SIZE_C) + #define BN_MP_COUNT_BITS_C +#endif + +#if defined(BN_MP_XOR_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_ZERO_C) +#endif + +#if defined(BN_PRIME_TAB_C) +#endif + +#if defined(BN_REVERSE_C) +#endif + +#if defined(BN_S_MP_ADD_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_S_MP_EXPTMOD_C) + #define BN_MP_COUNT_BITS_C + #define BN_MP_INIT_C + #define BN_MP_CLEAR_C + #define BN_MP_REDUCE_SETUP_C + #define BN_MP_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_MUL_C + #define BN_MP_SET_C + #define BN_MP_EXCH_C +#endif + +#if defined(BN_S_MP_MUL_DIGS_C) + #define BN_FAST_S_MP_MUL_DIGS_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_S_MP_MUL_HIGH_DIGS_C) + #define BN_FAST_S_MP_MUL_HIGH_DIGS_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_S_MP_SQR_C) + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_S_MP_SUB_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BNCORE_C) +#endif + +#ifdef LTM3 +#define LTM_LAST +#endif +#include +#include +#else +#define LTM_LAST +#endif diff --git a/src/ltm/tommath_private.h b/src/ltm/tommath_private.h new file mode 100644 index 0000000..3d6b6ac --- /dev/null +++ b/src/ltm/tommath_private.h @@ -0,0 +1,123 @@ +/* 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, tstdenis82@gmail.com, http://math.libtomcrypt.com + */ +#ifndef TOMMATH_PRIV_H_ +#define TOMMATH_PRIV_H_ + +#include +#include + +#ifndef MIN +#define MIN(x,y) (((x) < (y)) ? (x) : (y)) +#endif + +#ifndef MAX +#define MAX(x,y) (((x) > (y)) ? (x) : (y)) +#endif + +#ifdef __cplusplus +extern "C" { + +/* C++ compilers don't like assigning void * to mp_digit * */ +#define OPT_CAST(x) (x *) + +#else + +/* C on the other hand doesn't care */ +#define OPT_CAST(x) + +#endif + +/* define heap macros */ +#ifndef XMALLOC + /* default to libc stuff */ + #define XMALLOC malloc + #define XFREE free + #define XREALLOC realloc + #define XCALLOC calloc +#else + /* prototypes for our heap functions */ + extern void *XMALLOC(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 + +/* lowlevel functions, do not call! */ +int s_mp_add(mp_int *a, mp_int *b, mp_int *c); +int s_mp_sub(mp_int *a, mp_int *b, mp_int *c); +#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1) +int fast_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); +int fast_s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs); +int s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs); +int fast_s_mp_sqr(mp_int *a, mp_int *b); +int s_mp_sqr(mp_int *a, mp_int *b); +int mp_karatsuba_mul(mp_int *a, mp_int *b, mp_int *c); +int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c); +int mp_karatsuba_sqr(mp_int *a, mp_int *b); +int mp_toom_sqr(mp_int *a, mp_int *b); +int fast_mp_invmod(mp_int *a, mp_int *b, mp_int *c); +int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c); +int fast_mp_montgomery_reduce(mp_int *x, mp_int *n, mp_digit rho); +int mp_exptmod_fast(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int redmode); +int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode); +void bn_reverse(unsigned char *s, int len); + +extern const char *mp_s_rmap; + +/* Fancy macro to set an MPI from another type. + * There are several things assumed: + * x is the counter and unsigned + * a is the pointer to the MPI + * b is the original value that should be set in the MPI. + */ +#define MP_SET_XLONG(func_name, type) \ +int func_name (mp_int * a, type b) \ +{ \ + unsigned int x; \ + int res; \ + \ + mp_zero (a); \ + \ + /* set four bits at a time */ \ + for (x = 0; x < (sizeof(type) * 2u); x++) { \ + /* shift the number up four bits */ \ + if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) { \ + return res; \ + } \ + \ + /* OR in the top four bits of the source */ \ + a->dp[0] |= (b >> ((sizeof(type) * 8u) - 4u)) & 15u; \ + \ + /* shift the source up to the next four bits */ \ + b <<= 4; \ + \ + /* ensure that digits are not clamped off */ \ + a->used += 1; \ + } \ + mp_clamp (a); \ + return MP_OKAY; \ +} + +#ifdef __cplusplus + } +#endif + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ltm/tommath_superclass.h b/src/ltm/tommath_superclass.h new file mode 100644 index 0000000..1b26841 --- /dev/null +++ b/src/ltm/tommath_superclass.h @@ -0,0 +1,76 @@ +/* super class file for PK algos */ + +/* default ... include all MPI */ +#define LTM_ALL + +/* RSA only (does not support DH/DSA/ECC) */ +/* #define SC_RSA_1 */ + +/* For reference.... On an Athlon64 optimizing for speed... + + LTM's mpi.o with all functions [striped] is 142KiB in size. + +*/ + +/* Works for RSA only, mpi.o is 68KiB */ +#ifdef SC_RSA_1 + #define BN_MP_SHRINK_C + #define BN_MP_LCM_C + #define BN_MP_PRIME_RANDOM_EX_C + #define BN_MP_INVMOD_C + #define BN_MP_GCD_C + #define BN_MP_MOD_C + #define BN_MP_MULMOD_C + #define BN_MP_ADDMOD_C + #define BN_MP_EXPTMOD_C + #define BN_MP_SET_INT_C + #define BN_MP_INIT_MULTI_C + #define BN_MP_CLEAR_MULTI_C + #define BN_MP_UNSIGNED_BIN_SIZE_C + #define BN_MP_TO_UNSIGNED_BIN_C + #define BN_MP_MOD_D_C + #define BN_MP_PRIME_RABIN_MILLER_TRIALS_C + #define BN_REVERSE_C + #define BN_PRIME_TAB_C + + /* other modifiers */ + #define BN_MP_DIV_SMALL /* Slower division, not critical */ + + /* here we are on the last pass so we turn things off. The functions classes are still there + * but we remove them specifically from the build. This also invokes tweaks in functions + * like removing support for even moduli, etc... + */ +#ifdef LTM_LAST + #undef BN_MP_TOOM_MUL_C + #undef BN_MP_TOOM_SQR_C + #undef BN_MP_KARATSUBA_MUL_C + #undef BN_MP_KARATSUBA_SQR_C + #undef BN_MP_REDUCE_C + #undef BN_MP_REDUCE_SETUP_C + #undef BN_MP_DR_IS_MODULUS_C + #undef BN_MP_DR_SETUP_C + #undef BN_MP_DR_REDUCE_C + #undef BN_MP_REDUCE_IS_2K_C + #undef BN_MP_REDUCE_2K_SETUP_C + #undef BN_MP_REDUCE_2K_C + #undef BN_S_MP_EXPTMOD_C + #undef BN_MP_DIV_3_C + #undef BN_S_MP_MUL_HIGH_DIGS_C + #undef BN_FAST_S_MP_MUL_HIGH_DIGS_C + #undef BN_FAST_MP_INVMOD_C + + /* To safely undefine these you have to make sure your RSA key won't exceed the Comba threshold + * which is roughly 255 digits [7140 bits for 32-bit machines, 15300 bits for 64-bit machines] + * which means roughly speaking you can handle upto 2536-bit RSA keys with these defined without + * trouble. + */ + #undef BN_S_MP_MUL_DIGS_C + #undef BN_S_MP_SQR_C + #undef BN_MP_MONTGOMERY_REDUCE_C +#endif + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/t/001_compile.t b/t/001_compile.t new file mode 100644 index 0000000..0795acf --- /dev/null +++ b/t/001_compile.t @@ -0,0 +1,73 @@ +use strict; +use warnings; + +use Test::More tests => 1; + +diag( "Testing CryptX $CryptX::VERSION, Perl $], $^X" ); + +my $ok; +END { die "Could not load all modules" unless $ok } + +use CryptX; +use Crypt::Cipher::AES; +use Crypt::Cipher::Anubis; +use Crypt::Cipher::Blowfish; +use Crypt::Cipher::Camellia; +use Crypt::Cipher::CAST5; +use Crypt::Cipher::DES; +use Crypt::Cipher::DES_EDE; +use Crypt::Cipher::KASUMI; +use Crypt::Cipher::Khazad; +use Crypt::Cipher::MULTI2; +use Crypt::Cipher::Noekeon; +use Crypt::Cipher::RC2; +use Crypt::Cipher::RC5; +use Crypt::Cipher::RC6; +use Crypt::Cipher::SAFERP; +use Crypt::Cipher::SAFER_K128; +use Crypt::Cipher::SAFER_K64; +use Crypt::Cipher::SAFER_SK128; +use Crypt::Cipher::SAFER_SK64; +use Crypt::Cipher::SEED; +use Crypt::Cipher::Skipjack; +use Crypt::Cipher::Twofish; +use Crypt::Cipher::XTEA; +use Crypt::Cipher; +use Crypt::Digest::CHAES; +use Crypt::Digest::MD2; +use Crypt::Digest::MD4; +use Crypt::Digest::MD5; +use Crypt::Digest::RIPEMD128; +use Crypt::Digest::RIPEMD160; +use Crypt::Digest::RIPEMD256; +use Crypt::Digest::RIPEMD320; +use Crypt::Digest::SHA1; +use Crypt::Digest::SHA224; +use Crypt::Digest::SHA256; +use Crypt::Digest::SHA384; +use Crypt::Digest::SHA512; +use Crypt::Digest::Tiger192; +use Crypt::Digest::Whirlpool; +use Crypt::Digest; +use Crypt::Mac::F9; +use Crypt::Mac::HMAC; +use Crypt::Mac::OMAC; +use Crypt::Mac::Pelican; +use Crypt::Mac::PMAC; +use Crypt::Mac::XCBC; +use Crypt::Mode::CBC; +use Crypt::Mode::ECB; +use Crypt::Mode::OFB; +use Crypt::Mode::CFB; +use Crypt::Mode::CTR; +use Crypt::PK::RSA; +use Crypt::PK::DSA; +use Crypt::PK::ECC; +use Crypt::PK::DH; +use Crypt::Checksum; +use Crypt::Checksum::Adler32; +use Crypt::Checksum::CRC32; + +ok 1, 'All modules loaded successfully'; +$ok = 1; + diff --git a/t/002_all_pm.t b/t/002_all_pm.t new file mode 100644 index 0000000..60900a3 --- /dev/null +++ b/t/002_all_pm.t @@ -0,0 +1,19 @@ +use strict; +use warnings; + +use Test::More; + +plan skip_all => "File::Find not installed" unless eval { require File::Find }; +plan tests => 1; + +my @files; +File::Find::find({ wanted=>sub { push @files, $_ if /\.pm$/ }, no_chdir=>1 }, 'lib'); + +for my $m (sort @files) { + $m =~ s|[\\/]|::|g; + $m =~ s|^lib::||; + $m =~ s|\.pm$||; + eval "use $m; 1;" or die "ERROR: 'use $m' failed"; +} + +ok 1, 'all done'; diff --git a/t/003_all_pm_pod.t b/t/003_all_pm_pod.t new file mode 100644 index 0000000..4911c4f --- /dev/null +++ b/t/003_all_pm_pod.t @@ -0,0 +1,15 @@ +use strict; +use warnings; + +use Test::More; + +plan skip_all => "File::Find not installed" unless eval { require File::Find }; +plan skip_all => "Test::Pod not installed" unless eval { require Test::Pod }; +plan tests => 98; + +my @files; +File::Find::find({ wanted=>sub { push @files, $_ if /\.pm$/ }, no_chdir=>1 }, 'lib'); + +for my $m (sort @files) { + Test::Pod::pod_file_ok( $m, "Valid POD in '$m'" ); +} \ No newline at end of file diff --git a/t/auth_enc_ccm.t b/t/auth_enc_ccm.t new file mode 100644 index 0000000..6f03849 --- /dev/null +++ b/t/auth_enc_ccm.t @@ -0,0 +1,25 @@ +use strict; +use warnings; + +use Test::More tests => 6; + +use Crypt::AuthEnc::CCM qw( ccm_encrypt_authenticate ccm_decrypt_verify ); + +my $nonce = "random-nonce"; +my $key = "12345678901234561234567890123456"; + +{ + my ($ct, $tag) = ccm_encrypt_authenticate('AES', $key, $nonce, "header-abc", 16, "plain_halfplain_half"); + is(unpack('H*', $ct), "96b0114ff47da72e92631aadce84f203a8168b20", "ccm_encrypt_authenticate: ciphertext"); + is(unpack('H*', $tag), "9485c6d5709b43431a4f05370cc22603", "ccm_encrypt_authenticate: tag"); + my $pt = ccm_decrypt_verify('AES', $key, $nonce, "header-abc", $ct, $tag); + is($pt, "plain_halfplain_half", "ccm_decrypt_verify: plaintext"); +} + +{ + my ($ct, $tag) = ccm_encrypt_authenticate('AES', $key, $nonce, "", 16, "plain_halfplain_half"); + is(unpack('H*', $ct), "96b0114ff47da72e92631aadce84f203a8168b20", "ccm_encrypt_authenticate: ciphertext (no header)"); + is(unpack('H*', $tag), "9e9cba5dd4939d0d8e2687c85c5d3b89", "ccm_encrypt_authenticate: tag (no header)"); + my $pt = ccm_decrypt_verify('AES', $key, $nonce, "", $ct, $tag); + is($pt, "plain_halfplain_half", "ccm_decrypt_verify: plaintext (no header)"); +} \ No newline at end of file diff --git a/t/auth_enc_ccm_test_vector_ltc.t b/t/auth_enc_ccm_test_vector_ltc.t new file mode 100644 index 0000000..eeb80c3 --- /dev/null +++ b/t/auth_enc_ccm_test_vector_ltc.t @@ -0,0 +1,65 @@ +use strict; +use warnings; + +use Test::More tests => 16; + +use Crypt::AuthEnc::CCM qw( ccm_encrypt_authenticate ccm_decrypt_verify ); + +sub do_test { + my %a = @_; + + my $key = pack("H*", $a{key}); + my $nonce = pack("H*", $a{nonce}); + my $header = pack("H*", $a{header}); + my $plaintext = pack("H*", $a{plaintext}); + my $ciphertext = pack("H*", $a{ciphertext}); + my $tag = pack("H*", $a{tag}); + + my ($ct3, $tag3) = ccm_encrypt_authenticate('AES', $key, $nonce, $header, length($tag), $plaintext); + is(unpack('H*', $ct3), $a{ciphertext}, "enc: ciphertext"); + is(unpack('H*', $tag3), $a{tag}, "enc: tag"); + my $pt3 = ccm_decrypt_verify('AES', $key, $nonce, $header, $ciphertext, $tag); + is(unpack('H*', $pt3), $a{plaintext}, "dec: plaintext"); + ok(!defined ccm_decrypt_verify('AES', $key, $nonce, $header, $ciphertext, "BAD__TAG")); +} + +do_test(%$_) for ( + #/* 13 byte nonce, 8 byte auth, 23 byte pt */ + { + key=>'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf', + nonce=>'00000003020100a0a1a2a3a4a5', + header=>'0001020304050607', + plaintext=>'08090a0b0c0d0e0f101112131415161718191a1b1c1d1e', + ciphertext=>'588c979a61c663d2f066d0c2c0f989806d5f6b61dac384', + tag=>'17e8d12cfdf926e0', + }, + + #/* 13 byte nonce, 12 byte header, 19 byte pt */ + { + key=>'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf', + nonce=>'00000006050403a0a1a2a3a4a5', + header=>'000102030405060708090a0b', + plaintext=>'0c0d0e0f101112131415161718191a1b1c1d1e', + ciphertext=>'a28c6865939a9a79faaa5c4c2a9d4a91cdac8c', + tag=>'96c861b9c9e61ef1', + }, + + #/* supplied by Brian Gladman */ + { + key=>'404142434445464748494a4b4c4d4e4f', + nonce=>'10111213141516', + header=>'0001020304050607', + plaintext=>'20212223', + ciphertext=>'7162015b', + tag=>'4dac255d', + }, + + { + key=>'c97c1f67ce371185514a8a19f2bdd52f', + nonce=>'005030f1844408b5039776e70c', + header=>'08400fd2e128a57c5030f1844408abaea5b8fcba0000', + plaintext=>'f8ba1a55d02f85ae967bb62fb6cda8eb7e78a050', + ciphertext=>'f3d0a2fe9a3dbf2342a643e43246e80c3c04d019', + tag=>'7845ce0b16f97623', + }, +); diff --git a/t/auth_enc_chacha20poly1305.t b/t/auth_enc_chacha20poly1305.t new file mode 100644 index 0000000..b2ccfe9 --- /dev/null +++ b/t/auth_enc_chacha20poly1305.t @@ -0,0 +1,55 @@ +use strict; +use warnings; + +use Test::More tests => 12; + +use Crypt::AuthEnc::ChaCha20Poly1305 qw( chacha20poly1305_encrypt_authenticate chacha20poly1305_decrypt_verify ); + +my $key = "12345678901234561234567890123456"; + +{ + my $pt = "plain_half"; + my $ct; + + my $m1 = Crypt::AuthEnc::ChaCha20Poly1305->new($key, "123456789012"); + $m1->adata_add("adata-123456789012"); + $ct = $m1->encrypt_add($pt); + $ct .= $m1->encrypt_add($pt); + my $tag = $m1->encrypt_done; + + is(unpack('H*', $ct), "92dc41021189e1660d5dd4bbee2fd00cc9047fdf", "enc: ciphertext"); + is(unpack('H*', $tag), "e6f20b492b7bf34c914c72717af6f232", "enc: tag"); + + my $d1 = Crypt::AuthEnc::ChaCha20Poly1305->new($key, "123456789012"); + $d1->adata_add("adata-123456789012"); + my $pt2 = $d1->decrypt_add($ct); + my $tag2 = $d1->decrypt_done(); + + is($pt2, "plain_halfplain_half", "dec1: plaintext"); + is(unpack('H*', $tag2), "e6f20b492b7bf34c914c72717af6f232", "dec1: tag"); + + my $d2 = Crypt::AuthEnc::ChaCha20Poly1305->new($key, "123456789012"); + $d2->adata_add("adata-123456789012"); + my $pt3; + $pt3 .= $d2->decrypt_add(substr($ct,$_-1,1)) for (1..length($ct)); + my $tag3 = $d2->decrypt_done(); + + is($pt3, "plain_halfplain_half", "dec2: plaintext"); + is(unpack('H*', $tag3), "e6f20b492b7bf34c914c72717af6f232", "dec2: tag"); +} + +{ + my ($ct, $tag) = chacha20poly1305_encrypt_authenticate($key, "123456789012", "", "plain_halfplain_half"); + is(unpack('H*', $ct), "92dc41021189e1660d5dd4bbee2fd00cc9047fdf", "chacha20poly1305_encrypt_authenticate: ciphertext (no header)"); + is(unpack('H*', $tag), "d081beb3c3fe560c77f6c4e0da1d0dac", "chacha20poly1305_encrypt_authenticate: tag (no header)"); + my $pt = chacha20poly1305_decrypt_verify($key, "123456789012", "", $ct, $tag); + is($pt, "plain_halfplain_half", "chacha20poly1305_decrypt_verify: plaintext (no header)"); +} + +{ + my ($ct, $tag) = chacha20poly1305_encrypt_authenticate($key, "123456789012", "adata-123456789012", "plain_halfplain_half"); + is(unpack('H*', $ct), "92dc41021189e1660d5dd4bbee2fd00cc9047fdf", "chacha20poly1305_encrypt_authenticate: ciphertext (no header)"); + is(unpack('H*', $tag), "e6f20b492b7bf34c914c72717af6f232", "chacha20poly1305_encrypt_authenticate: tag (no header)"); + my $pt = chacha20poly1305_decrypt_verify($key, "123456789012", "adata-123456789012", $ct, $tag); + is($pt, "plain_halfplain_half", "chacha20poly1305_decrypt_verify: plaintext (no header)"); +} diff --git a/t/auth_enc_eax.t b/t/auth_enc_eax.t new file mode 100644 index 0000000..ad9c110 --- /dev/null +++ b/t/auth_enc_eax.t @@ -0,0 +1,60 @@ +use strict; +use warnings; + +use Test::More tests => 12; + +use Crypt::AuthEnc::EAX qw( eax_encrypt_authenticate eax_decrypt_verify ); + +my $nonce = "random-nonce"; +my $key = "12345678901234561234567890123456"; + +{ + my $pt = "plain_half"; + my $ct; + + my $m1 = Crypt::AuthEnc::EAX->new("AES", $key, $nonce); + $m1->header_add("a"); + $m1->header_add("b"); + $m1->header_add("c"); + $ct = $m1->encrypt_add($pt); + $ct .= $m1->encrypt_add($pt); + my $tag = $m1->encrypt_done; + + is(unpack('H*', $ct), "4b88b8819481fbc39839890fedf3e31cef7ea2a9", "enc: ciphertext"); + is(unpack('H*', $tag), "f83d77e5cf20979b3325266ff2fe342c", "enc: tag"); + + my $d1 = Crypt::AuthEnc::EAX->new("AES", $key, $nonce); + $d1->header_add("abc"); + my $pt2 = $d1->decrypt_add($ct); + my $tag2 = $d1->decrypt_done(); + + is($pt2, "plain_halfplain_half", "dec1: plaintext"); + is(unpack('H*', $tag2), "f83d77e5cf20979b3325266ff2fe342c", "dec1: tag"); + + my $d2 = Crypt::AuthEnc::EAX->new("AES", $key, $nonce); + $d2->header_add("a"); + $d2->header_add("b"); + $d2->header_add("c"); + my $pt3; + $pt3 .= $d2->decrypt_add(substr($ct,$_-1,1)) for (1..length($ct)); + my $tag3 = $d2->decrypt_done(); + + is($pt3, "plain_halfplain_half", "dec2: plaintext"); + is(unpack('H*', $tag3), "f83d77e5cf20979b3325266ff2fe342c", "dec2: tag"); +} + +{ + my ($ct, $tag) = eax_encrypt_authenticate('AES', $key, $nonce, "abc", "plain_halfplain_half"); + is(unpack('H*', $ct), "4b88b8819481fbc39839890fedf3e31cef7ea2a9", "eax_encrypt_authenticate: ciphertext"); + is(unpack('H*', $tag), "f83d77e5cf20979b3325266ff2fe342c", "eax_encrypt_authenticate: tag"); + my $pt = eax_decrypt_verify('AES', $key, $nonce, "abc", $ct, $tag); + is($pt, "plain_halfplain_half", "eax_decrypt_verify: plaintext"); +} + +{ + my ($ct, $tag) = eax_encrypt_authenticate('AES', $key, $nonce, "", "plain_halfplain_half"); + is(unpack('H*', $ct), "4b88b8819481fbc39839890fedf3e31cef7ea2a9", "eax_encrypt_authenticate: ciphertext (no header)"); + is(unpack('H*', $tag), "e5ad22aa2ba3b30cd50eb59593364f1b", "eax_encrypt_authenticate: tag (no header)"); + my $pt = eax_decrypt_verify('AES', $key, $nonce, "", $ct, $tag); + is($pt, "plain_halfplain_half", "eax_decrypt_verify: plaintext (no header)"); +} diff --git a/t/auth_enc_eax_test_vector_ltc.t b/t/auth_enc_eax_test_vector_ltc.t new file mode 100644 index 0000000..f196234 --- /dev/null +++ b/t/auth_enc_eax_test_vector_ltc.t @@ -0,0 +1,125 @@ +use strict; +use warnings; + +use Test::More tests => 56; + +use Crypt::AuthEnc::EAX qw( eax_encrypt_authenticate eax_decrypt_verify ); + +sub do_test { + my %a = @_; + + my $key = pack("H*", $a{key}); + my $nonce = pack("H*", $a{nonce}); + my $header = pack("H*", $a{header}); + my $plaintext = pack("H*", $a{plaintext}); + my $ciphertext = pack("H*", $a{ciphertext}); + my $tag = pack("H*", $a{tag}); + + # encrypt + my $m1 = Crypt::AuthEnc::EAX->new("AES", $key, $nonce); + $m1->header_add($header); + my $ct = $m1->encrypt_add($plaintext); + my $tag1 = $m1->encrypt_done; + + is(unpack('H*', $ct), $a{ciphertext}, "enc: ciphertext"); + is(unpack('H*', $tag1), $a{tag}, "enc: tag"); + + # decrypt + my $d1 = Crypt::AuthEnc::EAX->new("AES", $key, $nonce); + $d1->header_add($header); + my $pt = $d1->decrypt_add($ciphertext); + my $tag2 = $d1->decrypt_done(); + + is(unpack('H*', $pt), $a{plaintext}, "dec: plaintext"); + is(unpack('H*', $tag2), $a{tag}, "dec: tag"); + + # all-in-one + my ($ct3, $tag3) = eax_encrypt_authenticate('AES', $key, $nonce, $header, $plaintext); + is(unpack('H*', $ct3), $a{ciphertext}, "enc: ciphertext"); + is(unpack('H*', $tag3), $a{tag}, "enc: tag"); + my $pt3 = eax_decrypt_verify('AES', $key, $nonce, $header, $ciphertext, $tag); + is(unpack('H*', $pt3), $a{plaintext}, "dec: plaintext"); + +} + +do_test(%$_) for ( + #/* NULL message */ + { + #16, 0, 0, 0, + key => '000102030405060708090a0b0c0d0e0f', + nonce => '', + header => '', + plaintext => '', + ciphertext => '', + tag => '9ad07e7dbff301f505de596b9615dfff', + }, + #/* test with nonce */ + { + #16, 16, 0, 0, + key => '000102030405060708090a0b0c0d0e0f', + nonce => '000102030405060708090a0b0c0d0e0f', + header => '', + plaintext => '', + ciphertext => '', + tag => '1ce10d3effd4cadbe2e44b58d60ab9ec', + }, + #/* test with header [no nonce] */ + { + #16, 0, 16, 0, + key => '000102030405060708090a0b0c0d0e0f', + nonce => '', + header => '000102030405060708090a0b0c0d0e0f', + plaintext => '', + ciphertext => '', + tag => '3a698f7a270e51b0f65b3d3e47193cff', + }, + #/* test with header + nonce + plaintext */ + { + #16, 16, 16, 32, + key => '000102030405060708090a0b0c0d0e0f', + nonce => '000102030405060708090a0b0c0d0e0f', + header => '000102030405060708090a0b0c0d0e0f', + plaintext => '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f', + ciphertext => '29d878d1a3be857b6fb8c8ea5950a778331fbf2ccf33986f35e8cf121dcb30bc', + tag => '4fbe0338be1c8c7e1d7ae7e45b92c587', + }, + #/* test with header + nonce + plaintext [not even sizes!] */ + { + #16, 15, 14, 29, + key => '000102030405060708090a0b0c0d0e0f', + nonce => '000102030405060708090a0b0c0d0e', + header => '000102030405060708090a0b0c0d', + plaintext => '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c', + ciphertext => 'dd25c754c5b17c5928b69b73155f7bb8888faf37091ad92c8a24db868b', + tag => '0d1a14e52224ffd23a05fa02cdef52da', + }, + + #/* Vectors from Brian Gladman */ + { + #16, 16, 8, 0, + key => '233952dee4d5ed5f9b9c6d6ff80ff478', + nonce => '62ec67f9c3a4a407fcb2a8c49031a8b3', + header => '6bfb914fd07eae6b', + plaintext => '', + ciphertext => '', + tag => 'e037830e8389f27b025a2d6527e79d01', + }, + { + #16, 16, 8, 2, + key => '91945d3f4dcbee0bf45ef52255f095a4', + nonce => 'becaf043b0a23d843194ba972c66debd', + header => 'fa3bfd4806eb53fa', + plaintext => 'f7fb', + ciphertext => '19dd', + tag => '5c4c9331049d0bdab0277408f67967e5', + }, + { + #16, 16, 8, 5, + key => '01f74ad64077f2e704c0f60ada3dd523', + nonce => '70c3db4f0d26368400a10ed05d2bff5e', + header => '234a3463c1264ac6', + plaintext => '1a47cb4933', + ciphertext => 'd851d5bae0', + tag => '3a59f238a23e39199dc9266626c40f80', + }, +); diff --git a/t/auth_enc_gcm.t b/t/auth_enc_gcm.t new file mode 100644 index 0000000..1ff09fe --- /dev/null +++ b/t/auth_enc_gcm.t @@ -0,0 +1,58 @@ +use strict; +use warnings; + +use Test::More tests => 12; + +use Crypt::AuthEnc::GCM qw( gcm_encrypt_authenticate gcm_decrypt_verify ); + +my $key = "12345678901234561234567890123456"; + +{ + my $pt = "plain_half"; + my $ct; + + my $m1 = Crypt::AuthEnc::GCM->new("AES", $key); + $m1->iv_add("123456789012"); + $m1->adata_add("adata-123456789012"); + $ct = $m1->encrypt_add($pt); + $ct .= $m1->encrypt_add($pt); + my $tag = $m1->encrypt_done; + + is(unpack('H*', $ct), "1d56d8e991a7fc707135a79842ef9b57d885485d", "enc: ciphertext"); + is(unpack('H*', $tag), "d225e849d4d076cf9e85d5303450e793", "enc: tag"); + + my $d1 = Crypt::AuthEnc::GCM->new("AES", $key); + $d1->iv_add("123456789012"); + $d1->adata_add("adata-123456789012"); + my $pt2 = $d1->decrypt_add($ct); + my $tag2 = $d1->decrypt_done(); + + is($pt2, "plain_halfplain_half", "dec1: plaintext"); + is(unpack('H*', $tag2), "d225e849d4d076cf9e85d5303450e793", "dec1: tag"); + + my $d2 = Crypt::AuthEnc::GCM->new("AES", $key); + $d2->iv_add("123456789012"); + $d2->adata_add("adata-123456789012"); + my $pt3; + $pt3 .= $d2->decrypt_add(substr($ct,$_-1,1)) for (1..length($ct)); + my $tag3 = $d2->decrypt_done(); + + is($pt3, "plain_halfplain_half", "dec2: plaintext"); + is(unpack('H*', $tag3), "d225e849d4d076cf9e85d5303450e793", "dec2: tag"); +} + +{ + my ($ct, $tag) = gcm_encrypt_authenticate('AES', $key, "123456789012", "", "plain_halfplain_half"); + is(unpack('H*', $ct), "1d56d8e991a7fc707135a79842ef9b57d885485d", "gcm_encrypt_authenticate: ciphertext (no header)"); + is(unpack('H*', $tag), "1685ba0eda059ace4aab6539980c30c0", "gcm_encrypt_authenticate: tag (no header)"); + my $pt = gcm_decrypt_verify('AES', $key, "123456789012", "", $ct, $tag); + is($pt, "plain_halfplain_half", "gcm_decrypt_verify: plaintext (no header)"); +} + +{ + my ($ct, $tag) = gcm_encrypt_authenticate('AES', $key, "123456789012", "adata-123456789012", "plain_halfplain_half"); + is(unpack('H*', $ct), "1d56d8e991a7fc707135a79842ef9b57d885485d", "gcm_encrypt_authenticate: ciphertext (no header)"); + is(unpack('H*', $tag), "d225e849d4d076cf9e85d5303450e793", "gcm_encrypt_authenticate: tag (no header)"); + my $pt = gcm_decrypt_verify('AES', $key, "123456789012", "adata-123456789012", $ct, $tag); + is($pt, "plain_halfplain_half", "gcm_decrypt_verify: plaintext (no header)"); +} diff --git a/t/auth_enc_gcm_test_vector_ltc.t b/t/auth_enc_gcm_test_vector_ltc.t new file mode 100644 index 0000000..6afbaab --- /dev/null +++ b/t/auth_enc_gcm_test_vector_ltc.t @@ -0,0 +1,118 @@ +use strict; +use warnings; + +use Test::More tests => 42; + +use Crypt::AuthEnc::GCM qw( gcm_encrypt_authenticate gcm_decrypt_verify ); + +sub do_test { + my %a = @_; + + my $key = pack("H*", $a{key}); + my $adata = pack("H*", $a{adata}); + my $iv = pack("H*", $a{iv}); + my $plaintext = pack("H*", $a{plaintext}); + my $ciphertext = pack("H*", $a{ciphertext}); + my $tag = pack("H*", $a{tag}); + + # encrypt + my $m1 = Crypt::AuthEnc::GCM->new("AES", $key); + $m1->iv_add($iv); + $m1->adata_add($adata); + my $ct = $m1->encrypt_add($plaintext); + my $tag1 = $m1->encrypt_done; + + is(unpack('H*', $ct), $a{ciphertext}, "enc: ciphertext"); + is(unpack('H*', $tag1), $a{tag}, "enc: tag"); + + # decrypt + my $d1 = Crypt::AuthEnc::GCM->new("AES", $key); + $d1->iv_add($iv); + $d1->adata_add($adata); + my $pt = $d1->decrypt_add($ciphertext); + my $tag2 = $d1->decrypt_done(); + + is(unpack('H*', $pt), $a{plaintext}, "dec: plaintext"); + is(unpack('H*', $tag2), $a{tag}, "dec: tag"); + + # all-in-one + my ($ct3, $tag3) = gcm_encrypt_authenticate('AES', $key, $iv, $adata, $plaintext); + is(unpack('H*', $ct3), $a{ciphertext}, "enc: ciphertext"); + is(unpack('H*', $tag3), $a{tag}, "enc: tag"); + my $pt3 = gcm_decrypt_verify('AES', $key, $iv, $adata, $ciphertext, $tag); + is(unpack('H*', $pt3), $a{plaintext}, "dec: plaintext"); + +} + +do_test(%$_) for ( + #/* test case #1 */ + # XXX-FIXME this test fails!!!! + # { + # key => '00000000000000000000000000000000', + # plaintext => '', + # adata => '', + # iv => '000000000000000000000000', + # ciphertext => '', + # tag => '58e2fccefa7e3061367f1d57a4e7455a', + # }, + + #/* test case #2 */ + { + key => '00000000000000000000000000000000', + plaintext => '00000000000000000000000000000000', + adata => '', + iv => '000000000000000000000000', + ciphertext => '0388dace60b6a392f328c2b971b2fe78', + tag => 'ab6e47d42cec13bdf53a67b21257bddf', + }, + + #/* test case #3 */ + { + key => 'feffe9928665731c6d6a8f9467308308', + plaintext => 'd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255', + adata => '', + iv => 'cafebabefacedbaddecaf888', + ciphertext => '42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f5985', + tag => '4d5c2af327cd64a62cf35abd2ba6fab4', + }, + + #/* test case #4 */ + { + key => 'feffe9928665731c6d6a8f9467308308', + plaintext => 'd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39', + adata => 'feedfacedeadbeeffeedfacedeadbeefabaddad2', + iv => 'cafebabefacedbaddecaf888', + ciphertext => '42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091', + tag => '5bc94fbc3221a5db94fae95ae7121a47', + }, + + #/* test case #5 */ + { + key => 'feffe9928665731c6d6a8f9467308308', + plaintext => 'd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39', + adata => 'feedfacedeadbeeffeedfacedeadbeefabaddad2', + iv => 'cafebabefacedbad', + ciphertext => '61353b4c2806934a777ff51fa22a4755699b2a714fcdc6f83766e5f97b6c742373806900e49f24b22b097544d4896b424989b5e1ebac0f07c23f4598', + tag => '3612d2e79e3b0785561be14aaca2fccb', + }, + + #/* test case #6 */ + { + key => 'feffe9928665731c6d6a8f9467308308', + plaintext => 'd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39', + adata => 'feedfacedeadbeeffeedfacedeadbeefabaddad2', + iv => '9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b', + ciphertext => '8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca701e4a9a4fba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5', + tag => '619cc5aefffe0bfa462af43c1699d050', + }, + + #/* test case #46 from BG (catches the LTC bug of v1.15) */ + { + key => '00000000000000000000000000000000', + plaintext => 'a2aab3ad8b17acdda288426cd7c429b7ca86b7aca05809c70ce82db25711cb5302eb2743b036f3d750d6cf0dc0acb92950d546db308f93b4ff244afa9dc72bcd758d2c', + adata => '688e1aa984de926dc7b4c47f44', + iv => 'b72138b5a05ff5070e8cd94183f761d8', + ciphertext => 'cbc8d2f15481a4cc7dd1e19aaa83de5678483ec359ae7dec2ab8d534e0906f4b4663faff58a8b2d733b845eef7c9b331e9e10eb2612c995feb1ac15a6286cce8b297a8', + tag => '8d2d2a9372626f6bee8580276a6366bf', + } +); diff --git a/t/auth_enc_ocb.t b/t/auth_enc_ocb.t new file mode 100644 index 0000000..c98a698 --- /dev/null +++ b/t/auth_enc_ocb.t @@ -0,0 +1,46 @@ +use strict; +use warnings; + +use Test::More tests => 10; + +use Crypt::AuthEnc::OCB qw( ocb_encrypt_authenticate ocb_decrypt_verify ); + +my $key = "12345678901234561234567890123456"; + +{ + my $pt = "plain_half_12345"; + my $ct; + + my $m1 = Crypt::AuthEnc::OCB->new("AES", $key, "123456789012"); + $m1->adata_add("adata-123456789012"); + $ct = $m1->encrypt_add($pt); + $ct .= $m1->encrypt_last($pt); + my $tag = $m1->encrypt_done; + + is(unpack('H*', $ct), "4c85b38952e71220ecc323253547ae9b446f5a518717759ef8b0f24d5c4809a6", "enc: ciphertext"); + is(unpack('H*', $tag), "bd7a6a0aaf24420f97bf239ea5740a40", "enc: tag"); + + my $d1 = Crypt::AuthEnc::OCB->new("AES", $key, "123456789012"); + $d1->adata_add("adata-123456789012"); + my $pt2 = $d1->decrypt_last($ct); + my $tag2 = $d1->decrypt_done(); + + is($pt2, "plain_half_12345plain_half_12345", "dec1: plaintext"); + is(unpack('H*', $tag2), "bd7a6a0aaf24420f97bf239ea5740a40", "dec1: tag"); +} + +{ + my ($ct, $tag) = ocb_encrypt_authenticate('AES', $key, "123456789012", "", "plain_half_12345plain_half_12345"); + is(unpack('H*', $ct), "4c85b38952e71220ecc323253547ae9b446f5a518717759ef8b0f24d5c4809a6", "ocb_encrypt_authenticate: ciphertext (no header)"); + is(unpack('H*', $tag), "dfdfab80aca060268c0cc467040af4f9", "ocb_encrypt_authenticate: tag (no header)"); + my $pt = ocb_decrypt_verify('AES', $key, "123456789012", "", $ct, $tag); + is($pt, "plain_half_12345plain_half_12345", "ocb_decrypt_verify: plaintext (no header)"); +} + +{ + my ($ct, $tag) = ocb_encrypt_authenticate('AES', $key, "123456789012", "adata-123456789012", "plain_half_12345plain_half_12345"); + is(unpack('H*', $ct), "4c85b38952e71220ecc323253547ae9b446f5a518717759ef8b0f24d5c4809a6", "ocb_encrypt_authenticate: ciphertext (no header)"); + is(unpack('H*', $tag), "bd7a6a0aaf24420f97bf239ea5740a40", "ocb_encrypt_authenticate: tag (no header)"); + my $pt = ocb_decrypt_verify('AES', $key, "123456789012", "adata-123456789012", $ct, $tag); + is($pt, "plain_half_12345plain_half_12345", "ocb_decrypt_verify: plaintext (no header)"); +} diff --git a/t/auth_enc_ocb_test_vectors_ietf.t b/t/auth_enc_ocb_test_vectors_ietf.t new file mode 100644 index 0000000..d8c3656 --- /dev/null +++ b/t/auth_enc_ocb_test_vectors_ietf.t @@ -0,0 +1,144 @@ +use strict; +use warnings; + +use Test::More tests => 48; +use Crypt::AuthEnc::OCB; + +my $count = 1; +my $d = {}; +my $text; + +while (my $l = ) { + chomp($l); + next if $l =~ /^#/; + $l =~ s/[\s\t]+/ /g; + + if ($l eq '') { + next unless defined $d->{C}; + my $K = pack('H*', '000102030405060708090A0B0C0D0E0F'); + my $N = pack('H*', '000102030405060708090A0B'); + my $A = pack('H*', $d->{A}); + my $P = pack('H*', $d->{P}); + my $C = pack('H*', $d->{C}); + + { #ENCRYPT + my $m = Crypt::AuthEnc::OCB->new('AES', $K, $N); + $m->adata_add($A); + my $ct = $m->encrypt_last($P); + my $t = $m->encrypt_done(); + is(unpack('H*', $ct.$t), lc($d->{C}), "encrypt/$count aad_len=" . length($A) . " pt_len=" . length($P)); + } + + { #DECRYPT + my $m = Crypt::AuthEnc::OCB->new('AES', $K, $N); + $m->adata_add($A); + my $pt = $m->decrypt_last(substr($C,0,-16)); + my $t = $m->decrypt_done(); + is(unpack('H*', $pt), lc($d->{P}), "decrypt/$count/a aad_len=" . length($A) . " pt_len=" . length($P)); + is(unpack('H*', $t), unpack('H*', substr($C,-16)), "decrypt/$count/b aad_len=" . length($A) . " pt_len=" . length($P)); + } + + # $text .= "\t{ /* index:" . ($count-1) . " */\n"; + # $text .= "\t " . length($P) . ", /* PLAINTEXT length */\n"; + # $text .= "\t " . length($A) . ", /* AAD length */\n"; + # $text .= "\t { " . join(',', map { sprintf("0x%02x",unpack('C',$_)) } split(//, $P)) . " }, /* PLAINTEXT */\n"; + # $text .= "\t { " . join(',', map { sprintf("0x%02x",unpack('C',$_)) } split(//, $A)) . " }, /* AAD */\n"; + # $text .= "\t { " . join(',', map { sprintf("0x%02x",unpack('C',$_)) } split(//, substr($C,0,-16))) . " }, /* CIPHERTEXT */\n"; + # $text .= "\t { " . join(',', map { sprintf("0x%02x",unpack('C',$_)) } split(//, substr($C,-16))) . " }, /* TAG */\n"; + # $text .= "\t},\n"; + + $d = {}; + $count++; + } + else { + my ($k, $v) = split /:/, $l; + $d->{$k} = $v; + } + +} + +#print $text; + +__DATA__ +# +# test vectors from: http://tools.ietf.org/html/draft-krovetz-ocb-03 +# +# This section gives sample output values for various inputs when using +# the AEAD_AES_128_OCB_TAGLEN128 parameters defined in Section 3.1. All +# strings are represented in hexadecimal (eg, 0F represents the +# bitstring 00001111). +# +# Each of the following (A,P,C) triples show the ciphertext C that +# results from OCB-ENCRYPT(K,N,A,P) when K and N are fixed with the +# values +# +#K : 000102030405060708090A0B0C0D0E0F +#N : 000102030405060708090A0B +# +#An empty entry indicates the empty string. + +A: +P: +C:197B9C3C441D3C83EAFB2BEF633B9182 + +A:0001020304050607 +P:0001020304050607 +C:92B657130A74B85A16DC76A46D47E1EAD537209E8A96D14E + +A:0001020304050607 +P: +C:98B91552C8C009185044E30A6EB2FE21 + +A: +P:0001020304050607 +C:92B657130A74B85A971EFFCAE19AD4716F88E87B871FBEED + +A:000102030405060708090A0B0C0D0E0F +P:000102030405060708090A0B0C0D0E0F +C:BEA5E8798DBE7110031C144DA0B26122776C9924D6723A1FC4524532AC3E5BEB + +A:000102030405060708090A0B0C0D0E0F +P: +C:7DDB8E6CEA6814866212509619B19CC6 + +A: +P:000102030405060708090A0B0C0D0E0F +C:BEA5E8798DBE7110031C144DA0B2612213CC8B747807121A4CBB3E4BD6B456AF + +A:000102030405060708090A0B0C0D0E0F1011121314151617 +P:000102030405060708090A0B0C0D0E0F1011121314151617 +C:BEA5E8798DBE7110031C144DA0B26122FCFCEE7A2A8D4D485FA94FC3F38820F1DC3F3D1FD4E55E1C + +A:000102030405060708090A0B0C0D0E0F1011121314151617 +P: +C:282026DA3068BC9FA118681D559F10F6 + +A: +P:000102030405060708090A0B0C0D0E0F1011121314151617 +C:BEA5E8798DBE7110031C144DA0B26122FCFCEE7A2A8D4D486EF2F52587FDA0ED97DC7EEDE241DF68 + +A:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F +P:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F +C:BEA5E8798DBE7110031C144DA0B26122CEAAB9B05DF771A657149D53773463CBB2A040DD3BD5164372D76D7BB6824240 + +A:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F +P: +C:E1E072633BADE51A60E85951D9C42A1B + +A: +P:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F +C:BEA5E8798DBE7110031C144DA0B26122CEAAB9B05DF771A657149D53773463CB4A3BAE824465CFDAF8C41FC50C7DF9D9 + +A:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627 +P:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627 +C:BEA5E8798DBE7110031C144DA0B26122CEAAB9B05DF771A657149D53773463CB68C65778B058A635659C623211DEEA0DE30D2C381879F4C8 + +A:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627 +P: +C:7AEB7A69A1687DD082CA27B0D9A37096 + +A: +P:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627 +C:BEA5E8798DBE7110031C144DA0B26122CEAAB9B05DF771A657149D53773463CB68C65778B058A635060C8467F4ABAB5E8B3C2067A2E115DC + +LAST_ITEM_PLACEHOLDER_DO_NOT_DELETE!!! \ No newline at end of file diff --git a/t/checksum.t b/t/checksum.t new file mode 100644 index 0000000..b61a4b1 --- /dev/null +++ b/t/checksum.t @@ -0,0 +1,47 @@ +use strict; +use warnings; + +use Test::More tests => 24; + +use Crypt::Checksum ':all'; +use Crypt::Checksum::Adler32; +use Crypt::Checksum::CRC32; + +my $a32 = Crypt::Checksum::Adler32->new; +is($a32->hexdigest, "00000001"); +is($a32->hexdigest, "00000001"); +$a32->add("a"); +is($a32->hexdigest, "00620062"); +$a32->reset; +is($a32->hexdigest, "00000001"); +$a32->add("abc"); +is($a32->hexdigest, "024d0127"); +$a32->reset; +$a32->add("abc"); +$a32->add("abc"); +is($a32->hexdigest, "080c024d"); +$a32->reset; +$a32->add("abcabc"); +is($a32->hexdigest, "080c024d"); +$a32->reset; +$a32->add("\xFF" x 32); +is($a32->hexdigest, "0e2e1fe1"); +is(adler32_data_hex("a"), "00620062"); +is(adler32_data("a"), pack("H*","00620062")); + +is(crc32_data_hex("a"), "e8b7be43"); +is(crc32_data_hex("libtomcrypt"), "b37376ef"); +is(crc32_data_hex("This is the test string"), "6d680973"); +is(crc32_data_int("This is the test string"), 1835534707); +is(crc32_data_hex("This is another test string"), "806e15e9"); +is(crc32_data_int("This is another test string"), 2154698217); + +is(crc32_file_hex("t/data/binary-test.file"), "24111fed"); +is(crc32_file_hex("t/data/text-CR.file"), "1ca430c6"); +is(crc32_file_hex("t/data/text-CRLF.file"), "4d434dfb"); +is(crc32_file_hex("t/data/text-LF.file"), "9f9b8258"); + +is(adler32_file_hex("t/data/binary-test.file"), "f35fb68a"); +is(adler32_file_hex("t/data/text-CR.file"), "948e2644"); +is(adler32_file_hex("t/data/text-CRLF.file"), "3f0e2702"); +is(adler32_file_hex("t/data/text-LF.file"), "86ba260b"); diff --git a/t/cipher_aes.t b/t/cipher_aes.t new file mode 100644 index 0000000..ea924a7 --- /dev/null +++ b/t/cipher_aes.t @@ -0,0 +1,65 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 38; + +use Crypt::Cipher; +use Crypt::Cipher::AES; + +is( Crypt::Cipher::AES::blocksize, 16, '::blocksize'); +is( Crypt::Cipher::AES::keysize, 32, '::keysize'); +is( Crypt::Cipher::AES::max_keysize, 32, '::max_keysize'); +is( Crypt::Cipher::AES::min_keysize, 16, '::min_keysize'); +is( Crypt::Cipher::AES::default_rounds, 10, '::default_rounds'); + +is( Crypt::Cipher::AES->blocksize, 16, '->blocksize'); +is( Crypt::Cipher::AES->keysize, 32, '->keysize'); +is( Crypt::Cipher::AES->max_keysize, 32, '->max_keysize'); +is( Crypt::Cipher::AES->min_keysize, 16, '->min_keysize'); +is( Crypt::Cipher::AES->default_rounds, 10, '->default_rounds'); + +my $min_key = 'kkkkkkkkkkkkkkkk'; +my $max_key = 'KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK'; + +is( Crypt::Cipher::blocksize('AES'), 16, 'Cipher->blocksize'); +is( Crypt::Cipher::keysize('AES'), 32, 'Cipher->keysize'); +is( Crypt::Cipher::max_keysize('AES'), 32, 'Cipher->max_keysize'); +is( Crypt::Cipher::min_keysize('AES'), 16, 'Cipher->min_keysize'); +is( Crypt::Cipher::default_rounds('AES'), 10, 'Cipher->default_rounds'); + +is( Crypt::Cipher->blocksize('AES'), 16, 'Cipher->blocksize'); +is( Crypt::Cipher->keysize('AES'), 32, 'Cipher->keysize'); +is( Crypt::Cipher->max_keysize('AES'), 32, 'Cipher->max_keysize'); +is( Crypt::Cipher->min_keysize('AES'), 16, 'Cipher->min_keysize'); +is( Crypt::Cipher->default_rounds('AES'), 10, 'Cipher->default_rounds'); + +is( Crypt::Cipher::AES->new($min_key)->blocksize, 16, 'AES->new()->blocksize'); +is( Crypt::Cipher::AES->new($min_key)->keysize, 32, 'AES->new()->keysize'); +is( Crypt::Cipher::AES->new($min_key)->max_keysize, 32, 'AES->new()->max_keysize'); +is( Crypt::Cipher::AES->new($min_key)->min_keysize, 16, 'AES->new()->min_keysize'); +is( Crypt::Cipher::AES->new($min_key)->default_rounds, 10, 'AES->new()->default_rounds'); + +is( Crypt::Cipher->new('AES', $min_key)->blocksize, 16, 'Cipher->new()->blocksize'); +is( Crypt::Cipher->new('AES', $min_key)->keysize, 32, 'Cipher->new()->keysize'); +is( Crypt::Cipher->new('AES', $min_key)->max_keysize, 32, 'Cipher->new()->max_keysize'); +is( Crypt::Cipher->new('AES', $min_key)->min_keysize, 16, 'Cipher->new()->min_keysize'); +is( Crypt::Cipher->new('AES', $min_key)->default_rounds, 10, 'Cipher->new()->default_rounds'); + +my $block_plain = 'BBBBBBBBBBBBBBBB'; +my $block_encrypted_min_key_hex = '41920fa7d2902a858bb292e7a6605aba'; +my $block_encrypted_max_key_hex = '42c97158e8bca4a7706e37138e4e2dbf'; + +is( unpack('H*', Crypt::Cipher::AES->new($min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'AES->encrypt'); +is( Crypt::Cipher::AES->new($min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'AES->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('AES', $min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('AES', $min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Cipher->decrypt'); + +is( unpack('H*', Crypt::Cipher::AES->new($max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'AES->encrypt'); +is( Crypt::Cipher::AES->new($max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'AES->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('AES', $max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('AES', $max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Cipher->decrypt'); + diff --git a/t/cipher_aes_test_vectors_bc.t b/t/cipher_aes_test_vectors_bc.t new file mode 100644 index 0000000..fac267c --- /dev/null +++ b/t/cipher_aes_test_vectors_bc.t @@ -0,0 +1,50 @@ +use strict; +use warnings; + +use Test::More tests => 25; +use Crypt::Cipher::AES; + +ok(1); + +my $line = 1; +while (my $l = ) { + chomp($l); + $l =~ s/[\s\t]+/ /g; + my $d = {}; + for my $pair (split / /, $l) { + my ($k, $v) = split /:/, $pair; + $d->{$k} = $v; + } + + my $c = Crypt::Cipher::AES->new(pack('H*',$d->{key})); + my $result = pack('H*', $d->{pt}); + $result = $c->encrypt($result) for(1..$d->{iter}); + is(unpack('H*', $result), lc($d->{ct}), "line=$line"); + $line++; +} + +__DATA__ +iter:1 key:80000000000000000000000000000000 pt:00000000000000000000000000000000 ct:0EDD33D3C621E546455BD8BA1418BEC8 +iter:1 key:00000000000000000000000000000080 pt:00000000000000000000000000000000 ct:172AEAB3D507678ECAF455C12587ADB7 +iter:1 key:000000000000000000000000000000000000000000000000 pt:80000000000000000000000000000000 ct:6CD02513E8D4DC986B4AFE087A60BD0C +iter:1 key:0000000000000000000000000000000000000000000000000000000000000000 pt:80000000000000000000000000000000 ct:DDC6BF790C15760D8D9AEB6F9A75FD4E +iter:1 key:80000000000000000000000000000000 pt:00000000000000000000000000000000 ct:0EDD33D3C621E546455BD8BA1418BEC8 +iter:1 key:00000000000000000000000000000080 pt:00000000000000000000000000000000 ct:172AEAB3D507678ECAF455C12587ADB7 +iter:1 key:000000000000000000000000000000000000000000000000 pt:80000000000000000000000000000000 ct:6CD02513E8D4DC986B4AFE087A60BD0C +iter:1 key:0000000000000000000000000000000000000000000000000000000000000000 pt:80000000000000000000000000000000 ct:DDC6BF790C15760D8D9AEB6F9A75FD4E +iter:1 key:80000000000000000000000000000000 pt:00000000000000000000000000000000 ct:0EDD33D3C621E546455BD8BA1418BEC8 +iter:1 key:00000000000000000000000000000080 pt:00000000000000000000000000000000 ct:172AEAB3D507678ECAF455C12587ADB7 +iter:1 key:000000000000000000000000000000000000000000000000 pt:80000000000000000000000000000000 ct:6CD02513E8D4DC986B4AFE087A60BD0C +iter:1 key:0000000000000000000000000000000000000000000000000000000000000000 pt:80000000000000000000000000000000 ct:DDC6BF790C15760D8D9AEB6F9A75FD4E +iter:10000 key:00000000000000000000000000000000 pt:00000000000000000000000000000000 ct:C34C052CC0DA8D73451AFE5F03BE297F +iter:10000 key:5F060D3716B345C253F6749ABAC10917 pt:355F697E8B868B65B25A04E18D782AFA ct:ACC863637868E3E068D2FD6E3508454A +iter:10000 key:AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114 pt:F3F6752AE8D7831138F041560631B114 ct:77BA00ED5412DFF27C8ED91F3C376172 +iter:10000 key:28E79E2AFC5F7745FCCABE2F6257C2EF4C4EDFB37324814ED4137C288711A386 pt:C737317FE0846F132B23C8C2A672CE22 ct:E58B82BFBA53C0040DC610C642121168 +iter:10000 key:00000000000000000000000000000000 pt:00000000000000000000000000000000 ct:C34C052CC0DA8D73451AFE5F03BE297F +iter:10000 key:5F060D3716B345C253F6749ABAC10917 pt:355F697E8B868B65B25A04E18D782AFA ct:ACC863637868E3E068D2FD6E3508454A +iter:10000 key:AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114 pt:F3F6752AE8D7831138F041560631B114 ct:77BA00ED5412DFF27C8ED91F3C376172 +iter:10000 key:28E79E2AFC5F7745FCCABE2F6257C2EF4C4EDFB37324814ED4137C288711A386 pt:C737317FE0846F132B23C8C2A672CE22 ct:E58B82BFBA53C0040DC610C642121168 +iter:10000 key:00000000000000000000000000000000 pt:00000000000000000000000000000000 ct:C34C052CC0DA8D73451AFE5F03BE297F +iter:10000 key:5F060D3716B345C253F6749ABAC10917 pt:355F697E8B868B65B25A04E18D782AFA ct:ACC863637868E3E068D2FD6E3508454A +iter:10000 key:AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114 pt:F3F6752AE8D7831138F041560631B114 ct:77BA00ED5412DFF27C8ED91F3C376172 +iter:10000 key:28E79E2AFC5F7745FCCABE2F6257C2EF4C4EDFB37324814ED4137C288711A386 pt:C737317FE0846F132B23C8C2A672CE22 ct:E58B82BFBA53C0040DC610C642121168 diff --git a/t/cipher_anubis.t b/t/cipher_anubis.t new file mode 100644 index 0000000..5a0bd08 --- /dev/null +++ b/t/cipher_anubis.t @@ -0,0 +1,65 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 38; + +use Crypt::Cipher; +use Crypt::Cipher::Anubis; + +is( Crypt::Cipher::Anubis::blocksize, 16, '::blocksize'); +is( Crypt::Cipher::Anubis::keysize, 40, '::keysize'); +is( Crypt::Cipher::Anubis::max_keysize, 40, '::max_keysize'); +is( Crypt::Cipher::Anubis::min_keysize, 16, '::min_keysize'); +is( Crypt::Cipher::Anubis::default_rounds, 12, '::default_rounds'); + +is( Crypt::Cipher::Anubis->blocksize, 16, '->blocksize'); +is( Crypt::Cipher::Anubis->keysize, 40, '->keysize'); +is( Crypt::Cipher::Anubis->max_keysize, 40, '->max_keysize'); +is( Crypt::Cipher::Anubis->min_keysize, 16, '->min_keysize'); +is( Crypt::Cipher::Anubis->default_rounds, 12, '->default_rounds'); + +my $min_key = 'kkkkkkkkkkkkkkkk'; +my $max_key = 'KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK'; + +is( Crypt::Cipher::blocksize('Anubis'), 16, 'Cipher->blocksize'); +is( Crypt::Cipher::keysize('Anubis'), 40, 'Cipher->keysize'); +is( Crypt::Cipher::max_keysize('Anubis'), 40, 'Cipher->max_keysize'); +is( Crypt::Cipher::min_keysize('Anubis'), 16, 'Cipher->min_keysize'); +is( Crypt::Cipher::default_rounds('Anubis'), 12, 'Cipher->default_rounds'); + +is( Crypt::Cipher->blocksize('Anubis'), 16, 'Cipher->blocksize'); +is( Crypt::Cipher->keysize('Anubis'), 40, 'Cipher->keysize'); +is( Crypt::Cipher->max_keysize('Anubis'), 40, 'Cipher->max_keysize'); +is( Crypt::Cipher->min_keysize('Anubis'), 16, 'Cipher->min_keysize'); +is( Crypt::Cipher->default_rounds('Anubis'), 12, 'Cipher->default_rounds'); + +is( Crypt::Cipher::Anubis->new($min_key)->blocksize, 16, 'Anubis->new()->blocksize'); +is( Crypt::Cipher::Anubis->new($min_key)->keysize, 40, 'Anubis->new()->keysize'); +is( Crypt::Cipher::Anubis->new($min_key)->max_keysize, 40, 'Anubis->new()->max_keysize'); +is( Crypt::Cipher::Anubis->new($min_key)->min_keysize, 16, 'Anubis->new()->min_keysize'); +is( Crypt::Cipher::Anubis->new($min_key)->default_rounds, 12, 'Anubis->new()->default_rounds'); + +is( Crypt::Cipher->new('Anubis', $min_key)->blocksize, 16, 'Cipher->new()->blocksize'); +is( Crypt::Cipher->new('Anubis', $min_key)->keysize, 40, 'Cipher->new()->keysize'); +is( Crypt::Cipher->new('Anubis', $min_key)->max_keysize, 40, 'Cipher->new()->max_keysize'); +is( Crypt::Cipher->new('Anubis', $min_key)->min_keysize, 16, 'Cipher->new()->min_keysize'); +is( Crypt::Cipher->new('Anubis', $min_key)->default_rounds, 12, 'Cipher->new()->default_rounds'); + +my $block_plain = 'BBBBBBBBBBBBBBBB'; +my $block_encrypted_min_key_hex = 'a60b68b88d24d85f3b0cd708196ed99b'; +my $block_encrypted_max_key_hex = 'b71e0006978b57d6bf9b792cd4cacfe2'; + +is( unpack('H*', Crypt::Cipher::Anubis->new($min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Anubis->encrypt'); +is( Crypt::Cipher::Anubis->new($min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Anubis->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('Anubis', $min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('Anubis', $min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Cipher->decrypt'); + +is( unpack('H*', Crypt::Cipher::Anubis->new($max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Anubis->encrypt'); +is( Crypt::Cipher::Anubis->new($max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Anubis->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('Anubis', $max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('Anubis', $max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Cipher->decrypt'); + diff --git a/t/cipher_blowfish.t b/t/cipher_blowfish.t new file mode 100644 index 0000000..9c6978c --- /dev/null +++ b/t/cipher_blowfish.t @@ -0,0 +1,65 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 38; + +use Crypt::Cipher; +use Crypt::Cipher::Blowfish; + +is( Crypt::Cipher::Blowfish::blocksize, 8, '::blocksize'); +is( Crypt::Cipher::Blowfish::keysize, 56, '::keysize'); +is( Crypt::Cipher::Blowfish::max_keysize, 56, '::max_keysize'); +is( Crypt::Cipher::Blowfish::min_keysize, 8, '::min_keysize'); +is( Crypt::Cipher::Blowfish::default_rounds, 16, '::default_rounds'); + +is( Crypt::Cipher::Blowfish->blocksize, 8, '->blocksize'); +is( Crypt::Cipher::Blowfish->keysize, 56, '->keysize'); +is( Crypt::Cipher::Blowfish->max_keysize, 56, '->max_keysize'); +is( Crypt::Cipher::Blowfish->min_keysize, 8, '->min_keysize'); +is( Crypt::Cipher::Blowfish->default_rounds, 16, '->default_rounds'); + +my $min_key = 'kkkkkkkk'; +my $max_key = 'KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK'; + +is( Crypt::Cipher::blocksize('Blowfish'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher::keysize('Blowfish'), 56, 'Cipher->keysize'); +is( Crypt::Cipher::max_keysize('Blowfish'), 56, 'Cipher->max_keysize'); +is( Crypt::Cipher::min_keysize('Blowfish'), 8, 'Cipher->min_keysize'); +is( Crypt::Cipher::default_rounds('Blowfish'), 16, 'Cipher->default_rounds'); + +is( Crypt::Cipher->blocksize('Blowfish'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher->keysize('Blowfish'), 56, 'Cipher->keysize'); +is( Crypt::Cipher->max_keysize('Blowfish'), 56, 'Cipher->max_keysize'); +is( Crypt::Cipher->min_keysize('Blowfish'), 8, 'Cipher->min_keysize'); +is( Crypt::Cipher->default_rounds('Blowfish'), 16, 'Cipher->default_rounds'); + +is( Crypt::Cipher::Blowfish->new($min_key)->blocksize, 8, 'Blowfish->new()->blocksize'); +is( Crypt::Cipher::Blowfish->new($min_key)->keysize, 56, 'Blowfish->new()->keysize'); +is( Crypt::Cipher::Blowfish->new($min_key)->max_keysize, 56, 'Blowfish->new()->max_keysize'); +is( Crypt::Cipher::Blowfish->new($min_key)->min_keysize, 8, 'Blowfish->new()->min_keysize'); +is( Crypt::Cipher::Blowfish->new($min_key)->default_rounds, 16, 'Blowfish->new()->default_rounds'); + +is( Crypt::Cipher->new('Blowfish', $min_key)->blocksize, 8, 'Cipher->new()->blocksize'); +is( Crypt::Cipher->new('Blowfish', $min_key)->keysize, 56, 'Cipher->new()->keysize'); +is( Crypt::Cipher->new('Blowfish', $min_key)->max_keysize, 56, 'Cipher->new()->max_keysize'); +is( Crypt::Cipher->new('Blowfish', $min_key)->min_keysize, 8, 'Cipher->new()->min_keysize'); +is( Crypt::Cipher->new('Blowfish', $min_key)->default_rounds, 16, 'Cipher->new()->default_rounds'); + +my $block_plain = 'BBBBBBBB'; +my $block_encrypted_min_key_hex = 'b224e1799d6e0f7d'; +my $block_encrypted_max_key_hex = 'd060619385d48889'; + +is( unpack('H*', Crypt::Cipher::Blowfish->new($min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Blowfish->encrypt'); +is( Crypt::Cipher::Blowfish->new($min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Blowfish->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('Blowfish', $min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('Blowfish', $min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Cipher->decrypt'); + +is( unpack('H*', Crypt::Cipher::Blowfish->new($max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Blowfish->encrypt'); +is( Crypt::Cipher::Blowfish->new($max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Blowfish->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('Blowfish', $max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('Blowfish', $max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Cipher->decrypt'); + diff --git a/t/cipher_camellia.t b/t/cipher_camellia.t new file mode 100644 index 0000000..aafcfb1 --- /dev/null +++ b/t/cipher_camellia.t @@ -0,0 +1,65 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 38; + +use Crypt::Cipher; +use Crypt::Cipher::Camellia; + +is( Crypt::Cipher::Camellia::blocksize, 16, '::blocksize'); +is( Crypt::Cipher::Camellia::keysize, 32, '::keysize'); +is( Crypt::Cipher::Camellia::max_keysize, 32, '::max_keysize'); +is( Crypt::Cipher::Camellia::min_keysize, 16, '::min_keysize'); +is( Crypt::Cipher::Camellia::default_rounds, 18, '::default_rounds'); + +is( Crypt::Cipher::Camellia->blocksize, 16, '->blocksize'); +is( Crypt::Cipher::Camellia->keysize, 32, '->keysize'); +is( Crypt::Cipher::Camellia->max_keysize, 32, '->max_keysize'); +is( Crypt::Cipher::Camellia->min_keysize, 16, '->min_keysize'); +is( Crypt::Cipher::Camellia->default_rounds, 18, '->default_rounds'); + +my $min_key = 'kkkkkkkkkkkkkkkk'; +my $max_key = 'KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK'; + +is( Crypt::Cipher::blocksize('Camellia'), 16, 'Cipher->blocksize'); +is( Crypt::Cipher::keysize('Camellia'), 32, 'Cipher->keysize'); +is( Crypt::Cipher::max_keysize('Camellia'), 32, 'Cipher->max_keysize'); +is( Crypt::Cipher::min_keysize('Camellia'), 16, 'Cipher->min_keysize'); +is( Crypt::Cipher::default_rounds('Camellia'), 18, 'Cipher->default_rounds'); + +is( Crypt::Cipher->blocksize('Camellia'), 16, 'Cipher->blocksize'); +is( Crypt::Cipher->keysize('Camellia'), 32, 'Cipher->keysize'); +is( Crypt::Cipher->max_keysize('Camellia'), 32, 'Cipher->max_keysize'); +is( Crypt::Cipher->min_keysize('Camellia'), 16, 'Cipher->min_keysize'); +is( Crypt::Cipher->default_rounds('Camellia'), 18, 'Cipher->default_rounds'); + +is( Crypt::Cipher::Camellia->new($min_key)->blocksize, 16, 'Camellia->new()->blocksize'); +is( Crypt::Cipher::Camellia->new($min_key)->keysize, 32, 'Camellia->new()->keysize'); +is( Crypt::Cipher::Camellia->new($min_key)->max_keysize, 32, 'Camellia->new()->max_keysize'); +is( Crypt::Cipher::Camellia->new($min_key)->min_keysize, 16, 'Camellia->new()->min_keysize'); +is( Crypt::Cipher::Camellia->new($min_key)->default_rounds, 18, 'Camellia->new()->default_rounds'); + +is( Crypt::Cipher->new('Camellia', $min_key)->blocksize, 16, 'Cipher->new()->blocksize'); +is( Crypt::Cipher->new('Camellia', $min_key)->keysize, 32, 'Cipher->new()->keysize'); +is( Crypt::Cipher->new('Camellia', $min_key)->max_keysize, 32, 'Cipher->new()->max_keysize'); +is( Crypt::Cipher->new('Camellia', $min_key)->min_keysize, 16, 'Cipher->new()->min_keysize'); +is( Crypt::Cipher->new('Camellia', $min_key)->default_rounds, 18, 'Cipher->new()->default_rounds'); + +my $block_plain = 'BBBBBBBBBBBBBBBB'; +my $block_encrypted_min_key_hex = 'f492579d09aa161b527d944df13c01ab'; +my $block_encrypted_max_key_hex = 'a8f95dc649586f8c366c226cc728ccb4'; + +is( unpack('H*', Crypt::Cipher::Camellia->new($min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Camellia->encrypt'); +is( Crypt::Cipher::Camellia->new($min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Camellia->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('Camellia', $min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('Camellia', $min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Cipher->decrypt'); + +is( unpack('H*', Crypt::Cipher::Camellia->new($max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Camellia->encrypt'); +is( Crypt::Cipher::Camellia->new($max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Camellia->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('Camellia', $max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('Camellia', $max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Cipher->decrypt'); + diff --git a/t/cipher_cast5.t b/t/cipher_cast5.t new file mode 100644 index 0000000..32d648d --- /dev/null +++ b/t/cipher_cast5.t @@ -0,0 +1,65 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 38; + +use Crypt::Cipher; +use Crypt::Cipher::CAST5; + +is( Crypt::Cipher::CAST5::blocksize, 8, '::blocksize'); +is( Crypt::Cipher::CAST5::keysize, 16, '::keysize'); +is( Crypt::Cipher::CAST5::max_keysize, 16, '::max_keysize'); +is( Crypt::Cipher::CAST5::min_keysize, 5, '::min_keysize'); +is( Crypt::Cipher::CAST5::default_rounds, 16, '::default_rounds'); + +is( Crypt::Cipher::CAST5->blocksize, 8, '->blocksize'); +is( Crypt::Cipher::CAST5->keysize, 16, '->keysize'); +is( Crypt::Cipher::CAST5->max_keysize, 16, '->max_keysize'); +is( Crypt::Cipher::CAST5->min_keysize, 5, '->min_keysize'); +is( Crypt::Cipher::CAST5->default_rounds, 16, '->default_rounds'); + +my $min_key = 'kkkkk'; +my $max_key = 'KKKKKKKKKKKKKKKK'; + +is( Crypt::Cipher::blocksize('CAST5'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher::keysize('CAST5'), 16, 'Cipher->keysize'); +is( Crypt::Cipher::max_keysize('CAST5'), 16, 'Cipher->max_keysize'); +is( Crypt::Cipher::min_keysize('CAST5'), 5, 'Cipher->min_keysize'); +is( Crypt::Cipher::default_rounds('CAST5'), 16, 'Cipher->default_rounds'); + +is( Crypt::Cipher->blocksize('CAST5'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher->keysize('CAST5'), 16, 'Cipher->keysize'); +is( Crypt::Cipher->max_keysize('CAST5'), 16, 'Cipher->max_keysize'); +is( Crypt::Cipher->min_keysize('CAST5'), 5, 'Cipher->min_keysize'); +is( Crypt::Cipher->default_rounds('CAST5'), 16, 'Cipher->default_rounds'); + +is( Crypt::Cipher::CAST5->new($min_key)->blocksize, 8, 'CAST5->new()->blocksize'); +is( Crypt::Cipher::CAST5->new($min_key)->keysize, 16, 'CAST5->new()->keysize'); +is( Crypt::Cipher::CAST5->new($min_key)->max_keysize, 16, 'CAST5->new()->max_keysize'); +is( Crypt::Cipher::CAST5->new($min_key)->min_keysize, 5, 'CAST5->new()->min_keysize'); +is( Crypt::Cipher::CAST5->new($min_key)->default_rounds, 16, 'CAST5->new()->default_rounds'); + +is( Crypt::Cipher->new('CAST5', $min_key)->blocksize, 8, 'Cipher->new()->blocksize'); +is( Crypt::Cipher->new('CAST5', $min_key)->keysize, 16, 'Cipher->new()->keysize'); +is( Crypt::Cipher->new('CAST5', $min_key)->max_keysize, 16, 'Cipher->new()->max_keysize'); +is( Crypt::Cipher->new('CAST5', $min_key)->min_keysize, 5, 'Cipher->new()->min_keysize'); +is( Crypt::Cipher->new('CAST5', $min_key)->default_rounds, 16, 'Cipher->new()->default_rounds'); + +my $block_plain = 'BBBBBBBB'; +my $block_encrypted_min_key_hex = '33eb97c2c524cebc'; +my $block_encrypted_max_key_hex = 'aa493efb8bba2a45'; + +is( unpack('H*', Crypt::Cipher::CAST5->new($min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'CAST5->encrypt'); +is( Crypt::Cipher::CAST5->new($min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'CAST5->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('CAST5', $min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('CAST5', $min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Cipher->decrypt'); + +is( unpack('H*', Crypt::Cipher::CAST5->new($max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'CAST5->encrypt'); +is( Crypt::Cipher::CAST5->new($max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'CAST5->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('CAST5', $max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('CAST5', $max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Cipher->decrypt'); + diff --git a/t/cipher_des.t b/t/cipher_des.t new file mode 100644 index 0000000..2463214 --- /dev/null +++ b/t/cipher_des.t @@ -0,0 +1,65 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 38; + +use Crypt::Cipher; +use Crypt::Cipher::DES; + +is( Crypt::Cipher::DES::blocksize, 8, '::blocksize'); +is( Crypt::Cipher::DES::keysize, 8, '::keysize'); +is( Crypt::Cipher::DES::max_keysize, 8, '::max_keysize'); +is( Crypt::Cipher::DES::min_keysize, 8, '::min_keysize'); +is( Crypt::Cipher::DES::default_rounds, 16, '::default_rounds'); + +is( Crypt::Cipher::DES->blocksize, 8, '->blocksize'); +is( Crypt::Cipher::DES->keysize, 8, '->keysize'); +is( Crypt::Cipher::DES->max_keysize, 8, '->max_keysize'); +is( Crypt::Cipher::DES->min_keysize, 8, '->min_keysize'); +is( Crypt::Cipher::DES->default_rounds, 16, '->default_rounds'); + +my $min_key = 'kkkkkkkk'; +my $max_key = 'KKKKKKKK'; + +is( Crypt::Cipher::blocksize('DES'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher::keysize('DES'), 8, 'Cipher->keysize'); +is( Crypt::Cipher::max_keysize('DES'), 8, 'Cipher->max_keysize'); +is( Crypt::Cipher::min_keysize('DES'), 8, 'Cipher->min_keysize'); +is( Crypt::Cipher::default_rounds('DES'), 16, 'Cipher->default_rounds'); + +is( Crypt::Cipher->blocksize('DES'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher->keysize('DES'), 8, 'Cipher->keysize'); +is( Crypt::Cipher->max_keysize('DES'), 8, 'Cipher->max_keysize'); +is( Crypt::Cipher->min_keysize('DES'), 8, 'Cipher->min_keysize'); +is( Crypt::Cipher->default_rounds('DES'), 16, 'Cipher->default_rounds'); + +is( Crypt::Cipher::DES->new($min_key)->blocksize, 8, 'DES->new()->blocksize'); +is( Crypt::Cipher::DES->new($min_key)->keysize, 8, 'DES->new()->keysize'); +is( Crypt::Cipher::DES->new($min_key)->max_keysize, 8, 'DES->new()->max_keysize'); +is( Crypt::Cipher::DES->new($min_key)->min_keysize, 8, 'DES->new()->min_keysize'); +is( Crypt::Cipher::DES->new($min_key)->default_rounds, 16, 'DES->new()->default_rounds'); + +is( Crypt::Cipher->new('DES', $min_key)->blocksize, 8, 'Cipher->new()->blocksize'); +is( Crypt::Cipher->new('DES', $min_key)->keysize, 8, 'Cipher->new()->keysize'); +is( Crypt::Cipher->new('DES', $min_key)->max_keysize, 8, 'Cipher->new()->max_keysize'); +is( Crypt::Cipher->new('DES', $min_key)->min_keysize, 8, 'Cipher->new()->min_keysize'); +is( Crypt::Cipher->new('DES', $min_key)->default_rounds, 16, 'Cipher->new()->default_rounds'); + +my $block_plain = 'BBBBBBBB'; +my $block_encrypted_min_key_hex = 'dc58fab575ba33d8'; +my $block_encrypted_max_key_hex = 'c6b60209d8ef7379'; + +is( unpack('H*', Crypt::Cipher::DES->new($min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'DES->encrypt'); +is( Crypt::Cipher::DES->new($min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'DES->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('DES', $min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('DES', $min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Cipher->decrypt'); + +is( unpack('H*', Crypt::Cipher::DES->new($max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'DES->encrypt'); +is( Crypt::Cipher::DES->new($max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'DES->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('DES', $max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('DES', $max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Cipher->decrypt'); + diff --git a/t/cipher_des_ede.t b/t/cipher_des_ede.t new file mode 100644 index 0000000..cfd8d68 --- /dev/null +++ b/t/cipher_des_ede.t @@ -0,0 +1,65 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 38; + +use Crypt::Cipher; +use Crypt::Cipher::DES_EDE; + +is( Crypt::Cipher::DES_EDE::blocksize, 8, '::blocksize'); +is( Crypt::Cipher::DES_EDE::keysize, 24, '::keysize'); +is( Crypt::Cipher::DES_EDE::max_keysize, 24, '::max_keysize'); +is( Crypt::Cipher::DES_EDE::min_keysize, 24, '::min_keysize'); +is( Crypt::Cipher::DES_EDE::default_rounds, 16, '::default_rounds'); + +is( Crypt::Cipher::DES_EDE->blocksize, 8, '->blocksize'); +is( Crypt::Cipher::DES_EDE->keysize, 24, '->keysize'); +is( Crypt::Cipher::DES_EDE->max_keysize, 24, '->max_keysize'); +is( Crypt::Cipher::DES_EDE->min_keysize, 24, '->min_keysize'); +is( Crypt::Cipher::DES_EDE->default_rounds, 16, '->default_rounds'); + +my $min_key = 'kkkkkkkkkkkkkkkkkkkkkkkk'; +my $max_key = 'KKKKKKKKKKKKKKKKKKKKKKKK'; + +is( Crypt::Cipher::blocksize('DES_EDE'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher::keysize('DES_EDE'), 24, 'Cipher->keysize'); +is( Crypt::Cipher::max_keysize('DES_EDE'), 24, 'Cipher->max_keysize'); +is( Crypt::Cipher::min_keysize('DES_EDE'), 24, 'Cipher->min_keysize'); +is( Crypt::Cipher::default_rounds('DES_EDE'), 16, 'Cipher->default_rounds'); + +is( Crypt::Cipher->blocksize('DES_EDE'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher->keysize('DES_EDE'), 24, 'Cipher->keysize'); +is( Crypt::Cipher->max_keysize('DES_EDE'), 24, 'Cipher->max_keysize'); +is( Crypt::Cipher->min_keysize('DES_EDE'), 24, 'Cipher->min_keysize'); +is( Crypt::Cipher->default_rounds('DES_EDE'), 16, 'Cipher->default_rounds'); + +is( Crypt::Cipher::DES_EDE->new($min_key)->blocksize, 8, 'DES_EDE->new()->blocksize'); +is( Crypt::Cipher::DES_EDE->new($min_key)->keysize, 24, 'DES_EDE->new()->keysize'); +is( Crypt::Cipher::DES_EDE->new($min_key)->max_keysize, 24, 'DES_EDE->new()->max_keysize'); +is( Crypt::Cipher::DES_EDE->new($min_key)->min_keysize, 24, 'DES_EDE->new()->min_keysize'); +is( Crypt::Cipher::DES_EDE->new($min_key)->default_rounds, 16, 'DES_EDE->new()->default_rounds'); + +is( Crypt::Cipher->new('DES_EDE', $min_key)->blocksize, 8, 'Cipher->new()->blocksize'); +is( Crypt::Cipher->new('DES_EDE', $min_key)->keysize, 24, 'Cipher->new()->keysize'); +is( Crypt::Cipher->new('DES_EDE', $min_key)->max_keysize, 24, 'Cipher->new()->max_keysize'); +is( Crypt::Cipher->new('DES_EDE', $min_key)->min_keysize, 24, 'Cipher->new()->min_keysize'); +is( Crypt::Cipher->new('DES_EDE', $min_key)->default_rounds, 16, 'Cipher->new()->default_rounds'); + +my $block_plain = 'BBBBBBBB'; +my $block_encrypted_min_key_hex = 'dc58fab575ba33d8'; +my $block_encrypted_max_key_hex = 'c6b60209d8ef7379'; + +is( unpack('H*', Crypt::Cipher::DES_EDE->new($min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'DES_EDE->encrypt'); +is( Crypt::Cipher::DES_EDE->new($min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'DES_EDE->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('DES_EDE', $min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('DES_EDE', $min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Cipher->decrypt'); + +is( unpack('H*', Crypt::Cipher::DES_EDE->new($max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'DES_EDE->encrypt'); +is( Crypt::Cipher::DES_EDE->new($max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'DES_EDE->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('DES_EDE', $max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('DES_EDE', $max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Cipher->decrypt'); + diff --git a/t/cipher_kasumi.t b/t/cipher_kasumi.t new file mode 100644 index 0000000..b9d6a2e --- /dev/null +++ b/t/cipher_kasumi.t @@ -0,0 +1,65 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 38; + +use Crypt::Cipher; +use Crypt::Cipher::KASUMI; + +is( Crypt::Cipher::KASUMI::blocksize, 8, '::blocksize'); +is( Crypt::Cipher::KASUMI::keysize, 16, '::keysize'); +is( Crypt::Cipher::KASUMI::max_keysize, 16, '::max_keysize'); +is( Crypt::Cipher::KASUMI::min_keysize, 16, '::min_keysize'); +is( Crypt::Cipher::KASUMI::default_rounds, 8, '::default_rounds'); + +is( Crypt::Cipher::KASUMI->blocksize, 8, '->blocksize'); +is( Crypt::Cipher::KASUMI->keysize, 16, '->keysize'); +is( Crypt::Cipher::KASUMI->max_keysize, 16, '->max_keysize'); +is( Crypt::Cipher::KASUMI->min_keysize, 16, '->min_keysize'); +is( Crypt::Cipher::KASUMI->default_rounds, 8, '->default_rounds'); + +my $min_key = 'kkkkkkkkkkkkkkkk'; +my $max_key = 'KKKKKKKKKKKKKKKK'; + +is( Crypt::Cipher::blocksize('KASUMI'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher::keysize('KASUMI'), 16, 'Cipher->keysize'); +is( Crypt::Cipher::max_keysize('KASUMI'), 16, 'Cipher->max_keysize'); +is( Crypt::Cipher::min_keysize('KASUMI'), 16, 'Cipher->min_keysize'); +is( Crypt::Cipher::default_rounds('KASUMI'), 8, 'Cipher->default_rounds'); + +is( Crypt::Cipher->blocksize('KASUMI'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher->keysize('KASUMI'), 16, 'Cipher->keysize'); +is( Crypt::Cipher->max_keysize('KASUMI'), 16, 'Cipher->max_keysize'); +is( Crypt::Cipher->min_keysize('KASUMI'), 16, 'Cipher->min_keysize'); +is( Crypt::Cipher->default_rounds('KASUMI'), 8, 'Cipher->default_rounds'); + +is( Crypt::Cipher::KASUMI->new($min_key)->blocksize, 8, 'KASUMI->new()->blocksize'); +is( Crypt::Cipher::KASUMI->new($min_key)->keysize, 16, 'KASUMI->new()->keysize'); +is( Crypt::Cipher::KASUMI->new($min_key)->max_keysize, 16, 'KASUMI->new()->max_keysize'); +is( Crypt::Cipher::KASUMI->new($min_key)->min_keysize, 16, 'KASUMI->new()->min_keysize'); +is( Crypt::Cipher::KASUMI->new($min_key)->default_rounds, 8, 'KASUMI->new()->default_rounds'); + +is( Crypt::Cipher->new('KASUMI', $min_key)->blocksize, 8, 'Cipher->new()->blocksize'); +is( Crypt::Cipher->new('KASUMI', $min_key)->keysize, 16, 'Cipher->new()->keysize'); +is( Crypt::Cipher->new('KASUMI', $min_key)->max_keysize, 16, 'Cipher->new()->max_keysize'); +is( Crypt::Cipher->new('KASUMI', $min_key)->min_keysize, 16, 'Cipher->new()->min_keysize'); +is( Crypt::Cipher->new('KASUMI', $min_key)->default_rounds, 8, 'Cipher->new()->default_rounds'); + +my $block_plain = 'BBBBBBBB'; +my $block_encrypted_min_key_hex = '01882ff16cfff4f5'; +my $block_encrypted_max_key_hex = '748aeb4153b38bf2'; + +is( unpack('H*', Crypt::Cipher::KASUMI->new($min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'KASUMI->encrypt'); +is( Crypt::Cipher::KASUMI->new($min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'KASUMI->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('KASUMI', $min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('KASUMI', $min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Cipher->decrypt'); + +is( unpack('H*', Crypt::Cipher::KASUMI->new($max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'KASUMI->encrypt'); +is( Crypt::Cipher::KASUMI->new($max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'KASUMI->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('KASUMI', $max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('KASUMI', $max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Cipher->decrypt'); + diff --git a/t/cipher_khazad.t b/t/cipher_khazad.t new file mode 100644 index 0000000..77834a3 --- /dev/null +++ b/t/cipher_khazad.t @@ -0,0 +1,65 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 38; + +use Crypt::Cipher; +use Crypt::Cipher::Khazad; + +is( Crypt::Cipher::Khazad::blocksize, 8, '::blocksize'); +is( Crypt::Cipher::Khazad::keysize, 16, '::keysize'); +is( Crypt::Cipher::Khazad::max_keysize, 16, '::max_keysize'); +is( Crypt::Cipher::Khazad::min_keysize, 16, '::min_keysize'); +is( Crypt::Cipher::Khazad::default_rounds, 8, '::default_rounds'); + +is( Crypt::Cipher::Khazad->blocksize, 8, '->blocksize'); +is( Crypt::Cipher::Khazad->keysize, 16, '->keysize'); +is( Crypt::Cipher::Khazad->max_keysize, 16, '->max_keysize'); +is( Crypt::Cipher::Khazad->min_keysize, 16, '->min_keysize'); +is( Crypt::Cipher::Khazad->default_rounds, 8, '->default_rounds'); + +my $min_key = 'kkkkkkkkkkkkkkkk'; +my $max_key = 'KKKKKKKKKKKKKKKK'; + +is( Crypt::Cipher::blocksize('Khazad'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher::keysize('Khazad'), 16, 'Cipher->keysize'); +is( Crypt::Cipher::max_keysize('Khazad'), 16, 'Cipher->max_keysize'); +is( Crypt::Cipher::min_keysize('Khazad'), 16, 'Cipher->min_keysize'); +is( Crypt::Cipher::default_rounds('Khazad'), 8, 'Cipher->default_rounds'); + +is( Crypt::Cipher->blocksize('Khazad'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher->keysize('Khazad'), 16, 'Cipher->keysize'); +is( Crypt::Cipher->max_keysize('Khazad'), 16, 'Cipher->max_keysize'); +is( Crypt::Cipher->min_keysize('Khazad'), 16, 'Cipher->min_keysize'); +is( Crypt::Cipher->default_rounds('Khazad'), 8, 'Cipher->default_rounds'); + +is( Crypt::Cipher::Khazad->new($min_key)->blocksize, 8, 'Khazad->new()->blocksize'); +is( Crypt::Cipher::Khazad->new($min_key)->keysize, 16, 'Khazad->new()->keysize'); +is( Crypt::Cipher::Khazad->new($min_key)->max_keysize, 16, 'Khazad->new()->max_keysize'); +is( Crypt::Cipher::Khazad->new($min_key)->min_keysize, 16, 'Khazad->new()->min_keysize'); +is( Crypt::Cipher::Khazad->new($min_key)->default_rounds, 8, 'Khazad->new()->default_rounds'); + +is( Crypt::Cipher->new('Khazad', $min_key)->blocksize, 8, 'Cipher->new()->blocksize'); +is( Crypt::Cipher->new('Khazad', $min_key)->keysize, 16, 'Cipher->new()->keysize'); +is( Crypt::Cipher->new('Khazad', $min_key)->max_keysize, 16, 'Cipher->new()->max_keysize'); +is( Crypt::Cipher->new('Khazad', $min_key)->min_keysize, 16, 'Cipher->new()->min_keysize'); +is( Crypt::Cipher->new('Khazad', $min_key)->default_rounds, 8, 'Cipher->new()->default_rounds'); + +my $block_plain = 'BBBBBBBB'; +my $block_encrypted_min_key_hex = '8c686199eeb0100a'; +my $block_encrypted_max_key_hex = '0e9815a0167dd474'; + +is( unpack('H*', Crypt::Cipher::Khazad->new($min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Khazad->encrypt'); +is( Crypt::Cipher::Khazad->new($min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Khazad->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('Khazad', $min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('Khazad', $min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Cipher->decrypt'); + +is( unpack('H*', Crypt::Cipher::Khazad->new($max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Khazad->encrypt'); +is( Crypt::Cipher::Khazad->new($max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Khazad->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('Khazad', $max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('Khazad', $max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Cipher->decrypt'); + diff --git a/t/cipher_multi2.t b/t/cipher_multi2.t new file mode 100644 index 0000000..d9fdf90 --- /dev/null +++ b/t/cipher_multi2.t @@ -0,0 +1,75 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 42; + +use Crypt::Cipher; +use Crypt::Cipher::MULTI2; + +is( Crypt::Cipher::MULTI2::blocksize, 8, '::blocksize'); +is( Crypt::Cipher::MULTI2::keysize, 40, '::keysize'); +is( Crypt::Cipher::MULTI2::max_keysize, 40, '::max_keysize'); +is( Crypt::Cipher::MULTI2::min_keysize, 40, '::min_keysize'); +is( Crypt::Cipher::MULTI2::default_rounds, 128, '::default_rounds'); + +is( Crypt::Cipher::MULTI2->blocksize, 8, '->blocksize'); +is( Crypt::Cipher::MULTI2->keysize, 40, '->keysize'); +is( Crypt::Cipher::MULTI2->max_keysize, 40, '->max_keysize'); +is( Crypt::Cipher::MULTI2->min_keysize, 40, '->min_keysize'); +is( Crypt::Cipher::MULTI2->default_rounds, 128, '->default_rounds'); + +my $min_key = 'kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk'; +my $max_key = 'KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK'; + +is( Crypt::Cipher::blocksize('MULTI2'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher::keysize('MULTI2'), 40, 'Cipher->keysize'); +is( Crypt::Cipher::max_keysize('MULTI2'), 40, 'Cipher->max_keysize'); +is( Crypt::Cipher::min_keysize('MULTI2'), 40, 'Cipher->min_keysize'); +is( Crypt::Cipher::default_rounds('MULTI2'), 128, 'Cipher->default_rounds'); + +is( Crypt::Cipher->blocksize('MULTI2'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher->keysize('MULTI2'), 40, 'Cipher->keysize'); +is( Crypt::Cipher->max_keysize('MULTI2'), 40, 'Cipher->max_keysize'); +is( Crypt::Cipher->min_keysize('MULTI2'), 40, 'Cipher->min_keysize'); +is( Crypt::Cipher->default_rounds('MULTI2'), 128, 'Cipher->default_rounds'); + +is( Crypt::Cipher::MULTI2->new($min_key)->blocksize, 8, 'MULTI2->new()->blocksize'); +is( Crypt::Cipher::MULTI2->new($min_key)->keysize, 40, 'MULTI2->new()->keysize'); +is( Crypt::Cipher::MULTI2->new($min_key)->max_keysize, 40, 'MULTI2->new()->max_keysize'); +is( Crypt::Cipher::MULTI2->new($min_key)->min_keysize, 40, 'MULTI2->new()->min_keysize'); +is( Crypt::Cipher::MULTI2->new($min_key)->default_rounds, 128, 'MULTI2->new()->default_rounds'); + +is( Crypt::Cipher->new('MULTI2', $min_key)->blocksize, 8, 'Cipher->new()->blocksize'); +is( Crypt::Cipher->new('MULTI2', $min_key)->keysize, 40, 'Cipher->new()->keysize'); +is( Crypt::Cipher->new('MULTI2', $min_key)->max_keysize, 40, 'Cipher->new()->max_keysize'); +is( Crypt::Cipher->new('MULTI2', $min_key)->min_keysize, 40, 'Cipher->new()->min_keysize'); +is( Crypt::Cipher->new('MULTI2', $min_key)->default_rounds, 128, 'Cipher->new()->default_rounds'); + +my $block_plain = 'BBBBBBBB'; +my $block_encrypted_min_key_hex = '321f187e9d9810aa'; +my $block_encrypted_max_key_hex = '435923e078988203'; + +is( unpack('H*', Crypt::Cipher::MULTI2->new($min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'MULTI2->encrypt'); +is( Crypt::Cipher::MULTI2->new($min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'MULTI2->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('MULTI2', $min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('MULTI2', $min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Cipher->decrypt'); + +is( unpack('H*', Crypt::Cipher::MULTI2->new($max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'MULTI2->encrypt'); +is( Crypt::Cipher::MULTI2->new($max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'MULTI2->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('MULTI2', $max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('MULTI2', $max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Cipher->decrypt'); + + +my $spec_key = 'SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS'; +my $spec_rounds = '199'; +my $spec_block_encrypted_hex = 'ec944aa441dac52b'; + +is( unpack('H*', Crypt::Cipher::MULTI2->new($spec_key, $spec_rounds)->encrypt($block_plain)), $spec_block_encrypted_hex, 'MULTI2->encrypt'); +is( Crypt::Cipher::MULTI2->new($spec_key, $spec_rounds)->decrypt(pack('H*', $spec_block_encrypted_hex)), $block_plain, 'MULTI2->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('MULTI2', $spec_key, $spec_rounds)->encrypt($block_plain)), $spec_block_encrypted_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('MULTI2', $spec_key, $spec_rounds)->decrypt(pack('H*', $spec_block_encrypted_hex)), $block_plain, 'Cipher->decrypt'); diff --git a/t/cipher_multi2_rounds.t b/t/cipher_multi2_rounds.t new file mode 100644 index 0000000..c0d814e --- /dev/null +++ b/t/cipher_multi2_rounds.t @@ -0,0 +1,572 @@ +use strict; +use warnings; + +use Test::More tests => 1110; + +use Crypt::Cipher::MULTI2; + +my $key = 'SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS'; +my $plaintext = '12345678'; + +my $expected_results = [ + { ciphertext => "313233340404040c", rounds => 1 }, + { ciphertext => "202320410404040c", rounds => 2 }, + { ciphertext => "2023204154597453", rounds => 3 }, + { ciphertext => "d79fe59754597453", rounds => 4 }, + { ciphertext => "d79fe59783c691c4", rounds => 5 }, + { ciphertext => "3fcd632383c691c4", rounds => 6 }, + { ciphertext => "3fcd63231e3e35d5", rounds => 7 }, + { ciphertext => "913362211e3e35d5", rounds => 8 }, + { ciphertext => "913362218f0d57f4", rounds => 9 }, + { ciphertext => "118eb1ed8f0d57f4", rounds => 10 }, + { ciphertext => "118eb1ed8a7ce3c0", rounds => 11 }, + { ciphertext => "17e343198a7ce3c0", rounds => 12 }, + { ciphertext => "17e343199d9fa0d9", rounds => 13 }, + { ciphertext => "fb7966e09d9fa0d9", rounds => 14 }, + { ciphertext => "fb7966e079100e17", rounds => 15 }, + { ciphertext => "8e6e5cad79100e17", rounds => 16 }, + { ciphertext => "8e6e5cadf77e52ba", rounds => 17 }, + { ciphertext => "69ddb2acf77e52ba", rounds => 18 }, + { ciphertext => "69ddb2ac2fe11114", rounds => 19 }, + { ciphertext => "28bf67362fe11114", rounds => 20 }, + { ciphertext => "28bf6736075e7622", rounds => 21 }, + { ciphertext => "b2a0c140075e7622", rounds => 22 }, + { ciphertext => "b2a0c14095ebb737", rounds => 23 }, + { ciphertext => "b7c146aa95ebb737", rounds => 24 }, + { ciphertext => "b7c146aa222af19d", rounds => 25 }, + { ciphertext => "d3e676c8222af19d", rounds => 26 }, + { ciphertext => "d3e676c8982518dc", rounds => 27 }, + { ciphertext => "99508a48982518dc", rounds => 28 }, + { ciphertext => "99508a4801759294", rounds => 29 }, + { ciphertext => "6922e87501759294", rounds => 30 }, + { ciphertext => "6922e87510ac424b", rounds => 31 }, + { ciphertext => "0206d73a10ac424b", rounds => 32 }, + { ciphertext => "0206d73a12aa9571", rounds => 33 }, + { ciphertext => "ac6c736912aa9571", rounds => 34 }, + { ciphertext => "ac6c73690cd2d329", rounds => 35 }, + { ciphertext => "3e77d36a0cd2d329", rounds => 36 }, + { ciphertext => "3e77d36a32a50043", rounds => 37 }, + { ciphertext => "049fe89232a50043", rounds => 38 }, + { ciphertext => "049fe892ec5c3a35", rounds => 39 }, + { ciphertext => "b10bfe73ec5c3a35", rounds => 40 }, + { ciphertext => "b10bfe735d57c446", rounds => 41 }, + { ciphertext => "7cc3d1a65d57c446", rounds => 42 }, + { ciphertext => "7cc3d1a60bcb27b8", rounds => 43 }, + { ciphertext => "f03697680bcb27b8", rounds => 44 }, + { ciphertext => "f0369768fbfdb0d0", rounds => 45 }, + { ciphertext => "6e3180e6fbfdb0d0", rounds => 46 }, + { ciphertext => "6e3180e621beeef4", rounds => 47 }, + { ciphertext => "aeb01e7b21beeef4", rounds => 48 }, + { ciphertext => "aeb01e7b8f0ef08f", rounds => 49 }, + { ciphertext => "2ebb7ef68f0ef08f", rounds => 50 }, + { ciphertext => "2ebb7ef609b63c94", rounds => 51 }, + { ciphertext => "ac37d1ec09b63c94", rounds => 52 }, + { ciphertext => "ac37d1eca581ed78", rounds => 53 }, + { ciphertext => "f6f9adfba581ed78", rounds => 54 }, + { ciphertext => "f6f9adfb76effd3d", rounds => 55 }, + { ciphertext => "9c8f4bf076effd3d", rounds => 56 }, + { ciphertext => "9c8f4bf0ea60b6cd", rounds => 57 }, + { ciphertext => "2e52b507ea60b6cd", rounds => 58 }, + { ciphertext => "2e52b5073acaf464", rounds => 59 }, + { ciphertext => "59a6f32d3acaf464", rounds => 60 }, + { ciphertext => "59a6f32d636c0749", rounds => 61 }, + { ciphertext => "21caaeec636c0749", rounds => 62 }, + { ciphertext => "21caaeec23e64201", rounds => 63 }, + { ciphertext => "ea8c933223e64201", rounds => 64 }, + { ciphertext => "ea8c9332c96ad133", rounds => 65 }, + { ciphertext => "af6db068c96ad133", rounds => 66 }, + { ciphertext => "af6db0684ae8e5b0", rounds => 67 }, + { ciphertext => "67e44ccf4ae8e5b0", rounds => 68 }, + { ciphertext => "67e44ccf2d0ca97f", rounds => 69 }, + { ciphertext => "7d87a63a2d0ca97f", rounds => 70 }, + { ciphertext => "7d87a63a4c648993", rounds => 71 }, + { ciphertext => "e83a05824c648993", rounds => 72 }, + { ciphertext => "e83a0582a45e8c11", rounds => 73 }, + { ciphertext => "af357fe5a45e8c11", rounds => 74 }, + { ciphertext => "af357fe55ee983f3", rounds => 75 }, + { ciphertext => "83b86c135ee983f3", rounds => 76 }, + { ciphertext => "83b86c13dd51efe0", rounds => 77 }, + { ciphertext => "b9e69443dd51efe0", rounds => 78 }, + { ciphertext => "b9e6944314f1b724", rounds => 79 }, + { ciphertext => "399913ce14f1b724", rounds => 80 }, + { ciphertext => "399913ce2d68a4ea", rounds => 81 }, + { ciphertext => "63d87f752d68a4ea", rounds => 82 }, + { ciphertext => "63d87f75e8076748", rounds => 83 }, + { ciphertext => "b9fafbe8e8076748", rounds => 84 }, + { ciphertext => "b9fafbe851fd9ca0", rounds => 85 }, + { ciphertext => "41f161e751fd9ca0", rounds => 86 }, + { ciphertext => "41f161e79bfc77b7", rounds => 87 }, + { ciphertext => "62442b8d9bfc77b7", rounds => 88 }, + { ciphertext => "62442b8df9b85c3a", rounds => 89 }, + { ciphertext => "2207de0cf9b85c3a", rounds => 90 }, + { ciphertext => "2207de0c5518f490", rounds => 91 }, + { ciphertext => "d97d990b5518f490", rounds => 92 }, + { ciphertext => "d97d990b8c656d9b", rounds => 93 }, + { ciphertext => "fd417b688c656d9b", rounds => 94 }, + { ciphertext => "fd417b68e0972300", rounds => 95 }, + { ciphertext => "87fbd9b0e0972300", rounds => 96 }, + { ciphertext => "87fbd9b0676cfab0", rounds => 97 }, + { ciphertext => "0c75a101676cfab0", rounds => 98 }, + { ciphertext => "0c75a101ed85f12c", rounds => 99 }, + { ciphertext => "f9ee9710ed85f12c", rounds => 100 }, + { ciphertext => "f9ee9710146b663c", rounds => 101 }, + { ciphertext => "c4a6fd96146b663c", rounds => 102 }, + { ciphertext => "c4a6fd96ef3644e1", rounds => 103 }, + { ciphertext => "0770b1abef3644e1", rounds => 104 }, + { ciphertext => "0770b1abe846f54a", rounds => 105 }, + { ciphertext => "d8433a77e846f54a", rounds => 106 }, + { ciphertext => "d8433a7719fd2eb5", rounds => 107 }, + { ciphertext => "0bac53c819fd2eb5", rounds => 108 }, + { ciphertext => "0bac53c812517d7d", rounds => 109 }, + { ciphertext => "a2e67edb12517d7d", rounds => 110 }, + { ciphertext => "a2e67edb281d3be8", rounds => 111 }, + { ciphertext => "42bf61ba281d3be8", rounds => 112 }, + { ciphertext => "42bf61ba6aa25a52", rounds => 113 }, + { ciphertext => "655329f56aa25a52", rounds => 114 }, + { ciphertext => "655329f54bc37be5", rounds => 115 }, + { ciphertext => "a99dc2454bc37be5", rounds => 116 }, + { ciphertext => "a99dc245e25eb9a0", rounds => 117 }, + { ciphertext => "928f4356e25eb9a0", rounds => 118 }, + { ciphertext => "928f435658199125", rounds => 119 }, + { ciphertext => "42c98ac558199125", rounds => 120 }, + { ciphertext => "42c98ac51ad01be0", rounds => 121 }, + { ciphertext => "b23949711ad01be0", rounds => 122 }, + { ciphertext => "b239497151e132f8", rounds => 123 }, + { ciphertext => "595a367e51e132f8", rounds => 124 }, + { ciphertext => "595a367e08bb0486", rounds => 125 }, + { ciphertext => "1015dcf408bb0486", rounds => 126 }, + { ciphertext => "1015dcf49893406b", rounds => 127 }, + { ciphertext => "02b2e91a9893406b", rounds => 128 }, + { ciphertext => "02b2e91a9a21a971", rounds => 129 }, + { ciphertext => "8cffc9539a21a971", rounds => 130 }, + { ciphertext => "8cffc953abe79088", rounds => 131 }, + { ciphertext => "217c9b8fabe79088", rounds => 132 }, + { ciphertext => "217c9b8f8a9b0b07", rounds => 133 }, + { ciphertext => "9594c5638a9b0b07", rounds => 134 }, + { ciphertext => "9594c563582e1944", rounds => 135 }, + { ciphertext => "4539b74d582e1944", rounds => 136 }, + { ciphertext => "4539b74d1d17ae09", rounds => 137 }, + { ciphertext => "ddb586a41d17ae09", rounds => 138 }, + { ciphertext => "ddb586a467d20179", rounds => 139 }, + { ciphertext => "84a2013067d20179", rounds => 140 }, + { ciphertext => "84a20130e3700049", rounds => 141 }, + { ciphertext => "7fbb3c76e3700049", rounds => 142 }, + { ciphertext => "7fbb3c76e7b34d8d", rounds => 143 }, + { ciphertext => "e1fc4befe7b34d8d", rounds => 144 }, + { ciphertext => "e1fc4bef064f0662", rounds => 145 }, + { ciphertext => "7bbbd065064f0662", rounds => 146 }, + { ciphertext => "7bbbd065250def8c", rounds => 147 }, + { ciphertext => "70f8fd97250def8c", rounds => 148 }, + { ciphertext => "70f8fd9755f5121b", rounds => 149 }, + { ciphertext => "bb67c87e55f5121b", rounds => 150 }, + { ciphertext => "bb67c87e7ddf7043", rounds => 151 }, + { ciphertext => "3643ed577ddf7043", rounds => 152 }, + { ciphertext => "3643ed574b9c9d14", rounds => 153 }, + { ciphertext => "9361f1774b9c9d14", rounds => 154 }, + { ciphertext => "9361f177c6289193", rounds => 155 }, + { ciphertext => "a3a9a964c6289193", rounds => 156 }, + { ciphertext => "a3a9a964658138f7", rounds => 157 }, + { ciphertext => "b98bceb3658138f7", rounds => 158 }, + { ciphertext => "b98bceb3703360dc", rounds => 159 }, + { ciphertext => "f14c1695703360dc", rounds => 160 }, + { ciphertext => "f14c1695817f7649", rounds => 161 }, + { ciphertext => "94b230a0817f7649", rounds => 162 }, + { ciphertext => "94b230a07e078d81", rounds => 163 }, + { ciphertext => "5c91731c7e078d81", rounds => 164 }, + { ciphertext => "5c91731c2296fe9d", rounds => 165 }, + { ciphertext => "138394952296fe9d", rounds => 166 }, + { ciphertext => "138394951412d88c", rounds => 167 }, + { ciphertext => "6fa6ba011412d88c", rounds => 168 }, + { ciphertext => "6fa6ba017bb4628d", rounds => 169 }, + { ciphertext => "56d60c237bb4628d", rounds => 170 }, + { ciphertext => "56d60c238bd99497", rounds => 171 }, + { ciphertext => "5beb6b048bd99497", rounds => 172 }, + { ciphertext => "5beb6b04d032ff93", rounds => 173 }, + { ciphertext => "824dbdf8d032ff93", rounds => 174 }, + { ciphertext => "824dbdf8d710d6c0", rounds => 175 }, + { ciphertext => "c9569860d710d6c0", rounds => 176 }, + { ciphertext => "c95698601e464ea0", rounds => 177 }, + { ciphertext => "940ca7941e464ea0", rounds => 178 }, + { ciphertext => "940ca794f489a56b", rounds => 179 }, + { ciphertext => "8ca11cd8f489a56b", rounds => 180 }, + { ciphertext => "8ca11cd87828b9b3", rounds => 181 }, + { ciphertext => "df319e777828b9b3", rounds => 182 }, + { ciphertext => "df319e77610878c0", rounds => 183 }, + { ciphertext => "23c0d1ed610878c0", rounds => 184 }, + { ciphertext => "23c0d1ed42c8a92d", rounds => 185 }, + { ciphertext => "3ba0e43942c8a92d", rounds => 186 }, + { ciphertext => "3ba0e43964b4aff9", rounds => 187 }, + { ciphertext => "7224142d64b4aff9", rounds => 188 }, + { ciphertext => "7224142d1690bbd4", rounds => 189 }, + { ciphertext => "58fc71cd1690bbd4", rounds => 190 }, + { ciphertext => "58fc71cd98aa658a", rounds => 191 }, + { ciphertext => "4be69e4498aa658a", rounds => 192 }, + { ciphertext => "4be69e44d34cfbce", rounds => 193 }, + { ciphertext => "ca0921c0d34cfbce", rounds => 194 }, + { ciphertext => "ca0921c0de28342a", rounds => 195 }, + { ciphertext => "62cfa4c7de28342a", rounds => 196 }, + { ciphertext => "62cfa4c7bce790ed", rounds => 197 }, + { ciphertext => "cfe04d24bce790ed", rounds => 198 }, + { ciphertext => "cfe04d24a86102cf", rounds => 199 }, + { ciphertext => "ae4c4cc6a86102cf", rounds => 200 }, + { ciphertext => "ae4c4cc6062d4e09", rounds => 201 }, + { ciphertext => "3e135d2b062d4e09", rounds => 202 }, + { ciphertext => "3e135d2b05d178ee", rounds => 203 }, + { ciphertext => "510781f005d178ee", rounds => 204 }, + { ciphertext => "510781f054d6f91e", rounds => 205 }, + { ciphertext => "39d629a554d6f91e", rounds => 206 }, + { ciphertext => "39d629a59ef00bb9", rounds => 207 }, + { ciphertext => "0ba107d19ef00bb9", rounds => 208 }, + { ciphertext => "0ba107d195510c68", rounds => 209 }, + { ciphertext => "ad1f893095510c68", rounds => 210 }, + { ciphertext => "ad1f8930cbc4d2f1", rounds => 211 }, + { ciphertext => "e1ca17dacbc4d2f1", rounds => 212 }, + { ciphertext => "e1ca17da2a0ec52b", rounds => 213 }, + { ciphertext => "12ca9e6c2a0ec52b", rounds => 214 }, + { ciphertext => "12ca9e6c24bd4d3e", rounds => 215 }, + { ciphertext => "ddb3e86324bd4d3e", rounds => 216 }, + { ciphertext => "ddb3e863f90ea55d", rounds => 217 }, + { ciphertext => "fbc09fc9f90ea55d", rounds => 218 }, + { ciphertext => "fbc09fc930548786", rounds => 219 }, + { ciphertext => "b864ba1d30548786", rounds => 220 }, + { ciphertext => "b864ba1d88303d9b", rounds => 221 }, + { ciphertext => "9946c87d88303d9b", rounds => 222 }, + { ciphertext => "9946c87def618ba6", rounds => 223 }, + { ciphertext => "5de8666bef618ba6", rounds => 224 }, + { ciphertext => "5de8666bb289edcd", rounds => 225 }, + { ciphertext => "99038383b289edcd", rounds => 226 }, + { ciphertext => "9903838338b57d71", rounds => 227 }, + { ciphertext => "f48b70e838b57d71", rounds => 228 }, + { ciphertext => "f48b70e8cc3e0d99", rounds => 229 }, + { ciphertext => "efdbb2dacc3e0d99", rounds => 230 }, + { ciphertext => "efdbb2dab1d340ef", rounds => 231 }, + { ciphertext => "7f3c8a58b1d340ef", rounds => 232 }, + { ciphertext => "7f3c8a58ceefcab7", rounds => 233 }, + { ciphertext => "b5bd8cc8ceefcab7", rounds => 234 }, + { ciphertext => "b5bd8cc8e460cdd0", rounds => 235 }, + { ciphertext => "725c098de460cdd0", rounds => 236 }, + { ciphertext => "725c098d963cc45d", rounds => 237 }, + { ciphertext => "eb4aab39963cc45d", rounds => 238 }, + { ciphertext => "eb4aab3915c2c5db", rounds => 239 }, + { ciphertext => "6fde7a1915c2c5db", rounds => 240 }, + { ciphertext => "6fde7a197a1cbfc2", rounds => 241 }, + { ciphertext => "bd764f8b7a1cbfc2", rounds => 242 }, + { ciphertext => "bd764f8b9ceab77c", rounds => 243 }, + { ciphertext => "dfe55a2b9ceab77c", rounds => 244 }, + { ciphertext => "dfe55a2b430fed57", rounds => 245 }, + { ciphertext => "d7d12cda430fed57", rounds => 246 }, + { ciphertext => "d7d12cdac761deab", rounds => 247 }, + { ciphertext => "2b6161f4c761deab", rounds => 248 }, + { ciphertext => "2b6161f4ec00bf5f", rounds => 249 }, + { ciphertext => "72dd64faec00bf5f", rounds => 250 }, + { ciphertext => "72dd64fa09260860", rounds => 251 }, + { ciphertext => "0d66ceef09260860", rounds => 252 }, + { ciphertext => "0d66ceef0440c68f", rounds => 253 }, + { ciphertext => "7facf3d10440c68f", rounds => 254 }, + { ciphertext => "7facf3d1e63cd0c7", rounds => 255 }, + { ciphertext => "e95bf46ae63cd0c7", rounds => 256 }, + { ciphertext => "e95bf46a0f6724ad", rounds => 257 }, + { ciphertext => "f9de2e340f6724ad", rounds => 258 }, + { ciphertext => "f9de2e3405cdf50d", rounds => 259 }, + { ciphertext => "96dd674205cdf50d", rounds => 260 }, + { ciphertext => "96dd67429310924f", rounds => 261 }, + { ciphertext => "6e8dcd049310924f", rounds => 262 }, + { ciphertext => "6e8dcd0426c3aa90", rounds => 263 }, + { ciphertext => "b71485ad26c3aa90", rounds => 264 }, + { ciphertext => "b71485ad91d72f3d", rounds => 265 }, + { ciphertext => "b0637abb91d72f3d", rounds => 266 }, + { ciphertext => "b0637abb046020e1", rounds => 267 }, + { ciphertext => "d7bd5e21046020e1", rounds => 268 }, + { ciphertext => "d7bd5e21d3dd7ec0", rounds => 269 }, + { ciphertext => "4b1330d7d3dd7ec0", rounds => 270 }, + { ciphertext => "4b1330d7d45a61d7", rounds => 271 }, + { ciphertext => "7699edddd45a61d7", rounds => 272 }, + { ciphertext => "7699eddda2c38c0a", rounds => 273 }, + { ciphertext => "8fd796ffa2c38c0a", rounds => 274 }, + { ciphertext => "8fd796ff3f960714", rounds => 275 }, + { ciphertext => "003c35653f960714", rounds => 276 }, + { ciphertext => "003c35653faa3271", rounds => 277 }, + { ciphertext => "a0cdf1a53faa3271", rounds => 278 }, + { ciphertext => "a0cdf1a5e3be2ea5", rounds => 279 }, + { ciphertext => "2ab02cb4e3be2ea5", rounds => 280 }, + { ciphertext => "2ab02cb4c90e0211", rounds => 281 }, + { ciphertext => "7ce3d0d4c90e0211", rounds => 282 }, + { ciphertext => "7ce3d0d43e9629db", rounds => 283 }, + { ciphertext => "f60f81a93e9629db", rounds => 284 }, + { ciphertext => "f60f81a9c899a872", rounds => 285 }, + { ciphertext => "64a53ba3c899a872", rounds => 286 }, + { ciphertext => "64a53ba332e33fa8", rounds => 287 }, + { ciphertext => "7292098232e33fa8", rounds => 288 }, + { ciphertext => "729209824071362a", rounds => 289 }, + { ciphertext => "1d5556fd4071362a", rounds => 290 }, + { ciphertext => "1d5556fd6ebd0c62", rounds => 291 }, + { ciphertext => "66fbe8dc6ebd0c62", rounds => 292 }, + { ciphertext => "66fbe8dc0846e4be", rounds => 293 }, + { ciphertext => "cbd6d7be0846e4be", rounds => 294 }, + { ciphertext => "cbd6d7bee3c7809f", rounds => 295 }, + { ciphertext => "417aa14de3c7809f", rounds => 296 }, + { ciphertext => "417aa14da2bd21d2", rounds => 297 }, + { ciphertext => "bbddeb87a2bd21d2", rounds => 298 }, + { ciphertext => "bbddeb8758efa34a", rounds => 299 }, + { ciphertext => "b5765b2e58efa34a", rounds => 300 }, + { ciphertext => "b5765b2eed99f864", rounds => 301 }, + { ciphertext => "48ced3a7ed99f864", rounds => 302 }, + { ciphertext => "48ced3a73e36a2ce", rounds => 303 }, + { ciphertext => "0616f2783e36a2ce", rounds => 304 }, + { ciphertext => "0616f278382050b6", rounds => 305 }, + { ciphertext => "ce1f7b21382050b6", rounds => 306 }, + { ciphertext => "ce1f7b2187f9774c", rounds => 307 }, + { ciphertext => "37c3af9287f9774c", rounds => 308 }, + { ciphertext => "37c3af92b03ad8de", rounds => 309 }, + { ciphertext => "0004b291b03ad8de", rounds => 310 }, + { ciphertext => "0004b29146b09cd1", rounds => 311 }, + { ciphertext => "793eb17f46b09cd1", rounds => 312 }, + { ciphertext => "793eb17f3f8e2dae", rounds => 313 }, + { ciphertext => "c3d61e5f3f8e2dae", rounds => 314 }, + { ciphertext => "c3d61e5f540d842d", rounds => 315 }, + { ciphertext => "35970b47540d842d", rounds => 316 }, + { ciphertext => "35970b47619a8f6a", rounds => 317 }, + { ciphertext => "ec0137cb619a8f6a", rounds => 318 }, + { ciphertext => "ec0137cbdd109deb", rounds => 319 }, + { ciphertext => "851b3ea4dd109deb", rounds => 320 }, + { ciphertext => "851b3ea4580ba34f", rounds => 321 }, + { ciphertext => "5ef12267580ba34f", rounds => 322 }, + { ciphertext => "5ef1226737528801", rounds => 323 }, + { ciphertext => "386b0a5c37528801", rounds => 324 }, + { ciphertext => "386b0a5c0f39825d", rounds => 325 }, + { ciphertext => "1ce9d2ee0f39825d", rounds => 326 }, + { ciphertext => "1ce9d2ee4ac39347", rounds => 327 }, + { ciphertext => "917106d24ac39347", rounds => 328 }, + { ciphertext => "917106d2dbb29595", rounds => 329 }, + { ciphertext => "88b0645bdbb29595", rounds => 330 }, + { ciphertext => "88b0645ba68e2c58", rounds => 331 }, + { ciphertext => "1a7439b7a68e2c58", rounds => 332 }, + { ciphertext => "1a7439b7bcfa15ef", rounds => 333 }, + { ciphertext => "b3ab70aabcfa15ef", rounds => 334 }, + { ciphertext => "b3ab70aaccd0d646", rounds => 335 }, + { ciphertext => "a470539fccd0d646", rounds => 336 }, + { ciphertext => "a470539f68a085d9", rounds => 337 }, + { ciphertext => "e5e26c1568a085d9", rounds => 338 }, + { ciphertext => "e5e26c1538f7592f", rounds => 339 }, + { ciphertext => "8b30523438f7592f", rounds => 340 }, + { ciphertext => "8b305234b3c70b1b", rounds => 341 }, + { ciphertext => "f39400efb3c70b1b", rounds => 342 }, + { ciphertext => "f39400ef8f7175aa", rounds => 343 }, + { ciphertext => "176a40c38f7175aa", rounds => 344 }, + { ciphertext => "176a40c3981b3569", rounds => 345 }, + { ciphertext => "0f888512981b3569", rounds => 346 }, + { ciphertext => "0f888512f2e8de9a", rounds => 347 }, + { ciphertext => "1f015c25f2e8de9a", rounds => 348 }, + { ciphertext => "1f015c25ede982bf", rounds => 349 }, + { ciphertext => "1e9266afede982bf", rounds => 350 }, + { ciphertext => "1e9266af470154fa", rounds => 351 }, + { ciphertext => "645ffa14470154fa", rounds => 352 }, + { ciphertext => "645ffa14235eaeee", rounds => 353 }, + { ciphertext => "f65e9571235eaeee", rounds => 354 }, + { ciphertext => "f65e9571bfbbe35d", rounds => 355 }, + { ciphertext => "e6f66474bfbbe35d", rounds => 356 }, + { ciphertext => "e6f66474594d8729", rounds => 357 }, + { ciphertext => "87898457594d8729", rounds => 358 }, + { ciphertext => "87898457900cc8ed", rounds => 359 }, + { ciphertext => "6f8f642c900cc8ed", rounds => 360 }, + { ciphertext => "6f8f642cff83acc1", rounds => 361 }, + { ciphertext => "130f9b6bff83acc1", rounds => 362 }, + { ciphertext => "130f9b6b2a25f205", rounds => 363 }, + { ciphertext => "37b4a1242a25f205", rounds => 364 }, + { ciphertext => "37b4a1241d915321", rounds => 365 }, + { ciphertext => "58491c921d915321", rounds => 366 }, + { ciphertext => "58491c92740a62a9", rounds => 367 }, + { ciphertext => "03b3fdb5740a62a9", rounds => 368 }, + { ciphertext => "03b3fdb577b99f1c", rounds => 369 }, + { ciphertext => "69b84d7577b99f1c", rounds => 370 }, + { ciphertext => "69b84d7510d1f81d", rounds => 371 }, + { ciphertext => "cfaf15b210d1f81d", rounds => 372 }, + { ciphertext => "cfaf15b2df7eedaf", rounds => 373 }, + { ciphertext => "47f873e5df7eedaf", rounds => 374 }, + { ciphertext => "47f873e51396502a", rounds => 375 }, + { ciphertext => "3e4ef74f1396502a", rounds => 376 }, + { ciphertext => "3e4ef74f2dd8a765", rounds => 377 }, + { ciphertext => "85fe3b772dd8a765", rounds => 378 }, + { ciphertext => "85fe3b77e02a51f2", rounds => 379 }, + { ciphertext => "372f2298e02a51f2", rounds => 380 }, + { ciphertext => "372f2298d705736a", rounds => 381 }, + { ciphertext => "4a8b0a0fd705736a", rounds => 382 }, + { ciphertext => "4a8b0a0f3acfd4a5", rounds => 383 }, + { ciphertext => "775d111d3acfd4a5", rounds => 384 }, + { ciphertext => "775d111d4d92c5b8", rounds => 385 }, + { ciphertext => "7a75e8c14d92c5b8", rounds => 386 }, + { ciphertext => "7a75e8c1a753977c", rounds => 387 }, + { ciphertext => "ecea9d61a753977c", rounds => 388 }, + { ciphertext => "ecea9d614bb90a1d", rounds => 389 }, + { ciphertext => "52f830604bb90a1d", rounds => 390 }, + { ciphertext => "52f8306015811635", rounds => 391 }, + { ciphertext => "d1b4528215811635", rounds => 392 }, + { ciphertext => "d1b45282c43544b7", rounds => 393 }, + { ciphertext => "fe7de60dc43544b7", rounds => 394 }, + { ciphertext => "fe7de60d850bcde1", rounds => 395 }, + { ciphertext => "15456391850bcde1", rounds => 396 }, + { ciphertext => "15456391904eae70", rounds => 397 }, + { ciphertext => "8101eb63904eae70", rounds => 398 }, + { ciphertext => "8101eb63de06cb5b", rounds => 399 }, + { ciphertext => "ece907fcde06cb5b", rounds => 400 }, + { ciphertext => "ece907fc32efcca7", rounds => 401 }, + { ciphertext => "5276549f32efcca7", rounds => 402 }, + { ciphertext => "5276549fc9817532", rounds => 403 }, + { ciphertext => "13f29eb0c9817532", rounds => 404 }, + { ciphertext => "13f29eb0da73eb82", rounds => 405 }, + { ciphertext => "bf2b5aefda73eb82", rounds => 406 }, + { ciphertext => "bf2b5aefe9e1b598", rounds => 407 }, + { ciphertext => "1604253fe9e1b598", rounds => 408 }, + { ciphertext => "1604253fffe590a7", rounds => 409 }, + { ciphertext => "7c516256ffe590a7", rounds => 410 }, + { ciphertext => "7c516256dc6ab578", rounds => 411 }, + { ciphertext => "dc4269dbdc6ab578", rounds => 412 }, + { ciphertext => "dc4269db0028dca3", rounds => 413 }, + { ciphertext => "97efb37e0028dca3", rounds => 414 }, + { ciphertext => "97efb37e9d5c5554", rounds => 415 }, + { ciphertext => "bd7b2d059d5c5554", rounds => 416 }, + { ciphertext => "bd7b2d0520277851", rounds => 417 }, + { ciphertext => "bc0da0bb20277851", rounds => 418 }, + { ciphertext => "bc0da0bb47d6ab94", rounds => 419 }, + { ciphertext => "05237aa147d6ab94", rounds => 420 }, + { ciphertext => "05237aa142f5d135", rounds => 421 }, + { ciphertext => "f9c7a69a42f5d135", rounds => 422 }, + { ciphertext => "f9c7a69ac5d2fe5e", rounds => 423 }, + { ciphertext => "0d224d37c5d2fe5e", rounds => 424 }, + { ciphertext => "0d224d37c8f0b369", rounds => 425 }, + { ciphertext => "50486eefc8f0b369", rounds => 426 }, + { ciphertext => "50486eef1bc676dd", rounds => 427 }, + { ciphertext => "8c95bc681bc676dd", rounds => 428 }, + { ciphertext => "8c95bc689753cab5", rounds => 429 }, + { ciphertext => "44aa3ca49753cab5", rounds => 430 }, + { ciphertext => "44aa3ca4ef469a0c", rounds => 431 }, + { ciphertext => "808dcab0ef469a0c", rounds => 432 }, + { ciphertext => "808dcab06fcb50bc", rounds => 433 }, + { ciphertext => "9f95411e6fcb50bc", rounds => 434 }, + { ciphertext => "9f95411e805160a3", rounds => 435 }, + { ciphertext => "4c012278805160a3", rounds => 436 }, + { ciphertext => "4c012278cc5042db", rounds => 437 }, + { ciphertext => "53825deccc5042db", rounds => 438 }, + { ciphertext => "53825dec41c8d4a3", rounds => 439 }, + { ciphertext => "333146e441c8d4a3", rounds => 440 }, + { ciphertext => "333146e472f99247", rounds => 441 }, + { ciphertext => "437874ba72f99247", rounds => 442 }, + { ciphertext => "437874bab14854ce", rounds => 443 }, + { ciphertext => "8b1f5c80b14854ce", rounds => 444 }, + { ciphertext => "8b1f5c803a57084e", rounds => 445 }, + { ciphertext => "3b4b89283a57084e", rounds => 446 }, + { ciphertext => "3b4b89288e1d2d0e", rounds => 447 }, + { ciphertext => "e5135c088e1d2d0e", rounds => 448 }, + { ciphertext => "e5135c086b0e7106", rounds => 449 }, + { ciphertext => "097689986b0e7106", rounds => 450 }, + { ciphertext => "097689980ab818cc", rounds => 451 }, + { ciphertext => "8ee375aa0ab818cc", rounds => 452 }, + { ciphertext => "8ee375aa845b6d66", rounds => 453 }, + { ciphertext => "7b598c58845b6d66", rounds => 454 }, + { ciphertext => "7b598c58d270744d", rounds => 455 }, + { ciphertext => "48a0b500d270744d", rounds => 456 }, + { ciphertext => "48a0b5009ad0c14d", rounds => 457 }, + { ciphertext => "39af63649ad0c14d", rounds => 458 }, + { ciphertext => "39af63643f89079d", rounds => 459 }, + { ciphertext => "b605c5233f89079d", rounds => 460 }, + { ciphertext => "b605c523898cc2be", rounds => 461 }, + { ciphertext => "5ae33c58898cc2be", rounds => 462 }, + { ciphertext => "5ae33c586aea5d90", rounds => 463 }, + { ciphertext => "74b9fbf26aea5d90", rounds => 464 }, + { ciphertext => "74b9fbf21e53a662", rounds => 465 }, + { ciphertext => "278a407c1e53a662", rounds => 466 }, + { ciphertext => "278a407c5695e8d2", rounds => 467 }, + { ciphertext => "25614c2d5695e8d2", rounds => 468 }, + { ciphertext => "25614c2d73f4a4ff", rounds => 469 }, + { ciphertext => "94c9ad5d73f4a4ff", rounds => 470 }, + { ciphertext => "94c9ad5db17aff29", rounds => 471 }, + { ciphertext => "1be442f9b17aff29", rounds => 472 }, + { ciphertext => "1be442f9aa9ebdd0", rounds => 473 }, + { ciphertext => "732217ecaa9ebdd0", rounds => 474 }, + { ciphertext => "732217ec82ddc2df", rounds => 475 }, + { ciphertext => "9370597e82ddc2df", rounds => 476 }, + { ciphertext => "9370597e11ad9ba1", rounds => 477 }, + { ciphertext => "5d6b96b911ad9ba1", rounds => 478 }, + { ciphertext => "5d6b96b99c9fc951", rounds => 479 }, + { ciphertext => "7b8e74d59c9fc951", rounds => 480 }, + { ciphertext => "7b8e74d5e711bd84", rounds => 481 }, + { ciphertext => "6217dc57e711bd84", rounds => 482 }, + { ciphertext => "6217dc573deec77e", rounds => 483 }, + { ciphertext => "e5b0b9fb3deec77e", rounds => 484 }, + { ciphertext => "e5b0b9fbd85e7e85", rounds => 485 }, + { ciphertext => "dcada54bd85e7e85", rounds => 486 }, + { ciphertext => "dcada54be1055b7e", rounds => 487 }, + { ciphertext => "a04c1805e1055b7e", rounds => 488 }, + { ciphertext => "a04c18054149437b", rounds => 489 }, + { ciphertext => "f481ec1f4149437b", rounds => 490 }, + { ciphertext => "f481ec1fbe93d4aa", rounds => 491 }, + { ciphertext => "fe614b99be93d4aa", rounds => 492 }, + { ciphertext => "fe614b9940f29f33", rounds => 493 }, + { ciphertext => "657291bc40f29f33", rounds => 494 }, + { ciphertext => "657291bc6f57e54e", rounds => 495 }, + { ciphertext => "210cffdc6f57e54e", rounds => 496 }, + { ciphertext => "210cffdc4e5b1a92", rounds => 497 }, + { ciphertext => "00b2e2d64e5b1a92", rounds => 498 }, + { ciphertext => "00b2e2d6109744ee", rounds => 499 }, + { ciphertext => "a4433a0a109744ee", rounds => 500 }, + { ciphertext => "a4433a0ab4d47ee4", rounds => 501 }, + { ciphertext => "ac004e06b4d47ee4", rounds => 502 }, + { ciphertext => "ac004e06df6a995a", rounds => 503 }, + { ciphertext => "d8dbbc9cdf6a995a", rounds => 504 }, + { ciphertext => "d8dbbc9c07b125c6", rounds => 505 }, + { ciphertext => "0559a7fa07b125c6", rounds => 506 }, + { ciphertext => "0559a7faf0ab55e7", rounds => 507 }, + { ciphertext => "000f8a42f0ab55e7", rounds => 508 }, + { ciphertext => "000f8a42f0a4dfa5", rounds => 509 }, + { ciphertext => "9ce9b85ff0a4dfa5", rounds => 510 }, + { ciphertext => "9ce9b85fe21e49a7", rounds => 511 }, + { ciphertext => "1eb7dc44e21e49a7", rounds => 512 }, + { ciphertext => "1eb7dc44fca995e3", rounds => 513 }, + { ciphertext => "d2edac19fca995e3", rounds => 514 }, + { ciphertext => "d2edac1915605c0f", rounds => 515 }, + { ciphertext => "6e32e09815605c0f", rounds => 516 }, + { ciphertext => "6e32e0987b52bc97", rounds => 517 }, + { ciphertext => "5244dc227b52bc97", rounds => 518 }, + { ciphertext => "5244dc222db27c53", rounds => 519 }, + { ciphertext => "ae07bd5a2db27c53", rounds => 520 }, + { ciphertext => "ae07bd5a83b5c109", rounds => 521 }, + { ciphertext => "28c977af83b5c109", rounds => 522 }, + { ciphertext => "28c977af93b9ed0b", rounds => 523 }, + { ciphertext => "1c5656c493b9ed0b", rounds => 524 }, + { ciphertext => "1c5656c48fefbbcf", rounds => 525 }, + { ciphertext => "98d930038fefbbcf", rounds => 526 }, + { ciphertext => "98d93003122d169f", rounds => 527 }, + { ciphertext => "ea7154f0122d169f", rounds => 528 }, + { ciphertext => "ea7154f0f85c426f", rounds => 529 }, + { ciphertext => "e98359c0f85c426f", rounds => 530 }, + { ciphertext => "e98359c001382b4b", rounds => 531 }, + { ciphertext => "b195016c01382b4b", rounds => 532 }, + { ciphertext => "b195016cb0ad2a27", rounds => 533 }, + { ciphertext => "6cfc4a1bb0ad2a27", rounds => 534 }, + { ciphertext => "6cfc4a1be1fb5f4a", rounds => 535 }, + { ciphertext => "ed539a51e1fb5f4a", rounds => 536 }, + { ciphertext => "ed539a510ca8c51b", rounds => 537 }, + { ciphertext => "71549f210ca8c51b", rounds => 538 }, + { ciphertext => "71549f2179d7df31", rounds => 539 }, + { ciphertext => "c260430d79d7df31", rounds => 540 }, + { ciphertext => "c260430dbbb79c3c", rounds => 541 }, + { ciphertext => "2c3def8bbbb79c3c", rounds => 542 }, + { ciphertext => "2c3def8b56c89542", rounds => 543 }, + { ciphertext => "e58c31af56c89542", rounds => 544 }, + { ciphertext => "e58c31afb344a4ed", rounds => 545 }, + { ciphertext => "ca395ca7b344a4ed", rounds => 546 }, + { ciphertext => "ca395ca7327eb3cc", rounds => 547 }, + { ciphertext => "844e5f95327eb3cc", rounds => 548 }, + { ciphertext => "844e5f95b630ec59", rounds => 549 }, + { ciphertext => "734ee5ebb630ec59", rounds => 550 }, + { ciphertext => "734ee5eb0ba7c6ca", rounds => 551 }, + { ciphertext => "214330210ba7c6ca", rounds => 552 }, + { ciphertext => "214330212ae4f6eb", rounds => 553 }, + { ciphertext => "05e5f6cf2ae4f6eb", rounds => 554 }, + { ciphertext => "05e5f6cfb0b69a3c", rounds => 555 }, +]; + +for (@$expected_results) { + is( unpack('H*', Crypt::Cipher::MULTI2->new($key, $_->{rounds})->encrypt($plaintext)), $_->{ciphertext}, "MULTI2->encrypt - rounds=$_->{rounds}"); + is( Crypt::Cipher::MULTI2->new($key, $_->{rounds})->decrypt(pack('H*', $_->{ciphertext})), $plaintext, "MULTI2->decrypt - rounds=$_->{rounds}"); +} diff --git a/t/cipher_noekeon.t b/t/cipher_noekeon.t new file mode 100644 index 0000000..e687afc --- /dev/null +++ b/t/cipher_noekeon.t @@ -0,0 +1,65 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 38; + +use Crypt::Cipher; +use Crypt::Cipher::Noekeon; + +is( Crypt::Cipher::Noekeon::blocksize, 16, '::blocksize'); +is( Crypt::Cipher::Noekeon::keysize, 16, '::keysize'); +is( Crypt::Cipher::Noekeon::max_keysize, 16, '::max_keysize'); +is( Crypt::Cipher::Noekeon::min_keysize, 16, '::min_keysize'); +is( Crypt::Cipher::Noekeon::default_rounds, 16, '::default_rounds'); + +is( Crypt::Cipher::Noekeon->blocksize, 16, '->blocksize'); +is( Crypt::Cipher::Noekeon->keysize, 16, '->keysize'); +is( Crypt::Cipher::Noekeon->max_keysize, 16, '->max_keysize'); +is( Crypt::Cipher::Noekeon->min_keysize, 16, '->min_keysize'); +is( Crypt::Cipher::Noekeon->default_rounds, 16, '->default_rounds'); + +my $min_key = 'kkkkkkkkkkkkkkkk'; +my $max_key = 'KKKKKKKKKKKKKKKK'; + +is( Crypt::Cipher::blocksize('Noekeon'), 16, 'Cipher->blocksize'); +is( Crypt::Cipher::keysize('Noekeon'), 16, 'Cipher->keysize'); +is( Crypt::Cipher::max_keysize('Noekeon'), 16, 'Cipher->max_keysize'); +is( Crypt::Cipher::min_keysize('Noekeon'), 16, 'Cipher->min_keysize'); +is( Crypt::Cipher::default_rounds('Noekeon'), 16, 'Cipher->default_rounds'); + +is( Crypt::Cipher->blocksize('Noekeon'), 16, 'Cipher->blocksize'); +is( Crypt::Cipher->keysize('Noekeon'), 16, 'Cipher->keysize'); +is( Crypt::Cipher->max_keysize('Noekeon'), 16, 'Cipher->max_keysize'); +is( Crypt::Cipher->min_keysize('Noekeon'), 16, 'Cipher->min_keysize'); +is( Crypt::Cipher->default_rounds('Noekeon'), 16, 'Cipher->default_rounds'); + +is( Crypt::Cipher::Noekeon->new($min_key)->blocksize, 16, 'Noekeon->new()->blocksize'); +is( Crypt::Cipher::Noekeon->new($min_key)->keysize, 16, 'Noekeon->new()->keysize'); +is( Crypt::Cipher::Noekeon->new($min_key)->max_keysize, 16, 'Noekeon->new()->max_keysize'); +is( Crypt::Cipher::Noekeon->new($min_key)->min_keysize, 16, 'Noekeon->new()->min_keysize'); +is( Crypt::Cipher::Noekeon->new($min_key)->default_rounds, 16, 'Noekeon->new()->default_rounds'); + +is( Crypt::Cipher->new('Noekeon', $min_key)->blocksize, 16, 'Cipher->new()->blocksize'); +is( Crypt::Cipher->new('Noekeon', $min_key)->keysize, 16, 'Cipher->new()->keysize'); +is( Crypt::Cipher->new('Noekeon', $min_key)->max_keysize, 16, 'Cipher->new()->max_keysize'); +is( Crypt::Cipher->new('Noekeon', $min_key)->min_keysize, 16, 'Cipher->new()->min_keysize'); +is( Crypt::Cipher->new('Noekeon', $min_key)->default_rounds, 16, 'Cipher->new()->default_rounds'); + +my $block_plain = 'BBBBBBBBBBBBBBBB'; +my $block_encrypted_min_key_hex = 'e0d99f05c90e974bc6d8d0740e0dee44'; +my $block_encrypted_max_key_hex = '67220154141a0c32d92cb080df1fb081'; + +is( unpack('H*', Crypt::Cipher::Noekeon->new($min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Noekeon->encrypt'); +is( Crypt::Cipher::Noekeon->new($min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Noekeon->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('Noekeon', $min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('Noekeon', $min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Cipher->decrypt'); + +is( unpack('H*', Crypt::Cipher::Noekeon->new($max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Noekeon->encrypt'); +is( Crypt::Cipher::Noekeon->new($max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Noekeon->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('Noekeon', $max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('Noekeon', $max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Cipher->decrypt'); + diff --git a/t/cipher_rc2.t b/t/cipher_rc2.t new file mode 100644 index 0000000..39838c6 --- /dev/null +++ b/t/cipher_rc2.t @@ -0,0 +1,65 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 38; + +use Crypt::Cipher; +use Crypt::Cipher::RC2; + +is( Crypt::Cipher::RC2::blocksize, 8, '::blocksize'); +is( Crypt::Cipher::RC2::keysize, 128, '::keysize'); +is( Crypt::Cipher::RC2::max_keysize, 128, '::max_keysize'); +is( Crypt::Cipher::RC2::min_keysize, 8, '::min_keysize'); +is( Crypt::Cipher::RC2::default_rounds, 16, '::default_rounds'); + +is( Crypt::Cipher::RC2->blocksize, 8, '->blocksize'); +is( Crypt::Cipher::RC2->keysize, 128, '->keysize'); +is( Crypt::Cipher::RC2->max_keysize, 128, '->max_keysize'); +is( Crypt::Cipher::RC2->min_keysize, 8, '->min_keysize'); +is( Crypt::Cipher::RC2->default_rounds, 16, '->default_rounds'); + +my $min_key = 'kkkkkkkk'; +my $max_key = 'KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK'; + +is( Crypt::Cipher::blocksize('RC2'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher::keysize('RC2'), 128, 'Cipher->keysize'); +is( Crypt::Cipher::max_keysize('RC2'), 128, 'Cipher->max_keysize'); +is( Crypt::Cipher::min_keysize('RC2'), 8, 'Cipher->min_keysize'); +is( Crypt::Cipher::default_rounds('RC2'), 16, 'Cipher->default_rounds'); + +is( Crypt::Cipher->blocksize('RC2'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher->keysize('RC2'), 128, 'Cipher->keysize'); +is( Crypt::Cipher->max_keysize('RC2'), 128, 'Cipher->max_keysize'); +is( Crypt::Cipher->min_keysize('RC2'), 8, 'Cipher->min_keysize'); +is( Crypt::Cipher->default_rounds('RC2'), 16, 'Cipher->default_rounds'); + +is( Crypt::Cipher::RC2->new($min_key)->blocksize, 8, 'RC2->new()->blocksize'); +is( Crypt::Cipher::RC2->new($min_key)->keysize, 128, 'RC2->new()->keysize'); +is( Crypt::Cipher::RC2->new($min_key)->max_keysize, 128, 'RC2->new()->max_keysize'); +is( Crypt::Cipher::RC2->new($min_key)->min_keysize, 8, 'RC2->new()->min_keysize'); +is( Crypt::Cipher::RC2->new($min_key)->default_rounds, 16, 'RC2->new()->default_rounds'); + +is( Crypt::Cipher->new('RC2', $min_key)->blocksize, 8, 'Cipher->new()->blocksize'); +is( Crypt::Cipher->new('RC2', $min_key)->keysize, 128, 'Cipher->new()->keysize'); +is( Crypt::Cipher->new('RC2', $min_key)->max_keysize, 128, 'Cipher->new()->max_keysize'); +is( Crypt::Cipher->new('RC2', $min_key)->min_keysize, 8, 'Cipher->new()->min_keysize'); +is( Crypt::Cipher->new('RC2', $min_key)->default_rounds, 16, 'Cipher->new()->default_rounds'); + +my $block_plain = 'BBBBBBBB'; +my $block_encrypted_min_key_hex = '63b6aed38ebea067'; +my $block_encrypted_max_key_hex = '0579997e392f3d50'; + +is( unpack('H*', Crypt::Cipher::RC2->new($min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'RC2->encrypt'); +is( Crypt::Cipher::RC2->new($min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'RC2->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('RC2', $min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('RC2', $min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Cipher->decrypt'); + +is( unpack('H*', Crypt::Cipher::RC2->new($max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'RC2->encrypt'); +is( Crypt::Cipher::RC2->new($max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'RC2->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('RC2', $max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('RC2', $max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Cipher->decrypt'); + diff --git a/t/cipher_rc5.t b/t/cipher_rc5.t new file mode 100644 index 0000000..8631223 --- /dev/null +++ b/t/cipher_rc5.t @@ -0,0 +1,75 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 42; + +use Crypt::Cipher; +use Crypt::Cipher::RC5; + +is( Crypt::Cipher::RC5::blocksize, 8, '::blocksize'); +is( Crypt::Cipher::RC5::keysize, 128, '::keysize'); +is( Crypt::Cipher::RC5::max_keysize, 128, '::max_keysize'); +is( Crypt::Cipher::RC5::min_keysize, 8, '::min_keysize'); +is( Crypt::Cipher::RC5::default_rounds, 12, '::default_rounds'); + +is( Crypt::Cipher::RC5->blocksize, 8, '->blocksize'); +is( Crypt::Cipher::RC5->keysize, 128, '->keysize'); +is( Crypt::Cipher::RC5->max_keysize, 128, '->max_keysize'); +is( Crypt::Cipher::RC5->min_keysize, 8, '->min_keysize'); +is( Crypt::Cipher::RC5->default_rounds, 12, '->default_rounds'); + +my $min_key = 'kkkkkkkk'; +my $max_key = 'KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK'; + +is( Crypt::Cipher::blocksize('RC5'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher::keysize('RC5'), 128, 'Cipher->keysize'); +is( Crypt::Cipher::max_keysize('RC5'), 128, 'Cipher->max_keysize'); +is( Crypt::Cipher::min_keysize('RC5'), 8, 'Cipher->min_keysize'); +is( Crypt::Cipher::default_rounds('RC5'), 12, 'Cipher->default_rounds'); + +is( Crypt::Cipher->blocksize('RC5'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher->keysize('RC5'), 128, 'Cipher->keysize'); +is( Crypt::Cipher->max_keysize('RC5'), 128, 'Cipher->max_keysize'); +is( Crypt::Cipher->min_keysize('RC5'), 8, 'Cipher->min_keysize'); +is( Crypt::Cipher->default_rounds('RC5'), 12, 'Cipher->default_rounds'); + +is( Crypt::Cipher::RC5->new($min_key)->blocksize, 8, 'RC5->new()->blocksize'); +is( Crypt::Cipher::RC5->new($min_key)->keysize, 128, 'RC5->new()->keysize'); +is( Crypt::Cipher::RC5->new($min_key)->max_keysize, 128, 'RC5->new()->max_keysize'); +is( Crypt::Cipher::RC5->new($min_key)->min_keysize, 8, 'RC5->new()->min_keysize'); +is( Crypt::Cipher::RC5->new($min_key)->default_rounds, 12, 'RC5->new()->default_rounds'); + +is( Crypt::Cipher->new('RC5', $min_key)->blocksize, 8, 'Cipher->new()->blocksize'); +is( Crypt::Cipher->new('RC5', $min_key)->keysize, 128, 'Cipher->new()->keysize'); +is( Crypt::Cipher->new('RC5', $min_key)->max_keysize, 128, 'Cipher->new()->max_keysize'); +is( Crypt::Cipher->new('RC5', $min_key)->min_keysize, 8, 'Cipher->new()->min_keysize'); +is( Crypt::Cipher->new('RC5', $min_key)->default_rounds, 12, 'Cipher->new()->default_rounds'); + +my $block_plain = 'BBBBBBBB'; +my $block_encrypted_min_key_hex = '7c6231e94d317190'; +my $block_encrypted_max_key_hex = '94ffb45366bd4dda'; + +is( unpack('H*', Crypt::Cipher::RC5->new($min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'RC5->encrypt'); +is( Crypt::Cipher::RC5->new($min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'RC5->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('RC5', $min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('RC5', $min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Cipher->decrypt'); + +is( unpack('H*', Crypt::Cipher::RC5->new($max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'RC5->encrypt'); +is( Crypt::Cipher::RC5->new($max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'RC5->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('RC5', $max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('RC5', $max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Cipher->decrypt'); + + +my $spec_key = 'SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS'; +my $spec_rounds = '19'; +my $spec_block_encrypted_hex = 'a7ef4525157fb4e6'; + +is( unpack('H*', Crypt::Cipher::RC5->new($spec_key, $spec_rounds)->encrypt($block_plain)), $spec_block_encrypted_hex, 'RC5->encrypt'); +is( Crypt::Cipher::RC5->new($spec_key, $spec_rounds)->decrypt(pack('H*', $spec_block_encrypted_hex)), $block_plain, 'RC5->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('RC5', $spec_key, $spec_rounds)->encrypt($block_plain)), $spec_block_encrypted_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('RC5', $spec_key, $spec_rounds)->decrypt(pack('H*', $spec_block_encrypted_hex)), $block_plain, 'Cipher->decrypt'); diff --git a/t/cipher_rc6.t b/t/cipher_rc6.t new file mode 100644 index 0000000..a7ce963 --- /dev/null +++ b/t/cipher_rc6.t @@ -0,0 +1,65 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 38; + +use Crypt::Cipher; +use Crypt::Cipher::RC6; + +is( Crypt::Cipher::RC6::blocksize, 16, '::blocksize'); +is( Crypt::Cipher::RC6::keysize, 128, '::keysize'); +is( Crypt::Cipher::RC6::max_keysize, 128, '::max_keysize'); +is( Crypt::Cipher::RC6::min_keysize, 8, '::min_keysize'); +is( Crypt::Cipher::RC6::default_rounds, 20, '::default_rounds'); + +is( Crypt::Cipher::RC6->blocksize, 16, '->blocksize'); +is( Crypt::Cipher::RC6->keysize, 128, '->keysize'); +is( Crypt::Cipher::RC6->max_keysize, 128, '->max_keysize'); +is( Crypt::Cipher::RC6->min_keysize, 8, '->min_keysize'); +is( Crypt::Cipher::RC6->default_rounds, 20, '->default_rounds'); + +my $min_key = 'kkkkkkkk'; +my $max_key = 'KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK'; + +is( Crypt::Cipher::blocksize('RC6'), 16, 'Cipher->blocksize'); +is( Crypt::Cipher::keysize('RC6'), 128, 'Cipher->keysize'); +is( Crypt::Cipher::max_keysize('RC6'), 128, 'Cipher->max_keysize'); +is( Crypt::Cipher::min_keysize('RC6'), 8, 'Cipher->min_keysize'); +is( Crypt::Cipher::default_rounds('RC6'), 20, 'Cipher->default_rounds'); + +is( Crypt::Cipher->blocksize('RC6'), 16, 'Cipher->blocksize'); +is( Crypt::Cipher->keysize('RC6'), 128, 'Cipher->keysize'); +is( Crypt::Cipher->max_keysize('RC6'), 128, 'Cipher->max_keysize'); +is( Crypt::Cipher->min_keysize('RC6'), 8, 'Cipher->min_keysize'); +is( Crypt::Cipher->default_rounds('RC6'), 20, 'Cipher->default_rounds'); + +is( Crypt::Cipher::RC6->new($min_key)->blocksize, 16, 'RC6->new()->blocksize'); +is( Crypt::Cipher::RC6->new($min_key)->keysize, 128, 'RC6->new()->keysize'); +is( Crypt::Cipher::RC6->new($min_key)->max_keysize, 128, 'RC6->new()->max_keysize'); +is( Crypt::Cipher::RC6->new($min_key)->min_keysize, 8, 'RC6->new()->min_keysize'); +is( Crypt::Cipher::RC6->new($min_key)->default_rounds, 20, 'RC6->new()->default_rounds'); + +is( Crypt::Cipher->new('RC6', $min_key)->blocksize, 16, 'Cipher->new()->blocksize'); +is( Crypt::Cipher->new('RC6', $min_key)->keysize, 128, 'Cipher->new()->keysize'); +is( Crypt::Cipher->new('RC6', $min_key)->max_keysize, 128, 'Cipher->new()->max_keysize'); +is( Crypt::Cipher->new('RC6', $min_key)->min_keysize, 8, 'Cipher->new()->min_keysize'); +is( Crypt::Cipher->new('RC6', $min_key)->default_rounds, 20, 'Cipher->new()->default_rounds'); + +my $block_plain = 'BBBBBBBBBBBBBBBB'; +my $block_encrypted_min_key_hex = '404128633835b738252ba97d3f30e19a'; +my $block_encrypted_max_key_hex = '626d64582f8c75ac21211cd15ca23f1e'; + +is( unpack('H*', Crypt::Cipher::RC6->new($min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'RC6->encrypt'); +is( Crypt::Cipher::RC6->new($min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'RC6->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('RC6', $min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('RC6', $min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Cipher->decrypt'); + +is( unpack('H*', Crypt::Cipher::RC6->new($max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'RC6->encrypt'); +is( Crypt::Cipher::RC6->new($max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'RC6->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('RC6', $max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('RC6', $max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Cipher->decrypt'); + diff --git a/t/cipher_safer_k128.t b/t/cipher_safer_k128.t new file mode 100644 index 0000000..b858eeb --- /dev/null +++ b/t/cipher_safer_k128.t @@ -0,0 +1,75 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 42; + +use Crypt::Cipher; +use Crypt::Cipher::SAFER_K128; + +is( Crypt::Cipher::SAFER_K128::blocksize, 8, '::blocksize'); +is( Crypt::Cipher::SAFER_K128::keysize, 16, '::keysize'); +is( Crypt::Cipher::SAFER_K128::max_keysize, 16, '::max_keysize'); +is( Crypt::Cipher::SAFER_K128::min_keysize, 16, '::min_keysize'); +is( Crypt::Cipher::SAFER_K128::default_rounds, 10, '::default_rounds'); + +is( Crypt::Cipher::SAFER_K128->blocksize, 8, '->blocksize'); +is( Crypt::Cipher::SAFER_K128->keysize, 16, '->keysize'); +is( Crypt::Cipher::SAFER_K128->max_keysize, 16, '->max_keysize'); +is( Crypt::Cipher::SAFER_K128->min_keysize, 16, '->min_keysize'); +is( Crypt::Cipher::SAFER_K128->default_rounds, 10, '->default_rounds'); + +my $min_key = 'kkkkkkkkkkkkkkkk'; +my $max_key = 'KKKKKKKKKKKKKKKK'; + +is( Crypt::Cipher::blocksize('SAFER_K128'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher::keysize('SAFER_K128'), 16, 'Cipher->keysize'); +is( Crypt::Cipher::max_keysize('SAFER_K128'), 16, 'Cipher->max_keysize'); +is( Crypt::Cipher::min_keysize('SAFER_K128'), 16, 'Cipher->min_keysize'); +is( Crypt::Cipher::default_rounds('SAFER_K128'), 10, 'Cipher->default_rounds'); + +is( Crypt::Cipher->blocksize('SAFER_K128'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher->keysize('SAFER_K128'), 16, 'Cipher->keysize'); +is( Crypt::Cipher->max_keysize('SAFER_K128'), 16, 'Cipher->max_keysize'); +is( Crypt::Cipher->min_keysize('SAFER_K128'), 16, 'Cipher->min_keysize'); +is( Crypt::Cipher->default_rounds('SAFER_K128'), 10, 'Cipher->default_rounds'); + +is( Crypt::Cipher::SAFER_K128->new($min_key)->blocksize, 8, 'SAFER_K128->new()->blocksize'); +is( Crypt::Cipher::SAFER_K128->new($min_key)->keysize, 16, 'SAFER_K128->new()->keysize'); +is( Crypt::Cipher::SAFER_K128->new($min_key)->max_keysize, 16, 'SAFER_K128->new()->max_keysize'); +is( Crypt::Cipher::SAFER_K128->new($min_key)->min_keysize, 16, 'SAFER_K128->new()->min_keysize'); +is( Crypt::Cipher::SAFER_K128->new($min_key)->default_rounds, 10, 'SAFER_K128->new()->default_rounds'); + +is( Crypt::Cipher->new('SAFER_K128', $min_key)->blocksize, 8, 'Cipher->new()->blocksize'); +is( Crypt::Cipher->new('SAFER_K128', $min_key)->keysize, 16, 'Cipher->new()->keysize'); +is( Crypt::Cipher->new('SAFER_K128', $min_key)->max_keysize, 16, 'Cipher->new()->max_keysize'); +is( Crypt::Cipher->new('SAFER_K128', $min_key)->min_keysize, 16, 'Cipher->new()->min_keysize'); +is( Crypt::Cipher->new('SAFER_K128', $min_key)->default_rounds, 10, 'Cipher->new()->default_rounds'); + +my $block_plain = 'BBBBBBBB'; +my $block_encrypted_min_key_hex = 'e526bb4621fe70e3'; +my $block_encrypted_max_key_hex = 'b932ad8042552f3e'; + +is( unpack('H*', Crypt::Cipher::SAFER_K128->new($min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'SAFER_K128->encrypt'); +is( Crypt::Cipher::SAFER_K128->new($min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'SAFER_K128->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('SAFER_K128', $min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('SAFER_K128', $min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Cipher->decrypt'); + +is( unpack('H*', Crypt::Cipher::SAFER_K128->new($max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'SAFER_K128->encrypt'); +is( Crypt::Cipher::SAFER_K128->new($max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'SAFER_K128->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('SAFER_K128', $max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('SAFER_K128', $max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Cipher->decrypt'); + + +my $spec_key = 'SSSSSSSSSSSSSSSS'; +my $spec_rounds = '11'; +my $spec_block_encrypted_hex = '74874afc69ae6cd6'; + +is( unpack('H*', Crypt::Cipher::SAFER_K128->new($spec_key, $spec_rounds)->encrypt($block_plain)), $spec_block_encrypted_hex, 'SAFER_K128->encrypt'); +is( Crypt::Cipher::SAFER_K128->new($spec_key, $spec_rounds)->decrypt(pack('H*', $spec_block_encrypted_hex)), $block_plain, 'SAFER_K128->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('SAFER_K128', $spec_key, $spec_rounds)->encrypt($block_plain)), $spec_block_encrypted_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('SAFER_K128', $spec_key, $spec_rounds)->decrypt(pack('H*', $spec_block_encrypted_hex)), $block_plain, 'Cipher->decrypt'); diff --git a/t/cipher_safer_k64.t b/t/cipher_safer_k64.t new file mode 100644 index 0000000..d38c351 --- /dev/null +++ b/t/cipher_safer_k64.t @@ -0,0 +1,75 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 42; + +use Crypt::Cipher; +use Crypt::Cipher::SAFER_K64; + +is( Crypt::Cipher::SAFER_K64::blocksize, 8, '::blocksize'); +is( Crypt::Cipher::SAFER_K64::keysize, 8, '::keysize'); +is( Crypt::Cipher::SAFER_K64::max_keysize, 8, '::max_keysize'); +is( Crypt::Cipher::SAFER_K64::min_keysize, 8, '::min_keysize'); +is( Crypt::Cipher::SAFER_K64::default_rounds, 6, '::default_rounds'); + +is( Crypt::Cipher::SAFER_K64->blocksize, 8, '->blocksize'); +is( Crypt::Cipher::SAFER_K64->keysize, 8, '->keysize'); +is( Crypt::Cipher::SAFER_K64->max_keysize, 8, '->max_keysize'); +is( Crypt::Cipher::SAFER_K64->min_keysize, 8, '->min_keysize'); +is( Crypt::Cipher::SAFER_K64->default_rounds, 6, '->default_rounds'); + +my $min_key = 'kkkkkkkk'; +my $max_key = 'KKKKKKKK'; + +is( Crypt::Cipher::blocksize('SAFER_K64'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher::keysize('SAFER_K64'), 8, 'Cipher->keysize'); +is( Crypt::Cipher::max_keysize('SAFER_K64'), 8, 'Cipher->max_keysize'); +is( Crypt::Cipher::min_keysize('SAFER_K64'), 8, 'Cipher->min_keysize'); +is( Crypt::Cipher::default_rounds('SAFER_K64'), 6, 'Cipher->default_rounds'); + +is( Crypt::Cipher->blocksize('SAFER_K64'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher->keysize('SAFER_K64'), 8, 'Cipher->keysize'); +is( Crypt::Cipher->max_keysize('SAFER_K64'), 8, 'Cipher->max_keysize'); +is( Crypt::Cipher->min_keysize('SAFER_K64'), 8, 'Cipher->min_keysize'); +is( Crypt::Cipher->default_rounds('SAFER_K64'), 6, 'Cipher->default_rounds'); + +is( Crypt::Cipher::SAFER_K64->new($min_key)->blocksize, 8, 'SAFER_K64->new()->blocksize'); +is( Crypt::Cipher::SAFER_K64->new($min_key)->keysize, 8, 'SAFER_K64->new()->keysize'); +is( Crypt::Cipher::SAFER_K64->new($min_key)->max_keysize, 8, 'SAFER_K64->new()->max_keysize'); +is( Crypt::Cipher::SAFER_K64->new($min_key)->min_keysize, 8, 'SAFER_K64->new()->min_keysize'); +is( Crypt::Cipher::SAFER_K64->new($min_key)->default_rounds, 6, 'SAFER_K64->new()->default_rounds'); + +is( Crypt::Cipher->new('SAFER_K64', $min_key)->blocksize, 8, 'Cipher->new()->blocksize'); +is( Crypt::Cipher->new('SAFER_K64', $min_key)->keysize, 8, 'Cipher->new()->keysize'); +is( Crypt::Cipher->new('SAFER_K64', $min_key)->max_keysize, 8, 'Cipher->new()->max_keysize'); +is( Crypt::Cipher->new('SAFER_K64', $min_key)->min_keysize, 8, 'Cipher->new()->min_keysize'); +is( Crypt::Cipher->new('SAFER_K64', $min_key)->default_rounds, 6, 'Cipher->new()->default_rounds'); + +my $block_plain = 'BBBBBBBB'; +my $block_encrypted_min_key_hex = '7d24754eca0a4f1d'; +my $block_encrypted_max_key_hex = '89ea357f69ed7c27'; + +is( unpack('H*', Crypt::Cipher::SAFER_K64->new($min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'SAFER_K64->encrypt'); +is( Crypt::Cipher::SAFER_K64->new($min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'SAFER_K64->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('SAFER_K64', $min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('SAFER_K64', $min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Cipher->decrypt'); + +is( unpack('H*', Crypt::Cipher::SAFER_K64->new($max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'SAFER_K64->encrypt'); +is( Crypt::Cipher::SAFER_K64->new($max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'SAFER_K64->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('SAFER_K64', $max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('SAFER_K64', $max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Cipher->decrypt'); + + +my $spec_key = 'SSSSSSSS'; +my $spec_rounds = '9'; +my $spec_block_encrypted_hex = 'b501503f773d146e'; + +is( unpack('H*', Crypt::Cipher::SAFER_K64->new($spec_key, $spec_rounds)->encrypt($block_plain)), $spec_block_encrypted_hex, 'SAFER_K64->encrypt'); +is( Crypt::Cipher::SAFER_K64->new($spec_key, $spec_rounds)->decrypt(pack('H*', $spec_block_encrypted_hex)), $block_plain, 'SAFER_K64->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('SAFER_K64', $spec_key, $spec_rounds)->encrypt($block_plain)), $spec_block_encrypted_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('SAFER_K64', $spec_key, $spec_rounds)->decrypt(pack('H*', $spec_block_encrypted_hex)), $block_plain, 'Cipher->decrypt'); diff --git a/t/cipher_safer_sk128.t b/t/cipher_safer_sk128.t new file mode 100644 index 0000000..5c590c3 --- /dev/null +++ b/t/cipher_safer_sk128.t @@ -0,0 +1,75 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 42; + +use Crypt::Cipher; +use Crypt::Cipher::SAFER_SK128; + +is( Crypt::Cipher::SAFER_SK128::blocksize, 8, '::blocksize'); +is( Crypt::Cipher::SAFER_SK128::keysize, 16, '::keysize'); +is( Crypt::Cipher::SAFER_SK128::max_keysize, 16, '::max_keysize'); +is( Crypt::Cipher::SAFER_SK128::min_keysize, 16, '::min_keysize'); +is( Crypt::Cipher::SAFER_SK128::default_rounds, 10, '::default_rounds'); + +is( Crypt::Cipher::SAFER_SK128->blocksize, 8, '->blocksize'); +is( Crypt::Cipher::SAFER_SK128->keysize, 16, '->keysize'); +is( Crypt::Cipher::SAFER_SK128->max_keysize, 16, '->max_keysize'); +is( Crypt::Cipher::SAFER_SK128->min_keysize, 16, '->min_keysize'); +is( Crypt::Cipher::SAFER_SK128->default_rounds, 10, '->default_rounds'); + +my $min_key = 'kkkkkkkkkkkkkkkk'; +my $max_key = 'KKKKKKKKKKKKKKKK'; + +is( Crypt::Cipher::blocksize('SAFER_SK128'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher::keysize('SAFER_SK128'), 16, 'Cipher->keysize'); +is( Crypt::Cipher::max_keysize('SAFER_SK128'), 16, 'Cipher->max_keysize'); +is( Crypt::Cipher::min_keysize('SAFER_SK128'), 16, 'Cipher->min_keysize'); +is( Crypt::Cipher::default_rounds('SAFER_SK128'), 10, 'Cipher->default_rounds'); + +is( Crypt::Cipher->blocksize('SAFER_SK128'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher->keysize('SAFER_SK128'), 16, 'Cipher->keysize'); +is( Crypt::Cipher->max_keysize('SAFER_SK128'), 16, 'Cipher->max_keysize'); +is( Crypt::Cipher->min_keysize('SAFER_SK128'), 16, 'Cipher->min_keysize'); +is( Crypt::Cipher->default_rounds('SAFER_SK128'), 10, 'Cipher->default_rounds'); + +is( Crypt::Cipher::SAFER_SK128->new($min_key)->blocksize, 8, 'SAFER_SK128->new()->blocksize'); +is( Crypt::Cipher::SAFER_SK128->new($min_key)->keysize, 16, 'SAFER_SK128->new()->keysize'); +is( Crypt::Cipher::SAFER_SK128->new($min_key)->max_keysize, 16, 'SAFER_SK128->new()->max_keysize'); +is( Crypt::Cipher::SAFER_SK128->new($min_key)->min_keysize, 16, 'SAFER_SK128->new()->min_keysize'); +is( Crypt::Cipher::SAFER_SK128->new($min_key)->default_rounds, 10, 'SAFER_SK128->new()->default_rounds'); + +is( Crypt::Cipher->new('SAFER_SK128', $min_key)->blocksize, 8, 'Cipher->new()->blocksize'); +is( Crypt::Cipher->new('SAFER_SK128', $min_key)->keysize, 16, 'Cipher->new()->keysize'); +is( Crypt::Cipher->new('SAFER_SK128', $min_key)->max_keysize, 16, 'Cipher->new()->max_keysize'); +is( Crypt::Cipher->new('SAFER_SK128', $min_key)->min_keysize, 16, 'Cipher->new()->min_keysize'); +is( Crypt::Cipher->new('SAFER_SK128', $min_key)->default_rounds, 10, 'Cipher->new()->default_rounds'); + +my $block_plain = 'BBBBBBBB'; +my $block_encrypted_min_key_hex = 'f61b32cc7e1a09b9'; +my $block_encrypted_max_key_hex = '621d57c58719cb34'; + +is( unpack('H*', Crypt::Cipher::SAFER_SK128->new($min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'SAFER_SK128->encrypt'); +is( Crypt::Cipher::SAFER_SK128->new($min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'SAFER_SK128->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('SAFER_SK128', $min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('SAFER_SK128', $min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Cipher->decrypt'); + +is( unpack('H*', Crypt::Cipher::SAFER_SK128->new($max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'SAFER_SK128->encrypt'); +is( Crypt::Cipher::SAFER_SK128->new($max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'SAFER_SK128->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('SAFER_SK128', $max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('SAFER_SK128', $max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Cipher->decrypt'); + + +my $spec_key = 'SSSSSSSSSSSSSSSS'; +my $spec_rounds = '11'; +my $spec_block_encrypted_hex = '8c62673889cb02a2'; + +is( unpack('H*', Crypt::Cipher::SAFER_SK128->new($spec_key, $spec_rounds)->encrypt($block_plain)), $spec_block_encrypted_hex, 'SAFER_SK128->encrypt'); +is( Crypt::Cipher::SAFER_SK128->new($spec_key, $spec_rounds)->decrypt(pack('H*', $spec_block_encrypted_hex)), $block_plain, 'SAFER_SK128->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('SAFER_SK128', $spec_key, $spec_rounds)->encrypt($block_plain)), $spec_block_encrypted_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('SAFER_SK128', $spec_key, $spec_rounds)->decrypt(pack('H*', $spec_block_encrypted_hex)), $block_plain, 'Cipher->decrypt'); diff --git a/t/cipher_safer_sk64.t b/t/cipher_safer_sk64.t new file mode 100644 index 0000000..6d8c6ca --- /dev/null +++ b/t/cipher_safer_sk64.t @@ -0,0 +1,75 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 42; + +use Crypt::Cipher; +use Crypt::Cipher::SAFER_SK64; + +is( Crypt::Cipher::SAFER_SK64::blocksize, 8, '::blocksize'); +is( Crypt::Cipher::SAFER_SK64::keysize, 8, '::keysize'); +is( Crypt::Cipher::SAFER_SK64::max_keysize, 8, '::max_keysize'); +is( Crypt::Cipher::SAFER_SK64::min_keysize, 8, '::min_keysize'); +is( Crypt::Cipher::SAFER_SK64::default_rounds, 8, '::default_rounds'); + +is( Crypt::Cipher::SAFER_SK64->blocksize, 8, '->blocksize'); +is( Crypt::Cipher::SAFER_SK64->keysize, 8, '->keysize'); +is( Crypt::Cipher::SAFER_SK64->max_keysize, 8, '->max_keysize'); +is( Crypt::Cipher::SAFER_SK64->min_keysize, 8, '->min_keysize'); +is( Crypt::Cipher::SAFER_SK64->default_rounds, 8, '->default_rounds'); + +my $min_key = 'kkkkkkkk'; +my $max_key = 'KKKKKKKK'; + +is( Crypt::Cipher::blocksize('SAFER_SK64'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher::keysize('SAFER_SK64'), 8, 'Cipher->keysize'); +is( Crypt::Cipher::max_keysize('SAFER_SK64'), 8, 'Cipher->max_keysize'); +is( Crypt::Cipher::min_keysize('SAFER_SK64'), 8, 'Cipher->min_keysize'); +is( Crypt::Cipher::default_rounds('SAFER_SK64'), 8, 'Cipher->default_rounds'); + +is( Crypt::Cipher->blocksize('SAFER_SK64'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher->keysize('SAFER_SK64'), 8, 'Cipher->keysize'); +is( Crypt::Cipher->max_keysize('SAFER_SK64'), 8, 'Cipher->max_keysize'); +is( Crypt::Cipher->min_keysize('SAFER_SK64'), 8, 'Cipher->min_keysize'); +is( Crypt::Cipher->default_rounds('SAFER_SK64'), 8, 'Cipher->default_rounds'); + +is( Crypt::Cipher::SAFER_SK64->new($min_key)->blocksize, 8, 'SAFER_SK64->new()->blocksize'); +is( Crypt::Cipher::SAFER_SK64->new($min_key)->keysize, 8, 'SAFER_SK64->new()->keysize'); +is( Crypt::Cipher::SAFER_SK64->new($min_key)->max_keysize, 8, 'SAFER_SK64->new()->max_keysize'); +is( Crypt::Cipher::SAFER_SK64->new($min_key)->min_keysize, 8, 'SAFER_SK64->new()->min_keysize'); +is( Crypt::Cipher::SAFER_SK64->new($min_key)->default_rounds, 8, 'SAFER_SK64->new()->default_rounds'); + +is( Crypt::Cipher->new('SAFER_SK64', $min_key)->blocksize, 8, 'Cipher->new()->blocksize'); +is( Crypt::Cipher->new('SAFER_SK64', $min_key)->keysize, 8, 'Cipher->new()->keysize'); +is( Crypt::Cipher->new('SAFER_SK64', $min_key)->max_keysize, 8, 'Cipher->new()->max_keysize'); +is( Crypt::Cipher->new('SAFER_SK64', $min_key)->min_keysize, 8, 'Cipher->new()->min_keysize'); +is( Crypt::Cipher->new('SAFER_SK64', $min_key)->default_rounds, 8, 'Cipher->new()->default_rounds'); + +my $block_plain = 'BBBBBBBB'; +my $block_encrypted_min_key_hex = '639b30226c23e91f'; +my $block_encrypted_max_key_hex = 'd41cceb6c422eb99'; + +is( unpack('H*', Crypt::Cipher::SAFER_SK64->new($min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'SAFER_SK64->encrypt'); +is( Crypt::Cipher::SAFER_SK64->new($min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'SAFER_SK64->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('SAFER_SK64', $min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('SAFER_SK64', $min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Cipher->decrypt'); + +is( unpack('H*', Crypt::Cipher::SAFER_SK64->new($max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'SAFER_SK64->encrypt'); +is( Crypt::Cipher::SAFER_SK64->new($max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'SAFER_SK64->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('SAFER_SK64', $max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('SAFER_SK64', $max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Cipher->decrypt'); + + +my $spec_key = 'SSSSSSSS'; +my $spec_rounds = '9'; +my $spec_block_encrypted_hex = '5f8826052c1202ab'; + +is( unpack('H*', Crypt::Cipher::SAFER_SK64->new($spec_key, $spec_rounds)->encrypt($block_plain)), $spec_block_encrypted_hex, 'SAFER_SK64->encrypt'); +is( Crypt::Cipher::SAFER_SK64->new($spec_key, $spec_rounds)->decrypt(pack('H*', $spec_block_encrypted_hex)), $block_plain, 'SAFER_SK64->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('SAFER_SK64', $spec_key, $spec_rounds)->encrypt($block_plain)), $spec_block_encrypted_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('SAFER_SK64', $spec_key, $spec_rounds)->decrypt(pack('H*', $spec_block_encrypted_hex)), $block_plain, 'Cipher->decrypt'); diff --git a/t/cipher_saferp.t b/t/cipher_saferp.t new file mode 100644 index 0000000..e1bbe59 --- /dev/null +++ b/t/cipher_saferp.t @@ -0,0 +1,65 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 38; + +use Crypt::Cipher; +use Crypt::Cipher::SAFERP; + +is( Crypt::Cipher::SAFERP::blocksize, 16, '::blocksize'); +is( Crypt::Cipher::SAFERP::keysize, 32, '::keysize'); +is( Crypt::Cipher::SAFERP::max_keysize, 32, '::max_keysize'); +is( Crypt::Cipher::SAFERP::min_keysize, 16, '::min_keysize'); +is( Crypt::Cipher::SAFERP::default_rounds, 8, '::default_rounds'); + +is( Crypt::Cipher::SAFERP->blocksize, 16, '->blocksize'); +is( Crypt::Cipher::SAFERP->keysize, 32, '->keysize'); +is( Crypt::Cipher::SAFERP->max_keysize, 32, '->max_keysize'); +is( Crypt::Cipher::SAFERP->min_keysize, 16, '->min_keysize'); +is( Crypt::Cipher::SAFERP->default_rounds, 8, '->default_rounds'); + +my $min_key = 'kkkkkkkkkkkkkkkk'; +my $max_key = 'KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK'; + +is( Crypt::Cipher::blocksize('SAFERP'), 16, 'Cipher->blocksize'); +is( Crypt::Cipher::keysize('SAFERP'), 32, 'Cipher->keysize'); +is( Crypt::Cipher::max_keysize('SAFERP'), 32, 'Cipher->max_keysize'); +is( Crypt::Cipher::min_keysize('SAFERP'), 16, 'Cipher->min_keysize'); +is( Crypt::Cipher::default_rounds('SAFERP'), 8, 'Cipher->default_rounds'); + +is( Crypt::Cipher->blocksize('SAFERP'), 16, 'Cipher->blocksize'); +is( Crypt::Cipher->keysize('SAFERP'), 32, 'Cipher->keysize'); +is( Crypt::Cipher->max_keysize('SAFERP'), 32, 'Cipher->max_keysize'); +is( Crypt::Cipher->min_keysize('SAFERP'), 16, 'Cipher->min_keysize'); +is( Crypt::Cipher->default_rounds('SAFERP'), 8, 'Cipher->default_rounds'); + +is( Crypt::Cipher::SAFERP->new($min_key)->blocksize, 16, 'SAFERP->new()->blocksize'); +is( Crypt::Cipher::SAFERP->new($min_key)->keysize, 32, 'SAFERP->new()->keysize'); +is( Crypt::Cipher::SAFERP->new($min_key)->max_keysize, 32, 'SAFERP->new()->max_keysize'); +is( Crypt::Cipher::SAFERP->new($min_key)->min_keysize, 16, 'SAFERP->new()->min_keysize'); +is( Crypt::Cipher::SAFERP->new($min_key)->default_rounds, 8, 'SAFERP->new()->default_rounds'); + +is( Crypt::Cipher->new('SAFERP', $min_key)->blocksize, 16, 'Cipher->new()->blocksize'); +is( Crypt::Cipher->new('SAFERP', $min_key)->keysize, 32, 'Cipher->new()->keysize'); +is( Crypt::Cipher->new('SAFERP', $min_key)->max_keysize, 32, 'Cipher->new()->max_keysize'); +is( Crypt::Cipher->new('SAFERP', $min_key)->min_keysize, 16, 'Cipher->new()->min_keysize'); +is( Crypt::Cipher->new('SAFERP', $min_key)->default_rounds, 8, 'Cipher->new()->default_rounds'); + +my $block_plain = 'BBBBBBBBBBBBBBBB'; +my $block_encrypted_min_key_hex = 'ca40dc929ecb6cd6d8c193f2008b7b0f'; +my $block_encrypted_max_key_hex = 'd4c5aea977b9545517f451d84c3c0b31'; + +is( unpack('H*', Crypt::Cipher::SAFERP->new($min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'SAFERP->encrypt'); +is( Crypt::Cipher::SAFERP->new($min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'SAFERP->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('SAFERP', $min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('SAFERP', $min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Cipher->decrypt'); + +is( unpack('H*', Crypt::Cipher::SAFERP->new($max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'SAFERP->encrypt'); +is( Crypt::Cipher::SAFERP->new($max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'SAFERP->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('SAFERP', $max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('SAFERP', $max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Cipher->decrypt'); + diff --git a/t/cipher_seed.t b/t/cipher_seed.t new file mode 100644 index 0000000..49a988c --- /dev/null +++ b/t/cipher_seed.t @@ -0,0 +1,65 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 38; + +use Crypt::Cipher; +use Crypt::Cipher::SEED; + +is( Crypt::Cipher::SEED::blocksize, 16, '::blocksize'); +is( Crypt::Cipher::SEED::keysize, 16, '::keysize'); +is( Crypt::Cipher::SEED::max_keysize, 16, '::max_keysize'); +is( Crypt::Cipher::SEED::min_keysize, 16, '::min_keysize'); +is( Crypt::Cipher::SEED::default_rounds, 16, '::default_rounds'); + +is( Crypt::Cipher::SEED->blocksize, 16, '->blocksize'); +is( Crypt::Cipher::SEED->keysize, 16, '->keysize'); +is( Crypt::Cipher::SEED->max_keysize, 16, '->max_keysize'); +is( Crypt::Cipher::SEED->min_keysize, 16, '->min_keysize'); +is( Crypt::Cipher::SEED->default_rounds, 16, '->default_rounds'); + +my $min_key = 'kkkkkkkkkkkkkkkk'; +my $max_key = 'KKKKKKKKKKKKKKKK'; + +is( Crypt::Cipher::blocksize('SEED'), 16, 'Cipher->blocksize'); +is( Crypt::Cipher::keysize('SEED'), 16, 'Cipher->keysize'); +is( Crypt::Cipher::max_keysize('SEED'), 16, 'Cipher->max_keysize'); +is( Crypt::Cipher::min_keysize('SEED'), 16, 'Cipher->min_keysize'); +is( Crypt::Cipher::default_rounds('SEED'), 16, 'Cipher->default_rounds'); + +is( Crypt::Cipher->blocksize('SEED'), 16, 'Cipher->blocksize'); +is( Crypt::Cipher->keysize('SEED'), 16, 'Cipher->keysize'); +is( Crypt::Cipher->max_keysize('SEED'), 16, 'Cipher->max_keysize'); +is( Crypt::Cipher->min_keysize('SEED'), 16, 'Cipher->min_keysize'); +is( Crypt::Cipher->default_rounds('SEED'), 16, 'Cipher->default_rounds'); + +is( Crypt::Cipher::SEED->new($min_key)->blocksize, 16, 'SEED->new()->blocksize'); +is( Crypt::Cipher::SEED->new($min_key)->keysize, 16, 'SEED->new()->keysize'); +is( Crypt::Cipher::SEED->new($min_key)->max_keysize, 16, 'SEED->new()->max_keysize'); +is( Crypt::Cipher::SEED->new($min_key)->min_keysize, 16, 'SEED->new()->min_keysize'); +is( Crypt::Cipher::SEED->new($min_key)->default_rounds, 16, 'SEED->new()->default_rounds'); + +is( Crypt::Cipher->new('SEED', $min_key)->blocksize, 16, 'Cipher->new()->blocksize'); +is( Crypt::Cipher->new('SEED', $min_key)->keysize, 16, 'Cipher->new()->keysize'); +is( Crypt::Cipher->new('SEED', $min_key)->max_keysize, 16, 'Cipher->new()->max_keysize'); +is( Crypt::Cipher->new('SEED', $min_key)->min_keysize, 16, 'Cipher->new()->min_keysize'); +is( Crypt::Cipher->new('SEED', $min_key)->default_rounds, 16, 'Cipher->new()->default_rounds'); + +my $block_plain = 'BBBBBBBBBBBBBBBB'; +my $block_encrypted_min_key_hex = '64f1614aeda40bc2943a13b1c4c93fa4'; +my $block_encrypted_max_key_hex = '4cebfb51827596091fd3ee4e5923bd05'; + +is( unpack('H*', Crypt::Cipher::SEED->new($min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'SEED->encrypt'); +is( Crypt::Cipher::SEED->new($min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'SEED->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('SEED', $min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('SEED', $min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Cipher->decrypt'); + +is( unpack('H*', Crypt::Cipher::SEED->new($max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'SEED->encrypt'); +is( Crypt::Cipher::SEED->new($max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'SEED->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('SEED', $max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('SEED', $max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Cipher->decrypt'); + diff --git a/t/cipher_seed_test_vectors_bc.t b/t/cipher_seed_test_vectors_bc.t new file mode 100644 index 0000000..a0b28f1 --- /dev/null +++ b/t/cipher_seed_test_vectors_bc.t @@ -0,0 +1,29 @@ +use strict; +use warnings; + +use Test::More tests => 5; +use Crypt::Cipher::SEED; + +my $line = 1; +while (my $l = ) { + chomp($l); + $l =~ s/[\s\t]+/ /g; + my $d = {}; + for my $pair (split / /, $l) { + my ($k, $v) = split /:/, $pair; + $d->{$k} = $v; + } + + my $c = Crypt::Cipher::SEED->new(pack('H*',$d->{key})); + my $result = pack('H*', $d->{pt}); + $result = $c->encrypt($result) for(1..$d->{iter}); + is(unpack('H*', $result), lc($d->{ct}), "line=$line"); + $line++; +} + +__DATA__ +iter:1 key:00000000000000000000000000000000 pt:000102030405060708090a0b0c0d0e0f ct:5EBAC6E0054E166819AFF1CC6D346CDB +iter:1 key:000102030405060708090a0b0c0d0e0f pt:00000000000000000000000000000000 ct:c11f22f20140505084483597e4370f43 +iter:1 key:4706480851E61BE85D74BFB3FD956185 pt:83A2F8A288641FB9A4E9A5CC2F131C7D ct:EE54D13EBCAE706D226BC3142CD40D4A +iter:1 key:28DBC3BC49FFD87DCFA509B11D422BE7 pt:B41E6BE2EBA84A148E2EED84593C5EC7 ct:9B9B7BFCD1813CB95D0B3618F40F5122 +iter:1 key:0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E pt:0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E ct:8296F2F1B007AB9D533FDEE35A9AD850 diff --git a/t/cipher_skipjack.t b/t/cipher_skipjack.t new file mode 100644 index 0000000..9dea1d1 --- /dev/null +++ b/t/cipher_skipjack.t @@ -0,0 +1,65 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 38; + +use Crypt::Cipher; +use Crypt::Cipher::Skipjack; + +is( Crypt::Cipher::Skipjack::blocksize, 8, '::blocksize'); +is( Crypt::Cipher::Skipjack::keysize, 10, '::keysize'); +is( Crypt::Cipher::Skipjack::max_keysize, 10, '::max_keysize'); +is( Crypt::Cipher::Skipjack::min_keysize, 10, '::min_keysize'); +is( Crypt::Cipher::Skipjack::default_rounds, 32, '::default_rounds'); + +is( Crypt::Cipher::Skipjack->blocksize, 8, '->blocksize'); +is( Crypt::Cipher::Skipjack->keysize, 10, '->keysize'); +is( Crypt::Cipher::Skipjack->max_keysize, 10, '->max_keysize'); +is( Crypt::Cipher::Skipjack->min_keysize, 10, '->min_keysize'); +is( Crypt::Cipher::Skipjack->default_rounds, 32, '->default_rounds'); + +my $min_key = 'kkkkkkkkkk'; +my $max_key = 'KKKKKKKKKK'; + +is( Crypt::Cipher::blocksize('Skipjack'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher::keysize('Skipjack'), 10, 'Cipher->keysize'); +is( Crypt::Cipher::max_keysize('Skipjack'), 10, 'Cipher->max_keysize'); +is( Crypt::Cipher::min_keysize('Skipjack'), 10, 'Cipher->min_keysize'); +is( Crypt::Cipher::default_rounds('Skipjack'), 32, 'Cipher->default_rounds'); + +is( Crypt::Cipher->blocksize('Skipjack'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher->keysize('Skipjack'), 10, 'Cipher->keysize'); +is( Crypt::Cipher->max_keysize('Skipjack'), 10, 'Cipher->max_keysize'); +is( Crypt::Cipher->min_keysize('Skipjack'), 10, 'Cipher->min_keysize'); +is( Crypt::Cipher->default_rounds('Skipjack'), 32, 'Cipher->default_rounds'); + +is( Crypt::Cipher::Skipjack->new($min_key)->blocksize, 8, 'Skipjack->new()->blocksize'); +is( Crypt::Cipher::Skipjack->new($min_key)->keysize, 10, 'Skipjack->new()->keysize'); +is( Crypt::Cipher::Skipjack->new($min_key)->max_keysize, 10, 'Skipjack->new()->max_keysize'); +is( Crypt::Cipher::Skipjack->new($min_key)->min_keysize, 10, 'Skipjack->new()->min_keysize'); +is( Crypt::Cipher::Skipjack->new($min_key)->default_rounds, 32, 'Skipjack->new()->default_rounds'); + +is( Crypt::Cipher->new('Skipjack', $min_key)->blocksize, 8, 'Cipher->new()->blocksize'); +is( Crypt::Cipher->new('Skipjack', $min_key)->keysize, 10, 'Cipher->new()->keysize'); +is( Crypt::Cipher->new('Skipjack', $min_key)->max_keysize, 10, 'Cipher->new()->max_keysize'); +is( Crypt::Cipher->new('Skipjack', $min_key)->min_keysize, 10, 'Cipher->new()->min_keysize'); +is( Crypt::Cipher->new('Skipjack', $min_key)->default_rounds, 32, 'Cipher->new()->default_rounds'); + +my $block_plain = 'BBBBBBBB'; +my $block_encrypted_min_key_hex = 'c3341aa246606dec'; +my $block_encrypted_max_key_hex = 'bcad31948086062d'; + +is( unpack('H*', Crypt::Cipher::Skipjack->new($min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Skipjack->encrypt'); +is( Crypt::Cipher::Skipjack->new($min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Skipjack->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('Skipjack', $min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('Skipjack', $min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Cipher->decrypt'); + +is( unpack('H*', Crypt::Cipher::Skipjack->new($max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Skipjack->encrypt'); +is( Crypt::Cipher::Skipjack->new($max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Skipjack->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('Skipjack', $max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('Skipjack', $max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Cipher->decrypt'); + diff --git a/t/cipher_stream.t b/t/cipher_stream.t new file mode 100644 index 0000000..7fcd310 --- /dev/null +++ b/t/cipher_stream.t @@ -0,0 +1,42 @@ +use strict; +use warnings; + +use Test::More tests => 6; + +use Crypt::Stream::RC4; +use Crypt::Stream::Sober128; +use Crypt::Stream::ChaCha; + +{ + my $key = pack("H*", "0123456789abcdef"); + my $pt = pack("H*", "0123456789abcdef"); + my $ct = pack("H*", "75b7878099e0c596"); + my $enc = Crypt::Stream::RC4->new($key)->crypt($pt); + my $dec = Crypt::Stream::RC4->new($key)->crypt($ct); + is(unpack("H*", $enc), unpack("H*", $ct), "Crypt::Stream::RC4 encrypt"); + is(unpack("H*", $dec), unpack("H*", $pt), "Crypt::Stream::RC4 decrypt"); +} + +{ + my $key = pack("H*", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); + my $iv = pack("H*", "000000000000004a00000000"); + my $ct = pack("H*", "6E2E359A2568F98041BA0728DD0D6981E97E7AEC1D4360C20A27AFCCFD9FAE0BF91B65C5524733AB". + "8F593DABCD62B3571639D624E65152AB8F530C359F0861D807CA0DBF500D6A6156A38E088A22B65E". + "52BC514D16CCF806818CE91AB77937365AF90BBF74A35BE6B40B8EEDF2785E42874D"); + my $pt = "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it."; + my $enc = Crypt::Stream::ChaCha->new($key, $iv, 1, 20)->crypt($pt); + my $dec = Crypt::Stream::ChaCha->new($key, $iv, 1, 20)->crypt($ct); + is(unpack("H*", $enc), unpack("H*", $ct), "Crypt::Stream::ChaCha encrypt"); + is($dec, $pt, "Crypt::Stream::ChaCha decrypt"); +} + +{ + my $key = pack("H*", "74657374206b65792031323862697473"); + my $iv = pack("H*", "00000000"); + my $ct = pack("H*", "43500ccf89919f1daa377495f4b458c240378bbb"); + my $pt = pack("H*", "0000000000000000000000000000000000000000"); + my $enc = Crypt::Stream::Sober128->new($key, $iv)->crypt($pt); + my $dec = Crypt::Stream::Sober128->new($key, $iv)->crypt($ct); + is(unpack("H*", $enc), unpack("H*", $ct), "Crypt::Stream::Sober128 encrypt"); + is(unpack("H*", $dec), unpack("H*", $pt), "Crypt::Stream::Sober128 decrypt"); +} diff --git a/t/cipher_test_vectors_ltc.t b/t/cipher_test_vectors_ltc.t new file mode 100644 index 0000000..3658176 --- /dev/null +++ b/t/cipher_test_vectors_ltc.t @@ -0,0 +1,2190 @@ +use strict; +use warnings; + +use Test::More tests => 2000; +use Crypt::Cipher; + +my $trans = { + "3des" => 'DES_EDE', + "safer+" => 'SAFERP', + "khazad" => 'Khazad', + "safer-k128" => 'SAFER_K128', + "safer-sk128"=> 'SAFER_SK128', + "rc6" => 'RC6', + "safer-k64" => 'SAFER_K64', + "safer-sk64" => 'SAFER_SK64', + "anubis" => 'Anubis', + "blowfish" => 'Blowfish', + "xtea" => 'XTEA', + "aes" => 'AES', + "rc5" => 'RC5', + "cast5" => 'CAST5', + "skipjack" => 'Skipjack', + "twofish" => 'Twofish', + "noekeon" => 'Noekeon', + "rc2" => 'RC2', + "des" => 'DES', + "camellia" => 'Camellia', +}; + +my $tv; +my $name; +my $size; + +while (my $l = ) { + $l =~ s/[\r\n]*$//; + $l =~ s/^[\s]*([^\s\r\n]+).*?/$1/; + $l =~ s/\s+//g; + my ($k, $v) = split /:/, $l; + next unless defined $k && defined $v; + $name = $v if lc($k) eq 'cipher'; + if (lc($k) eq 'keysize') { + $size = $v; + $size =~ s/bytes//; + } + $tv->{$name}->{$size}->{$k} = $v if $name && $k =~ /\d+/; +} + +my $seq; +$seq .= pack('C',$_) for(0..255); +my $zeros = '\0' x 255; + +for my $n (sort keys %$tv) { + my $N = $trans->{$n} || die "FATAL: unknown name '$n'"; + for my $ks (sort keys %{$tv->{$n}}) { + my $key = substr($seq, 0, $ks); + my $bytes = substr($seq, 0, Crypt::Cipher->blocksize($N)); + for my $i (0..255) { + next unless $tv->{$n}->{$ks}->{$i}; + my $ct = Crypt::Cipher->new($N, $key)->encrypt($bytes); + is(unpack('H*', $ct), lc($tv->{$n}->{$ks}->{$i}), "$N/$ks/$i"); + $bytes = $ct; + $key = substr($ct x 100, 0, $ks); + } + } +} + +__DATA__ +Cipher Test Vectors + +These are test encryptions with key of nn bytes '00 01 02 03 .. (nn-1)' and original PT of the same style. +The output of step N is used as the key and plaintext for step N+1 (key bytes repeated as required to fill the key) + +Cipher: aes +Key Size: 16 bytes + 0: 0A940BB5416EF045F1C39458C653EA5A + 1: 2B20AF92A928562CF645B1B824F2E6D9 + 2: FC29C3356937ECC3159D8D6EF5E883A1 + 3: 4C07B5A2EF31A3229C87AB2E4DE88602 + 4: 93AFA1147E793FFCC3D852695A62D008 + 5: D4BCC317DC9AFE0E6C7AD1E76F79DBE9 + 6: FEDB3371F3C65162AFCCDC6D18C79A65 + 7: 4AF2A76F93F07C14161C16B5C176E439 + 8: 00A1A596AF7CF44FD12981FA12CB1515 + 9: 8013D7006AB38AEBD40D0DC10328751C +10: 81A077F3A262FA4D00D98EE4D1BEC390 +11: 0CCBC99A3135F26D2BE824D633C0366F +12: CDBB5568610AD428706408B64DB66E50 +13: CE94461EB0D57C8DB6AEB2BC8E8CE1D2 +14: 06F14868F4298979462595C0FBF33F5A +15: FE22A7097513246074B7C8DFD57D32B2 +16: 0F2D936610F6D9E32C0E624568BB8E6F +17: F32BCD92B563D475E98322E5850AC277 +18: 6E6FCB72930D81469F9E05B20FD406C0 +19: 42FF674CBA6C19C4AD84D42816173099 +20: 41C12474A49B6B2B5E7D38E03A4DD4E0 +21: F9E234E3CE3FCED184C775B6140AD733 +22: 7EB5CC6B183D8B3EB4FBA4717CD8838A +23: CB6C5D78F9721E5BF8E980F0EDCAD4AF +24: B3F20EF6C26FD9301576D82DA6D50809 +25: F9375037377D86599FB4F241166C43E9 +26: 98BAF9AB7402479C2DA356F5DAE35D5F +27: 58D1A8E0DC3BC53FD995BB0F60F25FE7 +28: 0A75C0D22D2627C97BA2A7344B9B8C74 +29: 88C299B2F8C9EDAF86A301BBF534BDA7 +30: 755E3A17420281F2C619588A6B521FF9 +31: 0E540DD25C0C147461146E11F832A63D +32: DC5B58691C6BA5B243036A41301BD7D1 +33: E9299A7336C2D8A51D6C7E2BD1B8F054 +34: 78CA6F682FC649DB289DD62D28D3A22D +35: 98D96EDA081DE416083650B22BD3869D +36: E747DE96D122CE1EF6F89BDE0FAE75FF +37: E48DDF2EDDEB54C861A1E42F5B649EEE +38: C650C2CF1E903B7F9C8536A2446CA762 +39: CF0BCDCE0F1FE7EB40016C1231FB2962 +40: 37B1C8BE3812147E0D5D115A797663EF +41: 45DD8184581049C4B28FBC0809690C5D +42: 11B0D889F96E677EEC2E934E9F7F5398 +43: CEC30BC1128A96CD506E406B5ADFAE19 +44: DE67D5439BF83D5338D53F362FCF79B6 +45: 724FBB2D95CBEABC568AA44941D9B6E5 +46: C63F480DA3C73B2A661F1FBC3E4D1F89 +47: 225CD18789D18FF09C982EF38AEF0AAF +48: B493DEC7E3D11911DEF8788102453670 +49: 23E0B12A67DF025CB77CBDF9E295FCAF + +Key Size: 24 bytes + 0: 0060BFFE46834BB8DA5CF9A61FF220AE + 1: 597FA00D03EDDC81C2575B4DD6B6AEFD + 2: 4881E4EF69005DCB9110BA327CAC8460 + 3: FC4A968AF65FCFF45E4698455918673D + 4: 3079D7B27A3DA5C0805A61CC37109EE0 + 5: 9B3F2C7C35806276E2C53826EC1B3C84 + 6: FCDFCB1FD9FCF1B63E1AB6737FC154E8 + 7: 4A8012AFD410D29CE2CEE0FD195EF9DA + 8: 9F4201C4174C71A3AEF8FD6822197D67 + 9: DE3E5E98DA60E895389A1C17E3D50DA1 +10: 20C9064A076C01D1BC121A5A2A1F913C +11: BA41A36CD24B515545B8B464B244E5BE +12: 2CC1DE9DBCAC45269C6DBBC9203095F4 +13: 2ED2499CFEB30203E6305B3E1C329C4D +14: FD709FC0AB48B204C95B74AD189C8832 +15: 7ED298B472C53A4CB7A3BAE588805E86 +16: CB0C6FE2BA76901F9EDE752634DCC31D +17: 6C5CA6EFCF7101881507AB8770ACF1DE +18: DEC3C5209E98BBFAA469C5FE6C02A674 +19: CFAC040C1198C8264679CACEAA7E9DE7 +20: EF990992EBA8ECA7E5F95E3B9D69D3A4 +21: 8FC1B640EB55A96D08D83D1184B77769 +22: E1F3DFB9D055BCB2D6CED6DCB8361BFB +23: 6621F47057706F2A079819DBC0197B9C +24: 882611AC68778CBD6A46FB5DD4611A37 +25: F35E1367A283CC641FBCE26512A8F2F1 +26: 5A4A71F69056CFBAB67DDA777F5CD945 +27: C446F2BFAD060A9E9E17F71B05ADABD0 +28: 1F0E50F71A67FAA7D169A7A1017FFD65 +29: A6A38588848915509451A2354D2AAC8E +30: 4C887574F2C5DB00ED4FBAF814A70302 +31: 1B642944162A049CCA9FD0284D7AB4C3 +32: 431BD9293C5BFD12F948C255C838880B +33: 32CD23A30039AE2FB80B804B905362B1 +34: EBB30E07E7517580A645CD1B5F664182 +35: 292F2BB28BB172620B05C7621BA347D6 +36: 46C06E1223F392D57B98EFCF4C832C18 +37: 451DFBAD2AA92080204F85432236A42C +38: 768D6206D2B3DD1B9C26FAA5977A6477 +39: 3705F9CEBFE8F91ECE07F84578C05494 +40: 085EB0DCF360F5403FF1E7402A0F7A03 +41: 2A0D56F2E7C7FCE3095F511BDE4AD9A2 +42: A8AB2F3643A61AF164F99FEFAE2CE1B4 +43: E73FD4B1FAE0E5E6A6A31CCC2AF96386 +44: 578E84FD1AA16FF350374E4FD5FDD529 +45: EEAE301DD57084801DB01F8B9C4036CE +46: 1C44A93B404298327857F71962E0604C +47: B5F64CD5835C85A68DC23E26D4B8FF80 +48: 6C6F97850A87088AF195D0500B3F5D78 +49: 0BAB3A60A25CD1A750C2C443AA01C57A + +Key Size: 32 bytes + 0: 5A6E045708FB7196F02E553D02C3A692 + 1: 5F7229D6AACF0DAFE3B518C0D4ADBAB4 + 2: 96477F47C0A6F482AC4036D2C60FAAD8 + 3: 7F791D54914F12E9F0D92F4416EFBEC0 + 4: 87DDB19415BEDC42BD361FE380553C5A + 5: 8EDB2A09DC8731DB76D9F67A03AC4D9E + 6: 269A7C08C28D5E4D9355DDBA161F862E + 7: 042A3397BA5029C443DD76755008DB2A + 8: 469C82A94BC5F7B2DF57F0CE1716EE74 + 9: 5A84A93077FA19146078310035F4B7E4 +10: 28CAF1C0D811F86CFD3C5EFC30DF79F9 +11: 05B575D06C2D593B708F7C695CE97571 +12: B7E8CACF0A0BD7F2F5DA0B09CC8B8AEC +13: 0ADDE90F66F1BCF38CEC63EFBF9DBD46 +14: 9BF99E7F5B8F176DD686AF017D5196E2 +15: ABC189EE80D4A4588B3D54DDACCD9778 +16: A57405378580B1E8A8D877791300374C +17: D1EF03F72FAB3DB68022FC60A2CEC13D +18: 3D2406231BA17FF7CC973C5E203872DF +19: C3E07233BD101502953D6186001838E4 +20: DC281C0CE02A83098C80D6C9463F3449 +21: A923023D2390B2230FCE9217776AAAFC +22: 92E28E69009959FB84046C5ED1B64D1A +23: CEF8F684EC64A31C651280CDC942DFC2 +24: 5A954684B22691F9CFC60442A654EF61 +25: 56A38A0D93188BAA50DFAF2CB799A76C +26: 54503340C5DE26679AA5F35215DE85EA +27: E74BFAF64946DFD699583FF9C47A1EAF +28: 01F234F9868B085E9B1A2EC84738E2DB +29: BBCA3DAEAB24EF25BC7B623F4D9FD680 +30: 3956C880F7F7D94ABC259D3D86157F27 +31: 4672C2149054C839C537BDA1F5BBF8F4 +32: CF1E9ACBEB391062593BD88C7948F64D +33: CA5B4E867AE9D8BA2D4416C908EB99F1 +34: 36666180C768636CF1708CC5C85A6875 +35: 53E396D2755218675494C7AA515A2310 +36: C2B7D31A59A602A65E155F80353DB83D +37: 0EBCE19FF6FC03E327A2602F858D835E +38: E47CC2A5E6C7FEF185806E2CFB304D91 +39: D61F15FF75E0F523FA3872132A09AF42 +40: DCC25495052980986AE30756BA0417DA +41: 451BF5B7C1F1AED9F3D5E18A391EA4DA +42: 1B6B105C580083D23F3A8EACE41B7984 +43: 8C2F86CD6C86B67C9EBDCAFC5720E4F8 +44: 41360BDB3E4C6836BE0D15B659CEC5AA +45: F972104AD851BAE0AD963817A3F03F58 +46: 396095F7C102B5A238110DD3D6D4ADFF +47: F58391AEB9A5D8BB32A3055B37556E81 +48: A23789B146CE89C876F3C331901261D8 +49: 2684AF345C4B13FA154E93A3E2CD2A90 + + +Cipher: blowfish +Key Size: 8 bytes + 0: 84BF44A1442B8217 + 1: 3981205BDD22C01E + 2: 0ACC5CCBA118CD07 + 3: DF76980D5E089145 + 4: A8503E8D849C599D + 5: 5E56574687038F5F + 6: D63296B036996F50 + 7: FD2FD7A0669A9E7A + 8: BC6583720A962585 + 9: 4B38C2856256103E +10: 48A4FA354DB3A8A6 +11: EF97C32734BE2A10 +12: A7467E9C729F8123 +13: 04D2507F9C4B5854 +14: 57F76A4D406B22D1 +15: ED0A3B26D842C8F2 +16: 047CB457E9730CD1 +17: 9F13BB1A97BF5E2F +18: 628CA4F77161C95A +19: 37C7D8EF718DFD50 +20: 2C9A9C655B839B1E +21: AB222D66579DBE0D +22: 57950CDEAD6FAE88 +23: 67AAB3669431E403 +24: 6B35C87144F6B748 +25: 94C2E8A1DBC963C2 +26: ECD68F56EED1F78E +27: 2E7BE0B866B1D3C7 +28: 6671DCDCB3D8EED4 +29: 8ACBE7A2F77FBB35 +30: 0BF0AC4EAE284F93 +31: 29928AE5DC8A57C6 +32: 84E48C27E21264DF +33: 4EF0E943E4F48ED3 +34: DA155BEFBFFD2638 +35: 611EC83E0931FFBE +36: 3BDDEC15BC543A92 +37: D7B9564BBAEE19FC +38: DE44907E9F0A1F11 +39: C8638C0594D13614 +40: 9E67F1B15418BF14 +41: EDF531A083F72852 +42: 7E5F8F9A72890BB3 +43: 2A0B060E3EDDE9C3 +44: 9B4B0F6FE6511106 +45: 328658F222C7FCE4 +46: F6F1B50B4F9F9C93 +47: A620519E69952F5E +48: 24DA24DFE96AD818 +49: 226C43435FBDA34A + +Key Size: 32 bytes + 0: 46CDCC4D4D14BA2E + 1: C079641BD6584E5A + 2: 38828DF8B4C4920C + 3: B4ABCF6B78A721F3 + 4: 8E7E2914CBBA708C + 5: C0EBE7002C888495 + 6: C60F404DE7CF9B78 + 7: B29E843E1771EF26 + 8: 983033386CA6A09B + 9: 76F1F89AFDCF7130 +10: BED4E2114F4376FA +11: 879A2B9D19AFAB87 +12: 366201BC87532AE5 +13: 6F409580FA907A64 +14: F7A202F00A38863E +15: 98B0A9C79FFC27B1 +16: 1CB68D9BBF8A1A8A +17: C21A2C54E5471D23 +18: 76A81C3DFC149934 +19: C7A0627412FC323A +20: A034684D7058E7A6 +21: AC87722F27029BC2 +22: 36A6C2AF10245E3E +23: 1F85B90D11217EBE +24: 9C2A0C383A4AB7D5 +25: 11D5C689039CA179 +26: B0B38C7077E1450B +27: C59C7DCCC3B8A1BB +28: 9BC539F29208AC24 +29: 8546F17C77C60C05 +30: B189C3E92AF53844 +31: 3C7689163B8D2776 +32: 6AFEB9A0671156A8 +33: 05514E39F2990008 +34: C941E31A2A1F42BF +35: 87C3777C74A730A0 +36: 2861667755C8B727 +37: AF75A0312433B151 +38: F76939331E9C9792 +39: 819FF8C81FC7C8DC +40: 31E7B07EB03D170D +41: 696E5EC1A741170E +42: 6C5BF0E0BA48FEC3 +43: 6D751BCCDC475797 +44: BB5A91D0CA7E60F4 +45: 7F7EC0531C88B14C +46: 9F302392529B70E8 +47: CAC9A1A88F09AC1D +48: 39D56A652E02D5B0 +49: 13641D42BC126517 + +Key Size: 56 bytes + 0: 373C66BBA50EB9CC + 1: A4E8C602AE3A2CEB + 2: A59F08BA78502F32 + 3: D0D4968015F4E4FF + 4: 0D3C2F291E6C2EE0 + 5: 3F99F5DADAD5FD2C + 6: 5BA41EC1A506396D + 7: 0BDE3B5B50591D35 + 8: 5C4A6AEFA69A115D + 9: ADABFE96D6D159E8 +10: F97F0B9C88ACD5C0 +11: 8882A163F0F02BB2 +12: F00556C9F5A56A32 +13: 257615BEC96CC228 +14: D58DAEC547DD8B89 +15: E677F4953EC44097 +16: 20156D066DC37000 +17: 6F18E01C6FDF947E +18: C8DFF24F12621237 +19: 032F91C5119AE308 +20: 394194AD8BC1E5CF +21: 6F24E937F3925581 +22: 086A4510D95759F3 +23: 073204BADF0EE942 +24: 5BC8B8E402D90F43 +25: A10B7E9D01DD3809 +26: 22C0B183AFFDA506 +27: 216306AE6DDBAF3F +28: E275E1F52430A1FD +29: C3BDB49D588D31BB +30: B860818C5923B688 +31: BE1BC7A444B0E141 +32: E4C4B67900DBC8DB +33: 36D7B7ECB6679A9C +34: C1EAD201EE34BEF7 +35: 9ABBC877CE825B14 +36: 3B211121C0C3C09A +37: BE3B34FF2E83F5A7 +38: 46C2B3E628A53EAD +39: B7E7DDE16C7DFF62 +40: 3C9A14C4226EBCC5 +41: C5FD46242DB29704 +42: D45A96723FF62201 +43: BB015D10878CF70D +44: 71DB021BE398D41A +45: 06F52D237F06C260 +46: 3552F47E8CCFC73F +47: 769E33828AD5D88E +48: 659861DDF080AA67 +49: CF7A13782F317342 + + +Cipher: xtea +Key Size: 16 bytes + 0: FFC52D10A010010B + 1: 9CFB2B659387BC37 + 2: 7067D153B259E0D6 + 3: 0A1769C085DD67A9 + 4: A9D781A1A7B4B292 + 5: 6FEF8300DF395062 + 6: A67B66CA99B9121C + 7: 006E657E1DAD46D3 + 8: 2D63322467438A5B + 9: 4F67A826126BE01D +10: 852C6FD597EBAB00 +11: F8DD14F59FF44A20 +12: CD4DC4E92B5CD40B +13: 802B89A3EFB75810 +14: CCA7D920F69A5491 +15: 0DFF98CA4F71CA0E +16: 80118F2AE4E83DE8 +17: CD6935285D45D83C +18: 47B4613483889187 +19: 87F3F1975B8618E3 +20: 49BF15EF40C72DBA +21: F850822AD58AD1CC +22: 9701AD2EF51FD705 +23: 705AE7F6FD60420B +24: E885CC84A9866B28 +25: 93E0D712D27E4E22 +26: 8C9CE43E517D3324 +27: 31004841AF51FB0E +28: B250BEBF0E58457C +29: 78290B6D83D442E9 +30: 3EC72388709CC6E2 +31: 099FB875AB5CA6EA +32: B15E20B58F5E8DD0 +33: A41511E198E0B1E7 +34: B8B5CDD9607B6B40 +35: BEF9624E922DB8AC +36: AF198FCD314D8DD4 +37: 1A37E433C261EF9D +38: AB7895A2E9D41EE4 +39: 4C95BE8D34A7D75B +40: 0D90A8EB03F2852E +41: 9AAD1D630D835C67 +42: 6AD88003661B2C5E +43: 4FA7E2CC53EBA728 +44: 862245D794441522 +45: FAB262C13D245B3E +46: C0A29AA315A5721E +47: F98617BBEFA6AD6A +48: 6F84EAB462F10F36 +49: 30850051303CDB96 + + +Cipher: rc5 +Key Size: 8 bytes + 0: 04F6B9B18E6828C1 + 1: BEA50D165E50EA04 + 2: 6F3728FE19F09B03 + 3: C682C26278B372FE + 4: 78BCC81E144E1B0F + 5: B62775716366450F + 6: 5BC49690F97CBCFC + 7: 359414E9EACDE379 + 8: D3331D8ECBF684FF + 9: 13129FB10EAFC82E +10: 7F29218421CC4B5A +11: FC225A4F31A75162 +12: 29BF8BFDA8A15D37 +13: 6854AC5BD98EEE95 +14: DEF05AB6D102E992 +15: 317C3EA6F0600016 +16: D6F3658B2E80B77F +17: 7C1DF7ED6C92C23D +18: F8665145BAFE28C5 +19: 9D8059C34B79F0EF +20: DC8D1617D3EBC7DB +21: 2D8FF59FCA19BE6C +22: 5C6956743715EA13 +23: 91160BE1F4F3D4A0 +24: 1D482C2359EC93F5 +25: 9C21D1A3755A7251 +26: E48D1BB926D51E63 +27: 08A054946263F617 +28: 9C900BA37199B7C7 +29: 0C6C58743EC83082 +30: B24197EEB5603D3D +31: CF5B735F8A492E49 +32: 337C504698BBE553 +33: 3A2BCCC88BE9ED51 +34: F3E9241743203ABF +35: B67BCC625815C585 +36: F8E96E4EEBC2566C +37: E27D162006C67C8D +38: 08CE8C1A5E3C169A +39: 0CF8AD04125EFCD8 +40: 6712F9F044864FAA +41: 0FD465AFFD64085E +42: 6BA8C82B3974391F +43: A5FFF24CE9659357 +44: 0947F81E1EB4970E +45: DEA966CA50243067 +46: 1F1BE4866F48E39F +47: 03A7D7CE793F52C7 +48: A1FADE3F801B414A +49: DE7DA6D14A50E305 + +Key Size: 68 bytes + 0: C8704ABBDA9624EE + 1: C719C645E301FC16 + 2: 32D82553B0E35EF8 + 3: C63C77EE6C2A6E36 + 4: F84EDA1E77ECB5F0 + 5: 382C1E72AA1FD1BC + 6: 6B00939F535F9C83 + 7: 3CE0825AE10C2B0E + 8: 1F9E7738602BDD0A + 9: 9273E7933CED0B0A +10: 4CAB45EEA45C32DC +11: FD0208C6A89FB519 +12: 520D8E6912E9551D +13: 5B88684544868BD5 +14: 32AA2A8EE58135D4 +15: 281045702DD38766 +16: 26D68E073C996747 +17: 23DFB9E174D86192 +18: E32FD5AF5101E45C +19: 3DEFB679670A143C +20: E616394D859BFE94 +21: 217B9BE0ED47DDAD +22: 4F7901A5620EA484 +23: 6654C042783F5737 +24: 752AA74BACF9BE65 +25: 2FAEBEB8B325F89B +26: 6FEA020B058F32CB +27: 2A32682A36691665 +28: 338C8AB628A30105 +29: DFAE9DD082DFE38C +30: 51B451C29DBA19C4 +31: A2993DA9B8C1D5FD +32: 24D92FA331E2F93A +33: 821A961C0524C89D +34: A07BF305EE8964D9 +35: 981652361262C5CE +36: 3DD770C3761B695B +37: F36359AFE1C8A07C +38: BEBC629B8938F4A3 +39: 2E31DC53F77898B3 +40: 52E4104C4E8E6901 +41: 75C912DA610525EA +42: 2F280F70963F82DE +43: D7E3FCCA75AEE5DF +44: 8EBC7E825A14A2BB +45: C1138701F64187DB +46: 1294E21ED2550DFA +47: 577820D772BE2C8E +48: 48CE93C46BFD33CD +49: 3B50D264382E03BC + +Key Size: 128 bytes + 0: 236CF0A207576E8E + 1: AC12D8F1AE55F057 + 2: CEC4230F747B547A + 3: 61EA1B510D033B26 + 4: E064F51998E20804 + 5: 6247797DF02BAEF7 + 6: D25A766244063A7F + 7: 2C2B3FDDA0E07067 + 8: 04EED646C3F6FF90 + 9: 05487E7702865E4A +10: 6C0A92AC23ED07C5 +11: 6E54E768C797F797 +12: A7C53BF7B252A884 +13: 731052795E12C80B +14: 3E4DAD15A826C43D +15: 10B1191B4012C2A0 +16: ADD244B33AEAEF7E +17: F6CC7B5F0885E056 +18: E23489F3B7BE438E +19: B0C27661692FDE4C +20: E81CE014DA769F07 +21: 7A8BE0D2D52623A8 +22: 082F444E00D5E127 +23: AE42F684ADD1DAC7 +24: 9061BA686F76A450 +25: 9BEB7141B8F6F5F0 +26: 38CBA9933AEF85E7 +27: C66F4245901CB341 +28: 8659AA47E6B06BC3 +29: 357AB20DCE2DDA3E +30: 236689C2F36976D9 +31: 331EFD7D5CF7AD50 +32: C373526C2D44DB80 +33: 79F7ACBA770F5C92 +34: 64325C5A67F364F6 +35: DF2F720829FF1694 +36: 9EE17F47ED487BC6 +37: C41067896AF4CFC5 +38: 5776E1E5FBE59933 +39: 07A05B1508B739E0 +40: B19EF72A65B3C035 +41: F8BF5FF4095C0173 +42: 7F1226C6CA7B4072 +43: 8A6C8F26A97DD33B +44: 62948A9A627E98AD +45: 9EC58E3F8A477D21 +46: A656F285AE0684B4 +47: 8489690681A53EE5 +48: 940915E733721837 +49: 1221956BCEE0143B + + +Cipher: rc6 +Key Size: 8 bytes + 0: 6533F7041D69B9B883A5305180A85520 + 1: 496683D6356950E8F4AF4582630BE46C + 2: CA421828FCFCEF2F042F6D81F14CBE76 + 3: 92DB67F2F057858FC806E071D239F245 + 4: 203CDFE0C36434AEDDBE2DA68ADC5EF0 + 5: 8EB23BDBD58A279C1F3BF75199FC9E34 + 6: 8FA8BB4E772E09DD1EFBE03090E77FF8 + 7: 2018803BFD91D157AE20C6E8FF1894B0 + 8: 267319634294F0684AFA7B26EB612B3C + 9: 108745E1F2E80864D9043582CD5550EE +10: E4F9EFE5A6C426BB719EA17174890D0A +11: EFFD4CAE649740B3309692AA19ACA227 +12: EB909E6D0789F649538E7EA1686FC0F9 +13: 0216851E23EDAE52D9964939DA0A7493 +14: D6A9CD3429D1679D26A9599EBDE5409A +15: 5DCDECA6E89A7F0EB40649EFDE6420AF +16: B74FD556B06C07BA8D9E517348CC66CC +17: 9A22CB5B73EF1DDE68A5AEF1B1510ECC +18: 77F78557143E08A7449A75A13098FEF8 +19: 548FE6700BD17D0AE247B07C2F1AB0E7 +20: B7DFD8CB428A36733BBE9A51CF45C072 +21: E7E8B7AA2D93E3DE99C543A473CC6760 +22: 3FA5821248B0F0AEB5CF00EEF7958F5E +23: 0A655AC6C51DB33849BCDA72DAE106F1 +24: 9EE93EAB01E1A1DC57B698C266469481 +25: A7D398720E0ABA2D0D143D8306FD5AC8 +26: 98A46C94125BD2E5600BD26EEA420F2A +27: F4789EDC3C50BC4186816F14A86403D1 +28: F8AFBA8EC652EFDC3AF5EA5CFE143E16 +29: CEEEBD4B6724A30E1859A5B4EF9B2B3D +30: 766715B4C4FA7CD4B365A2A67C79E48A +31: 92C5EB7BE61155D79DE0A6F55715DA22 +32: 42CF0C9B2BAACB085CB1603688037D0F +33: 6C4BE816F7B573CCFA8BB6E399EEB17F +34: B6D7E606CC99D267ECCFDBC006878691 +35: 2048B58B74F9A721B2E33D2EB86F5991 +36: 3E458C1015ECB08CC7B8980135E71893 +37: E4E28A032CF2F3C8262CD4BBE7A4CDF8 +38: 701EAA449AD9E5AF81DF3F436AB25620 +39: D1C3FB7C16F5249503EB389A692B112F +40: 7012790DB65526DC87F9A2BF0FBB5664 +41: B782A3104FFE65DDB340F713ACFFE25B +42: A155F033E4536FB1176EBDF9EB5FEC4C +43: 8898BCC7A008127014850D5529327352 +44: 8F4B3BE150FAA0371CDE69891E52A3C9 +45: D371C8283F68DE983C98D98A7563B934 +46: DEB679915E8F0D0B65B37918BE4596F7 +47: 84D74F7FA199304A47BB37B8AF893CF0 +48: 5367B0187496539F6DF6CCE0965B376D +49: 4B9C6011D43CF2D8FAFA2E7105D85024 + +Key Size: 68 bytes + 0: 6BBF763FF30876A4BBB68A7E7E290770 + 1: 59852279E82E98B8B680E5CEE12BB99A + 2: F96989565E5B163EA483FF74ACA22DC9 + 3: 221F7A410F5AD73C1C67DEBA99683E0A + 4: 55F058D1D9B8C372E2A28AB6E953A851 + 5: 24A8F7E07620A55D69CC3981B92E5CCE + 6: F4D9DA95BF66FE28BA3A84E77E62822D + 7: EE7EAC2BD34DDE6F83E6D4F23C0A49D3 + 8: 4218AA697FB7C5D897E66EB00A9FB489 + 9: 55A8CDF8608A3B1A6B14275E2258A096 +10: 18D50743982F5C8A5C528BDB5896CDFC +11: 391403B889F0CEE865893EBE9F1BF90A +12: F3CA9C30C163C510432D3207DB6967EA +13: B14B6574DF53257BE4508DBE78843B47 +14: F52F1E5FD6FB19C1F5466276F9C33A97 +15: 9D5AABA86E8B65E4F633B6EDE17516E8 +16: 9038CF746F722DA1A0C34461359FD378 +17: 398E317E9CC074C2293B59598F72EA64 +18: 9D75D897D487DD2B5BC534B4B223ADD1 +19: 6C6DFF734BFB9700EDD6B3CFC6E311F7 +20: E27591407CA9771F227A5B6B3A77C928 +21: 1618F15FFA8E2692A3B3EF8EB6151427 +22: FA426AC6161F31F0D63FC9DA97A6A393 +23: 1281869E9959DED2CF75F50DA7FAB66A +24: E8BF17E4B76D6DC5C1D07DC80970665A +25: 9A869B6C5EEF391C7E7C4585FFD9FF3A +26: 59564F799AFC984D39A8168D1A30C8C8 +27: 1D3927AA2E2C48E6CFEF88D04ADD30DE +28: 39BF89DE1365DF15A8ABA86856ED074B +29: 0CCC4A4DEB36A000E7EB271F5EE54543 +30: 26476623D35A514B8833D868426A2BE9 +31: C3C85993EA15AB2D056D670707851802 +32: BF5F7ED18E1320BAD536DCEDEE1A9AF7 +33: 337BDC5FF0F7AD44E6A3F5D6712BD5DF +34: 7DBA76B3D9C818D0CE1A530BC79E77D2 +35: 20DF55E617CD2598F18534DA7A22B555 +36: B0A0C1BDF9E81B4F07F47D31A9CC8408 +37: CB9586F4B27F759B9B9C6C7DB01D26A8 +38: 1E79A2894906A64098AC43799CEFED38 +39: 82FA120F237EB0B3A1F8B52379B8346F +40: 3DB9848603E3B1134585E5C9001D119B +41: A750875900E244996887EC995131D151 +42: 12133748D3745F77C161470A921F73BD +43: A265C351694574B44517FDAD8816133F +44: 5E50CC8281C2A69FD376250D99620DD3 +45: 443ABBC1AD5605A0BA05B8E6ABA5D2A1 +46: 73546A87B39C54F0639EBEC118ADA007 +47: 380244C822817453C75405B727D67C4B +48: 73F1E23DFF05EFAB5D39E503031C4165 +49: 8030071491490590A8913AE4B5D082CC + +Key Size: 128 bytes + 0: 24B06811BD97AE9512B3799E3189DCD3 + 1: 92DBA6269E880F8D8A09143D792A46DE + 2: F956F459C333DFBA4C6A309C613DD661 + 3: C31488EA551CC0FC8885F6817CA696FF + 4: F59634FE907F9DF9467BD1059F82DAAC + 5: 051AF11DD2FCF742169B58A786128CE7 + 6: 87326A3A4A98CC15B23DFBFFC5AE16D3 + 7: 58FCDE2E88A79D5682729ADB4D971142 + 8: EAA787D68EB68CA79CCC6BFAC3BE9247 + 9: 8BCF6980AEED36AF38B68A50DD454AF0 +10: 4B0E31AE48E903DFF52939800BB16DC0 +11: 19766AA929B40840715D53D9170C986F +12: F9CAEB36F03CE7B3BB363AC7EB3ACF99 +13: C8E34A6BDEDA4DB836DF3D863D02A6EB +14: 370547CEA441FDCBAFD281A8653BE2D4 +15: 77E0F33343158A8C3AC3C6D14FD69431 +16: 7A985B1368F842C644538C654D081FD3 +17: 60E0C8933F43D40003030196E8E881AC +18: 3473474B58AE6BC7582ADD7AE24711B7 +19: 75936C8D46F6D5AF5C7EE0E8DCEB5AB2 +20: 4A04F619FB0E05F7B07C43F4B9F2E134 +21: FD53A5A7F4F0B9D933E38D9F07AC88CD +22: F62EE43B20F582AC77879AD7E66FCCAC +23: 4436AD771624896683D7D29E8879F89F +24: F88F3C0EF2B9FD0CA997BEF17787DA2F +25: FF5576F42CE9A0665A1D6A2420A691D0 +26: C077D6AEBA65B61CD1A9AAE17FCFC04D +27: 84D0D7C52D6DB3979BC3F6F34456CB91 +28: F163121D9EB7569CA7DE3B7619E0BE51 +29: 727D23FB43215467B57DC67A8890CF26 +30: 60BA577F3C6627267D7B33E693FB7BCB +31: 82C66B23586CCEA2AE1480B469B3F3C3 +32: A65092726D6CF2F77CE00648E2D117B0 +33: EC30662CBA891A3380B846DA6C64024E +34: CE1B253FBCE36B217ED1EFBAAAD2E783 +35: 9D963CD5E65A9ECD2DAEE93B6C6C1178 +36: 1B8E3D07E7BD4BB4248B6A7DF8935980 +37: DBC3FD5888B80C4CEFC6C5E170E271CE +38: 307CA8CDDFE5DA152B66E10346BB2E1C +39: 8858250F933650D978B403A4504EA581 +40: F06005FA6E56E0C0D96988A3FAD359FC +41: 816CBE37FDE3719804DBFD093E3FD87D +42: 4878C07B127D696214393DDC66F5EB36 +43: EFBA6045243050C0D8D82046B17008E8 +44: 3D30C3E5892D32BA3C685DC5B186E959 +45: D4A4C41F0E6687E4021FB90D7A8A9F81 +46: FE1057B2013308C4CE839B4186F43B4C +47: D7333AC65F66ED6D4BB8D069E265020F +48: 33C262F58BF0D91DF2047E799BAA5F37 +49: B960A18764D7A6E17FA1F88487EFF192 + + +Cipher: safer+ +Key Size: 16 bytes + 0: 7D42607880B424C27E5A73A34FECE686 + 1: 1A99D469F1946EA46523083FBAA79CBB + 2: 831385E400FD681C8A30AAD9477F1ABB + 3: 5C1BB8F259CDEC2C1BE0B803C7D9447F + 4: C57C1CBB18D87FCF72A87B247392752D + 5: 1625183B0C595A33FE0E8AE0DCE40ADE + 6: 4AF3A9D6733DC4FFF3422AA5BE5ADC94 + 7: 853133894C87A23318DFAD2B247FBFF3 + 8: 8C7F68E01A8413D19B9A479246E54722 + 9: 8620898ECD3BF91A47CC54E6D9987FA7 +10: 33F12ABB7CC6A9041543A2073AEDFFA7 +11: A096E46F2834F79C096D0B655EDC9A63 +12: 3DD0D7824A87C9F5D8D25F5AF57E70B7 +13: 6B7C99E5CD29AC1C5A8D66AB460E5AD5 +14: 95A9F6009AB4DD2AC7E8E45F36D91E9C +15: 60CCEFC6630329C341782B17365995A2 +16: 0276C96A7B1191BC16C8A9C98468DB05 +17: 1F352CB77C21139C058837B8194E3E64 +18: 2DB8E340F58844705F217551782F6B4D +19: 34E99832E0722C5AE8F0CA1A50E9E7E2 +20: 7E1538DC10C1F56C3723A87BFD127743 +21: 36B9714A8ACDC8B8A17E85E2803A8C88 +22: 11848329B0DB9DC7768C07D95F0CF662 +23: 93ECEDEB4C6369AC56AF1F49345720A6 +24: A3ED7F9D17067C2650728E266B623124 +25: F33574590B435D1DDBBA925F0D0EA8AD +26: 87E542DBD40DCBD80C4AB52555C264C1 +27: 6D806991AB8E3604C8267AC1EBEC2E21 +28: 4B7333F87EBB46BB2A8ECD392C85A12B +29: 4FF49ACA62898F558AC065B66CAD0234 +30: 62DE7B2133B09544EDD0DF66DC4F5E2A +31: 82195B39FF7B8A85D7F0EE52D19E510F +32: 24FA56176A4F0B37F851CBAB176C9702 +33: 85FA9230D9B93CDCC0752FC738211703 +34: D441132032BDAC6715F4453CBC2434D8 +35: 438AB9BEA8A900368D84EF870EAF7E84 +36: 433BE5BFE1529BFA7C5688CFE3BD4DE5 +37: 2A79FB6F37AA08533445B8BEA5098EA2 +38: B9C986EE45D204B6A1CA152944912C9F +39: 8289C9F78760D02AA71873FD97E2ECB8 +40: 48B0D1244523165055BE9A5E95CF852E +41: 471E211E5E784C2AF476DB3CB555CF35 +42: F290CBEB1F1009D250F7B12E044B80C3 +43: 1B9796D80C3976FE3071B1C01154D42E +44: A80E21A1A1007B69E8BCAE728BBE6A92 +45: 652058EF0FAF8549424F998669660931 +46: 89418FB4740E9801F6DFFEDC593FA32E +47: 907561A69CFA117F167A52B88777D89C +48: EA2EB4B1EE739320F99894B476A8A51E +49: E627E64AAB6E2FF6B99643A7FBB84BFC + +Key Size: 24 bytes + 0: E8975F94A8B1392FBA78CBDDCC8E8F08 + 1: 708CEFB68A0281AEA424B3D4698D2F2B + 2: 21A0DE56545BC950FCE4DF209C96CE6F + 3: F2CA4103B703264D46CBC09E13D5B8EE + 4: 2892101077FEE427C434CCFBBAB598B5 + 5: C2F191CC5C681CBFC098B264C479B2AD + 6: 308C3B794C8A7971BBA96FE4C727F48E + 7: 8A4F9D4463B5DC4DD461ED0763CDAEA2 + 8: B7E1BBBE455AEDF18329A6EECD6E222C + 9: C80DAAE7FBDF56DE05A897FBDBB53DEC +10: 6A3D38758BF0390156F22F83C20F0262 +11: CA493DF771E37A93822D6117ED14B60C +12: 623012748826A08F3C59B71FF3D66327 +13: A283BCB126B9795D306B129035BCC2DC +14: 3790A6704BB0F119139A0264F7E8B2C8 +15: 9B369BBC095428EBD712517B2C4D06F0 +16: 0F488018162193ADB11E4C39CFDEE0DC +17: 8AFB7C6FD7D6DD64C2C77DA3A0D91EE2 +18: B8BEFA241BA339BF6F059464C533F9F0 +19: E76141C8CD54200FAB2F8C2B76AF5FEE +20: 80B4FE57851C0240D81E78DA8200F195 +21: 8BF1C690EF5FCE7ADC74E31C24F83F5E +22: D30C4F78703BDE91750E0E49FA0E8982 +23: 86C5D1E0B88EF0AF9B899850510000EB +24: FDE727442BCC0305A7B06E6EE179D836 +25: 0B4A719342F9226FA680796887A98FA5 +26: 980D4BE9AF3E3CF9D4558478D1DD03AB +27: 03ECD11992D3D5864B8D1987966BA544 +28: 8DBC2931D7D17657BF38E3931F486850 +29: 76AE069E39FA7308BBF507ABE35BC1E8 +30: 9541B59CE18EA255CDC06DFD3FFCD1C1 +31: 5A382748AE3641ABF6D9CA24A35B2002 +32: 9B7A49DCC2CFC5A6078AB41E6F62B4CD +33: 91B2EAC878E5628DBCC7C876B91B73D1 +34: 31125CFFC41A0D3528FB16BAE761C47A +35: 916D2A769DA002ADCA8C87F8241BB50D +36: 681C3F601EE5D82F9B040932F2FB4AEF +37: 6B6F32E5EAC2F424074C33F7C988D5FE +38: D15A5FDC2A4956DE61BA6E1C98867242 +39: 0747BCFE1B979E947EED5225FAFCA44F +40: 133B43C85CCBC360DF8649BBBD2EB45B +41: 052D943062A6D475D30100EA412C30EE +42: BD6401C591D585F4A82CDCF678679D5B +43: F95D1A5E338F56760C425D972D67B57B +44: 9B1569308608CA00BB1E2BC9E20289A7 +45: B6454C52C64F64D69F1D36D2D224A222 +46: 529B5B013AE3F37E38BE340D1D200A64 +47: 1B65904F177212AC8E9ED4D8DB287810 +48: CD5CAC56236E0B9A25A5D306F12D8C4B +49: 01DF7E1D0F5F7A5DAA0B379388425126 + +Key Size: 32 bytes + 0: 7FBC212996ECE9CA2C4D5BD88FA0B3D9 + 1: EA3D788C25CF3BE7F4101EDECF23455B + 2: BD0B98481366AE0869ABA11DB18D1E95 + 3: 53393E2B757C90489EB6B47F67837337 + 4: E1D350640CCA6C13648C3B57BE00B950 + 5: 951E1EF99E6DE72744A9D8D9EBFBA94E + 6: 433E4D4E64B41818097BD5E2EBA01D8E + 7: 8FCBD07E303B381B2935FB82CA0CBF13 + 8: CF46569005BD968B9310149E892B4D69 + 9: F1B672657C2657AD53BFFE2BA5DDE1D2 +10: 0035337210703240F9CF2F5A9184FDB7 +11: 773951841F77DCF8A6730109DEDF3E9A +12: E47DC0FB381DB86EBD208A0D649E7B03 +13: 0D9E34ADB257146EAB95AF14636301D2 +14: AB5D5C106E52AC7662C26F9F27F2CD55 +15: 6938F205DC23C3500B7723281E9F626F +16: 3CABD52558D7F418CAF6B41CEC334DAD +17: D2192F1E5AFC3B989C42C396B3764862 +18: 59D32E3A41141C6CAA2A8F44FD587D94 +19: 483CFECF65D71CB2994E1C12A1A7F907 +20: 8F086AD81B1FD5B13195EDB4DAB7DC73 +21: EFEB1328CE7AE6A63E7D8B3ECA9E12B9 +22: 362AAE308B3BBA588DBCFBB7197E693C +23: B817A136EB30CD127B5015A85A7B6E95 +24: 03796E7F244CC916BE02AF61E5FEC42F +25: 5854F2889CFF44B0688718C23B0A822D +26: 0F772AC6E37364AA7B844AEACB33F4A2 +27: B3E95F5195BA646DAF333AA89130451F +28: 911A32AF7CC44309B37D75E158A4AB18 +29: 232CFE228EB72A949616B307C2BEED15 +30: 7C8989F135B8DE6FD26C7792B8354F35 +31: E79231779BFB9F792BD179C0625280A8 +32: 015F6CCAE8A1275A2E836A207D8254EA +33: 4EB94709245CE1FBF7C6D9587FA92D40 +34: 63D82005320F974EFDC4C021FB73ABB5 +35: 0F15B2E8E389C2D59289D7DA41ABD07D +36: CEE7FBBF766540D4E39903D0494DB797 +37: FB564C18A15D53108C1954FCD3518FC1 +38: A67C5F4A4A95AF2BD8E4FC1182B2EEBB +39: 0D354E664C35B9364E4EE9DB8DE0CA76 +40: 3295826D52F3B980B50EFF3E9317F1CB +41: BC65592A9C0BADD84F363A175EE6BC54 +42: 58DE762ADA621FE2A7A6A83F68E93213 +43: AD774FC8402F7DDBB881B703EC836057 +44: F1C95AD5E004AF35AE315AE88A2577FA +45: 968775A2C3485875B024B008D96182EC +46: 623E736238B5800ACD9B67D76C84D236 +47: 1C5E9F65D43343D743E50C80D0E0F648 +48: A62E4A197E15CF90C2569DC38D9FC915 +49: 165B139BE483A71381B9A8E93D9473DA + + +Cipher: twofish +Key Size: 16 bytes + 0: 9FB63337151BE9C71306D159EA7AFAA4 + 1: 8CC5A931DEC29B4C7D85595D24FF8405 + 2: E867FC0E144FDEA24FEA88D22D8776EA + 3: B450A2969C67D93E1AE3A4093BA4C48F + 4: 7AEA41F9956149F336612E868E42B3C4 + 5: F201FBB730E6E58CF9E5AD1DC4844C4C + 6: 13D8869E66412C6C288B5D7F37F2D94A + 7: CD57DDDDB782C0A04C40E47D920799DC + 8: 65371C8ABC919EC09004A7D63D9302BF + 9: CC31DFD3B7DCCC86866CC79D45A89C3F +10: 541D548D311714EF8661BFA721568D16 +11: 269F3AA2D2D10DBD3DD3992BFEE23C05 +12: F86DA5D73AFBA94A9D592D02B5855D25 +13: EAD8D785B50E036437E39F3B27DB4657 +14: 2AD0A13C493B9F3EDD259E11A495B205 +15: C05F9D72AA384F05B28A3519AF218CA9 +16: D442072F588D38AC8B9D447762E9FCF3 +17: FDD3BFB91EFD127196FF9F19ADADBF28 +18: F56717661B424E41D7DE1CD13E21DF89 +19: 0F6C952D9BE6CA49B5147EFD44455A92 +20: 6C214935726364F2766BE7B4C2B64362 +21: 5D5316D7E057FF481CCC10C7452D1A17 +22: 56C78DBD802CC9B040446A3EFF3F12AC +23: A38CEADA8448DBE29C2D11DF2A487715 +24: CB2F786AB8063350F3FAE11EC8C65A5B +25: F5B7298B6F558E2C4FCC11744AD22653 +26: 01BF89C1B48C5F6918FC6BDC10B12A21 +27: A031F25AAFF294EE79220BC76E73E52E +28: 42C94B50E12499DA35F14BB6BB6E684D +29: FD68B6840DC9A271CDE2032EF0200295 +30: A9863C1B04B3FE3945D29966F67B87E2 +31: 6226D4CEEC1E8AEC1B7B3E13D80A83FF +32: 6100A71B1E3ABBBA48A9ED280DD1617E +33: 5CE93A26D4EFF0CC7DFA2DD43A511871 +34: 282D165BFBA0F7F229161BE533BFC4D9 +35: E6AC479970891392972B2845C949A068 +36: 4E4A887368F8443BE51FA7CD16CF0B87 +37: 121AFC81AA2750572B35D100BDC34DB5 +38: 7C41FA7E0A18A87E44BE488F331B35E0 +39: C8847D295E1F505C04E2F5CE2CBF5E00 +40: 4686EE8628BC1BBB92CE825F04B1D5E8 +41: 397DFACD19C283B3FC27D3FCBE952254 +42: 815B6C69608B5A379E3C9E67FB1BA15A +43: A73E72B912EB3AA4929E9EAF73A448BB +44: 5BC4E2C88512BCD55408CC5AEAD15A91 +45: EF20B2BF297456DED1F4AB7BE0747902 +46: 3D876135E19BB56B98050450C6B0FD06 +47: D68100E1BAD07B438786337C0957471D +48: CE85A91938049B5E21C983F7C45ECA3E +49: 9FACEFFB9D08BB65DDC34E3C575B8442 + +Key Size: 24 bytes + 0: 95ACCC625366547617F8BE4373D10CD7 + 1: 99AEB25CCE73B3796C351A19791ACD52 + 2: 56B9D6689830275C1A3E4266B3D56D53 + 3: 2F5F822E11F087BCB8A0F428414855A0 + 4: 65400F729990FE175AAA894BCFBB1A59 + 5: 947BA33D20194BBB0D4904023FB32FFB + 6: 116B0C6744D215AE98DEB1F9FF1D36C0 + 7: BA6964C101FA044ED06877E46D540850 + 8: A36B18526FA0004CF557C99A3AC1423A + 9: 573099674B8AFC2DD6424A2E4C581B89 +10: F46169CFE9496A2696A93EEB7EC561FB +11: 2C64BC052898F3F3A2B78F2591F2BF1E +12: E8A0D40B08585459199DD6ECC108A490 +13: 47927989BE5EB55B9A0F294C04FF035F +14: 54A3024E3AD86005A2C44E4B8BDBBEFB +15: D0AD51D1DADFAD7ED0EBCC756DBCDCC9 +16: 5DE698B7014C34AA6F0099CBB5937A20 +17: 9BA30F49470C6DB9632C5EDE34F8EE73 +18: 0BDF558A2AE9298288E60616442D3408 +19: 25F6DD23BA4E090E1CFFA6EE3487AFA7 +20: DAC5FB99E299D2672F79F0C38E177D83 +21: 58CB113430895C9890D96EA60E3DDC23 +22: 48A0771F0049B776A44AE8877B57EFFB +23: 2F12B26A4BF7065076417530CDEE14CC +24: AA6ADCB0176D5324C4C1FFD640D502EE +25: 384B52A66F4C7A70ED36091BC3FEA09C +26: 2AFE7ACF071C6B0FD69930A09D6DD5E5 +27: 9A2DB9A5E7712A5BFB095D2C09453CA3 +28: 716C0EF522A13EA05A48F16BAD3FD10A +29: 44AB46F3CCFD02BDD2C77A332293A4D9 +30: CE6AB27A0F60F410B1B3CACD9AB923A8 +31: 69EAFAFC171C55D1D90ED1C6E1F3A48F +32: 5EEEB0B7833121AD7D27BCFAF2D4F8ED +33: 47133445A4EBCC60E27B29FCC160FA75 +34: 9F1BFEB9715A20D5FA7BA3BFF1A27BBC +35: 516D4615F07756B4DBE7D37EBBF4684E +36: B88744E53073BDA0F1B115E3DB224E83 +37: 1B77C3D067BBE00420450BA5CD9A83CA +38: 94B87AC96F8CBFF36B01A68E0651E591 +39: 52ACE87A1A8E46655935536FB3701290 +40: B406BB632D5B7985400EC78D621C8801 +41: 20F9ABCBF97A9917EC6C5DE3CB2C925B +42: 539A8AF920833F9E81A20A6D10543176 +43: B79AFB8BB39B0351094F37C6EC93F8A9 +44: 5830BD21289FED3F95C3E3740AC6C5BF +45: 86C4AF5839ECB9860B175642ADA32895 +46: A6427E5E08CEA2A50B8426B063AEE189 +47: 2E872129B5BC5F535BCE2B81F013A103 +48: 2203EB9B2BF51FC2025549D0BF1924A7 +49: 6A5E383A4FC78F6E03B9B276F81195BE + +Key Size: 32 bytes + 0: 8EF0272C42DB838BCF7B07AF0EC30F38 + 1: 9F8801E94E41A7DC875665663BFA7912 + 2: EBE2CA6B45A0BEE83B54402E1A843A3B + 3: F6C5A1187AEF4B5A88E97E866CD757A1 + 4: B3E62CD473E53812EDF9ECE875F39F5B + 5: D8C38B1EC23264BB7C42B5589C1300B2 + 6: BE315EB75B944EC9E51F5EAE65F70BD2 + 7: D4275409941A44993037364886B60598 + 8: FC34F1D4E9C4A634C1349F6D4E9AB94E + 9: BE712387C59A40A8A35F854333A0302E +10: 1F1FE164834BABC71DBFDFCCA7D2B4B6 +11: BB2413CCB5347B5157651819E698D988 +12: 6EB5523A968ECE965D9AA4B975D7C2EF +13: B5DD49AB7E269F9D8516FB57EB47D57D +14: 74F5D81856F192D49A70B3743945BFC0 +15: 95437BB00D57CD88BD52DE0A66D934C6 +16: AE4804A975D67C6B6F99176F407AAA3C +17: 5E5B2FB9B2A028A5467B56F8BDBA6980 +18: 8C617FF1F9C50A36BE2EC19A629BA96B +19: E3401F7CBE177A1D224117894E7EA08A +20: F8451D9DD31A08BE828FA9AF39708921 +21: 5BE66DD577826804817B85A07BCEDE28 +22: E426227780943AA1A830B7E7D7F7CA0A +23: B39C7277C3A5CA21897563DBD8DD6D94 +24: FA9992385396F959841D1E0E68CCE00D +25: E1DE89B1DD5CC31685558A51CC731E6C +26: 64618455C46C6FF117F19FF300B3B557 +27: 882758C02B3C11D406A21012977D4BF8 +28: F948B62F8038D3A3AFB73041B2F263AE +29: AE3BF626020D2877052B90B31E70B8A4 +30: F1C6DBBC166985C9EC2E1A3A61BD8E75 +31: 82C343FA36B6D4E9E7AF6D0B7741FB09 +32: 0BFB756EC55AC63BEA71E4A8187C2B10 +33: F1941AD10BE60DAD3FBA33CB899B63A3 +34: 18236A39CD34743DE7B60B2575A9B204 +35: AA37FBC2525F74710D7561D316E8D90B +36: 413E0F72C2B349FE2691554F77162B5C +37: 5B9E6F98B2CA0F637E463BE4A6EFD39E +38: 1B4A4CA36DC60D51BA981392D6070379 +39: B1E26163A90F339E33F86D252EFBAB99 +40: BB98F9F844FA81B25ECC89A8482404BE +41: CE142F512A42A28F4788847B971AA7E9 +42: C5CE782936F3D28C69C2BD45FD7BC117 +43: 9B6E142582E0A309EDB550DED51238B0 +44: 0D9D80C01612977FF3A2C7A982D0894A +45: A7630C752B1F787B07C382693334C6AF +46: 9F24990F270D575881C746481A59C245 +47: C38B5E11479C200B5ACE1D6522FC6B1F +48: 99118D8114D24B6559CC5D9456F1BEDB +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 + 1: 7DCB9C9E50D15508 + 2: C724D535853CDE79 + 3: 113AFD4BA7D3D7E3 + 4: CFA06CFB93C2280C + 5: B3F291C1AAD9CB07 + 6: 606F74D9AAD4FA71 + 7: 1CC3F7AD551C5F89 + 8: 43F8772BA6C6B60D + 9: 2F933E12F57689DD +10: 2BC1AF0D5571D17E +11: 4123AAFABDB254E5 +12: 413E0AD5C709DCE0 +13: 6B3CF01A7542BD2F +14: 1E5E2CA0CD605999 +15: D0F7C9DC472A0709 +16: 00482798857A2BB9 +17: EED583440CFA8B48 +18: DFB377FE1EE5E055 +19: 30511C4C565E8F75 +20: F74A72482B43B99E +21: 1EE4EA7849B0B070 +22: DB7A4ACF022706FD +23: 2D7EBABC8C8E4DD4 +24: 6F0369BF66A8B637 +25: 59E5D13B247EE0F6 +26: C7BAB430AA89A5FE +27: AE0F03746D38138B +28: 942DF0B523D02482 +29: 929CE0963CFA46B1 +30: F8C68A91DC53B7CC +31: 5735395C63E15094 +32: 7821605C18D83D42 +33: DEC892FD743BA6DC +34: 77AC80C1177963D3 +35: 3E223EB4EA297456 +36: AF63B231D671D9DC +37: 665CA287AF32E92C +38: E451EAB337DC1EB6 +39: 95B179EC950992CA +40: B8937115492802AE +41: 355A6E5EDF40A939 +42: 353E77D4A5A28D79 +43: C958FA5903F921B8 +44: C334E296BCB24ABE +45: 4F37F7F652FE31ED +46: 77304A655B03ED67 +47: 3548A4209ACB6EE2 +48: 696E712B1911B695 +49: E4B63641D22A3DDD + +Key Size: 68 bytes + 0: 7ED68E8B30A7D5DA + 1: 867E18AE64B783EE + 2: 032E554D6AAD7055 + 3: 26BD785D0DDAD48B + 4: FFBD4009ABF53D03 + 5: A71006E1E30C3855 + 6: 92638EE741BE65B5 + 7: FC8C5F28CB38C83D + 8: F03F145CBCC4CF80 + 9: A28A7C63F67DDE7B +10: 3089486A2247B72A +11: CDD6E6BA5ED53A8D +12: B75A2DE8CB96A267 +13: F74D72A2CD68CEF5 +14: 3865AC8D170EEDBA +15: B1B520CE5FC2BA39 +16: 658DACFDD701B4EA +17: 6B5C1DA9484FCEDF +18: E3CDFB5755BDFFC1 +19: 56DAFF7E9A908880 +20: B6F8B970F68BC2BD +21: 7A00DEE6977A91F2 +22: 6C0CE4FD2D02B36C +23: 8EDA10D868504648 +24: 76FB106689E66EA7 +25: 67F45BB28A20E110 +26: 5F3207099AF93B07 +27: F5E382F7266AB342 +28: 0E31AC2E4CEFFBDC +29: 8DBA1B2FC6980FF0 +30: 311368E62EC2A9E2 +31: 50DD1F7A319727EB +32: F0DE146C9ECF5662 +33: 81CE0842CE223F15 +34: 4C442535A8BC9AD2 +35: 06EE8869DB91EBDA +36: 4078E7CAC29DCEE7 +37: 115D619FB705F289 +38: 3D3F8A380DCB8FB1 +39: 9044E5AB8049D21A +40: 66327F00B07CFC76 +41: 811AB23A4AD3F132 +42: D4A507E96BB39BC2 +43: 51C9E4C9318F87D9 +44: D2255C13DBD09E88 +45: ECB76BCB961F812D +46: 83D7E39727BBBEC5 +47: 415540F0AE34DD65 +48: 232D20F9E188E2C7 +49: EE37261ABA270B22 + +Key Size: 128 bytes + 0: 8A8F8E5C5A04C73B + 1: B197CF922883CE71 + 2: 8AF3F896460CC597 + 3: 755F313AEB18D3B8 + 4: F1DB52688BB879A8 + 5: 29D68EA6456B1CF9 + 6: BE7C444267A7925D + 7: 46A7BF7DED575933 + 8: E2C7AD7C902E5E15 + 9: 90A38AE1DD69C2EA +10: AA95FA050CD3388C +11: 23822B6AD5B83018 +12: 8FD42F0DBFF3FEE1 +13: 645098BC94FDE21B +14: 7E43D43EAC50E992 +15: 2F540FC66A9E0F43 +16: 453E52EA7B2D1F92 +17: F6F731E8C5A32C54 +18: B1E89646504E4D7C +19: AB8168452A7984E1 +20: 044BB0758DB5435B +21: E9BAE7C99A152BFF +22: B758F70708B6597E +23: 23A1EFD0AA925D7E +24: CA60DD174CBA23DC +25: 5E916F2DF7B6B3CF +26: F2723A9BFD82BB62 +27: 2BC381F6C048687E +28: 573BFD71896A4133 +29: 03DF7250C3D69801 +30: 8639060454669BCB +31: E31945F0A87221AB +32: AA39447BBF0A77EA +33: 174F1B65BF6A34A3 +34: 2712F966022A9589 +35: B6358876D6D56D16 +36: 2A92C131E68B77BE +37: 040C6935F4CFC43B +38: F23503C74121C660 +39: EDD120883F1F813D +40: AFC6500D34BD9D33 +41: 963117444417BDD3 +42: 2FC3A58861B4A58E +43: CFDB70ED8BCD1173 +44: 91B75760CF38B8D5 +45: 93A59048B78B3415 +46: 7E60C5E75225D45F +47: D4212C6422878FFA +48: DDD1B241E0E0EF6E +49: 20337DB931078078 + + +Cipher: des +Key Size: 8 bytes + 0: E1B246E5A7C74CBC + 1: 9262AFD8AD571E2E + 2: 36D2067D960EB870 + 3: 319834DC66705192 + 4: B4508A7C5F012C93 + 5: CAD1DECDDEE81342 + 6: AE9E1CBB71C719E6 + 7: D7FBB1CDAFD5B2C1 + 8: BE1A70564E3BFB5A + 9: 96D9EC1407A1BD34 +10: 05E4B9AF3A4DABB3 +11: 0DC77419E1F12C02 +12: F73E62369190A5E3 +13: 830C1CA7820ABA2D +14: D2574B6AEED0A4F4 +15: BC08782E293546A1 +16: A35DCC9AAD1EBFB3 +17: 79B2224667B33706 +18: F9462FFD2808233A +19: D6421CD0D9697DC5 +20: 57CB2173D67E7001 +21: DBE2DB0BDC07644F +22: 014E72E7E99C969F +23: 37901B1963D0B29B +24: 8E12C23929125686 +25: 73AA9E2A60C327A1 +26: 54A19D07D941EAC2 +27: ADB8CBBAEE1848D6 +28: 3997E866119856B5 +29: 4D647526FE7E1E27 +30: D574FE7342104F93 +31: B84383E34A790E11 +32: 322214BE9B93BB6F +33: D4C8E0B7AA139D68 +34: 2B9747CD280E48C8 +35: F92EB2E3711FEE2C +36: 5CEE84E124B7882B +37: 82427488597FF618 +38: B1E8B313D2DC76CF +39: 03E237CD40D7F214 +40: 8C8DC1299293E15D +41: D6C7463FE86D4EF8 +42: CF1550CACE647779 +43: B998B3D32B69F00B +44: 1B94C342C3D91107 +45: ABD4551B27F58BE8 +46: 2B24D978D1BFB3DA +47: 85361D36950635CB +48: 448009F38F1DBB4A +49: 6B901B2B79B6950C + + +Cipher: 3des +Key Size: 24 bytes + 0: 58ED248F77F6B19E + 1: DA5C39983FD34F30 + 2: 0BD322177B935920 + 3: 9D093F3174EDBAE3 + 4: 756B1F2CDF02B791 + 5: 57C31C2A913C1126 + 6: CF936257517C53FA + 7: 5F06305849E5E158 + 8: 9A85DFD788C59D19 + 9: 6392279BBE29DC1F +10: 76B0AF835D79C4E8 +11: 7073F36DB1E31464 +12: 276258605F2CAB3B +13: 3B69E97811FDA996 +14: 3E6E491D2862A1F3 +15: F8F3F68BDB006520 +16: FD376E66D401A097 +17: CA2FE47825804996 +18: 6F5C256F84FD14AF +19: D7B07F5C40FF0CDE +20: 73F2E074F1324496 +21: 0B2A35016F24BD21 +22: B040D2E3B311C193 +23: 3938DEA347112E2E +24: 9D7C1703CEC0BFAA +25: A07949F76BDFAF68 +26: 43087EEF52564C4C +27: 11132B599734AF0E +28: 62A04C819FDD9A8C +29: B74F0E5649D33690 +30: 8E77E5009B0AA322 +31: 5174134B9A1889B9 +32: 053E33441D11AE63 +33: 01EF381013F86E4C +34: BCA358DEF35DFD60 +35: 5908A88513E2E5A0 +36: A3214C8367E04B05 +37: B2CBBE851A54BE9C +38: B271817F63B3B76A +39: 08AFBF82ABB97D8A +40: 2CE02ED014186B86 +41: 63F3011C97F6E990 +42: C392351F432738D9 +43: 0534DDA50E685725 +44: 1509456871F5CC20 +45: 2383029935901342 +46: 8714F1A53CCB213A +47: 2491B2FD3CE6A7CB +48: 4BB02399D85BB66E +49: B8AC2CDFF7AC22C1 + + +Cipher: cast5 +Key Size: 5 bytes + 0: 9B32EF7653DAB4E6 + 1: 48AEB06B1BDB2397 + 2: B530927183622D58 + 3: 0ECC8F24BA742216 + 4: F6352F9B6461D82C + 5: AF6315AE98E12A71 + 6: C364D4B506EF28B9 + 7: 817061BEDF5E0A5D + 8: C19DE7B1F2066C04 + 9: A6E1345E3AA1B79D +10: 06B036B04785428F +11: 244DAB3F7223F567 +12: B9CF3791F6C79F4A +13: 86C5A02AF0517C5E +14: A16E3198F1317E04 +15: CF72A44C01E36DDD +16: 199C72ECD5E632ED +17: 0BC66BF05EB7887A +18: AE1F696F3D6B7952 +19: 685C92084F600885 +20: DBC1353A95AD2097 +21: F481E98CB36CAB3B +22: 8F1C06A482C70BB6 +23: EA087739954A9CE5 +24: 6D0AD727D8E4EF9D +25: 61CA0F7965FEE246 +26: 0D664CA16BA785DA +27: 2359D363755605B9 +28: 6B6E3A216ABFB55A +29: 6FBCCF7B0342D3C9 +30: 3431F4572E2CBE57 +31: 36D84FCE6D5D8FE4 +32: C234F6AD41E34E76 +33: 522F12E8D0617263 +34: AD8199B6E94D4E74 +35: 56DEC7C21C83B2AD +36: 22CDBFBC5B476E69 +37: 70BAD497381F378D +38: 4584F15DBC0EB7F3 +39: DE0603CEE19BCFCD +40: EA8D582C1CE62FC9 +41: 4299C28A912CE568 +42: 7208AB000E3FA9D4 +43: 7AAE6CB398D01665 +44: 33A6AA42B6D7949C +45: 2AEC5640AD535D69 +46: 74D37D9DD7B67248 +47: A5300FFF5CF85833 +48: 834F83398D591C38 +49: 85C787A8B7E519DB + +Key Size: 10 bytes + 0: 95827CB504BD43C7 + 1: 8FBF4EBCB8413ABF + 2: 5CFF411BECED9971 + 3: CEE2AEB4415E0A5D + 4: BB3A8DF7C54FA88F + 5: D508B933EF335111 + 6: 993745722EF0D8D3 + 7: 04EFB233AA88E796 + 8: 478A7DCEAF243F90 + 9: 269CC3D138ED48E7 +10: 88EBD14D2F999C89 +11: B7441626D4487A20 +12: 46A6E2CE6C66058E +13: 60687D2D5381757F +14: 885D05ABBF187B89 +15: 5032A7ECD3D51521 +16: 50BAF36BC5C14A8B +17: 8E805499569FBB0E +18: F8359B18AF3E69C5 +19: F24E415CB4D2AA95 +20: 361805D4E45B56B4 +21: 3172336F01E3530C +22: 333A551E0A03C4A3 +23: E2B991995A2D2962 +24: 067CEEDD8F213B67 +25: FEC3F306851F8616 +26: 4B80DAE6AB11894F +27: 250C26E21A8273A2 +28: 313F2A505915C909 +29: 42E0DC3D4816B38D +30: 9FAEEF0510DEE721 +31: 3BB5F5EF74B4CD7E +32: 0FBC9007F462BEAC +33: B9D1467B0D7A1043 +34: D9B991C9348DF321 +35: 061D577806C50742 +36: 48AEA67AAAB6FA23 +37: 22F7910383BDA87C +38: 9987087EDBA56FD8 +39: 2FCC8341B69BAA14 +40: 29DEDB6C2A433F50 +41: E067D2746B99A9CB +42: A5C9CB975A856D57 +43: AAFEFD3A82D6185B +44: BBE8952CC93CCCC8 +45: FC08CE0934EF2E25 +46: E44E642DBA7CF3F0 +47: CC26F0E8E85AB372 +48: D95D63B8389082E0 +49: BCA941C921B91E16 + +Key Size: 16 bytes + 0: 20B42D77A79EBAE5 + 1: 96CF6C91E5183CA2 + 2: BD87E77A38DDB4E2 + 3: E7454CA30B69DE2D + 4: 888F278D219384EE + 5: 972CB887CDE920F8 + 6: 49BEC1E7913F3CAE + 7: 96A81B37FEF63CA5 + 8: 408DD23A6DA940FC + 9: DA86E92BB735755F +10: 2032F2D972F228BD +11: 8F9EF7DEEF74EFEA +12: 547C92025DCAF9F4 +13: 80CD440DFF2EA62A +14: 7D6141D102E1B941 +15: 307596ABF5C9A6B2 +16: 82E3F1B17EBD52FE +17: 5917DDD11EDB55A3 +18: 2909F77166F24F9F +19: 88BDE9D686328942 +20: 8F987B737F6A011A +21: A74B3D1D6433B9F4 +22: DA8F95DE949482EC +23: 953BA9B26B9AC476 +24: 76A52FE193CBFAF9 +25: 4BB7D2597A78F2D8 +26: 5C8BE951251F4B1D +27: 6E8AB32A4A279D84 +28: BB94BC9937B42848 +29: FF0EE686F97BF8DB +30: 4146656AB1477E13 +31: 1BFCA7053E6DB8AC +32: 4B9A6A349BFA926E +33: 3B5F6FDD127B0A87 +34: 53C996E956598599 +35: 62C142E63C28B5EE +36: BBB71D6548F32693 +37: 107576AA26352455 +38: DE32E31FFE02B6F9 +39: 4C5DB81D1715FF5C +40: 8E5C706206F493A6 +41: 4BBC51E184A67C92 +42: AAE216B413DE2A06 +43: 77AE26F467233B06 +44: E8680D0E71F6AAD6 +45: 7061DCED4BC94F78 +46: 06772D63818C7E86 +47: EE5B9CFC06CBD639 +48: 5784B3EFCDC28DD4 +49: 4F962107A2EF843C + + +Cipher: noekeon +Key Size: 16 bytes + 0: 22C082F55D7F6D861B11C36911BE694F + 1: 0485388F24B147918116347E942BCF4A + 2: 47388A4B060617B21134D3B4EB1CABCA + 3: AA8866CFB9D7507CC67A7F271AEF11E0 + 4: F6A078AEF1BDF8B621A76CB732804FF3 + 5: 8301F76E39A4E8C8AC38A7751B26DD31 + 6: 5BE06821E7B23277B808143F36BABDE0 + 7: E326A3A32F4F0D8A4FA94877997DA11B + 8: 2BA7773B55F90B5399C11EA80D6CADEF + 9: E64776D92B81770E51E4E2F44688A59D +10: E987ED52D4C33B2668BB9DCF0889D5AB +11: 351F5BC075D06BC6977D31A442CCC2B6 +12: 645468E2497FA5EB913C04032457C1DF +13: 10CFDBEC689B01FB969AA2C760F76CCB +14: 0BC5B171A3B727B9594238EC522F72F0 +15: 887D105D54D8EAABABC892F04F3455C0 +16: 53CC30B5F16713AC77205B0F194FED59 +17: CD63AD99CC0D5F34D67C363F99F7CF1E +18: 59BE7B22114383FE8491304FB291D2BC +19: 4B107C8D37CD46EF1DB68ECF4588FEF3 +20: 46034C755D278E368305D1133BA6B4FA +21: E2472AC6D4048AB59E126930F6476D06 +22: 821014CDA5084A85058F1D556854D33D +23: F67C3FB5CB1271B454810FEE632F7EE8 +24: 57705CB352AF1A8B342E1E555C9DAEAA +25: 72AB36C1A8D3C2111330D0EF78726227 +26: 1931783D7E3DD6A33962BAD6962D8A33 +27: 06029A07CA801027D97BFAFF4719FB89 +28: D78B7E4E3083A60610C42BFC03810590 +29: 3CA3B14C5741A43F1FF5AF2179684DBA +30: D1BCC52AE476999E25391E7FFDC59C81 +31: 1E102DBAA4224ED5E32515A59A07EDAA +32: 81BE227D2663DBB733F9CB5018AED67C +33: 92C5A77D5D62A16C031DA0BD968FBAC0 +34: 9EC8E61B543BE73AAD711A9F58C86790 +35: B6A1FD059A7D8D73C143C17D97E4C177 +36: 0316ED78EA520EE98BB568413A390E44 +37: BEFEE68550E2FAFC4AECBE309031BEFD +38: D394CBCC38A47482B2B6900BD68D6540 +39: C58F2EE6C493BD1EB41DEB88A169D240 +40: 0A45FFA6D6E888B1F6E95E388818C6AE +41: 8A9CAD2C511F284CE1D77167E5D23456 +42: 577CB9155A69CA34213FFD15E03D54F4 +43: 2AB7DD760EB7DDDD3883A6966B9D44D2 +44: 4564DC5318B0A940CBBC3C1607804B70 +45: 0E9F42D9C2AC03694CC2E82BA3C4BBBF +46: A49089D9FD9E13DF35B0490E59A9B7C9 +47: D58B3008003D6C8D556D7D76180691FF +48: 1FBC6D5F3F1B0E599DED48FF7A63CB76 +49: 077533478FABE8AD5DC2B9E96E7CC6CB + + +Cipher: skipjack +Key Size: 10 bytes + 0: F62E83484FE30190 + 1: 03B4DFE5423A117B + 2: 8CE4DAA2307CF018 + 3: 77D8C958DAE4336D + 4: 00D367D5C1FC95D8 + 5: C1F1305A5B01A474 + 6: C3956225C846F695 + 7: 2A8977DC186749A3 + 8: 433AC6B56AE5C200 + 9: 10489A7E87F803CE +10: F176DF022D02D136 +11: 1395AE1C0C00AA1B +12: 0C1C3FF32E93F789 +13: 901EAAD562EE92DF +14: 59D55D9EE3EA0154 +15: D9135CE0BBF68AC7 +16: 90A8E4A8E76349A3 +17: C04ED52AA69D1ED0 +18: 19E842698B5008A4 +19: 26FCA0FA3AA7718D +20: 62635FD1A542C7C0 +21: 5A3695398C979E40 +22: 34998BB72108D89F +23: F889CF892998D689 +24: 2C6A4D61F468F19C +25: EC70D59FC906349B +26: B95F11FD098B34A6 +27: 32F86206BB4E525B +28: E6BE51063B60CB9A +29: 8964E47BAC22F995 +30: B1C297883819747B +31: F2AE1F39F55FB6C2 +32: E633EA2DE342767E +33: AF1F0ECBCA788A28 +34: 6A898F4407696B27 +35: CD9CB5374EA080BD +36: 15881B0200AE6A42 +37: 579D05E5F5DE7840 +38: 86F8C683D23EB976 +39: FDAC7DC6C8F7777D +40: 10D6F7641409F027 +41: FCDAA0872D1EC61A +42: 7A353991A81344DC +43: 43661187956D3F8D +44: 5190FDFB904A78F0 +45: EF651E67F65CCD57 +46: 5E539C61748BDE3D +47: E11E23BA8BEBA42E +48: BAEF0956173B32AD +49: 0AAB29DF65861F4C + + +Cipher: anubis +Key Size: 16 bytes + 0: 30FF064629BF7EF5B010830BF3D4E1E9 + 1: DD7A8E87CFD352AF9F63EA24ADA7E353 + 2: 0D0BE8F05510EBD6A3EC842E5BD9FC2A + 3: 330F09581FDC897B3FE6EC1A5056A410 + 4: 30349D965F43C295B9484C389C4D942C + 5: 9225343F0056BC355060C0282C638D02 + 6: E3A85D41B5337533C4D87730948A9D4E + 7: 09DA0DDB65FF431081CAB08A28010B76 + 8: 6C0D0BD6CEAFB9783B31023FD455DAC6 + 9: FBE6F26B7CA322A45312856D586DE2EE +10: 1F269EC072D0FBA72E87CA77F8B983FB +11: CFFAE9ADE3006BD511ED172D42F16D05 +12: 73F0E9DE89F4C7541506F052D181BAC2 +13: FCFA3E2E89FF769834295C77431EF7CE +14: 0452360383D56F827C81263F6B0855BC +15: 40744E07299D6A2A210BE5598835221B +16: 2F0FC61148C36F4C7B42DF274AD0DDE0 +17: 2EA0E9BE9E4E4DF85488FE6E7CFCD6E3 +18: 0AD1254FA64C3996BBD485D41A3687A0 +19: 5B55988652DF200348A114F802FD3C03 +20: C32906AF76934C1436CA60BAD58A0C66 +21: 59D87987DE9DD485C4537F3A95A164A0 +22: 0A706ADF488D84632C96F4BEC43D9FA8 +23: 0B74E0CDD14D984B37491E2D9FA63CAE +24: 47CB1827D151A60473E67BD5D233102F +25: F455B4B665D3D0AFB25FDE4A3312AFF6 +26: F9A0649421D45DF604206854F681DBDB +27: 21477F5546339E4B6D8215368EE9F884 +28: 577640F23CA73345701B0906DFABA4B7 +29: 89F8D08A6E173759020DD7301E0FE361 +30: 44EF7AF7043FD4B8112345CEE42BC969 +31: D7CF0CE04A57253F4C63CABC4A5CB034 +32: AF73D3F4CED32593B315E27079131D22 +33: F6E603E3455359FE43A3B83AAF3AF0C5 +34: DCC3FB557F2C301B631DEF499097E4FD +35: 8285A25CF6F7E701644708E12081C62C +36: EC702DD0293F4C646B1C9C2606762816 +37: 289491E5A65DCA605B78E88DA8A9F8AB +38: D82FBC14452BE34C5840DAD81FC2A65E +39: B88A340EB1BF8D5ADE6A4E6C16104FC8 +40: C9FC3D70D2BA26C4059BD3D34134264C +41: 18CE3D2920E3BDEFA91C369E9DE57BF4 +42: 50917AE58278E15A18A47B284D8027A3 +43: BDA6F9DE33704302CE056412143B4F82 +44: C287898C1451774675EB7A964C004E0D +45: 3BDE73E0D357319AB06D3675F1D3E28D +46: 30FF4326C89C0FFE4D31D2E92CC0BF9B +47: F69816F304ED892232F220F290320A8D +48: 1368153F1A54EFF8D61F93A2D6AF21E3 +49: 06DD274894B6EDF3159A1403F47F09C7 + +Key Size: 28 bytes + 0: 7828B1997D3D050201DC6EE45C8521B5 + 1: 0D77F896F9CEF16DAAFCF962C2257AAE + 2: 89C27B0623F5EECCA38BAE1AD86AE156 + 3: 44EC09834052009CC3CD66E1BA11AF01 + 4: F922BFDB03FB186A069C1E7B48222E3D + 5: 277F7971955D8984AAECF287C32B8211 + 6: E77ED0144A3ED827B71453B91562FE25 + 7: 1760EFD04477AE527BC37F72C8BBBCAE + 8: 26259425ACD58207AE328B3F1A217AC1 + 9: 0876C4DC51D22657C4121E9067C2C3BA +10: 0214981592C9CEDD4D654F84AF1793A5 +11: 3E11FA027BC4F15048D27B187062259A +12: 24E7D61BB21EA90B5282B43AAFB0DBDC +13: 688F56ECB45B7C242000653460F04A23 +14: DFA587501A875ACDE8687A04AE404861 +15: 4C21CC3FBB768CC9AF2242FA206FE406 +16: 5CA0B03FA7751DEBBE70CB21AA61765A +17: 4879B3AC26270C422645B9CA29CAD8BB +18: 24F941E1B9AF84C18D03885EAACE16E3 +19: 05E163A0150123C2664131A81B20AFC1 +20: D606CAA85362E23598E5B8BD60C60506 +21: 33BD0AE751019BB751C151AE47BD5811 +22: 75DA523F5F793F90034144A3599DC5E6 +23: CD4709B56521EA306F5AD95CCA878183 +24: 6A4EC2EDDEBBBFEB62C1F13F7A59BF20 +25: 2A36272DC4EFDFC03F4DCF049ED2ADFF +26: FD4F3904E8E37E7C31508E5829482965 +27: BA64BAE1C2ABB8599A31B245DBAD1153 +28: 757E0151783A50FC92AE55861DCD797D +29: 5E63BDA3217ECB544972CA14A9074DA5 +30: E52F1195921767FA2410BA095EA5C328 +31: 6D7E42D67E329D669299B5A590017E8D +32: 0516F6F7D99ADE5DC42E635BB5832E80 +33: 57FB4E6B82ED2A3091248DCEF9C27F14 +34: 25231D0E9B96534977D2F2AF93DD10AB +35: 847C4C524A586568D19EFA3ECA343F1C +36: 52448814064E0F33A4EA89368C2E1ACC +37: 461275466FAA7BC16ABAD9EC459BD67A +38: 16C8324A383A00DA06DBEC419B69C551 +39: 5F26F7CF715FF2649DCC3C71EB6B92DF +40: 575363411FB07C067CD4357A1CD1D695 +41: AB70F08BAB51C5F57139A107EE858A12 +42: 887F62AE3D700EC5323EDA231C6B4C48 +43: 7B9851B01DC9083293F3B226690A54F4 +44: 36E03DF51C574E35EF2077DB7A49548E +45: E238A564246B163F97EDD733A235EDEB +46: 30679CE080915DC3BFA91D0DAFF5E82E +47: 7C2E8145D803D4FE18EE32995AAC16B0 +48: 24D6F61ECC87206804885D33BFA7B2CA +49: 1F4F81751CB3FAFDC9F9C27E639F370B + +Key Size: 40 bytes + 0: 31C3221C218E4CA1762B0DE77B964528 + 1: 0B6E4BD937773597647FFE0A3859BB12 + 2: 67A116E5F762619DE72F99AD1562A943 + 3: B6A841663FB466ACAF89C8DA5BA080F0 + 4: 0442708BF804642B9B1C69F5D905817E + 5: BC77391EAB530B96CA35319E510DB306 + 6: AED37991A50AECB70C1B99137D5B38F2 + 7: 8735F7AF0BF6C5C7E3C98021E83A31EE + 8: A614243B1B871D80BDCE4A23AD00F9FA + 9: 16AC67B139A92AD777871C990D3DA571 +10: B1774A2A12A8CAB25D28A575B67CEF5D +11: 4C9B1A120BC6A33C62AF903FEEC3AF5F +12: 7B128F00480E497C5754EE333457EE5E +13: AB56D578229492B95ED309C0EC566658 +14: 42FAF577855FEDB3446D40B4B6677445 +15: 84E0C19B4A4512001F663E22D3184F0A +16: 8B01680D049F5A9421BA9BED100CC272 +17: 2B1D70B92A5DF12CE0FA6A7AA43E4CEE +18: C7F61340D1B2321A1884E54D74576657 +19: 153C07C56B32530866722C4DEAC86A50 +20: 2EACBEFC4A29D1250EEAFD12A1D4AE77 +21: FCCB40B0997E47512295066F1A0344DD +22: C149A543345E2A1B8249F71CB9F903A4 +23: 3FD0688A8D0BE5F06F157C234C29BF9A +24: 6A3F813F396D77C7F4641ECC3E0BF3AA +25: E2888B9D2A6D819367F61C5792866A8F +26: 1A8A000F91AF4E600DDD88E098BD938B +27: 2283E758C04548EF8C37FA9F5700A7AD +28: 4FD6D8E1678D2B85520B96C038C582BF +29: D13C0B228F792EF88F09ED192C571029 +30: 1A2A06B1987BE0DADA4B558AE5E6A128 +31: 097B0460C47F1801986F5706A69EB01C +32: DD17BAC0737515C6386ECA6A6D6C02B6 +33: 5989BD1D46FD6EC14D4C55D5D6D17F99 +34: 431002E0224BD34B0B93988356C19E7C +35: 37DB7570296DCCE45ABDDE36EBE4731D +36: 4731DE78EEBAA1D02568EEEA2E04A2F5 +37: 1F879753A7964AF44C84FD5765D8E080 +38: 54F120726F68EA4B0501365CD2A84759 +39: 366E43BB744C615999E896D01A0D1D0E +40: 18747BD79F1D0529D09CAC70F4D08948 +41: 4F9854BAE0834A0C5FD12381225958F2 +42: 7C14ADF94A0B61828996D902E4CCFF3E +43: 242F0E9CE96E4E208A9E0C5D76F8E698 +44: 27EE179E2A9301B521B2C94ED3D36A77 +45: 892C84A5E77E88A67F5F00F3597F4C04 +46: FC7880D7860E90DE17E935700FC8C030 +47: BC49373F775BF9CD6BDC22C87F71E192 +48: 365646D0DE092AF42EC8F12A19840342 +49: 62D0E9C210A20ECD2FF191AD3495DE6F + + +Cipher: khazad +Key Size: 16 bytes + 0: 9C4C292A989175FC + 1: F49E366AF89BD6B7 + 2: 9E859C8F323666F9 + 3: 349EC57A02451059 + 4: 59E34CF03134A662 + 5: 436C16BAB80E3E2D + 6: 81C35012B08A194C + 7: 056CCC9991C1F087 + 8: 0A59F24C4715B303 + 9: 3C2CFF98AE8500FD +10: 9136C3FCC332D974 +11: FA3FA726E6BEBA65 +12: DD84E4F9F39FB7EE +13: A3F397CC9FB771F5 +14: E2D6ECC1F40A51C7 +15: 6704A1A705163A02 +16: BD820F5AF7DEEB04 +17: E21E37CC122027FF +18: E319085D8E2C1F4F +19: 0DDFE55B199A49A9 +20: B70F39CCCB2BA9A6 +21: 3F2F25723AED2E29 +22: 751FACD5F517AB2F +23: D32CE55FBF217CE9 +24: 91393018EA847012 +25: D50F1C54BABE7081 +26: C73350FBC5B3A82B +27: E9A054F709FD5C57 +28: 94BD5121B25746D4 +29: EE19F88B28BEB4B7 +30: CE6845FD13A3B78A +31: 566729D0183496BC +32: DC0E1D38CB5E03A8 +33: 251AD2B2842C75E3 +34: D344AC41190F3594 +35: 579B956A36ADA3A8 +36: 5F83D3AFEE9A6F25 +37: 2D3FF8708A03C600 +38: 32A732C7BEEBB693 +39: F437276FAA05BB39 +40: 58DDD4CD0281C5FD +41: ECC2C84BD8C0A4DC +42: BAB24C2CEFE23531 +43: 5244BFA3E2821E7D +44: A4B273E960946B2C +45: 039376D02A8D6788 +46: D3EB7074E3B05206 +47: 89C18FFA26ED0836 +48: 1F05A2D2D78927D9 +49: 0133E1745856C44C + + +Cipher: camellia +Key Size: 16 bytes + 0: ED18D83F3153160C5A6D01AC3717515C + 1: 1012886CCDF3FFD25E588BA10D6CE363 + 2: D25562F6943EBE3A7E0EF28D33CF091E + 3: C26FDC4539DD1E6D0330B5836AB24420 + 4: E14A50CE727B74B8CEBEB284FEF3C810 + 5: AABFD72D334F594344C617EF8E8F5741 + 6: E8D941419ABE88060835E9BD375455BB + 7: ED863784E1590139A2CA50D77450300A + 8: 545FCF42030BD764724C3EF5C139B038 + 9: 08C194E007FAA99997D855A759D10743 +10: 3899D3731500C79D2945AFC2980B4C17 +11: 2720FA4B402AB7F1B019AF6248702369 +12: 3FF6C3C90AB4141DEE5FF30EA2047F73 +13: BB5BAF7545AA774C7AA5A58568F96832 +14: 66349C52709EDE0EE34AB6501B420C7C +15: E1E93D923504A5421BAEA5F1D61D4C9A +16: 3C07DFD64B2407BB7575A905F3F31E83 +17: 0FC569AC89ED790F69BBD1E998700C97 +18: 6B6F390AFA1052BD2E8DB0DC261E4D26 +19: CBEA83ED55DA9DED95B87F2BBBEAC37D +20: CE005DECECB98F5937D5ED26FD83154E +21: 738301D76316EC4173F124A9C9D6577A +22: D00A1E40CFB5F2B8FD2C0714580FAD50 +23: 7EBF497C78B72E646EB72A326F1D5C4B +24: 7E0023900F6000D00737242DA8F2E1B1 +25: 0F7737E715BEF0DEA503E355394540A9 +26: 15452DD70DEBF45BEF39782CDB8BB086 +27: E7464917B3AF060BC763D8959DDF90C1 +28: CBE4B90FF8C66672122D53585198773B +29: B7262E6CAA2C14B18EE374DF922CDB98 +30: 01E695E3CD87A2FD4B9C49D08D032DAD +31: AA1686BA0B5C5688D0F370C6E2BFA43C +32: 9448BA348E8E904992C3F4233C226B22 +33: A1DCD1CB810DFB46BDCE6FBE3A192560 +34: 4345D200A309FA8C5A0CE9EC60EE506C +35: 54C7F64D9B411BF90B283ED62686D28F +36: E347E882EC2635081547612B1D9589D1 +37: 36D44CC101B37BB6F6AF68C3FEA3A7B7 +38: F38C2D5B921965D2AFFDBF4EC5BCEC19 +39: F7ED6BF85782F0526301BD1CD1624E67 +40: 7959C134BFC85CA176550EA689F81054 +41: A8FC96504C437F0EFD0BDF6CCEF516D2 +42: 6B88D1A06D7C8C74379FEFE2D6A7C895 +43: 39C21AA165F4A71A161971D89CA5DC32 +44: CC123C40071BF02D282DC83D2AC18226 +45: 0780A63741AE47CD03FA99A74C320E33 +46: DFB0831BA27AA0750701439603B8A805 +47: 0C783CBA4ECD9EEE1F91838259831187 +48: 1456624438B22555B08D59CA50D6E95D +49: D5F463D983A9A6FE9A0B47C245596D40 + +Key Size: 24 bytes + 0: 1D1DAF85EA5CAE19F5F5EA1DC61E5B83 + 1: DDAC7FCF2C2F275C7041E7821AAC84A3 + 2: 591091C3755816AAEB9170D5DF77A0B3 + 3: C4BC965CDC20E6FC039F07DA2CD10BE3 + 4: CD8DA54FC48524EDCFEF985C0C39C961 + 5: 14FA12F39AC3D701A958765B4499FFAC + 6: 2BBEA5F3AA140CFFED9F1EB2BC969D56 + 7: 5F73CA8BF641770D6833A43947D9A5C3 + 8: 3E872D303B882284AB02393D43137450 + 9: 01EF55D4CE182FA03216A83A5128F761 +10: 915C2F5793692A6D118D865783317C58 +11: 4368A442B61D6F12D5447F1CB8854714 +12: 3477ECB27ECFF2D7108ED1297DE80F86 +13: 89C875CB55C1CE80FF2D430921FADB05 +14: C5AAFE7A4588D4D9039E4552B3FC9B02 +15: BF1E7509405AB219B540BDD0D3DE7528 +16: 7E5CC85B6563099B902638B7E0D09728 +17: FF04D2350647F117F81DA037A9E11946 +18: EA294A53395A20B391B11AB9F97262F3 +19: 448C801307E9405F740623BA55A45639 +20: 62032AE6EB01322233FB321B2D6A8C38 +21: 79A54FFB9CA25AE315BA0E7B6E59EA99 +22: EDE7E634C396926876A49DB3C0E261E1 +23: E9DA5106B8BD33391C28407E9B3758BD +24: D8EAF9F744E060695AD1F55F85AF3D76 +25: F1E61F0F467C0785B6053332129114EA +26: 3119CACB24B012F3B96EFAD3FB856AFB +27: 97753ACDAFD6224E5D289BF76673A73A +28: 8D5912FFFD628736C64B3DE01DF1E674 +29: 8951CEDB758DF5EA5D2A78B2A08480EE +30: 3C0FC9DFD8CF79A5F9F75CC43B1A9247 +31: 4C7047481FE0849EA0416BDC00A52321 +32: 97034388AE8553570366EDFB9F6D618F +33: F16BCC0FB2B77CCBDC5EF7AB2233599D +34: 6D94D041196F43F0224B1DAC84165E7C +35: 313C6BA0AD767259860DCF8003F2F5A2 +36: C5F835DCF63D1C40E56DBAC7ADCE7F3C +37: DAFAFF6BB46EA9280562E5DDFA793BA8 +38: 5C8C0570B06C595E296DD4A9FB864FCE +39: 72B433F78D7CA638C2ADA09D99CFB769 +40: B6D7A6C47339743E9739D35D0F08A25D +41: 6CFD73F9E9781FFCE53C69AD2EF11E03 +42: B7F0BA994EF90642B80FDD798666D752 +43: DD49766125316ED4F546B246A2CFA23A +44: 8ED53D6CEF3CFB9DB0147F02656EDA35 +45: 95690401D61C84A013EC6D25CCAC5CD1 +46: 7693648B4A6CA804B6F01AE67816746C +47: F08C5898CE7970C41A5F8C05882CAB8B +48: 91EC0EC1CF839B58009E6CAAB3FD67A0 +49: 853DFA14A029EB8FB8D693B0A65306A1 + +Key Size: 32 bytes + 0: 5F77DC44E5E6701E8755C1FA176E2434 + 1: 5C1F70FC144C66D82D8F21DD2A0BA54E + 2: A98317BC656475F83E83062A69A17EF6 + 3: D5B8C0DB1095E65D49CEC82D78FD4C7E + 4: 37A537292409ABE5B922DD97EC0F6CA4 + 5: C7FD40883DE6BBC6059327DA586AD96E + 6: F4D19C443A2195B66085DACA7EFFDADF + 7: 6F12FD74B4D25C9F2856CAA1BA32461E + 8: DFC00046F41BC27684321B980BF68F6E + 9: 4A8BECB6A8D57002FCC6FE08B6D31118 +10: 859562FB3727E535BD4A914907822545 +11: EBA65EA3BD622DC044CA5384E568C65F +12: 79C16A751FBE22340F30462600724324 +13: 8F4FB71B5B3E0C1DB870B4BC81E995D0 +14: 4B82E7E8D64D8EF9D78DA944B292CED9 +15: D873F8D7125A63EBB04473F7331B1975 +16: 2FA25AF9E8D5A4DC82CAD98505E5DA60 +17: C80C24625096E6E9852A6F9EE12735BB +18: 10D4434CB795DC06E926CFA3B43D2368 +19: 070795AEA2765A443213F9CA909DF6C4 +20: 7184D2F5644306FB6DD55F1C90C111CA +21: F4FAEDF12FB40DE7CE7B08121A340557 +22: 86CE014AA863FD3030A26E6F8C178673 +23: 5A46BF2B3F14D5FEA884C3361EA87ED3 +24: 456584515D983D17ED4F3AE944BFB2C4 +25: E1E8F394691C2A9123023A8EE3FCBBEF +26: AC73E8BD1758850DEDAA3817B01E6353 +27: 15AE5395CBC3371F81A6F5B05C52671F +28: F15AA72D34C4E0EEF8DDDDA90D9A9539 +29: 3325E709043735898EA242E94D169112 +30: 044AB447754DADD4E2709FEE08D5CEA2 +31: E02DD5E86D32B3A6CC7F0016375AEC5F +32: 790278BD19E2860618E24DC69993F92B +33: F776D24FD90A43A78D000CFC1189E56A +34: A3EE4A3D121280750F7C70E55DD40FF4 +35: 32928BBBF98DF4B9E107599DFB30364F +36: B3E9296B529118B656D27AFF0F4D1A55 +37: 4668FD77100255C3406281EC813719AE +38: 16F9FF27B26F13300DB8DEE2EDD023AA +39: 9295F8435D688D12BE631A31B2531482 +40: D86917DF41ED4342C0ABF10628DBD1B4 +41: 1F5215B987C3F079769292E65D04B823 +42: F68B98BD2F12AACEBE78666AA83CA7D0 +43: 09BB635B67279F5A6B1D5C5D880A1357 +44: AE4ABBCC1D35CD8C4C254111D5F27158 +45: 5552B3E39DE67F759799A686222EE4EC +46: 1CA439434B9FD2F24561A32A0A2A79C5 +47: 0E33BE7CE3B9A5CFF00A73BD27DFE9EF +48: 6B7056FDC97983173D6B3D5BFC9B09B8 +49: DA293A4CB96FE3608CFFD89B927C9ED6 diff --git a/t/cipher_test_vectors_openssl.t b/t/cipher_test_vectors_openssl.t new file mode 100644 index 0000000..aa2d95a --- /dev/null +++ b/t/cipher_test_vectors_openssl.t @@ -0,0 +1,389 @@ +use strict; +use warnings; + +use Test::More tests => 356; + +use Crypt::Mode::CBC; +use Crypt::Mode::ECB; +use Crypt::Mode::CFB; +use Crypt::Mode::ECB; +use Crypt::Mode::OFB; +use Crypt::Mode::CTR; +use Crypt::Cipher; + +while (my $l = ) { + $l =~ s/[\r\n]*$//; + $l =~ s/^\s*([^\s\r\n]+).*?/$1/; + $l =~ s/\s+//; + next if !$l || $l =~ /^#/; + my ($cipher_name, $key, $iv, $pt, $ct, $flag) = $l =~ /^([^:]+):([^:]+):([^:]*):([^:]+):([^:]+)(:\d)?$/; + $flag = ($flag && $flag eq ':1') ? 1 : 0; + $cipher_name = uc($cipher_name); + next if $cipher_name =~ /^(DESX-CBC|RC4)$/; + die "UNEXPECTED '$l'" unless $cipher_name; + my ($cipher, undef, $klen, $mode) = $cipher_name =~ /^(AES|DES|DES-EDE3|SEED|CAMELLIA)(-(\d+))?-(CBC|CFB|ECB|OFB|CTR)$/i; + die "UNKNOWN CIPHER '$cipher_name'" unless $cipher; + $klen ||= 'n.a.'; + $cipher = 'DES_EDE' if $cipher eq 'DES-EDE3'; + $key = pack("H*", $key); + $iv = pack("H*", $iv); + $pt = pack("H*", $pt); + $ct = pack("H*", $ct); + if ($mode eq 'CBC') { + my $ciphertext = Crypt::Mode::CBC->new($cipher,0)->encrypt($pt, $key, $iv); + my $plaintext = Crypt::Mode::CBC->new($cipher,0)->decrypt($ct, $key, $iv); + is(unpack('H*', $ciphertext), unpack('H*', $ct), "encrypt: [$cipher-$mode] $klen"); + is(unpack('H*', $plaintext), unpack('H*', $pt), "decrypt: [$cipher-$mode] $klen"); + } + elsif ($mode eq 'ECB') { + my $ciphertext = Crypt::Mode::ECB->new($cipher,0)->encrypt($pt, $key); + my $plaintext = Crypt::Mode::ECB->new($cipher,0)->decrypt($ct, $key); + is(unpack('H*', $ciphertext), unpack('H*', $ct), "encrypt: [$cipher-$mode] $klen"); + is(unpack('H*', $plaintext), unpack('H*', $pt), "decrypt: [$cipher-$mode] $klen"); + } + elsif ($mode eq 'CFB') { + my $ciphertext = Crypt::Mode::CFB->new($cipher)->encrypt($pt, $key, $iv); + my $plaintext = Crypt::Mode::CFB->new($cipher)->decrypt($ct, $key, $iv); + is(unpack('H*', $ciphertext), unpack('H*', $ct), "encrypt: [$cipher-$mode] $klen"); + is(unpack('H*', $plaintext), unpack('H*', $pt), "decrypt: [$cipher-$mode] $klen"); + } + elsif ($mode eq 'OFB') { + my $ciphertext = Crypt::Mode::OFB->new($cipher)->encrypt($pt, $key, $iv); + my $plaintext = Crypt::Mode::OFB->new($cipher)->decrypt($ct, $key, $iv); + is(unpack('H*', $ciphertext), unpack('H*', $ct), "encrypt: [$cipher-$mode] $klen"); + is(unpack('H*', $plaintext), unpack('H*', $pt), "decrypt: [$cipher-$mode] $klen"); + } + elsif ($mode eq 'CTR') { + my $ciphertext = Crypt::Mode::CTR->new($cipher,1)->encrypt($pt, $key, $iv); + my $plaintext = Crypt::Mode::CTR->new($cipher,1)->decrypt($ct, $key, $iv); + is(unpack('H*', $ciphertext), unpack('H*', $ct), "encrypt: [$cipher-$mode] $klen"); + is(unpack('H*', $plaintext), unpack('H*', $pt), "decrypt: [$cipher-$mode] $klen"); + } + else { + die "UNKNOWN MODE '$mode'"; + } + #warn "[$cipher|$mode, ".length($key).", ".length($iv).", ".length($pt).", ".length($ct).", ".length($flag)."]\n"; +} + +__DATA__ +#cipher:key:iv:plaintext:ciphertext:0/1(decrypt/encrypt) + +# AES 128 ECB tests (from FIPS-197 test vectors, encrypt) + +AES-128-ECB:000102030405060708090A0B0C0D0E0F::00112233445566778899AABBCCDDEEFF:69C4E0D86A7B0430D8CDB78070B4C55A:1 + +# AES 192 ECB tests (from FIPS-197 test vectors, encrypt) + +AES-192-ECB:000102030405060708090A0B0C0D0E0F1011121314151617::00112233445566778899AABBCCDDEEFF:DDA97CA4864CDFE06EAF70A0EC0D7191:1 + +# AES 256 ECB tests (from FIPS-197 test vectors, encrypt) + +AES-256-ECB:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF:8EA2B7CA516745BFEAFC49904B496089:1 + +# AES 128 ECB tests (from NIST test vectors, encrypt) + +#AES-128-ECB:00000000000000000000000000000000::00000000000000000000000000000000:C34C052CC0DA8D73451AFE5F03BE297F:1 + +# AES 128 ECB tests (from NIST test vectors, decrypt) + +#AES-128-ECB:00000000000000000000000000000000::44416AC2D1F53C583303917E6BE9EBE0:00000000000000000000000000000000:0 + +# AES 192 ECB tests (from NIST test vectors, decrypt) + +#AES-192-ECB:000000000000000000000000000000000000000000000000::48E31E9E256718F29229319C19F15BA4:00000000000000000000000000000000:0 + +# AES 256 ECB tests (from NIST test vectors, decrypt) + +#AES-256-ECB:0000000000000000000000000000000000000000000000000000000000000000::058CCFFDBBCB382D1F6F56585D8A4ADE:00000000000000000000000000000000:0 + +# AES 128 CBC tests (from NIST test vectors, encrypt) + +#AES-128-CBC:00000000000000000000000000000000:00000000000000000000000000000000:00000000000000000000000000000000:8A05FC5E095AF4848A08D328D3688E3D:1 + +# AES 192 CBC tests (from NIST test vectors, encrypt) + +#AES-192-CBC:000000000000000000000000000000000000000000000000:00000000000000000000000000000000:00000000000000000000000000000000:7BD966D53AD8C1BB85D2ADFAE87BB104:1 + +# AES 256 CBC tests (from NIST test vectors, encrypt) + +#AES-256-CBC:0000000000000000000000000000000000000000000000000000000000000000:00000000000000000000000000000000:00000000000000000000000000000000:FE3C53653E2F45B56FCD88B2CC898FF0:1 + +# AES 128 CBC tests (from NIST test vectors, decrypt) + +#AES-128-CBC:00000000000000000000000000000000:00000000000000000000000000000000:FACA37E0B0C85373DF706E73F7C9AF86:00000000000000000000000000000000:0 + +# AES tests from NIST document SP800-38A +# For all ECB encrypts and decrypts, the transformed sequence is +# AES-bits-ECB:key::plaintext:ciphertext:encdec +# ECB-AES128.Encrypt and ECB-AES128.Decrypt +AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::6BC1BEE22E409F96E93D7E117393172A:3AD77BB40D7A3660A89ECAF32466EF97 +AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::AE2D8A571E03AC9C9EB76FAC45AF8E51:F5D3D58503B9699DE785895A96FDBAAF +AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::30C81C46A35CE411E5FBC1191A0A52EF:43B1CD7F598ECE23881B00E3ED030688 +AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::F69F2445DF4F9B17AD2B417BE66C3710:7B0C785E27E8AD3F8223207104725DD4 +# ECB-AES192.Encrypt and ECB-AES192.Decrypt +AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::6BC1BEE22E409F96E93D7E117393172A:BD334F1D6E45F25FF712A214571FA5CC +AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::AE2D8A571E03AC9C9EB76FAC45AF8E51:974104846D0AD3AD7734ECB3ECEE4EEF +AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::30C81C46A35CE411E5FBC1191A0A52EF:EF7AFD2270E2E60ADCE0BA2FACE6444E +AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::F69F2445DF4F9B17AD2B417BE66C3710:9A4B41BA738D6C72FB16691603C18E0E +# ECB-AES256.Encrypt and ECB-AES256.Decrypt +AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::6BC1BEE22E409F96E93D7E117393172A:F3EED1BDB5D2A03C064B5A7E3DB181F8 +AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::AE2D8A571E03AC9C9EB76FAC45AF8E51:591CCB10D410ED26DC5BA74A31362870 +AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::30C81C46A35CE411E5FBC1191A0A52EF:B6ED21B99CA6F4F9F153E7B1BEAFED1D +AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::F69F2445DF4F9B17AD2B417BE66C3710:23304B7A39F9F3FF067D8D8F9E24ECC7 +# For all CBC encrypts and decrypts, the transformed sequence is +# AES-bits-CBC:key:IV/ciphertext':plaintext:ciphertext:encdec +# CBC-AES128.Encrypt and CBC-AES128.Decrypt +AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:7649ABAC8119B246CEE98E9B12E9197D +AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:7649ABAC8119B246CEE98E9B12E9197D:AE2D8A571E03AC9C9EB76FAC45AF8E51:5086CB9B507219EE95DB113A917678B2 +AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:5086CB9B507219EE95DB113A917678B2:30C81C46A35CE411E5FBC1191A0A52EF:73BED6B8E3C1743B7116E69E22229516 +AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:73BED6B8E3C1743B7116E69E22229516:F69F2445DF4F9B17AD2B417BE66C3710:3FF1CAA1681FAC09120ECA307586E1A7 +# CBC-AES192.Encrypt and CBC-AES192.Decrypt +AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:4F021DB243BC633D7178183A9FA071E8 +AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:4F021DB243BC633D7178183A9FA071E8:AE2D8A571E03AC9C9EB76FAC45AF8E51:B4D9ADA9AD7DEDF4E5E738763F69145A +AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:B4D9ADA9AD7DEDF4E5E738763F69145A:30C81C46A35CE411E5FBC1191A0A52EF:571B242012FB7AE07FA9BAAC3DF102E0 +AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:571B242012FB7AE07FA9BAAC3DF102E0:F69F2445DF4F9B17AD2B417BE66C3710:08B0E27988598881D920A9E64F5615CD +# CBC-AES256.Encrypt and CBC-AES256.Decrypt +AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:F58C4C04D6E5F1BA779EABFB5F7BFBD6 +AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:F58C4C04D6E5F1BA779EABFB5F7BFBD6:AE2D8A571E03AC9C9EB76FAC45AF8E51:9CFC4E967EDB808D679F777BC6702C7D +AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:9CFC4E967EDB808D679F777BC6702C7D:30C81C46A35CE411E5FBC1191A0A52EF:39F23369A9D9BACFA530E26304231461 +AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39F23369A9D9BACFA530E26304231461:F69F2445DF4F9B17AD2B417BE66C3710:B2EB05E2C39BE9FCDA6C19078C6A9D1B +# We don't support CFB{1,8}-AESxxx.{En,De}crypt +# For all CFB128 encrypts and decrypts, the transformed sequence is +# AES-bits-CFB:key:IV/ciphertext':plaintext:ciphertext:encdec +# CFB128-AES128.Encrypt +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:1 +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:3B3FD92EB72DAD20333449F8E83CFB4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:C8A64537A0B3A93FCDE3CDAD9F1CE58B:1 +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:C8A64537A0B3A93FCDE3CDAD9F1CE58B:30C81C46A35CE411E5FBC1191A0A52EF:26751F67A3CBB140B1808CF187A4F4DF:1 +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:26751F67A3CBB140B1808CF187A4F4DF:F69F2445DF4F9B17AD2B417BE66C3710:C04B05357C5D1C0EEAC4C66F9FF7F2E6:1 +# CFB128-AES128.Decrypt +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:0 +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:3B3FD92EB72DAD20333449F8E83CFB4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:C8A64537A0B3A93FCDE3CDAD9F1CE58B:0 +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:C8A64537A0B3A93FCDE3CDAD9F1CE58B:30C81C46A35CE411E5FBC1191A0A52EF:26751F67A3CBB140B1808CF187A4F4DF:0 +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:26751F67A3CBB140B1808CF187A4F4DF:F69F2445DF4F9B17AD2B417BE66C3710:C04B05357C5D1C0EEAC4C66F9FF7F2E6:0 +# CFB128-AES192.Encrypt +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:1 +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:CDC80D6FDDF18CAB34C25909C99A4174:AE2D8A571E03AC9C9EB76FAC45AF8E51:67CE7F7F81173621961A2B70171D3D7A:1 +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:67CE7F7F81173621961A2B70171D3D7A:30C81C46A35CE411E5FBC1191A0A52EF:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:1 +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:F69F2445DF4F9B17AD2B417BE66C3710:C05F9F9CA9834FA042AE8FBA584B09FF:1 +# CFB128-AES192.Decrypt +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:0 +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:CDC80D6FDDF18CAB34C25909C99A4174:AE2D8A571E03AC9C9EB76FAC45AF8E51:67CE7F7F81173621961A2B70171D3D7A:0 +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:67CE7F7F81173621961A2B70171D3D7A:30C81C46A35CE411E5FBC1191A0A52EF:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:0 +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:F69F2445DF4F9B17AD2B417BE66C3710:C05F9F9CA9834FA042AE8FBA584B09FF:0 +# CFB128-AES256.Encrypt +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:1 +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DC7E84BFDA79164B7ECD8486985D3860:AE2D8A571E03AC9C9EB76FAC45AF8E51:39FFED143B28B1C832113C6331E5407B:1 +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39FFED143B28B1C832113C6331E5407B:30C81C46A35CE411E5FBC1191A0A52EF:DF10132415E54B92A13ED0A8267AE2F9:1 +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DF10132415E54B92A13ED0A8267AE2F9:F69F2445DF4F9B17AD2B417BE66C3710:75A385741AB9CEF82031623D55B1E471:1 +# CFB128-AES256.Decrypt +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:0 +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DC7E84BFDA79164B7ECD8486985D3860:AE2D8A571E03AC9C9EB76FAC45AF8E51:39FFED143B28B1C832113C6331E5407B:0 +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39FFED143B28B1C832113C6331E5407B:30C81C46A35CE411E5FBC1191A0A52EF:DF10132415E54B92A13ED0A8267AE2F9:0 +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DF10132415E54B92A13ED0A8267AE2F9:F69F2445DF4F9B17AD2B417BE66C3710:75A385741AB9CEF82031623D55B1E471:0 +# For all OFB encrypts and decrypts, the transformed sequence is +# AES-bits-CFB:key:IV/output':plaintext:ciphertext:encdec +# OFB-AES128.Encrypt +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:1 +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:7789508D16918F03F53C52DAC54ED825:1 +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:9740051E9C5FECF64344F7A82260EDCC:1 +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:304C6528F659C77866A510D9C1D6AE5E:1 +# OFB-AES128.Decrypt +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:0 +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:7789508D16918F03F53C52DAC54ED825:0 +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:9740051E9C5FECF64344F7A82260EDCC:0 +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:304C6528F659C77866A510D9C1D6AE5E:0 +# OFB-AES192.Encrypt +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:1 +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:FCC28B8D4C63837C09E81700C1100401:1 +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:8D9A9AEAC0F6596F559C6D4DAF59A5F2:1 +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:6D9F200857CA6C3E9CAC524BD9ACC92A:1 +# OFB-AES192.Decrypt +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:0 +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:FCC28B8D4C63837C09E81700C1100401:0 +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:8D9A9AEAC0F6596F559C6D4DAF59A5F2:0 +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:6D9F200857CA6C3E9CAC524BD9ACC92A:0 +# OFB-AES256.Encrypt +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:1 +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:4FEBDC6740D20B3AC88F6AD82A4FB08D:1 +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:71AB47A086E86EEDF39D1C5BBA97C408:1 +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0126141D67F37BE8538F5A8BE740E484:1 +# OFB-AES256.Decrypt +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:0 +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:4FEBDC6740D20B3AC88F6AD82A4FB08D:0 +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:71AB47A086E86EEDF39D1C5BBA97C408:0 +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0126141D67F37BE8538F5A8BE740E484:0 + +# AES Counter test vectors from RFC3686 +aes-128-ctr:AE6852F8121067CC4BF7A5765577F39E:00000030000000000000000000000001:53696E676C6520626C6F636B206D7367:E4095D4FB7A7B3792D6175A3261311B8:1 +aes-128-ctr:7E24067817FAE0D743D6CE1F32539163:006CB6DBC0543B59DA48D90B00000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:5104A106168A72D9790D41EE8EDAD388EB2E1EFC46DA57C8FCE630DF9141BE28:1 +aes-128-ctr:7691BE035E5020A8AC6E618529F9A0DC:00E0017B27777F3F4A1786F000000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223:C1CF48A89F2FFDD9CF4652E9EFDB72D74540A42BDE6D7836D59A5CEAAEF3105325B2072F:1 + +aes-192-ctr:16AF5B145FC9F579C175F93E3BFB0EED863D06CCFDB78515:0000004836733C147D6D93CB00000001:53696E676C6520626C6F636B206D7367:4B55384FE259C9C84E7935A003CBE928:1 +aes-192-ctr:7C5CB2401B3DC33C19E7340819E0F69C678C3DB8E6F6A91A:0096B03B020C6EADC2CB500D00000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:453243FC609B23327EDFAAFA7131CD9F8490701C5AD4A79CFC1FE0FF42F4FB00:1 +aes-192-ctr:02BF391EE8ECB159B959617B0965279BF59B60A786D3E0FE:0007BDFD5CBD60278DCC091200000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223:96893FC55E5C722F540B7DD1DDF7E758D288BC95C69165884536C811662F2188ABEE0935:1 + +aes-256-ctr:776BEFF2851DB06F4C8A0542C8696F6C6A81AF1EEC96B4D37FC1D689E6C1C104:00000060DB5672C97AA8F0B200000001:53696E676C6520626C6F636B206D7367:145AD01DBF824EC7560863DC71E3E0C0:1 +aes-256-ctr:F6D66D6BD52D59BB0796365879EFF886C66DD51A5B6A99744B50590C87A23884:00FAAC24C1585EF15A43D87500000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:F05E231B3894612C49EE000B804EB2A9B8306B508F839D6A5530831D9344AF1C:1 +aes-256-ctr:FF7A617CE69148E4F1726E2F43581DE2AA62D9F805532EDFF1EED687FB54153D:001CC5B751A51D70A1C1114800000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223:EB6C52821D0BBBF7CE7594462ACA4FAAB407DF866569FD07F48CC0B583D6071F1EC0E6B8:1 + +# DES ECB tests (from destest) + +DES-ECB:0000000000000000::0000000000000000:8CA64DE9C1B123A7 +DES-ECB:FFFFFFFFFFFFFFFF::FFFFFFFFFFFFFFFF:7359B2163E4EDC58 +DES-ECB:3000000000000000::1000000000000001:958E6E627A05557B +DES-ECB:1111111111111111::1111111111111111:F40379AB9E0EC533 +DES-ECB:0123456789ABCDEF::1111111111111111:17668DFC7292532D +DES-ECB:1111111111111111::0123456789ABCDEF:8A5AE1F81AB8F2DD +DES-ECB:FEDCBA9876543210::0123456789ABCDEF:ED39D950FA74BCC4 + +# DESX-CBC tests (from destest) +DESX-CBC:0123456789abcdeff1e0d3c2b5a49786fedcba9876543210:fedcba9876543210:37363534333231204E6F77206973207468652074696D6520666F722000000000:846B2914851E9A2954732F8AA0A611C115CDC2D7951B1053A63C5E03B21AA3C4 + +# DES EDE3 CBC tests (from destest) +DES-EDE3-CBC:0123456789abcdeff1e0d3c2b5a49786fedcba9876543210:fedcba9876543210:37363534333231204E6F77206973207468652074696D6520666F722000000000:3FE301C962AC01D02213763C1CBD4CDC799657C064ECF5D41C673812CFDE9675 + +# RC4 tests (from rc4test) +RC4:0123456789abcdef0123456789abcdef::0123456789abcdef:75b7878099e0c596 +RC4:0123456789abcdef0123456789abcdef::0000000000000000:7494c2e7104b0879 +RC4:00000000000000000000000000000000::0000000000000000:de188941a3375d3a +RC4:ef012345ef012345ef012345ef012345::0000000000000000000000000000000000000000:d6a141a7ec3c38dfbd615a1162e1c7ba36b67858 +RC4:0123456789abcdef0123456789abcdef::123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345678:66a0949f8af7d6891f7f832ba833c00c892ebe30143ce28740011ecf +RC4:ef012345ef012345ef012345ef012345::00000000000000000000:d6a141a7ec3c38dfbd61 + + +# Camellia tests from RFC3713 +# For all ECB encrypts and decrypts, the transformed sequence is +# CAMELLIA-bits-ECB:key::plaintext:ciphertext:encdec +CAMELLIA-128-ECB:0123456789abcdeffedcba9876543210::0123456789abcdeffedcba9876543210:67673138549669730857065648eabe43 +CAMELLIA-192-ECB:0123456789abcdeffedcba98765432100011223344556677::0123456789abcdeffedcba9876543210:b4993401b3e996f84ee5cee7d79b09b9 +CAMELLIA-256-ECB:0123456789abcdeffedcba987654321000112233445566778899aabbccddeeff::0123456789abcdeffedcba9876543210:9acc237dff16d76c20ef7c919e3a7509 + +# ECB-CAMELLIA128.Encrypt +CAMELLIA-128-ECB:000102030405060708090A0B0C0D0E0F::00112233445566778899AABBCCDDEEFF:77CF412067AF8270613529149919546F:1 +CAMELLIA-192-ECB:000102030405060708090A0B0C0D0E0F1011121314151617::00112233445566778899AABBCCDDEEFF:B22F3C36B72D31329EEE8ADDC2906C68:1 +CAMELLIA-256-ECB:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF:2EDF1F3418D53B88841FC8985FB1ECF2:1 + +# ECB-CAMELLIA128.Encrypt and ECB-CAMELLIA128.Decrypt +CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::6BC1BEE22E409F96E93D7E117393172A:432FC5DCD628115B7C388D770B270C96 +CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::AE2D8A571E03AC9C9EB76FAC45AF8E51:0BE1F14023782A22E8384C5ABB7FAB2B +CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::30C81C46A35CE411E5FBC1191A0A52EF:A0A1ABCD1893AB6FE0FE5B65DF5F8636 +CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::F69F2445DF4F9B17AD2B417BE66C3710:E61925E0D5DFAA9BB29F815B3076E51A + +# ECB-CAMELLIA192.Encrypt and ECB-CAMELLIA192.Decrypt +CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::6BC1BEE22E409F96E93D7E117393172A:CCCC6C4E138B45848514D48D0D3439D3 +CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::AE2D8A571E03AC9C9EB76FAC45AF8E51:5713C62C14B2EC0F8393B6AFD6F5785A +CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::30C81C46A35CE411E5FBC1191A0A52EF:B40ED2B60EB54D09D030CF511FEEF366 +CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::F69F2445DF4F9B17AD2B417BE66C3710:909DBD95799096748CB27357E73E1D26 + +# ECB-CAMELLIA256.Encrypt and ECB-CAMELLIA256.Decrypt +CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::6BC1BEE22E409F96E93D7E117393172A:BEFD219B112FA00098919CD101C9CCFA +CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::AE2D8A571E03AC9C9EB76FAC45AF8E51:C91D3A8F1AEA08A9386CF4B66C0169EA +CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::30C81C46A35CE411E5FBC1191A0A52EF:A623D711DC5F25A51BB8A80D56397D28 +CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::F69F2445DF4F9B17AD2B417BE66C3710:7960109FB6DC42947FCFE59EA3C5EB6B + +# For all CBC encrypts and decrypts, the transformed sequence is +# CAMELLIA-bits-CBC:key:IV/ciphertext':plaintext:ciphertext:encdec +# CBC-CAMELLIA128.Encrypt and CBC-CAMELLIA128.Decrypt +CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:1607CF494B36BBF00DAEB0B503C831AB +CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:1607CF494B36BBF00DAEB0B503C831AB:AE2D8A571E03AC9C9EB76FAC45AF8E51:A2F2CF671629EF7840C5A5DFB5074887 +CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:A2F2CF671629EF7840C5A5DFB5074887:30C81C46A35CE411E5FBC1191A0A52EF:0F06165008CF8B8B5A63586362543E54 +CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:36A84CDAFD5F9A85ADA0F0A993D6D577:F69F2445DF4F9B17AD2B417BE66C3710:74C64268CDB8B8FAF5B34E8AF3732980 + +# CBC-CAMELLIA192.Encrypt and CBC-CAMELLIA192.Decrypt +CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:2A4830AB5AC4A1A2405955FD2195CF93 +CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:2A4830AB5AC4A1A2405955FD2195CF93:AE2D8A571E03AC9C9EB76FAC45AF8E51:5D5A869BD14CE54264F892A6DD2EC3D5 +CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:5D5A869BD14CE54264F892A6DD2EC3D5:30C81C46A35CE411E5FBC1191A0A52EF:37D359C3349836D884E310ADDF68C449 +CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:37D359C3349836D884E310ADDF68C449:F69F2445DF4F9B17AD2B417BE66C3710:01FAAA930B4AB9916E9668E1428C6B08 + +# CBC-CAMELLIA256.Encrypt and CBC-CAMELLIA256.Decrypt +CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:E6CFA35FC02B134A4D2C0B6737AC3EDA +CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E6CFA35FC02B134A4D2C0B6737AC3EDA:AE2D8A571E03AC9C9EB76FAC45AF8E51:36CBEB73BD504B4070B1B7DE2B21EB50 +CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:36CBEB73BD504B4070B1B7DE2B21EB50:30C81C46A35CE411E5FBC1191A0A52EF:E31A6055297D96CA3330CDF1B1860A83 +CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E31A6055297D96CA3330CDF1B1860A83:F69F2445DF4F9B17AD2B417BE66C3710:5D563F6D1CCCF236051C0C5C1C58F28F + +# We don't support CFB{1,8}-CAMELLIAxxx.{En,De}crypt +# For all CFB128 encrypts and decrypts, the transformed sequence is +# CAMELLIA-bits-CFB:key:IV/ciphertext':plaintext:ciphertext:encdec +# CFB128-CAMELLIA128.Encrypt +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:1 +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:14F7646187817EB586599146B82BD719:AE2D8A571E03AC9C9EB76FAC45AF8E51:A53D28BB82DF741103EA4F921A44880B:1 +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:A53D28BB82DF741103EA4F921A44880B:30C81C46A35CE411E5FBC1191A0A52EF:9C2157A664626D1DEF9EA420FDE69B96:1 +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:9C2157A664626D1DEF9EA420FDE69B96:F69F2445DF4F9B17AD2B417BE66C3710:742A25F0542340C7BAEF24CA8482BB09:1 + +# CFB128-CAMELLIA128.Decrypt +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:0 +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:14F7646187817EB586599146B82BD719:AE2D8A571E03AC9C9EB76FAC45AF8E51:A53D28BB82DF741103EA4F921A44880B:0 +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:A53D28BB82DF741103EA4F921A44880B:30C81C46A35CE411E5FBC1191A0A52EF:9C2157A664626D1DEF9EA420FDE69B96:0 +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:9C2157A664626D1DEF9EA420FDE69B96:F69F2445DF4F9B17AD2B417BE66C3710:742A25F0542340C7BAEF24CA8482BB09:0 + +# CFB128-CAMELLIA192.Encrypt +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:1 +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:C832BB9780677DAA82D9B6860DCD565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:86F8491627906D780C7A6D46EA331F98:1 +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:86F8491627906D780C7A6D46EA331F98:30C81C46A35CE411E5FBC1191A0A52EF:69511CCE594CF710CB98BB63D7221F01:1 +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:69511CCE594CF710CB98BB63D7221F01:F69F2445DF4F9B17AD2B417BE66C3710:D5B5378A3ABED55803F25565D8907B84:1 + +# CFB128-CAMELLIA192.Decrypt +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:0 +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:C832BB9780677DAA82D9B6860DCD565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:86F8491627906D780C7A6D46EA331F98:0 +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:86F8491627906D780C7A6D46EA331F98:30C81C46A35CE411E5FBC1191A0A52EF:69511CCE594CF710CB98BB63D7221F01:0 +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:69511CCE594CF710CB98BB63D7221F01:F69F2445DF4F9B17AD2B417BE66C3710:D5B5378A3ABED55803F25565D8907B84:0 + +# CFB128-CAMELLIA256.Encrypt +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:1 +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:CF6107BB0CEA7D7FB1BD31F5E7B06C93:AE2D8A571E03AC9C9EB76FAC45AF8E51:89BEDB4CCDD864EA11BA4CBE849B5E2B:1 +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:89BEDB4CCDD864EA11BA4CBE849B5E2B:30C81C46A35CE411E5FBC1191A0A52EF:555FC3F34BDD2D54C62D9E3BF338C1C4:1 +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:555FC3F34BDD2D54C62D9E3BF338C1C4:F69F2445DF4F9B17AD2B417BE66C3710:5953ADCE14DB8C7F39F1BD39F359BFFA:1 + +# CFB128-CAMELLIA256.Decrypt +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:0 +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:CF6107BB0CEA7D7FB1BD31F5E7B06C93:AE2D8A571E03AC9C9EB76FAC45AF8E51:89BEDB4CCDD864EA11BA4CBE849B5E2B:0 +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:89BEDB4CCDD864EA11BA4CBE849B5E2B:30C81C46A35CE411E5FBC1191A0A52EF:555FC3F34BDD2D54C62D9E3BF338C1C4:0 +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:555FC3F34BDD2D54C62D9E3BF338C1C4:F69F2445DF4F9B17AD2B417BE66C3710:5953ADCE14DB8C7F39F1BD39F359BFFA:0 + +# For all OFB encrypts and decrypts, the transformed sequence is +# CAMELLIA-bits-OFB:key:IV/output':plaintext:ciphertext:encdec +# OFB-CAMELLIA128.Encrypt +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:1 +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:25623DB569CA51E01482649977E28D84:1 +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:C776634A60729DC657D12B9FCA801E98:1 +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:D776379BE0E50825E681DA1A4C980E8E:1 + +# OFB-CAMELLIA128.Decrypt +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:0 +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:25623DB569CA51E01482649977E28D84:0 +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:C776634A60729DC657D12B9FCA801E98:0 +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:D776379BE0E50825E681DA1A4C980E8E:0 + +# OFB-CAMELLIA192.Encrypt +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:1 +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:8ECEB7D0350D72C7F78562AEBDF99339:1 +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:BDD62DBBB9700846C53B507F544696F0:1 +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:E28014E046B802F385C4C2E13EAD4A72:1 + +# OFB-CAMELLIA192.Decrypt +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:0 +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:8ECEB7D0350D72C7F78562AEBDF99339:0 +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:BDD62DBBB9700846C53B507F544696F0:0 +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:E28014E046B802F385C4C2E13EAD4A72:0 + +# OFB-CAMELLIA256.Encrypt +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:1 +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:127AD97E8E3994E4820027D7BA109368:1 +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:6BFF6265A6A6B7A535BC65A80B17214E:1 +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0A4A0404E26AA78A27CB271E8BF3CF20:1 + +# OFB-CAMELLIA256.Decrypt +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:0 +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:127AD97E8E3994E4820027D7BA109368:0 +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:6BFF6265A6A6B7A535BC65A80B17214E:0 +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0A4A0404E26AA78A27CB271E8BF3CF20:0 + +# SEED test vectors from RFC4269 +SEED-ECB:00000000000000000000000000000000::000102030405060708090A0B0C0D0E0F:5EBAC6E0054E166819AFF1CC6D346CDB:0 +SEED-ECB:000102030405060708090A0B0C0D0E0F::00000000000000000000000000000000:C11F22F20140505084483597E4370F43:0 +SEED-ECB:4706480851E61BE85D74BFB3FD956185::83A2F8A288641FB9A4E9A5CC2F131C7D:EE54D13EBCAE706D226BC3142CD40D4A:0 +SEED-ECB:28DBC3BC49FFD87DCFA509B11D422BE7::B41E6BE2EBA84A148E2EED84593C5EC7:9B9B7BFCD1813CB95D0B3618F40F5122:0 +SEED-ECB:00000000000000000000000000000000::000102030405060708090A0B0C0D0E0F:5EBAC6E0054E166819AFF1CC6D346CDB:1 +SEED-ECB:000102030405060708090A0B0C0D0E0F::00000000000000000000000000000000:C11F22F20140505084483597E4370F43:1 +SEED-ECB:4706480851E61BE85D74BFB3FD956185::83A2F8A288641FB9A4E9A5CC2F131C7D:EE54D13EBCAE706D226BC3142CD40D4A:1 +SEED-ECB:28DBC3BC49FFD87DCFA509B11D422BE7::B41E6BE2EBA84A148E2EED84593C5EC7:9B9B7BFCD1813CB95D0B3618F40F5122:1 \ No newline at end of file diff --git a/t/cipher_twofish.t b/t/cipher_twofish.t new file mode 100644 index 0000000..310f8d0 --- /dev/null +++ b/t/cipher_twofish.t @@ -0,0 +1,65 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 38; + +use Crypt::Cipher; +use Crypt::Cipher::Twofish; + +is( Crypt::Cipher::Twofish::blocksize, 16, '::blocksize'); +is( Crypt::Cipher::Twofish::keysize, 32, '::keysize'); +is( Crypt::Cipher::Twofish::max_keysize, 32, '::max_keysize'); +is( Crypt::Cipher::Twofish::min_keysize, 16, '::min_keysize'); +is( Crypt::Cipher::Twofish::default_rounds, 16, '::default_rounds'); + +is( Crypt::Cipher::Twofish->blocksize, 16, '->blocksize'); +is( Crypt::Cipher::Twofish->keysize, 32, '->keysize'); +is( Crypt::Cipher::Twofish->max_keysize, 32, '->max_keysize'); +is( Crypt::Cipher::Twofish->min_keysize, 16, '->min_keysize'); +is( Crypt::Cipher::Twofish->default_rounds, 16, '->default_rounds'); + +my $min_key = 'kkkkkkkkkkkkkkkk'; +my $max_key = 'KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK'; + +is( Crypt::Cipher::blocksize('Twofish'), 16, 'Cipher->blocksize'); +is( Crypt::Cipher::keysize('Twofish'), 32, 'Cipher->keysize'); +is( Crypt::Cipher::max_keysize('Twofish'), 32, 'Cipher->max_keysize'); +is( Crypt::Cipher::min_keysize('Twofish'), 16, 'Cipher->min_keysize'); +is( Crypt::Cipher::default_rounds('Twofish'), 16, 'Cipher->default_rounds'); + +is( Crypt::Cipher->blocksize('Twofish'), 16, 'Cipher->blocksize'); +is( Crypt::Cipher->keysize('Twofish'), 32, 'Cipher->keysize'); +is( Crypt::Cipher->max_keysize('Twofish'), 32, 'Cipher->max_keysize'); +is( Crypt::Cipher->min_keysize('Twofish'), 16, 'Cipher->min_keysize'); +is( Crypt::Cipher->default_rounds('Twofish'), 16, 'Cipher->default_rounds'); + +is( Crypt::Cipher::Twofish->new($min_key)->blocksize, 16, 'Twofish->new()->blocksize'); +is( Crypt::Cipher::Twofish->new($min_key)->keysize, 32, 'Twofish->new()->keysize'); +is( Crypt::Cipher::Twofish->new($min_key)->max_keysize, 32, 'Twofish->new()->max_keysize'); +is( Crypt::Cipher::Twofish->new($min_key)->min_keysize, 16, 'Twofish->new()->min_keysize'); +is( Crypt::Cipher::Twofish->new($min_key)->default_rounds, 16, 'Twofish->new()->default_rounds'); + +is( Crypt::Cipher->new('Twofish', $min_key)->blocksize, 16, 'Cipher->new()->blocksize'); +is( Crypt::Cipher->new('Twofish', $min_key)->keysize, 32, 'Cipher->new()->keysize'); +is( Crypt::Cipher->new('Twofish', $min_key)->max_keysize, 32, 'Cipher->new()->max_keysize'); +is( Crypt::Cipher->new('Twofish', $min_key)->min_keysize, 16, 'Cipher->new()->min_keysize'); +is( Crypt::Cipher->new('Twofish', $min_key)->default_rounds, 16, 'Cipher->new()->default_rounds'); + +my $block_plain = 'BBBBBBBBBBBBBBBB'; +my $block_encrypted_min_key_hex = '7fb9ade3245d2c1a230e03a94bcfb0ce'; +my $block_encrypted_max_key_hex = '2ff825152c6b500a3bf53cb334626e65'; + +is( unpack('H*', Crypt::Cipher::Twofish->new($min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Twofish->encrypt'); +is( Crypt::Cipher::Twofish->new($min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Twofish->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('Twofish', $min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('Twofish', $min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Cipher->decrypt'); + +is( unpack('H*', Crypt::Cipher::Twofish->new($max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Twofish->encrypt'); +is( Crypt::Cipher::Twofish->new($max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Twofish->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('Twofish', $max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('Twofish', $max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Cipher->decrypt'); + diff --git a/t/cipher_twofish_test_vectors_bc.t b/t/cipher_twofish_test_vectors_bc.t new file mode 100644 index 0000000..11f616a --- /dev/null +++ b/t/cipher_twofish_test_vectors_bc.t @@ -0,0 +1,27 @@ +use strict; +use warnings; + +use Test::More tests => 3; +use Crypt::Cipher::Twofish; + +my $line = 1; +while (my $l = ) { + chomp($l); + $l =~ s/[\s\t]+/ /g; + my $d = {}; + for my $pair (split / /, $l) { + my ($k, $v) = split /:/, $pair; + $d->{$k} = $v; + } + + my $c = Crypt::Cipher::Twofish->new(pack('H*',$d->{key})); + my $result = pack('H*', $d->{pt}); + $result = $c->encrypt($result) for(1..$d->{iter}); + is(unpack('H*', $result), lc($d->{ct}), "line=$line"); + $line++; +} + +__DATA__ +iter:1 key:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f pt:000102030405060708090A0B0C0D0E0F ct:8ef0272c42db838bcf7b07af0ec30f38 +iter:1 key:000102030405060708090a0b0c0d0e0f1011121314151617 pt:000102030405060708090A0B0C0D0E0F ct:95accc625366547617f8be4373d10cd7 +iter:1 key:000102030405060708090a0b0c0d0e0f pt:000102030405060708090A0B0C0D0E0F ct:9fb63337151be9c71306d159ea7afaa4 diff --git a/t/cipher_xtea.t b/t/cipher_xtea.t new file mode 100644 index 0000000..78b3c72 --- /dev/null +++ b/t/cipher_xtea.t @@ -0,0 +1,65 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 38; + +use Crypt::Cipher; +use Crypt::Cipher::XTEA; + +is( Crypt::Cipher::XTEA::blocksize, 8, '::blocksize'); +is( Crypt::Cipher::XTEA::keysize, 16, '::keysize'); +is( Crypt::Cipher::XTEA::max_keysize, 16, '::max_keysize'); +is( Crypt::Cipher::XTEA::min_keysize, 16, '::min_keysize'); +is( Crypt::Cipher::XTEA::default_rounds, 32, '::default_rounds'); + +is( Crypt::Cipher::XTEA->blocksize, 8, '->blocksize'); +is( Crypt::Cipher::XTEA->keysize, 16, '->keysize'); +is( Crypt::Cipher::XTEA->max_keysize, 16, '->max_keysize'); +is( Crypt::Cipher::XTEA->min_keysize, 16, '->min_keysize'); +is( Crypt::Cipher::XTEA->default_rounds, 32, '->default_rounds'); + +my $min_key = 'kkkkkkkkkkkkkkkk'; +my $max_key = 'KKKKKKKKKKKKKKKK'; + +is( Crypt::Cipher::blocksize('XTEA'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher::keysize('XTEA'), 16, 'Cipher->keysize'); +is( Crypt::Cipher::max_keysize('XTEA'), 16, 'Cipher->max_keysize'); +is( Crypt::Cipher::min_keysize('XTEA'), 16, 'Cipher->min_keysize'); +is( Crypt::Cipher::default_rounds('XTEA'), 32, 'Cipher->default_rounds'); + +is( Crypt::Cipher->blocksize('XTEA'), 8, 'Cipher->blocksize'); +is( Crypt::Cipher->keysize('XTEA'), 16, 'Cipher->keysize'); +is( Crypt::Cipher->max_keysize('XTEA'), 16, 'Cipher->max_keysize'); +is( Crypt::Cipher->min_keysize('XTEA'), 16, 'Cipher->min_keysize'); +is( Crypt::Cipher->default_rounds('XTEA'), 32, 'Cipher->default_rounds'); + +is( Crypt::Cipher::XTEA->new($min_key)->blocksize, 8, 'XTEA->new()->blocksize'); +is( Crypt::Cipher::XTEA->new($min_key)->keysize, 16, 'XTEA->new()->keysize'); +is( Crypt::Cipher::XTEA->new($min_key)->max_keysize, 16, 'XTEA->new()->max_keysize'); +is( Crypt::Cipher::XTEA->new($min_key)->min_keysize, 16, 'XTEA->new()->min_keysize'); +is( Crypt::Cipher::XTEA->new($min_key)->default_rounds, 32, 'XTEA->new()->default_rounds'); + +is( Crypt::Cipher->new('XTEA', $min_key)->blocksize, 8, 'Cipher->new()->blocksize'); +is( Crypt::Cipher->new('XTEA', $min_key)->keysize, 16, 'Cipher->new()->keysize'); +is( Crypt::Cipher->new('XTEA', $min_key)->max_keysize, 16, 'Cipher->new()->max_keysize'); +is( Crypt::Cipher->new('XTEA', $min_key)->min_keysize, 16, 'Cipher->new()->min_keysize'); +is( Crypt::Cipher->new('XTEA', $min_key)->default_rounds, 32, 'Cipher->new()->default_rounds'); + +my $block_plain = 'BBBBBBBB'; +my $block_encrypted_min_key_hex = '29917be6d71868b4'; +my $block_encrypted_max_key_hex = '6b5f7efad4270837'; + +is( unpack('H*', Crypt::Cipher::XTEA->new($min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'XTEA->encrypt'); +is( Crypt::Cipher::XTEA->new($min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'XTEA->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('XTEA', $min_key)->encrypt($block_plain)), $block_encrypted_min_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('XTEA', $min_key)->decrypt(pack('H*', $block_encrypted_min_key_hex)), $block_plain, 'Cipher->decrypt'); + +is( unpack('H*', Crypt::Cipher::XTEA->new($max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'XTEA->encrypt'); +is( Crypt::Cipher::XTEA->new($max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'XTEA->decrypt'); + +is( unpack('H*', Crypt::Cipher->new('XTEA', $max_key)->encrypt($block_plain)), $block_encrypted_max_key_hex, 'Cipher->encrypt'); +is( Crypt::Cipher->new('XTEA', $max_key)->decrypt(pack('H*', $block_encrypted_max_key_hex)), $block_plain, 'Cipher->decrypt'); + diff --git a/t/cipher_xtea_test_vectors_bc.t b/t/cipher_xtea_test_vectors_bc.t new file mode 100644 index 0000000..4a4dbb8 --- /dev/null +++ b/t/cipher_xtea_test_vectors_bc.t @@ -0,0 +1,28 @@ +use strict; +use warnings; + +use Test::More tests => 4; +use Crypt::Cipher::XTEA; + +my $line = 1; +while (my $l = ) { + chomp($l); + $l =~ s/[\s\t]+/ /g; + my $d = {}; + for my $pair (split / /, $l) { + my ($k, $v) = split /:/, $pair; + $d->{$k} = $v; + } + + my $c = Crypt::Cipher::XTEA->new(pack('H*',$d->{key})); + my $result = pack('H*', $d->{pt}); + $result = $c->encrypt($result) for(1..$d->{iter}); + is(unpack('H*', $result), lc($d->{ct}), "line=$line"); + $line++; +} + +__DATA__ +iter:1 key:00000000000000000000000000000000 pt:0000000000000000 ct:dee9d4d8f7131ed9 +iter:1 key:00000000000000000000000000000000 pt:0102030405060708 ct:065c1b8975c6a816 +iter:1 key:0123456712345678234567893456789A pt:0000000000000000 ct:1ff9a0261ac64264 +iter:1 key:0123456712345678234567893456789A pt:0102030405060708 ct:8c67155b2ef91ead diff --git a/t/crypt-misc.t b/t/crypt-misc.t new file mode 100644 index 0000000..e7064ae --- /dev/null +++ b/t/crypt-misc.t @@ -0,0 +1,56 @@ +use strict; +use warnings; +use Test::More tests => 41; + +use Crypt::Misc qw(encode_b64 decode_b64 encode_b64u decode_b64u pem_to_der der_to_pem read_rawfile write_rawfile slow_eq is_v4uuid random_v4uuid); + +is(encode_b64(pack("H*","702fad4215a04a657f011d3ea5711879c696788c91d2")), "cC+tQhWgSmV/AR0+pXEYecaWeIyR0g==", "encode_b64"); +is(unpack("H*", decode_b64("cC+tQhWgSmV/AR0+pXEYecaWeIyR0g==")), "702fad4215a04a657f011d3ea5711879c696788c91d2", "decode_b64"); +is(unpack("H*", decode_b64("cC+tQhWgSmV/AR0+pXEYecaWeIyR0g")), "702fad4215a04a657f011d3ea5711879c696788c91d2", "decode_b64/relaxed1"); +is(unpack("H*", decode_b64("cC+tQh\nWgSmV/A\nR0+pXEYec\naWeIyR0g")), "702fad4215a04a657f011d3ea5711879c696788c91d2", "decode_b64/relaxed2"); +is(unpack("H*", decode_b64("cC+tQh\r\nWgSmV/A\r\nR0+pXEYec\r\naWeIyR0g")), "702fad4215a04a657f011d3ea5711879c696788c91d2", "decode_b64/relaxed3"); +is(unpack("H*", decode_b64("cC+tQh WgSmV/A R0+pXEYec aWeIyR0g")), "702fad4215a04a657f011d3ea5711879c696788c91d2", "decode_b64/relaxed4"); +is(unpack("H*", decode_b64("cC+tQh\tWgSmV/A\tR0+pXEYec\taWeIyR0g")), "702fad4215a04a657f011d3ea5711879c696788c91d2", "decode_b64/relaxed5"); + +is(encode_b64u(pack("H*","702fad4215a04a657f011d3ea5711879c696788c91d2")), "cC-tQhWgSmV_AR0-pXEYecaWeIyR0g", "encode_b64u"); +is(unpack("H*", decode_b64u("cC-tQhWgSmV_AR0-pXEYecaWeIyR0g")), "702fad4215a04a657f011d3ea5711879c696788c91d2", "decode_b64u"); +is(unpack("H*", decode_b64u("cC-tQhWgSmV_AR0-pXEYecaWeIyR0g==")), "702fad4215a04a657f011d3ea5711879c696788c91d2", "decode_b64u/padded"); +is(unpack("H*", decode_b64u("cC-tQh\nWgSmV_A\nR0-pXEYec\naWeIyR0g")), "702fad4215a04a657f011d3ea5711879c696788c91d2", "decode_b64u/relaxed1"); +is(unpack("H*", decode_b64u("cC-tQh\r\nWgSmV_A\r\nR0-pXEYec\r\naWeIyR0g")), "702fad4215a04a657f011d3ea5711879c696788c91d2", "decode_b64u/relaxed2"); +is(unpack("H*", decode_b64u("cC-tQh WgSmV_A R0-pXEYec aWeIyR0g")), "702fad4215a04a657f011d3ea5711879c696788c91d2", "decode_b64u/relaxed3"); +is(unpack("H*", decode_b64u("cC-tQh\tWgSmV_A\tR0-pXEYec\taWeIyR0g")), "702fad4215a04a657f011d3ea5711879c696788c91d2", "decode_b64u/relaxed4"); + +is(decode_b64("Zg==" ), "f", "ltc 1a"); +is(decode_b64("Zg=" ), "f", "ltc 1b"); +is(decode_b64("Zg" ), "f", "ltc 1c"); +is(decode_b64("Zm8=" ), "fo", "ltc 2a"); +is(decode_b64("Zm8" ), "fo", "ltc 2b"); +is(decode_b64("Zm9v" ), "foo", "ltc 3"); +is(decode_b64("Zm9vYg=="), "foob", "ltc 4a"); +is(decode_b64("Zm9vYg=" ), "foob", "ltc 4b"); +is(decode_b64("Zm9vYg" ), "foob", "ltc 4c"); +is(decode_b64("Zm9vYmE="), "fooba", "ltc 5a"); +is(decode_b64("Zm9vYmE" ), "fooba", "ltc 5b"); +is(decode_b64("Zm9vYmFy"), "foobar", "ltc 6"); + +is(decode_b64u("Zg==" ), "f", "ltcu 1a"); +is(decode_b64u("Zg=" ), "f", "ltcu 1b"); +is(decode_b64u("Zg" ), "f", "ltcu 1c"); +is(decode_b64u("Zm8=" ), "fo", "ltcu 2a"); +is(decode_b64u("Zm8" ), "fo", "ltcu 2b"); +is(decode_b64u("Zm9v" ), "foo", "ltcu 3"); +is(decode_b64u("Zm9vYg=="), "foob", "ltcu 4a"); +is(decode_b64u("Zm9vYg=" ), "foob", "ltcu 4b"); +is(decode_b64u("Zm9vYg" ), "foob", "ltcu 4c"); +is(decode_b64u("Zm9vYmE="), "fooba", "ltcu 5a"); +is(decode_b64u("Zm9vYmE" ), "fooba", "ltcu 5b"); +is(decode_b64u("Zm9vYmFy"), "foobar", "ltcu 6"); + +write_rawfile("tmp.$$.file", "a\nb\r\nc\rd\te"); +ok(slow_eq(read_rawfile("tmp.$$.file"), "a\nb\r\nc\rd\te"), "slow_eq + read_rawfile + write_rawfile"); +unlink "tmp.$$.file"; + +my $uuid = random_v4uuid; +ok($uuid, 'random_v4uuid'); +ok(is_v4uuid($uuid), 'is_v4uuid'); + diff --git a/t/data/binary-test.file b/t/data/binary-test.file new file mode 100644 index 0000000..380ee63 Binary files /dev/null and b/t/data/binary-test.file differ diff --git a/t/data/cryptx_priv_dh1.bin b/t/data/cryptx_priv_dh1.bin new file mode 100644 index 0000000..1b73aeb Binary files /dev/null and b/t/data/cryptx_priv_dh1.bin differ diff --git a/t/data/cryptx_priv_dh2.bin b/t/data/cryptx_priv_dh2.bin new file mode 100644 index 0000000..e0a4525 Binary files /dev/null and b/t/data/cryptx_priv_dh2.bin differ diff --git a/t/data/cryptx_priv_dh_pg1.bin b/t/data/cryptx_priv_dh_pg1.bin new file mode 100644 index 0000000..5e9bd0e Binary files /dev/null and b/t/data/cryptx_priv_dh_pg1.bin differ diff --git a/t/data/cryptx_priv_dh_pg2.bin b/t/data/cryptx_priv_dh_pg2.bin new file mode 100644 index 0000000..9344acb Binary files /dev/null and b/t/data/cryptx_priv_dh_pg2.bin differ diff --git a/t/data/cryptx_priv_dsa1.der b/t/data/cryptx_priv_dsa1.der new file mode 100644 index 0000000..31d68ae Binary files /dev/null and b/t/data/cryptx_priv_dsa1.der differ diff --git a/t/data/cryptx_priv_dsa1.pem b/t/data/cryptx_priv_dsa1.pem new file mode 100644 index 0000000..62b0ba2 --- /dev/null +++ b/t/data/cryptx_priv_dsa1.pem @@ -0,0 +1,18 @@ +-----BEGIN DSA PRIVATE KEY----- +MIIDUwIBAAKCAQEAqvg5p2TgTYCCS3n6HwSWwJNPhYAPYTj5c4hxiPXxFgbECtxAfaj8opwMc0/L +kNIuA8iW0HaUmWQm8K4l/HzGZsH28ABbYbSRVDFc88fxiT9rv28382V7FhsrBqXcsS65H3r3pgUD +P1wq9d0J760PgTavt1i49Lpp4OyoY+rVLcNkwhx9+lEdsjhHAni4HpZeb81aU6eE2sozpEtNoPgH +um+BzMth1lUsABuFaG/Hw49tK6GIZef7Uy1LDCXiyYsu4omsUFVd+IpEUUQCN5qS76QWSpR9wPwL +fzCNWjpfD0wt9m/azvJqDfoFGOqORS9TQZqpEGztl7wtQJVez4w7PQIfANBcTLRfKdNTRC8f7EOm +vivox4Zb0EPvFfN+fwuCCQKCAQEAhH6IltEsm/GP4oOuetWO1/N3Ft4nDY/WZGQ45iY8xqvwf/qt +ShG8siu6yWHRpiw6WInq2pgoPh8H6NttginoekQp2ZLGLsl240MGOq5wfuYkdf/b0xFGsu1pukn0 +DNwUif+2v2/jQiXhzg1wVlR7uDmVBwNJhUy2W6VY/oGyWTNPrpha2XkgkWEWVA94fB/epRBI/zFy +E5KBIzjJEK5Bn0ZClqPM2p+L+hdhBtBwk+AwBN695K37hw2Brg5+2SKqp3UtWEJwUs2H9kptS//X +7ws07Yc3GS6y7H1EJ3lOSCYkaBmrwqipd0bxHbPoT0/L5SzswMI78XQztaFAja7jnwKCAQEAj3YE +13+mLHU5ViRYpjx2Ebc4t9QYb7k2xGK4KsJPHjj+Yn2eV1ZB1y48d7v1e/Yob6UGPWrFj9jdELL9 +rj8Ej4dMfO6oYZzGnMC4gW6VNmgXORlw2ZSlCGpWuUM51uCN8yBvMa76d9I/ThpE9k40a/PYnVyC +m2dQTSzZtv9wv/m+CDwzisEcngzJKAyrZpcE3r4O6G1w10I1bucstCasKKMtLOBzzPys8Zvbpnpb +aMK2OFVyQohj0Ej7GPvfIG7scU/6ArGmOzCGvGsVWYLmPHTNExO+PG+E9FiEN21c6VihAAR+itOp +YhETXPmS3vq3HdoxM0IvnhE7EGF6W0yPFgIebIAZAax04txxTXWp9paUg88COdFCq34/Mp7Y1J4H +-----END DSA PRIVATE KEY----- + \ No newline at end of file diff --git a/t/data/cryptx_priv_dsa2.der b/t/data/cryptx_priv_dsa2.der new file mode 100644 index 0000000..f125f2d Binary files /dev/null and b/t/data/cryptx_priv_dsa2.der differ diff --git a/t/data/cryptx_priv_dsa2.pem b/t/data/cryptx_priv_dsa2.pem new file mode 100644 index 0000000..35a4d7b --- /dev/null +++ b/t/data/cryptx_priv_dsa2.pem @@ -0,0 +1,18 @@ +-----BEGIN DSA PRIVATE KEY----- +MIIDUQIBAAKCAQEAv0s313ssAxTEdb83x9TKX7fSAgLiWegQwBEONcKCqeMr9SHoUk2KBe1KFLwa +l3htNWYkAwzGEpDGJwZSQroEK14WidisDEDhVbH2k7F14EBKcv1HbltnmROMTFAFijr6m0IEYjaf +rdbZiMTazgdwou4Z1lyyktGFhgi7Y51EyXyGUccQ1tTXUJH2l9kk/wxVlA8NF0QDh78CNh8tAzc8 +wmalXENDd2mfPaWTTK+YukluPlhDUtW//f2BmLF+6sGTSwDvHif80LbThz0nPaMWOFiAZX2GEMkr +iX++N+WPe8tjmSzZrqvoM+yXjbFO84iKPkUHVBezh0kd7MhAn2o8kwIfAOWBR/TiloBRwvLe70vM ++dyPacbkfoAw7VrZPfp+vwKCAQBIY2xBOavwnI/GQAgFqQNvgvMpNeCol0ythezqe9EQaN40Oh0n +XW9PX3b3JAsSF7C3qOJGALeLhUxi+PysAAg/UYYQXmLQs4kOpfyeHwa+CQKEuWwlePzp4hkIF46s +/mG7kbO+ArU3ug4GECD346c5gCpsC7+aCdYy0uKJGAa0eWiD84jjl+sxg/E0XAj5yThCsxYRsE5P +SOGI1R/6CDIsfl/DOY+PpncS11Ldo9nLA//IbFMpyJ266hnv5V1nEOOnylDD1UJQjT6s5L+Tcn18 +GJUg7AhEE+Rk5PY/5Ht2iYgRVNUXMK8ID9KthD8+1wE+QF0EtIt24Dt0aMMriAvBAoIBAFdMTl64 +0sxJ/cjJhGeGBvTroX6iqqo+/5i/LxPYfsjU+r027uJeubnf6htTbGTLYmd9MRbC3tzoy8/YWZJt +jTgOcphDtKjIZLxJqXeGIsv0T6egyTs60ykDZ+BJ8qQAl3uM+DR6dh1nh/NNBgr5HY798B4qCXMZ +QIzKh38RKhfcWNoh+z+inBBeEO8z3w2XxACgiKc5/oBymCDKC5e4aU7Jrgh0Jx0qktpFUiuOgYWA +/dJttzfpN0APYITufEX8Y3j8TX3VT5QL0l9xAGjFt6E7VexL/U8lEG8H5Pv/rqpdgEH2n8lh/INc +Z8HRBvqzBPETH7v1nJ/MfDfjoG4Tf84CHlwPKUGyz9PPsqJQfOwM8ec39EOrvL31haA8SlIwyw== +-----END DSA PRIVATE KEY----- + \ No newline at end of file diff --git a/t/data/cryptx_priv_ecc1.der b/t/data/cryptx_priv_ecc1.der new file mode 100644 index 0000000..e5048b1 Binary files /dev/null and b/t/data/cryptx_priv_ecc1.der differ diff --git a/t/data/cryptx_priv_ecc1.pem b/t/data/cryptx_priv_ecc1.pem new file mode 100644 index 0000000..7af44a8 --- /dev/null +++ b/t/data/cryptx_priv_ecc1.pem @@ -0,0 +1,8 @@ +-----BEGIN EC PRIVATE KEY----- +MIIBEwIBAQQg722QX6XVTBoXlyXCtQxpRtQK76sEA+rP7f9SF8zyg02ggaUwgaIC +AQEwLAYHKoZIzj0BAQIhAP////////////////////////////////////7///wv +MAYEAQAEAQcEQQR5vmZ++dy7rFWgYpXOhwsHApv82y3OKNlZ8oFbFvgXmEg62ncm +o8RlXaT7/A4RCKj9F7RIpoVUGZxH0I/7ENS4AiEA/////////////////////rqu +3OavSKA7v9JejNA2QUECAQGhRANCAATAaLdUh3pKsyilabrG1GSoGxflJ9LWUlcq +uxG9o1ctUL+M52NFkNKSOgMRLKau405TyHFrQ0Q+EjQCRkNvO4yK +-----END EC PRIVATE KEY----- diff --git a/t/data/cryptx_priv_ecc1_OLD.der b/t/data/cryptx_priv_ecc1_OLD.der new file mode 100644 index 0000000..d1e4552 Binary files /dev/null and b/t/data/cryptx_priv_ecc1_OLD.der differ diff --git a/t/data/cryptx_priv_ecc1_OLD.pem b/t/data/cryptx_priv_ecc1_OLD.pem new file mode 100644 index 0000000..20bab3a --- /dev/null +++ b/t/data/cryptx_priv_ecc1_OLD.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MG8DAgeAAgEgAiEAq1PtXRbOVQuq8Wuk8WEzKq1W1jeQYpwnhx7VFdT8IpwCIHj8NMajIOImcqlu +u22kg4ekBUGj1+XPrg1YpRPjjIiIAiEAp/Q6zUoF1prkWX5ucj618em5t+qlG23oPPNvloe1fe4= +-----END EC PRIVATE KEY----- + \ No newline at end of file diff --git a/t/data/cryptx_priv_ecc2.der b/t/data/cryptx_priv_ecc2.der new file mode 100644 index 0000000..3371ebb Binary files /dev/null and b/t/data/cryptx_priv_ecc2.der differ diff --git a/t/data/cryptx_priv_ecc2.pem b/t/data/cryptx_priv_ecc2.pem new file mode 100644 index 0000000..b150bd5 --- /dev/null +++ b/t/data/cryptx_priv_ecc2.pem @@ -0,0 +1,8 @@ +-----BEGIN EC PRIVATE KEY----- +MIIBEwIBAQQgDoQBZ4/WvEv60n7lQ2MO9CCmm2+D1TAVROsCG2FTAJ2ggaUwgaIC +AQEwLAYHKoZIzj0BAQIhAP////////////////////////////////////7///wv +MAYEAQAEAQcEQQR5vmZ++dy7rFWgYpXOhwsHApv82y3OKNlZ8oFbFvgXmEg62ncm +o8RlXaT7/A4RCKj9F7RIpoVUGZxH0I/7ENS4AiEA/////////////////////rqu +3OavSKA7v9JejNA2QUECAQGhRANCAASE4xf5yit44KY5gUVylgL+3pEdSqPzW+RR +Tx14x9LA66Uu6kcRQC8CR7+8pRp3pIHylN783HsDbJb46QWLdGIO +-----END EC PRIVATE KEY----- diff --git a/t/data/cryptx_priv_ecc2_OLD.der b/t/data/cryptx_priv_ecc2_OLD.der new file mode 100644 index 0000000..99c62e7 Binary files /dev/null and b/t/data/cryptx_priv_ecc2_OLD.der differ diff --git a/t/data/cryptx_priv_ecc2_OLD.pem b/t/data/cryptx_priv_ecc2_OLD.pem new file mode 100644 index 0000000..ec2eb67 --- /dev/null +++ b/t/data/cryptx_priv_ecc2_OLD.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MG8DAgeAAgEgAiEAwlhDYQrUrJwbA37CWwk6Yr4SUEls2ZljuK0Lre1m5xcCIEy8lSEMcDIOi+ON +RXG95gi61HJaNi2fuiqXEMg0EOzCAiEA7Tu/FCpxSTkBWWDnbyEI0Mrfa0FeHARIYvdYyaZhkeY= +-----END EC PRIVATE KEY----- + \ No newline at end of file diff --git a/t/data/cryptx_priv_rsa1.der b/t/data/cryptx_priv_rsa1.der new file mode 100644 index 0000000..a01cd4f Binary files /dev/null and b/t/data/cryptx_priv_rsa1.der differ diff --git a/t/data/cryptx_priv_rsa1.pem b/t/data/cryptx_priv_rsa1.pem new file mode 100644 index 0000000..8eaa5ea --- /dev/null +++ b/t/data/cryptx_priv_rsa1.pem @@ -0,0 +1,24 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEA0KXMyuA9+cL1xMjAzoQNYs3ieZkNxnJxXvgDYx+vb+K30DiBdQyM5i7nCUcQ +oMPswnNTCx4NBJX4km0pp53NsqGIcT+OM0URPWMaCfVeAvYFPYe5BBxtVKQit0qOD95Mb13oxr3m +LKC1VKHsvbNSexlkjebq61lhirBlDGla6d1t9XElkLnZ+Z/H+BCPgGpKEriSQAcp27Ke6EbHlVNo +l25lnV6Z3pZkmeAv9SSWEnw/MHrG64AM7e0izOaNtPheLp1PGqp5vD2HgMD7L6VZn+PsZ4RPskd1 +bVaxfsbdvgUD6C2hhrxle9QUtzhfi0MO1sq5+B4wJ6yT1jd3n9uujwIDAQABAoIBAAntXD0/hm4G +lXyg6UeKJzw5u9pO6sWz4UAEVd5BU4QOdJzJa3i/DvR5a9BYW2qtbRY4DXiccUB0GukV8jhBklgQ +RnZ48Hzw/tJ9uhnvh4262IymaKpQ6Job2x5UbkZEAef/PwQ3DydgGBs9lGQsOYhA24oYNWTa56ta +cYcHJju1PCMF23rNVx49hSbG/H3TNRAAqOjmYsnvoG+w62Si1np7IBdlIbSdnTYC27kqRIBTIhMW +xkdWSChsgIbrNA5iYtOOeJ4yq17oAikEpUiDwMYqd522WXVRHvleHJQ9CnneOiTuRvnWHTrjeeS+ +lW1lPWQMTzdaTVLV0i+5+F5MIP0CgYEA0+8AKP+rUI4nc8ZZ5CioD7DpIRNGtD8/86QAv4w49nmX +P+g9TBmItLD7mQzjOGxrbe8Stt4hALUIb2Oe5beJQDlKJpe1Y6sSk9+Tx6IdgY75NWjvhQCnJu28 +QQXbO8Q/Eapqz/VH18cXLYfZnScI2toJXC8GwghQM8NYTwdimmUCgYEA/AfkaxY8q2qDuORn0WlT +SyB33N7sro/PwMOtLrosSwLSNyNpmQxiqSPSLhBxnO0ZHiMcSDL7SJbs3C4fOWiNImx7RuNfk8vY +Ox9WowtmYOC+5D5xnJ9TPvuKBhjsLRZMwK5k8gr7iIwU6v+Mjoif8SJ6MRUrPiNDK0ChHGVBu+MC +gYBIbxQv7wofUyaaxD0u5NJj4oQbYNo2erOh0vjKfuNtIiuWlQp2OvflQeQL8EKsoymofiB4Tb0b +38PNRlAllTAcujfkrs85DFwiHDUG8xqAkFwObBoI7Cs0++Xul1DRwYYIxKUTBHMUhaAfWKIAuzmk +iwbN8eiuYmb++hHxmMWTnQKBgEWXKEspaLcsQhLbfo8kNguYe4BRTaklrIfdgARXA8Pyk3kGHjJU +aSmq6m4tvDFIhpb7uuN0sE3q3pwtYBHJ/K50pdV9EvcMYjhw/ssmaq51YEBFvbkxhRru+b2VRCFu +9uJ9RQJQZgPeKih5R6ZTs1Yx3uuOnNIbioB26AWfL/dhAoGACIxtQG+DPfc8i3NFSOA4UmGtUfQY +fP4V9/26RAZ0o5PM9arVxp6gIZzU5++83DFCmlPjvN7cbSQmQgkjn7I5KJkiUEB0i95hDRISgaNl +QsvXdLhE3x77KR/76AAxv+4VxK6y4rrbi1MQwRCEVjp6BVzvdyT+2lMexhLmzucpP3w= +-----END RSA PRIVATE KEY----- + \ No newline at end of file diff --git a/t/data/cryptx_priv_rsa2.der b/t/data/cryptx_priv_rsa2.der new file mode 100644 index 0000000..ee817e6 Binary files /dev/null and b/t/data/cryptx_priv_rsa2.der differ diff --git a/t/data/cryptx_priv_rsa2.pem b/t/data/cryptx_priv_rsa2.pem new file mode 100644 index 0000000..250cb01 --- /dev/null +++ b/t/data/cryptx_priv_rsa2.pem @@ -0,0 +1,24 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAu6ev5Yw8H0B8msvHeXo0d5g13WFp6BbXJWXBNhS7mKcg8+TANm8pRpAcxQw8 +j1wxhrec/J6JtWpGna04nm1Z7MmfgdQ3n+pGuE79SkJsuDykNtNK/M+WCt9TeXJw+ANbJzfJlLyC +/E0yLYJ0AsA5uFZqDhRgPVYmoSWA8g5Y3asnmYgGmHyORc8G0HJzAIJLZ2v6jNh66Nd3BFbl6Sqm +6sJ5nzbVV8lWVwB4exDXI2+/Fa9bzzsglNdD5+qZ5O4qgEAWGFkx7LDJczPKX+RzCBqXeE6dm/qK ++Jg9ivUfwD3mpJJ/6l9je65KCUWLTgmMvsd27Wr9rkJHZdV3CFRavQIDAQABAoIBAAIAQZZo3pKW +Ep4TR98U6AP8dK/rJCt25DgVs9qP8bN+LhJGYVb97B/rVSXewbM6UEbiT1i8QgtUBPO/z0eVMpfH +9fJMS9mMhdDc+sN0yN8AD9+Lyj6+4e00wMRImEl0vl9BL4jtUleUD9G/ad2bpMyWk06aIK/sFWuz +etgEl3r+8wVGnbam6b22SYWR0z1DM1Z3kdKLdre/+7tM51nMoUghNIO+Qvpfljnb1ElQW5H9NP3j +7LFaNgY4p0duKQSpfvPCBhFJ1Wc11MFPt+BVFpXwGMJuNyLVJohonL3GdMF5t6NcosL5GvbJh2up +I37QREycnWMG523ZoBEPYH6u4jECgYEA9Y5lpac2DrcMLMZLnh+sQNkRl8DhAC/jmEJU8CFfahrO +3jPTecH+QpauI4qs6sRLVHgd0N1n3/t35bxaojDutkKJnxw9dVnSIQZNEeuJ0XHpZGwCGOuOLeN/ +t0fi4/PpH3lzZp/LK3U0V/t1Q3zzf/V+YI1e8Ba/RobrLSd1RjUCgYEAw6LdZDPHLbMEVpTcmUHf +h2lTv0B5rDhcKEkCg+axv45iXhQ5RX7AihgY40PMbexxKyUEaoun41VLCWV2xWYGzLzWF/4JiIod +QEahS1UL1x8hf0twJkgo8rRVN+jiDO8FD4y1L4lE7r0Xgt2uZj09NJO2IW9jIeQNv7ga/VsGM2kC +gYBxvDHih09ng2s1NeeCZuMu6hvW8TSGFKhTNq4Gxz5dc+tLSi/yXmM5Tnd76NhsqNzHVBdjTZm2 +SdBf7V0BcK6wZqM9uiPRPfgw6a061qDwDNXweIKELl6dbJkUOEykDq50sJk9+FdvWosTEVpgFvjl +1LxjVjeZ9r9DmGxHbtZH3QKBgBPOalGZuGGVDSxi186gT6wa6sKjGW5pKlNdyOZntbkqBiV2MLIr +efzBIcvockrytCZlEgRjbTTjzrv9zL+Ba9DQkXBOZNKxAPMf83Z3/sHhwfdsQMdvaM3hmfsWFcSv +cji3yyQr5pGxDS9PmDd7nbWz+q155HRq7UVqszjRPVh5AoGAfDG1vKjdbbGzTsxVI9J3EWayJxca ++9D9yPMeMCwTxrUyYZ+eCdMcuT5Sy9ronoc7/Wy8RMIntviD1+vHbKEkD7hH5dmaizlfvzf3Ot1X +UxA6PBKeFi2Pc82sSewvbDC3jRu1Yi43jzPMl/37XuMU74wGWQhZGGMHqHAqc/08Fkc= +-----END RSA PRIVATE KEY----- + \ No newline at end of file diff --git a/t/data/cryptx_pub_dh1.bin b/t/data/cryptx_pub_dh1.bin new file mode 100644 index 0000000..4b2d818 Binary files /dev/null and b/t/data/cryptx_pub_dh1.bin differ diff --git a/t/data/cryptx_pub_dh2.bin b/t/data/cryptx_pub_dh2.bin new file mode 100644 index 0000000..9f9d0c4 Binary files /dev/null and b/t/data/cryptx_pub_dh2.bin differ diff --git a/t/data/cryptx_pub_dh_pg1.bin b/t/data/cryptx_pub_dh_pg1.bin new file mode 100644 index 0000000..9323f59 Binary files /dev/null and b/t/data/cryptx_pub_dh_pg1.bin differ diff --git a/t/data/cryptx_pub_dh_pg2.bin b/t/data/cryptx_pub_dh_pg2.bin new file mode 100644 index 0000000..cd65025 Binary files /dev/null and b/t/data/cryptx_pub_dh_pg2.bin differ diff --git a/t/data/cryptx_pub_dsa1.der b/t/data/cryptx_pub_dsa1.der new file mode 100644 index 0000000..ad4e7a1 Binary files /dev/null and b/t/data/cryptx_pub_dsa1.der differ diff --git a/t/data/cryptx_pub_dsa1.pem b/t/data/cryptx_pub_dsa1.pem new file mode 100644 index 0000000..8b5da72 --- /dev/null +++ b/t/data/cryptx_pub_dsa1.pem @@ -0,0 +1,18 @@ +-----BEGIN PUBLIC KEY----- +MIIDRjCCAjgGByqGSM44BAEwggIrAoIBAQCq+DmnZOBNgIJLefofBJbAk0+FgA9hOPlziHGI9fEW +BsQK3EB9qPyinAxzT8uQ0i4DyJbQdpSZZCbwriX8fMZmwfbwAFthtJFUMVzzx/GJP2u/bzfzZXsW +GysGpdyxLrkfevemBQM/XCr13QnvrQ+BNq+3WLj0umng7Khj6tUtw2TCHH36UR2yOEcCeLgell5v +zVpTp4TayjOkS02g+Ae6b4HMy2HWVSwAG4Vob8fDj20roYhl5/tTLUsMJeLJiy7iiaxQVV34ikRR +RAI3mpLvpBZKlH3A/At/MI1aOl8PTC32b9rO8moN+gUY6o5FL1NBmqkQbO2XvC1AlV7PjDs9Ah8A +0FxMtF8p01NELx/sQ6a+K+jHhlvQQ+8V835/C4IJAoIBAQCEfoiW0Syb8Y/ig6561Y7X83cW3icN +j9ZkZDjmJjzGq/B/+q1KEbyyK7rJYdGmLDpYieramCg+Hwfo222CKeh6RCnZksYuyXbjQwY6rnB+ +5iR1/9vTEUay7Wm6SfQM3BSJ/7a/b+NCJeHODXBWVHu4OZUHA0mFTLZbpVj+gbJZM0+umFrZeSCR +YRZUD3h8H96lEEj/MXITkoEjOMkQrkGfRkKWo8zan4v6F2EG0HCT4DAE3r3krfuHDYGuDn7ZIqqn +dS1YQnBSzYf2Sm1L/9fvCzTthzcZLrLsfUQneU5IJiRoGavCqKl3RvEds+hPT8vlLOzAwjvxdDO1 +oUCNruOfA4IBBgACggEBAI92BNd/pix1OVYkWKY8dhG3OLfUGG+5NsRiuCrCTx44/mJ9nldWQdcu +PHe79Xv2KG+lBj1qxY/Y3RCy/a4/BI+HTHzuqGGcxpzAuIFulTZoFzkZcNmUpQhqVrlDOdbgjfMg +bzGu+nfSP04aRPZONGvz2J1cgptnUE0s2bb/cL/5vgg8M4rBHJ4MySgMq2aXBN6+DuhtcNdCNW7n +LLQmrCijLSzgc8z8rPGb26Z6W2jCtjhVckKIY9BI+xj73yBu7HFP+gKxpjswhrxrFVmC5jx0zRMT +vjxvhPRYhDdtXOlYoQAEforTqWIRE1z5kt76tx3aMTNCL54ROxBheltMjxY= +-----END PUBLIC KEY----- + \ No newline at end of file diff --git a/t/data/cryptx_pub_dsa2.der b/t/data/cryptx_pub_dsa2.der new file mode 100644 index 0000000..b9e20f6 Binary files /dev/null and b/t/data/cryptx_pub_dsa2.der differ diff --git a/t/data/cryptx_pub_dsa2.pem b/t/data/cryptx_pub_dsa2.pem new file mode 100644 index 0000000..a844f77 --- /dev/null +++ b/t/data/cryptx_pub_dsa2.pem @@ -0,0 +1,18 @@ +-----BEGIN PUBLIC KEY----- +MIIDRDCCAjcGByqGSM44BAEwggIqAoIBAQC/SzfXeywDFMR1vzfH1Mpft9ICAuJZ6BDAEQ41woKp +4yv1IehSTYoF7UoUvBqXeG01ZiQDDMYSkMYnBlJCugQrXhaJ2KwMQOFVsfaTsXXgQEpy/UduW2eZ +E4xMUAWKOvqbQgRiNp+t1tmIxNrOB3Ci7hnWXLKS0YWGCLtjnUTJfIZRxxDW1NdQkfaX2ST/DFWU +Dw0XRAOHvwI2Hy0DNzzCZqVcQ0N3aZ89pZNMr5i6SW4+WENS1b/9/YGYsX7qwZNLAO8eJ/zQttOH +PSc9oxY4WIBlfYYQySuJf7435Y97y2OZLNmuq+gz7JeNsU7ziIo+RQdUF7OHSR3syECfajyTAh8A +5YFH9OKWgFHC8t7vS8z53I9pxuR+gDDtWtk9+n6/AoIBAEhjbEE5q/Ccj8ZACAWpA2+C8yk14KiX +TK2F7Op70RBo3jQ6HSddb09fdvckCxIXsLeo4kYAt4uFTGL4/KwACD9RhhBeYtCziQ6l/J4fBr4J +AoS5bCV4/OniGQgXjqz+YbuRs74CtTe6DgYQIPfjpzmAKmwLv5oJ1jLS4okYBrR5aIPziOOX6zGD +8TRcCPnJOEKzFhGwTk9I4YjVH/oIMix+X8M5j4+mdxLXUt2j2csD/8hsUynInbrqGe/lXWcQ46fK +UMPVQlCNPqzkv5NyfXwYlSDsCEQT5GTk9j/ke3aJiBFU1RcwrwgP0q2EPz7XAT5AXQS0i3bgO3Ro +wyuIC8EDggEFAAKCAQBXTE5euNLMSf3IyYRnhgb066F+oqqqPv+Yvy8T2H7I1Pq9Nu7iXrm53+ob +U2xky2JnfTEWwt7c6MvP2FmSbY04DnKYQ7SoyGS8Sal3hiLL9E+noMk7OtMpA2fgSfKkAJd7jPg0 +enYdZ4fzTQYK+R2O/fAeKglzGUCMyod/ESoX3FjaIfs/opwQXhDvM98Nl8QAoIinOf6AcpggyguX +uGlOya4IdCcdKpLaRVIrjoGFgP3Sbbc36TdAD2CE7nxF/GN4/E191U+UC9JfcQBoxbehO1XsS/1P +JRBvB+T7/66qXYBB9p/JYfyDXGfB0Qb6swTxEx+79ZyfzHw346BuE3/O +-----END PUBLIC KEY----- + \ No newline at end of file diff --git a/t/data/cryptx_pub_ecc1.der b/t/data/cryptx_pub_ecc1.der new file mode 100644 index 0000000..45ef915 Binary files /dev/null and b/t/data/cryptx_pub_ecc1.der differ diff --git a/t/data/cryptx_pub_ecc1.pem b/t/data/cryptx_pub_ecc1.pem new file mode 100644 index 0000000..e327004 --- /dev/null +++ b/t/data/cryptx_pub_ecc1.pem @@ -0,0 +1,8 @@ +-----BEGIN PUBLIC KEY----- +MIH1MIGuBgcqhkjOPQIBMIGiAgEBMCwGByqGSM49AQECIQD///////////////// +///////////////////+///8LzAGBAEABAEHBEEEeb5mfvncu6xVoGKVzocLBwKb +/NstzijZWfKBWxb4F5hIOtp3JqPEZV2k+/wOEQio/Re0SKaFVBmcR9CP+xDUuAIh +AP////////////////////66rtzmr0igO7/SXozQNkFBAgEBA0IABMBot1SHekqz +KKVpusbUZKgbF+Un0tZSVyq7Eb2jVy1Qv4znY0WQ0pI6AxEspq7jTlPIcWtDRD4S +NAJGQ287jIo= +-----END PUBLIC KEY----- diff --git a/t/data/cryptx_pub_ecc1_OLD.der b/t/data/cryptx_pub_ecc1_OLD.der new file mode 100644 index 0000000..269aea4 Binary files /dev/null and b/t/data/cryptx_pub_ecc1_OLD.der differ diff --git a/t/data/cryptx_pub_ecc1_OLD.pem b/t/data/cryptx_pub_ecc1_OLD.pem new file mode 100644 index 0000000..13b19f6 --- /dev/null +++ b/t/data/cryptx_pub_ecc1_OLD.pem @@ -0,0 +1,5 @@ +-----BEGIN PUBLIC KEY----- +MEwDAgcAAgEgAiEAq1PtXRbOVQuq8Wuk8WEzKq1W1jeQYpwnhx7VFdT8IpwCIHj8NMajIOImcqlu +u22kg4ekBUGj1+XPrg1YpRPjjIiI +-----END PUBLIC KEY----- + \ No newline at end of file diff --git a/t/data/cryptx_pub_ecc2.der b/t/data/cryptx_pub_ecc2.der new file mode 100644 index 0000000..2078c2a Binary files /dev/null and b/t/data/cryptx_pub_ecc2.der differ diff --git a/t/data/cryptx_pub_ecc2.pem b/t/data/cryptx_pub_ecc2.pem new file mode 100644 index 0000000..e7b48ff --- /dev/null +++ b/t/data/cryptx_pub_ecc2.pem @@ -0,0 +1,8 @@ +-----BEGIN PUBLIC KEY----- +MIH1MIGuBgcqhkjOPQIBMIGiAgEBMCwGByqGSM49AQECIQD///////////////// +///////////////////+///8LzAGBAEABAEHBEEEeb5mfvncu6xVoGKVzocLBwKb +/NstzijZWfKBWxb4F5hIOtp3JqPEZV2k+/wOEQio/Re0SKaFVBmcR9CP+xDUuAIh +AP////////////////////66rtzmr0igO7/SXozQNkFBAgEBA0IABITjF/nKK3jg +pjmBRXKWAv7ekR1Ko/Nb5FFPHXjH0sDrpS7qRxFALwJHv7ylGnekgfKU3vzcewNs +lvjpBYt0Yg4= +-----END PUBLIC KEY----- diff --git a/t/data/cryptx_pub_ecc2_OLD.der b/t/data/cryptx_pub_ecc2_OLD.der new file mode 100644 index 0000000..c8150b3 Binary files /dev/null and b/t/data/cryptx_pub_ecc2_OLD.der differ diff --git a/t/data/cryptx_pub_ecc2_OLD.pem b/t/data/cryptx_pub_ecc2_OLD.pem new file mode 100644 index 0000000..d30f904 --- /dev/null +++ b/t/data/cryptx_pub_ecc2_OLD.pem @@ -0,0 +1,5 @@ +-----BEGIN PUBLIC KEY----- +MEwDAgcAAgEgAiEAwlhDYQrUrJwbA37CWwk6Yr4SUEls2ZljuK0Lre1m5xcCIEy8lSEMcDIOi+ON +RXG95gi61HJaNi2fuiqXEMg0EOzC +-----END PUBLIC KEY----- + \ No newline at end of file diff --git a/t/data/cryptx_pub_rsa1.der b/t/data/cryptx_pub_rsa1.der new file mode 100644 index 0000000..abe21f0 Binary files /dev/null and b/t/data/cryptx_pub_rsa1.der differ diff --git a/t/data/cryptx_pub_rsa1.pem b/t/data/cryptx_pub_rsa1.pem new file mode 100644 index 0000000..fe21265 --- /dev/null +++ b/t/data/cryptx_pub_rsa1.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0KXMyuA9+cL1xMjAzoQNYs3ieZkNxnJx +XvgDYx+vb+K30DiBdQyM5i7nCUcQoMPswnNTCx4NBJX4km0pp53NsqGIcT+OM0URPWMaCfVeAvYF +PYe5BBxtVKQit0qOD95Mb13oxr3mLKC1VKHsvbNSexlkjebq61lhirBlDGla6d1t9XElkLnZ+Z/H ++BCPgGpKEriSQAcp27Ke6EbHlVNol25lnV6Z3pZkmeAv9SSWEnw/MHrG64AM7e0izOaNtPheLp1P +Gqp5vD2HgMD7L6VZn+PsZ4RPskd1bVaxfsbdvgUD6C2hhrxle9QUtzhfi0MO1sq5+B4wJ6yT1jd3 +n9uujwIDAQAB +-----END PUBLIC KEY----- + \ No newline at end of file diff --git a/t/data/cryptx_pub_rsa2.der b/t/data/cryptx_pub_rsa2.der new file mode 100644 index 0000000..f44fe79 Binary files /dev/null and b/t/data/cryptx_pub_rsa2.der differ diff --git a/t/data/cryptx_pub_rsa2.pem b/t/data/cryptx_pub_rsa2.pem new file mode 100644 index 0000000..7a6f76c --- /dev/null +++ b/t/data/cryptx_pub_rsa2.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu6ev5Yw8H0B8msvHeXo0d5g13WFp6BbX +JWXBNhS7mKcg8+TANm8pRpAcxQw8j1wxhrec/J6JtWpGna04nm1Z7MmfgdQ3n+pGuE79SkJsuDyk +NtNK/M+WCt9TeXJw+ANbJzfJlLyC/E0yLYJ0AsA5uFZqDhRgPVYmoSWA8g5Y3asnmYgGmHyORc8G +0HJzAIJLZ2v6jNh66Nd3BFbl6Sqm6sJ5nzbVV8lWVwB4exDXI2+/Fa9bzzsglNdD5+qZ5O4qgEAW +GFkx7LDJczPKX+RzCBqXeE6dm/qK+Jg9ivUfwD3mpJJ/6l9je65KCUWLTgmMvsd27Wr9rkJHZdV3 +CFRavQIDAQAB +-----END PUBLIC KEY----- + \ No newline at end of file diff --git a/t/data/dsa-aes128.pem b/t/data/dsa-aes128.pem new file mode 100644 index 0000000..168e0d1 --- /dev/null +++ b/t/data/dsa-aes128.pem @@ -0,0 +1,15 @@ +-----BEGIN DSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,D5AA4E2FC68B30CC904B43873EF31A38 + ++VjbpU/gBzYiOyicUuDXBHuQccCeam1b+J50z/hI2wHVS6IItRlqYxax/fB4fePC +SHnlzoV0uDPsCUwGIVdfLXC88gsmof/hsKF0qxKnuKakKG+u1p+fauYbe3QWfAf5 +6StHmFqEB6vaX2j2RpEoFsXcTf96Dp6+p+RAXXSK14VsD2kNha2jt9wi/7MXrbdQ +QWL8LNaZGP7QnN5+qyNNmCscjpoKZRP+g1Gswnz7GCDGmOFeopKfYJBGP+mqJuzG +1KklNxJcZ9aoga58Az/hkf/EUjQjI5yvysTVwjqxNkpRAa+43z1t2WXVui4dGBvP ++OPcRwqZviQlzTFz4ArOl/jNz/ZEwAmJJSS1SuKfSTGb4/7ErWTBPUS3XoFUtd79 +79tRYrhomhlv8qThsJtnz3cBrYgzuKbipPdyLH49bg+4+R3UWQuPKa3g9b+KiqlY +hftPVHgzzxdb2oVhERx9Tjx3/QTJ1fiSgZdpGpYA5wL7wM8AHBpH3CBdDdwAq2XS +JpFq4iMIN93BF3kcxwiPPnC95yOOGt91RmiV+FHPfZGFvh0P6ZF4E3l5fH9LBRTQ +ODvimQy7N5/m048YxXyiyb6T0FqMluNfF6EGt+YAiyc= +-----END DSA PRIVATE KEY----- diff --git a/t/data/dsa-aes192.pem b/t/data/dsa-aes192.pem new file mode 100644 index 0000000..3ceccb3 --- /dev/null +++ b/t/data/dsa-aes192.pem @@ -0,0 +1,15 @@ +-----BEGIN DSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-192-CBC,7AF69ABEBB17E476DF28AA325F4219F4 + +zMTTppHV4c6wg2II7EjxZ2Sr7fmvX86UQELRue2cr1fGJNupWmJ2/bYdKxz0hIaj +7/WLPSms2YJqBHNXr6YH4lWTJ8plitAHMrhd1dUTOPnZvZ0/idMzSy8E2yVh707k +hAh8gl9eVttUEFGVA0oRRnpAwt5Lh64+R3MdFoKNLxeg7qL6suLq0bd9AC0YTGzr +QiHFBT3xm+Iwhpij7T0KxfkG0QAM5dRGGqOCo9BdEXUYs2Y9kj5ZkkLysK3dp51k +/tRkq69eRS3Ox8X885NITpP6DjxA6IAui5AWMZ1ASysbdude9cgIf8FGjxLjjItd +ny2NZ5b/zWzEAEAlnHm7BnR2uatG5GrFLO1L1gKSde9UUKZ5GAnTVNPpSGcih37p +vzP7l+PKk+mSjS3O82FtTFBX/Wz8aw7DP8B9LP8pQ6NQIL9vzYiP/ZBde8KDuFM9 +e5ViwXrxIB3QQadGkPNsUitKDtw/fn9cDrH1VDJ+V9Ce/yTx0uKdzfZ/Lko5tcLg +dovfjBy93qEiF5dF3cNU8+67uW4MJKtG6/K4AAi0nsl9ZpoAxkviyXUOgX+uWyzR +34vr/UhtnqZ+WbobvRsbUw== +-----END DSA PRIVATE KEY----- diff --git a/t/data/dsa-aes256.pem b/t/data/dsa-aes256.pem new file mode 100644 index 0000000..e22d97b --- /dev/null +++ b/t/data/dsa-aes256.pem @@ -0,0 +1,15 @@ +-----BEGIN DSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-256-CBC,14ED68BBD5515C2E83ABF597D7AA0ACD + +YOIUB/SU/320rjnJuaiTTb/8b2ND6E6s9zumY2/axEnWwtscFHIefS/oqPKyJAbM +W//Kq1J4lWZ5oJEVVTE1Y6DNI0StQ7xubVOQg6KbY5tDMG9JzvBPoEXVVtOeegXV +EcPFFuOlKmmWkqF6bWYGsXnBpxSR52cexBsk/G0WP19GkUoIYQM84GeecGdAJvZN +iGdgX9ecGtzNeWprfTsrMMBTCFDb7twyj0OLuzUeoTapnx68wmkeWebBMk1DaOkR +6HZT6UT6MfjnDDJLt/myCQhNoNymN0y53EAvPQDWOA3cOXCrHdvBICgq5ezdmNBZ +O/yD/+Lk/S7lbrPeo/cdJZw7CCQdy3Jn9J6dmPRT/J/I5/uuR14igOL944WGIT/j ++FslH2g9YnLA6lkYCBRUf7pM6cbKIDUS/nNvSW914Qug08WxIc0oUZ7DZBuaOAVC +crq2k5R3PnQ0OtggvOx8zj9/M/Tk99sjGwhj3DfoIJfZlFbORoZ1e4S93Qy9ekw0 +vVKXmChFoTnt+QpYOF5U3QOfK0VL9Sf44mE8/FIYPssI+rusX2tVjr8lEElRwoqB +ZDupgGBZSu+mZ8E/dVnScA== +-----END DSA PRIVATE KEY----- diff --git a/t/data/dsa-camellia128.pem b/t/data/dsa-camellia128.pem new file mode 100644 index 0000000..b9368c2 --- /dev/null +++ b/t/data/dsa-camellia128.pem @@ -0,0 +1,15 @@ +-----BEGIN DSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: CAMELLIA-128-CBC,4AAF8AA37E76D1BC8F72F37DC2D865AD + +S+DAz1fM1R1IaCO+F5pOw6JF6sHEQQk1fHDvubOFOH5hrWsYFwrla2o0fJvhBbon +4KcXE8QNRy1ss8g1EqLI+ok0wUVGvvn7m2CcvZzcVC9tZE+WtKHKQVNFfJaKm7dA +VdY23Ad79vBQ0cpda+aR4EerGdqI8uVkf8eqveOXbBIR/TvqOXuh9XotdTPfds2j +DyzmocgPgnQSEXNS6zB2meyo3gUt16/VBA0oW0Fh2TvKYksV5f8XRJqmpRSZXPx8 +ZBA51+odZ/8By1sZuONvME/xeFZ5PLI5vMiYoBfhEphVAWPvtgDuxTOOxZSrCpT5 +dZ2tUr9D4dzZcLEvnaXXZNDw69HJJWeAjiM/76tLgzSLN6i4T35bYQiMdjMyYOIB +QLIazPfN1llBb7DHjzQPATJ2w59U1bTO28oGmwZJNp4xL6hc0TcHb4N+HIHtyxQB +jJPdl8wiWdJC1Cc9dNa3pmDpYoxdP01FcQOWomUOpC1gZNRVBTIph/tL5Jd15P0R +nW4Jm6/8pOAUo7GkA5eXa3RRjwroN61EJQlyuBsURM/26WnFGcSFArCL6V7ILcMx +TmShOEasVHRDWd509h4cFg== +-----END DSA PRIVATE KEY----- diff --git a/t/data/dsa-camellia192.pem b/t/data/dsa-camellia192.pem new file mode 100644 index 0000000..2601af0 --- /dev/null +++ b/t/data/dsa-camellia192.pem @@ -0,0 +1,15 @@ +-----BEGIN DSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: CAMELLIA-192-CBC,473E445A0D5FD8803AA40F48225CD6A3 + +w2e2vMYEj7pO33x/Me+9MzrTJYRI9vfPdzYQCsowxdlybFTcwUtqeCgPzeW5C6BZ +rx9WTX3OcYFPnAX22BFgDvGqT+3+ybR9NKylxUvoUC7OOofOa1gW+e1XqSRbkr+r +Jo26GT4ROBVY/i56qTUlYqg7X182wIp0MQSXJq+HXPhEogO4zYMXbROC9U7LcG4/ +KO40Nx+C/18xRUAg2ZDjdkjK9L5u+QBpXa8qQuFtYd20NdDf8DQvgO9IwcDzPrMD +kYznrMosCMPpEfBik4PwjQDjyKFAe0j6O8ePIA+KVPO/gXF6EqNP/QZoGEwzpXIo +7Vu50ztdomni6L/EjpsltlmdJMXNA/JozYiWqp8UnQbdHOt7wvwTlJCpDas+GvHk +hHQ6HC4rOgCxCuZIzTlYVxx+ca6FEXnNs1hzmlVc692nkvSwQIt3i65IENH7hC4q +0yU2hF2+JANPiYVAfd2ERWDbpkTM8ug6XT9lcAKVUw3AI1aWA6xMLdZSU8atdIT9 +6/KVFN/tXrNbm/U0C0EDcojNsSLE+vb4A6SBkuYZka/b5nXea1qOcwt/CNmn3bzf +bK68/s9EKkZQOekHrklfAw== +-----END DSA PRIVATE KEY----- diff --git a/t/data/dsa-camellia256.pem b/t/data/dsa-camellia256.pem new file mode 100644 index 0000000..6853019 --- /dev/null +++ b/t/data/dsa-camellia256.pem @@ -0,0 +1,15 @@ +-----BEGIN DSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: CAMELLIA-256-CBC,5D6BC3C2DCE61EC62D34FF9379050AFE + +OQd/C+mhpHyFgjg8qR3esn54ENjfIg/+JjF996zi/fzA4vFeO6uJ257dFui3m84b +O6Q71wOpXWTpx8TKRCGUnoTE4Few4c+HJwwqu1I2NrKiiBi7DfuJF7T+PMX6z66E +R7gzUo+Zy7QdNKHAG75gDE9dgQBwbMHcuJ0iM0RWE59SleCtyQos+bFhR/ny7Amg +hPKq909XnmVbvWP5y84b8nK394PKqoK51lP0HoKY1NSPkuwj/RM61SiMRX1t5hpC +FdGQE9INaNCi8MJsq1oGPVAM1f72C5qb+JmCcGcaMyHxZf1YJYLYkraeSijrbwm9 +Tz4n1vZOdgHckf31na78g79zlTWjDkON/QVFP3Ln4lT1sU9c7Gg/DducPnNQ9d00 +2Czc8NofsR9DkafhUT9+Hr9QsNB6eukROlfpyiHSZeaN0Y1hkbwGIXvU85fW8zfb +ZYntNY+bTFDRCZyI04I87Z+DWxRAo8XJEskzGpJLuQYJzBZnHKnracPCYQtnSqFz +k5Kd3ZzoqksjVHVcI9m3reSFFY+NHcKQ15OQp+SMTQQnu1+nAhZQIV/tMhDslRMr +dDS9tkq8CiLdtRac3vcZCQ== +-----END DSA PRIVATE KEY----- diff --git a/t/data/dsa-des.pem b/t/data/dsa-des.pem new file mode 100644 index 0000000..96f92e6 --- /dev/null +++ b/t/data/dsa-des.pem @@ -0,0 +1,15 @@ +-----BEGIN DSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-CBC,227ADC3AA0299491 + +UISxBYAxPQMl2eK9LMAeHsssF6IxO+4G2ta2Jn8VE+boJrrH3iSTKeMXGjGaXl0z +DwcLGV+KMR70y+cxtTb34rFy+uSpBy10dOQJhxALDbe1XfCDQIUfaXRfMNA3um2I +JdZixUD/zcxBOUzao+MCr0V9XlJDgqBhJ5EEr53XHH07Eo5fhiBfbbR9NzdUPFrQ +p2ASyZtFh7RXoIBUCQgg21oeLddcNWV7gd/Y46kghO9s0JbJ8C+IsuWEPRSq502h +tSoDN6B0sxbVvOUICLLbQaxt7yduTAhRxVIJZ1PWATTVD7CZBVz9uIDZ7LOv+er2 +1q3vkwb8E9spPsA240+BnfD571XEop4jrawxC0VKQZ+3cPVLc6jhIsxvzzFQUt67 +g66v8GUgt7KF3KhVV7qEtntybQWDWb+K/uTIH9Ra8nP820d3Rnl61pPXDPlluteT +WSLOvEMN2zRmkaxQNv/tLdT0SYpQtdjw74G3A6T7+KnvinKrjtp1a/AXkCF9hNEx +DGbxOYo1UOmk8qdxWCrab34nO+Q8oQc9wjXHG+ZtRYIMoGMKREK8DeL4H1RPNkMf +rwXWk8scd8QFmJAb8De1VQ== +-----END DSA PRIVATE KEY----- diff --git a/t/data/dsa-des3.pem b/t/data/dsa-des3.pem new file mode 100644 index 0000000..f1f25c2 --- /dev/null +++ b/t/data/dsa-des3.pem @@ -0,0 +1,15 @@ +-----BEGIN DSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,C4193B6D1BF3F2BF + +A6o3o6+4F8iri8HFnDZuvYJmT3nNZQht14ysR2KZcjHs/J/vuOk4vKlk4C76Qdg4 +uwpK1kep5Noi59odAwdmVPLOoVvmQDBRt2Jfvg61+lBXTywnBYNse8XhrBZLX08W +T/zb/edyf8ct/kSkKqGsQXtpmNR2RdXDW+5zkCRHHkd6QFnlFD5E5GCFt6vsXVrK +LlDzS7+iiPAaclEpW7HzsuR62PCyc7tPycxkWhqiM1b68/sShwurz1R7FPpzkpIc +EnL+B4kNwtxhwdITqe4DEuHM5+7DhfovHImvDsBD1KyPd3Y5unMHj/Aw94se/P4l +TTV3SYQnFzStcRpAKcgRysWr7dR+uZ86QEAVeoY6sL1r2gdNgV2AxjEhMoTeu++n +j2nf59WJHbQfLs3yFAmK+xtSv0VAffvbchbnI05vZOaMNTtVY83e68ftoRCK3PWC +VbgAec0zcce0qvuxbicUFhg/oLQbdWTV5w56a23QsPSkG+DFIp8BKrLL75SpcBKi +nnbApxb0nFcJkYn9747mPXjOp6RYHE/7DkyqkGkK5q0eO2R6xf4GaOFq6MfDM6aH +iQCsZt5wMjirfSSNALfuI4X4NlrqBN+2 +-----END DSA PRIVATE KEY----- diff --git a/t/data/dsa-param.pem b/t/data/dsa-param.pem new file mode 100644 index 0000000..f9851c7 --- /dev/null +++ b/t/data/dsa-param.pem @@ -0,0 +1,9 @@ +-----BEGIN DSA PARAMETERS----- +MIIBHgKBgQCkSN9kp68di6qn62zD56W13LM8zWB9H3oa7jRGFsH2kXIn4iKSf4pU +HI43XLtHAnu5QVhwC+tf+Y5lcnbCzv27mxd+/tMV5vT3kcnmgeB+KnhONZhktcAt +ktZ+ph3G7RA9N5CwxagXpATH7i+6QImZNG0DVh7uu6PLHSk9K64hUwIVAP+7jv0v +Fn1Lurrjmh3GHkNJ3pc/AoGAQ31/Z3w1ymitWAr5B9Tv7zIWTe5BLuMRrJ673j2d +/qbV8rDpDv14GykOlflgLxd/xSaL7D2NJw/7bRXWOaa2t9ht4ENsJ3Qf2jJMzj5Z +QO3qpkLH58UKX/j9LQfbxLBlIdqxI4k2UlCEd54vIjgrDlvwUR58fzmSSB1USfpH +SAE= +-----END DSA PARAMETERS----- diff --git a/t/data/dsa-seed.pem b/t/data/dsa-seed.pem new file mode 100644 index 0000000..d23f880 --- /dev/null +++ b/t/data/dsa-seed.pem @@ -0,0 +1,15 @@ +-----BEGIN DSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: SEED-CBC,B4BD523CD59DA8DF3E8F397BBC025D8F + +Twepa9tc/xebHwoZq9HidpglTPYPsxFY2LtidA9oHgLRLrbnhxNnf4LXmcqT69RG +QziI9YK0wlH31FRqaGbaQ6bP8E18EsSs2yGbHMciSHYr5Sz7KLxF7tE3urUCISZ1 +NKuPe48PxLn4izKKgynKELzrtPjqQhCxBOmltSSNQ6HqW6qJQ5iyIKZHBWz3r9Lg +0/P3J2tjmViteStyeAdKjJI8HqipdghB12jNjAFE0M8LhUK2VYJYJd45Yur/z3NB +6nA6UgEeNCL4BT7hVsoQ7Fil4j641hSdo4rVVkLEobb+PFwvEqIM8KaQR8Xyn0Hx +imzGYxONqbr0JzWIZOwD2ty8X2CMS4q7k2GS8OkWwiupK8ksMhxWTDkrT5aysvDE +ZYNwXKrR5aaIKnJG0bwZvxpLNn1Nuy1EoGwLcMyCwCqfndg2AqTXgDx5+fUWx7UZ +EN22lEbWdGcbPh8gMVdyWG452xDc271SgEOhNF6fEAKvA00/C3FqgrmU4jDfv1H0 +t9nCQLOM3CN/PbcCf0umMn1ZuSWRMB8laVqgsRs+Io0AJx/73/Aix8U4jCWSJQwD +ogz8cKEeceuywzqADWGcxg== +-----END DSA PRIVATE KEY----- diff --git a/t/data/ec-aes128.pem b/t/data/ec-aes128.pem new file mode 100644 index 0000000..7124245 --- /dev/null +++ b/t/data/ec-aes128.pem @@ -0,0 +1,11 @@ +-----BEGIN EC PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,98245C830C9282F7937E13D1D5BA11EC + +0Y85oZ2+BKXYwrkBjsZdj6gnhOAfS5yDVmEsxFCDug+R3+Kw3QvyIfO4MVo9iWoA +D7wtoRfbt2OlBaLVl553+6QrUoa2DyKf8kLHQs1x1/J7tJOMM4SCXjlrOaToQ0dT +o7fOnjQjHne16pjgBVqGilY/I79Ab85AnE4uw7vgEucBEiU0d3nrhwuS2Opnhzyx +009q9VLDPwY2+q7tXjTqnk9mCmQgsiaDJqY09wlauSukYPgVuOJFmi1VdkRSDKYZ +rUUsQvz6Q6Q+QirSlfHna+NhUgQ2eyhGszwcP6NU8iqIxI+NCwfFVuAzw539yYwS +8SICczoC/YRlaclayXuomQ== +-----END EC PRIVATE KEY----- diff --git a/t/data/ec-aes192.pem b/t/data/ec-aes192.pem new file mode 100644 index 0000000..39ca0f8 --- /dev/null +++ b/t/data/ec-aes192.pem @@ -0,0 +1,10 @@ +-----BEGIN EC PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-192-CBC,CF0DF9FBAECBEF5FCE53EF2264D61B50 + +dXLk+Rgos3L2WJRAtmJ690eHwjLhNeHppsdBS83T/xcJQtW//8Fkxa9XyJp4PG43 +MxYt5x9bJysmRVZ5Z+lxrkwxh1P82Fj8lq8wJ0ijnxrdQUG8dj3M5b6TvXZ9Wwml +D5t28yduo4f+72UOAyfKLIbh/fbYg0sejdRaK6s1aFDpbhg1oKqhjldgPZsLB+M2 +awzwlYtfQaCPxlGMSyfvanS4X7TL1KHcaX7g1ygvwBcqli85cIynZsaGKTj26Itb +pvOECs6IE81hsFbHBe4KeLakqVcqdo4wBwbwbrZANxk= +-----END EC PRIVATE KEY----- diff --git a/t/data/ec-aes256.pem b/t/data/ec-aes256.pem new file mode 100644 index 0000000..2174f76 --- /dev/null +++ b/t/data/ec-aes256.pem @@ -0,0 +1,11 @@ +-----BEGIN EC PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-256-CBC,5112DF71CEEE534741673D8F36CFF9FF + +lqxba1ld8+3CaMQJWNWVPmHqaipNSSKeEPDShvdvTgUEGn6gaCxcS2volX0FPTRp +CS38ie3jOhbY6d8D62QCyMLFeY43nlzJnxJ2KdA8b7/RM+XXw9M/QK0xI7sMdDRp +JorqKquZWHa4YmhdEi7rUwMTycivBzO7dhadgpH5V0R3XvHYiZjGdGwNnFGb4VzU +fIeZWgMA86Vd8yP4vrMxzufcvY6Whjtnoj3ruHOdYU/Y93BdgmYojGWWdEanDp1k +WiBAEDQBtsfOZS2OTQ0dVMJX1HooTSn1U8yM/iKf1VcdXCvfZrOyHMkN1pEM2RYK +5/Bq5dfLXqiwbxWOKoelsQ== +-----END EC PRIVATE KEY----- diff --git a/t/data/ec-camellia128.pem b/t/data/ec-camellia128.pem new file mode 100644 index 0000000..184f96f --- /dev/null +++ b/t/data/ec-camellia128.pem @@ -0,0 +1,12 @@ +-----BEGIN EC PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: CAMELLIA-128-CBC,118544E97AC088140AC1C0C06ABC759E + +f/moV4xfY8b+3foS4l8MFfkdVYW1x3mausivtv3O7aMpJCS46bEvYvQ0xTPZwvDc +3jnxmkHGem6yaofmxcLDEpOV4Hr2sBGK4OAxtdv+w5BzN9U0iOTehG83nlcp280u +wkd8r2h4Yz7wyZZClGccPw7CGBcBwhkvhfAVK9p/qISDo2HKPSSAx5STZ1QhsIro +ALd+UGup+LLfckn2no1A1EAnq721XpYPJUyO0KacvZXGkGEX8FGpKcBfPHIZY01M +KaxsuEbxPldHFUDOWkT+ID3jPiSlUlurQtUKbagzPJS2opQXRcW5WiZZ/fgJMETV +mXrESk3A1j3eHEgqJlsWSQyNyxcvmc1EN8WFgzjwWBA3yaG/dyYyjjAOzaIOAwO8 +QhOwQFD9t7JU0C2CKvgv/JAx/4maOyNUcncNY+4JlYrsV/U5Hp1kvGmjAZP7CVuD +-----END EC PRIVATE KEY----- diff --git a/t/data/ec-camellia192.pem b/t/data/ec-camellia192.pem new file mode 100644 index 0000000..8e05c2f --- /dev/null +++ b/t/data/ec-camellia192.pem @@ -0,0 +1,11 @@ +-----BEGIN EC PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: CAMELLIA-192-CBC,3D2679B0FA9626F66AC2855E10732713 + +1xhoIqCYu1HBKVW0G8o3TKQQFkrD/KrOWTRNTCuP4WDVjCL7YLTBeJQbEuAxpuci +tICDjO0FSy5L4RjKOveoL+akG52LflnsWpYkwcxmsp+FIPHTR0sFZvkD5HDID0ZB +y2XpDhMNInVELjAcHGg8NfzrgLFb7xzgWBUTIONzqw4Komfkes31mIalbh+/V1Z4 +ZE0r7BiOnd+NO2Rydw2u4zWRsgZBXdVTGm+97ZIWoiNLN6unAU1Q65gYRABg94nq +APFIJZz800WXIcCFFyrM7QsX2WCP5Q/121j8k0l5Quw+ylkziZSFxivcZXyM2a24 +43gZt/1Hu5zVK0e4dDfUlQIDw5ugPO/B/ShkuaY1B12BMTf6EeNtAyBjFjX+TP+4 +-----END EC PRIVATE KEY----- diff --git a/t/data/ec-camellia256.pem b/t/data/ec-camellia256.pem new file mode 100644 index 0000000..9408e44 --- /dev/null +++ b/t/data/ec-camellia256.pem @@ -0,0 +1,16 @@ +-----BEGIN EC PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: CAMELLIA-256-CBC,E1CB2335163192A57FD06C3279CFD052 + +z3zB6/uGCQL2Drl2lr3Hl/85yHdt/WFW/5XHka2SVO8v9scr77AJdshZyypPbFLi +ieS1lEedDbsADjwbyFrHQmO1Tz6vNfAfAnUCEVJnFcAxtkdeYabN25srhJ1pQYte +6vzi+7uOmNjLQRmSvN1NaA20JKuyFFEhSPKiVhK84tl6GOKhyu0ETzjjAP89RtDm +5+sHmGxedPonEDilAYcWo3Y55v0nbctwDhBQXio2VGgjw9QiCoa9pApjcNo9sr9S +uj/OWTTlaiiBTZQ7PJ93zeNkpomV4eZxrSVDPRTkAyR9emKScVLVZN8/rACgwZzi +t80ALww0VVnoyNuMqVh008fEE96X3MjixzdyXpOXfGeiXjFHCka+8M/SQ92C4G45 +XFR0C2ql1yDeo4zoNihrsm0VXoz5M/beOGZtELoase0mNsqmOPmKQQKnb3Lkm0aE ++iuasKk3fQ5J30FLegrNr4xcLKO5ztkiykjMp/9G4dsm30iWEcdfJETMvYsfPXox +WptJWdMP6RtCyz9v+6KBjvHi05GHph+STgRm8QGUDVDaQdP27p2za9xJokWbzbxa +Hk0/WUBdboa0a7MTCUFJqVqT+IIHK4Y34DKqw1no7aki3UJJNiR4Dnlta7bR4m4q +yKCvFVaxKE+Y/WippfyKEZciiZxHprrQUCv+yy6rRGo= +-----END EC PRIVATE KEY----- diff --git a/t/data/ec-des.pem b/t/data/ec-des.pem new file mode 100644 index 0000000..4eb4638 --- /dev/null +++ b/t/data/ec-des.pem @@ -0,0 +1,10 @@ +-----BEGIN EC PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-CBC,25CCB799403FC4A8 + +cVh3cIHbAHumbPxqkNyUTijnJxs5gAYx/R6XazSzfOv5AVniXWcBYXUz8xxu5ihG +njKhB/A7NnMrRBT3MU//Q16sKnnsC1YwRVFn5Ynzs0ZE+Z2XKHbV/pgRtlYWbgUA +fiXZttximkYqHr4BB0lfcm89jV8Ks50wGMmpADd/b09R5BhrYEt30poLqArKokZ+ +YIxR/nf1pcd6frbvnQmR/6TiX6SNf+9GZohIkBhkcT24OTSEtLdJnQg4wCzwuKW/ +oLKMPxKtHtQ= +-----END EC PRIVATE KEY----- diff --git a/t/data/ec-des3.pem b/t/data/ec-des3.pem new file mode 100644 index 0000000..fb7691e --- /dev/null +++ b/t/data/ec-des3.pem @@ -0,0 +1,10 @@ +-----BEGIN EC PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,BCC03F44667493FB + +OcnqVLNcxYQyDJKMkWEFv1sLOFnui9hN8wPidDYS3rP1HTeFZRQeWznTtqAs6MAH +vFnHHLTYMJXlGJ/qSb9sJmRJw2XAkRUtsT6vxXvf0IhPTd5632aXSjewUllOfl+N +1tmztrOGWtHIms9Kz4noG1ApXhv66eUtLMDkiKR85D2Wai4yzyftFQyFT0BzFTxu +IHcZ7oDYYX50+iru0x9aP990jyXzzrlURLCpgtr940YkoLquudvyn9s/6wtKqeyG +SIEU6SHQhYrsiVTpQWMIUQc2T0HVoCoHBUGFAtj4wYA= +-----END EC PRIVATE KEY----- diff --git a/t/data/ec-seed.pem b/t/data/ec-seed.pem new file mode 100644 index 0000000..759f880 --- /dev/null +++ b/t/data/ec-seed.pem @@ -0,0 +1,11 @@ +-----BEGIN EC PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: SEED-CBC,94487C737A60F0E41D5AF5A3BA0B155E + +3MjBEjo9vDpSKd0UbyCngNl7dVJfxdEwqTOQw0rjl8qYBlvbdx+zSMQTixKXJR70 ++Z+z1UvW415QTEyTArnuwwfDMkgGB5w3tr2+YuF8908vvtyX2GKvkdaEvFHdYb0X +8PSABZgiAPdjgzDDm3WZHj72wcgiJeXs+UCId2Aqueqxfd+qRT9UmpBUJ7VGlT6w +u3YV+1SbCqNZr/vV6XoJ5z8VuaXQiv2HuROzbqZ5gKSag4Mk9UlmMhLs6SeN40du +xQDZj3NStwbZUlPlJwkSMzmzjoyHMY5xFbKdtFB8LiYTYlDu7qQr2E/T2TviquBw +HobzhyW1rPKfJ/4uUpflww== +-----END EC PRIVATE KEY----- diff --git a/t/data/jwk_ec-priv1.json b/t/data/jwk_ec-priv1.json new file mode 100644 index 0000000..1d2fe37 --- /dev/null +++ b/t/data/jwk_ec-priv1.json @@ -0,0 +1,7 @@ +{"kty":"EC", + "crv":"P-256", + "x":"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4", + "y":"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM", + "d":"870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE", + "use":"enc", + "kid":"1"} \ No newline at end of file diff --git a/t/data/jwk_ec-pub.json b/t/data/jwk_ec-pub.json new file mode 100644 index 0000000..9f48811 --- /dev/null +++ b/t/data/jwk_ec-pub.json @@ -0,0 +1,6 @@ +{"kty":"EC", + "crv":"P-256", + "x":"f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU", + "y":"x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0", + "kid":"Public key used in JWS A.3 example" +} \ No newline at end of file diff --git a/t/data/jwk_ec-pub1.json b/t/data/jwk_ec-pub1.json new file mode 100644 index 0000000..365a99a --- /dev/null +++ b/t/data/jwk_ec-pub1.json @@ -0,0 +1,6 @@ +{"kty":"EC", + "crv":"P-256", + "x":"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4", + "y":"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM", + "use":"enc", + "kid":"1"} \ No newline at end of file diff --git a/t/data/jwk_rsa-priv.json b/t/data/jwk_rsa-priv.json new file mode 100644 index 0000000..3ea9808 --- /dev/null +++ b/t/data/jwk_rsa-priv.json @@ -0,0 +1,13 @@ +{ + "kty":"RSA", + "kid":"juliet@capulet.lit", + "use":"enc", + "n":"t6Q8PWSi1dkJj9hTP8hNYFlvadM7DflW9mWepOJhJ66w7nyoK1gPNqFMSQRyO125Gp-TEkodhWr0iujjHVx7BcV0llS4w5ACGgPrcAd6ZcSR0-Iqom-QFcNP8Sjg086MwoqQU_LYywlAGZ21WSdS_PERyGFiNnj3QQlO8Yns5jCtLCRwLHL0Pb1fEv45AuRIuUfVcPySBWYnDyGxvjYGDSM-AqWS9zIQ2ZilgT-GqUmipg0XOC0Cc20rgLe2ymLHjpHciCKVAbY5-L32-lSeZO-Os6U15_aXrk9Gw8cPUaX1_I8sLGuSiVdt3C_Fn2PZ3Z8i744FPFGGcG1qs2Wz-Q", + "e":"AQAB", + "d":"GRtbIQmhOZtyszfgKdg4u_N-R_mZGU_9k7JQ_jn1DnfTuMdSNprTeaSTyWfSNkuaAwnOEbIQVy1IQbWVV25NY3ybc_IhUJtfri7bAXYEReWaCl3hdlPKXy9UvqPYGR0kIXTQRqns-dVJ7jahlI7LyckrpTmrM8dWBo4_PMaenNnPiQgO0xnuToxutRZJfJvG4Ox4ka3GORQd9CsCZ2vsUDmsXOfUENOyMqADC6p1M3h33tsurY15k9qMSpG9OX_IJAXmxzAh_tWiZOwk2K4yxH9tS3Lq1yX8C1EWmeRDkK2ahecG85-oLKQt5VEpWHKmjOi_gJSdSgqcN96X52esAQ", + "p":"2rnSOV4hKSN8sS4CgcQHFbs08XboFDqKum3sc4h3GRxrTmQdl1ZK9uw-PIHfQP0FkxXVrx-WE-ZEbrqivH_2iCLUS7wAl6XvARt1KkIaUxPPSYB9yk31s0Q8UK96E3_OrADAYtAJs-M3JxCLfNgqh56HDnETTQhH3rCT5T3yJws", + "q":"1u_RiFDP7LBYh3N4GXLT9OpSKYP0uQZyiaZwBtOCBNJgQxaj10RWjsZu0c6Iedis4S7B_coSKB0Kj9PaPaBzg-IySRvvcQuPamQu66riMhjVtG6TlV8CLCYKrYl52ziqK0E_ym2QnkwsUX7eYTB7LbAHRK9GqocDE5B0f808I4s", + "dp":"KkMTWqBUefVwZ2_Dbj1pPQqyHSHjj90L5x_MOzqYAJMcLMZtbUtwKqvVDq3tbEo3ZIcohbDtt6SbfmWzggabpQxNxuBpoOOf_a_HgMXK_lhqigI4y_kqS1wY52IwjUn5rgRrJ-yYo1h41KR-vz2pYhEAeYrhttWtxVqLCRViD6c", + "dq":"AvfS0-gRxvn0bwJoMSnFxYcK1WnuEjQFluMGfwGitQBWtfZ1Er7t1xDkbN9GQTB9yqpDoYaN06H7CFtrkxhJIBQaj6nkF5KKS3TQtQ5qCzkOkmxIe3KRbBymXxkb5qwUpX5ELD5xFc6FeiafWYY63TmmEAu_lRFCOJ3xDea-ots", + "qi":"lSQi-w9CpyUReMErP1RsBLk7wNtOvs5EQpPqmuMvqW57NBUczScEoPwmUqqabu9V0-Py4dQ57_bapoKRu1R90bvuFnU63SHWEFglZQvJDMeAvmj4sm-Fp0oYu_neotgQ0hzbI5gry7ajdYy9-2lNx_76aBZoOUu9HCJ-UsfSOI8" +} \ No newline at end of file diff --git a/t/data/jwk_rsa-priv1.json b/t/data/jwk_rsa-priv1.json new file mode 100644 index 0000000..35095ae --- /dev/null +++ b/t/data/jwk_rsa-priv1.json @@ -0,0 +1,11 @@ +{"kty":"RSA", + "n":"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw", + "e":"AQAB", + "d":"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2vv7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoAC8Q", + "p":"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs", + "q":"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3vobLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelxk", + "dp":"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA77Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0", + "dq":"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cgk", + "qi":"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_mHZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU", + "alg":"RS256", + "kid":"2011-04-29"} \ No newline at end of file diff --git a/t/data/jwk_rsa-pub1.json b/t/data/jwk_rsa-pub1.json new file mode 100644 index 0000000..45b49e0 --- /dev/null +++ b/t/data/jwk_rsa-pub1.json @@ -0,0 +1,5 @@ +{"kty":"RSA", + "n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw", + "e":"AQAB", + "alg":"RS256", + "kid":"2011-04-29"} \ No newline at end of file diff --git a/t/data/openssl_dsa1.der b/t/data/openssl_dsa1.der new file mode 100644 index 0000000..ed27555 Binary files /dev/null and b/t/data/openssl_dsa1.der differ diff --git a/t/data/openssl_dsa1.pem b/t/data/openssl_dsa1.pem new file mode 100644 index 0000000..81185e5 --- /dev/null +++ b/t/data/openssl_dsa1.pem @@ -0,0 +1,20 @@ +-----BEGIN DSA PRIVATE KEY----- +MIIDVQIBAAKCAQEAy9TLbw0jG2FzEYlhXSNqgCCuw7DR5uWQurOb6VDPN0MDGH7/ +XCSGyI3ac6FqC3UltYM3mSpLPq8NFMiwVPQaTKOMMEJSvJCMhy7h9h4YADtr0bFj +Rylq0R5qiP49KfKXYpX5ht04q2aj2iqNHQ6jNjY5Rj0jp9y78h1YOtad/1c8UJCS +DSEvMz1JotPtDU6j0Mzj8p+t2DHVHVGSbatIVSi4tYEnGXYoaXssokkfnEh3sX8h +k+cmWlaK+O2MHRJfmpsK7xneWnv4aO5JrUGqe2gaDMnS0DZRjSqAeyt6AeCwT/4U +194ERo5OI6mKzeecc13TO46asdAFNJPk7tbwEwIhAMKM1NaESOKBtStmcYVlGCyN +ofJ17DSrzcnBaNt+RFHTAoIBAGC6XoMAUEId7I0jP0ARv7DzL+vCnjng0k3RPS6L +YMEyToBPLUuxweUgy9yxtgZNErPqI/wl1sDCji7mK+NLKB2JeyJ1NLEoLjWYhKnf +2dT3XgKm48Vjw17M4DkaDkXCjfGxB6PHiw6ZHmLD6rRSIcx7rVoIQWDmkcyV4hJN +O9Di7fpIVexxVk9UsyMGCcm1/2CjD5+o0MxmVl+RJGJfwwORRDnoWPWMslwsj0ML +24ev4bEUSNzy0QSEu6QsgMeL4jYa1MapluBWtMs9dgIc8JOgR0elwtVRgYEqQVT0 +wom0U2MNk5hQ+YZT1PWUke/U+Uj4UsVkPROv+QczREL66l4CggEAGaC+fIZl1nix +bG7wDb+VWRyhnvyvs9BxoFFLNiSMcm2j0rIkKKmMgNACDxsKLIofoKkkUwbij1wZ +klcFzUcgjv487WX5pT/S8LfF1gazwUtJonJzt0zhqp/4CwedLMXVEGOgXyjKxGwe +Fw9EpZfjm2WSSg3GjKUMV6STK8+wZKzAmQ5NV8gWr+4COr4TUVFhn8gtUkd3p80Y +hg6okOjJkfUS6Viw1N8qMxImgub6FZ4KcAP09DdfBOu8dUJXEJuOMel3Da4mu1jP ++g6NOcgC8iDDgxOT7NnGQT8ZP2gHvOV+gYmwrD3nmne10G3yDZUztRhrFDXzF6wh +/GX7UsuYYAIgcfgcOeGQUHijr9Hc8iiwxeulrdHU6t23yb9t+lZACnM= +-----END DSA PRIVATE KEY----- diff --git a/t/data/openssl_dsa2.der b/t/data/openssl_dsa2.der new file mode 100644 index 0000000..643db3e Binary files /dev/null and b/t/data/openssl_dsa2.der differ diff --git a/t/data/openssl_dsa2.pem b/t/data/openssl_dsa2.pem new file mode 100644 index 0000000..d021fd9 --- /dev/null +++ b/t/data/openssl_dsa2.pem @@ -0,0 +1,20 @@ +-----BEGIN DSA PRIVATE KEY----- +MIIDVgIBAAKCAQEAy9TLbw0jG2FzEYlhXSNqgCCuw7DR5uWQurOb6VDPN0MDGH7/ +XCSGyI3ac6FqC3UltYM3mSpLPq8NFMiwVPQaTKOMMEJSvJCMhy7h9h4YADtr0bFj +Rylq0R5qiP49KfKXYpX5ht04q2aj2iqNHQ6jNjY5Rj0jp9y78h1YOtad/1c8UJCS +DSEvMz1JotPtDU6j0Mzj8p+t2DHVHVGSbatIVSi4tYEnGXYoaXssokkfnEh3sX8h +k+cmWlaK+O2MHRJfmpsK7xneWnv4aO5JrUGqe2gaDMnS0DZRjSqAeyt6AeCwT/4U +194ERo5OI6mKzeecc13TO46asdAFNJPk7tbwEwIhAMKM1NaESOKBtStmcYVlGCyN +ofJ17DSrzcnBaNt+RFHTAoIBAGC6XoMAUEId7I0jP0ARv7DzL+vCnjng0k3RPS6L +YMEyToBPLUuxweUgy9yxtgZNErPqI/wl1sDCji7mK+NLKB2JeyJ1NLEoLjWYhKnf +2dT3XgKm48Vjw17M4DkaDkXCjfGxB6PHiw6ZHmLD6rRSIcx7rVoIQWDmkcyV4hJN +O9Di7fpIVexxVk9UsyMGCcm1/2CjD5+o0MxmVl+RJGJfwwORRDnoWPWMslwsj0ML +24ev4bEUSNzy0QSEu6QsgMeL4jYa1MapluBWtMs9dgIc8JOgR0elwtVRgYEqQVT0 +wom0U2MNk5hQ+YZT1PWUke/U+Uj4UsVkPROv+QczREL66l4CggEAd4gJ/md6IrGL +VBZlf9HDizOwn1QrQ5g1xzm0Ls7VHCWEKOSuLpEvyVf1xwADszgK/wavmvKeEyz0 +oYGKH6n6HbujmwX6oIG9RradAXJMmZA430n0eUUhAtP6bbqpJMHpmM6dBmQnoMdS +uhPxEsZkm8fvZyDJyOg+EG1VAEuVdhN7pStpmzFd23tvgvn6oL+/EmPGAWNHI6MM +2/OHb8CchiTXuY98c1N5Lk4C27R//bUKckbk0BODl9AUEkxdMec7X3hsXPlA4sDA +YXS4fNEvkt2pSSFseWg0wSmiSnamcHZZ/PiBfFmWzHlox09a8mkBo2c6dqnmgmeS ++S/Jp+A3/AIhAK9gZ6ecBAOdWnA/54X12DnanC7tF8lYHcbDE7OYMhYj +-----END DSA PRIVATE KEY----- diff --git a/t/data/openssl_ec-short.der b/t/data/openssl_ec-short.der new file mode 100644 index 0000000..442d3e8 Binary files /dev/null and b/t/data/openssl_ec-short.der differ diff --git a/t/data/openssl_ec-short.pem b/t/data/openssl_ec-short.pem new file mode 100644 index 0000000..bd3e4d9 --- /dev/null +++ b/t/data/openssl_ec-short.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIBG1c3z52T8XwMsahGVdOZWgKCQJfv+l7djuJjgetdbDoAoGCCqGSM49 +AwEHoUQDQgAEoBUyo8CQAFPeYPvv78ylh5MwFZjTCLQeb042TjiMJxG+9DLFmRSM +lBQ9T/RsLLc+PmpB1+7yPAR+oR5gZn3kJQ== +-----END EC PRIVATE KEY----- diff --git a/t/data/openssl_ec-short.pub.der b/t/data/openssl_ec-short.pub.der new file mode 100644 index 0000000..3964a8f Binary files /dev/null and b/t/data/openssl_ec-short.pub.der differ diff --git a/t/data/openssl_ec-short.pub.pem b/t/data/openssl_ec-short.pub.pem new file mode 100644 index 0000000..8e4f6a9 --- /dev/null +++ b/t/data/openssl_ec-short.pub.pem @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEoBUyo8CQAFPeYPvv78ylh5MwFZjT +CLQeb042TjiMJxG+9DLFmRSMlBQ9T/RsLLc+PmpB1+7yPAR+oR5gZn3kJQ== +-----END PUBLIC KEY----- diff --git a/t/data/openssl_ec1.key.pem b/t/data/openssl_ec1.key.pem new file mode 100644 index 0000000..55003dd --- /dev/null +++ b/t/data/openssl_ec1.key.pem @@ -0,0 +1,23 @@ +-----BEGIN EC PARAMETERS----- +MIIBVwIBATA8BgcqhkjOPQEBAjEA//////////////////////////////////// +//////7/////AAAAAAAAAAD/////MHsEMP////////////////////////////// +///////////+/////wAAAAAAAAAA/////AQwszEvp+I+5+SYjgVr4/gtGRgdnG7+ +gUESAxQIj1ATh1rGVjmNii7RnSqFyO3T7CrvAxUAozWSaqMZonodAIlqZ3OkgnrN +rHMEYQSqh8oivosFN46xxx7zIK10bh07Younm5hZ90HgglQqOFUC8l2/VSlsOlRe +OHJ2Crc2F95KliYsb12emL+Sktwp+PQdvSiaFHzp2jETtfC4wApgsc4dfoGdekMd +fJDqDl8CMQD////////////////////////////////HY02B9Dct31gaDbJIsKd6 +7OwZaszFKXMCAQE= +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MIIB+gIBAQQwCKEAcA6cIt6CGfyLKm57LyXWv2PgTjydrHSbvhDJTOl+7bzUW8DS +rgSdtSPONPq1oIIBWzCCAVcCAQEwPAYHKoZIzj0BAQIxAP////////////////// +///////////////////////+/////wAAAAAAAAAA/////zB7BDD///////////// +/////////////////////////////v////8AAAAAAAAAAP////wEMLMxL6fiPufk +mI4Fa+P4LRkYHZxu/oFBEgMUCI9QE4daxlY5jYou0Z0qhcjt0+wq7wMVAKM1kmqj +GaJ6HQCJamdzpIJ6zaxzBGEEqofKIr6LBTeOscce8yCtdG4dO2KLp5uYWfdB4IJU +KjhVAvJdv1UpbDpUXjhydgq3NhfeSpYmLG9dnpi/kpLcKfj0Hb0omhR86doxE7Xw +uMAKYLHOHX6BnXpDHXyQ6g5fAjEA////////////////////////////////x2NN +gfQ3Ld9YGg2ySLCneuzsGWrMxSlzAgEBoWQDYgAEeGyHPLmHcszPQ9MIIYnznpzi +QbvuJtYSjCqtIGxDfzgcLcc3nCc5tBxo+qX6OJEzcWdDAC0bwplY+9Z9jHR3ylNy +ovlHoK4ItdWkVO8NH89SLSRyVuOF8N5t3CHIo93B +-----END EC PRIVATE KEY----- diff --git a/t/data/openssl_ec1.pri.der b/t/data/openssl_ec1.pri.der new file mode 100644 index 0000000..d393408 Binary files /dev/null and b/t/data/openssl_ec1.pri.der differ diff --git a/t/data/openssl_ec1.pri.pem b/t/data/openssl_ec1.pri.pem new file mode 100644 index 0000000..b7facfb --- /dev/null +++ b/t/data/openssl_ec1.pri.pem @@ -0,0 +1,13 @@ +-----BEGIN EC PRIVATE KEY----- +MIIB+gIBAQQwCKEAcA6cIt6CGfyLKm57LyXWv2PgTjydrHSbvhDJTOl+7bzUW8DS +rgSdtSPONPq1oIIBWzCCAVcCAQEwPAYHKoZIzj0BAQIxAP////////////////// +///////////////////////+/////wAAAAAAAAAA/////zB7BDD///////////// +/////////////////////////////v////8AAAAAAAAAAP////wEMLMxL6fiPufk +mI4Fa+P4LRkYHZxu/oFBEgMUCI9QE4daxlY5jYou0Z0qhcjt0+wq7wMVAKM1kmqj +GaJ6HQCJamdzpIJ6zaxzBGEEqofKIr6LBTeOscce8yCtdG4dO2KLp5uYWfdB4IJU +KjhVAvJdv1UpbDpUXjhydgq3NhfeSpYmLG9dnpi/kpLcKfj0Hb0omhR86doxE7Xw +uMAKYLHOHX6BnXpDHXyQ6g5fAjEA////////////////////////////////x2NN +gfQ3Ld9YGg2ySLCneuzsGWrMxSlzAgEBoWQDYgAEeGyHPLmHcszPQ9MIIYnznpzi +QbvuJtYSjCqtIGxDfzgcLcc3nCc5tBxo+qX6OJEzcWdDAC0bwplY+9Z9jHR3ylNy +ovlHoK4ItdWkVO8NH89SLSRyVuOF8N5t3CHIo93B +-----END EC PRIVATE KEY----- diff --git a/t/data/openssl_ec1.pric.der b/t/data/openssl_ec1.pric.der new file mode 100644 index 0000000..3d0bcb8 Binary files /dev/null and b/t/data/openssl_ec1.pric.der differ diff --git a/t/data/openssl_ec1.pric.pem b/t/data/openssl_ec1.pric.pem new file mode 100644 index 0000000..4494dd9 --- /dev/null +++ b/t/data/openssl_ec1.pric.pem @@ -0,0 +1,11 @@ +-----BEGIN EC PRIVATE KEY----- +MIIBmgIBAQQwCKEAcA6cIt6CGfyLKm57LyXWv2PgTjydrHSbvhDJTOl+7bzUW8DS +rgSdtSPONPq1oIIBKzCCAScCAQEwPAYHKoZIzj0BAQIxAP////////////////// +///////////////////////+/////wAAAAAAAAAA/////zB7BDD///////////// +/////////////////////////////v////8AAAAAAAAAAP////wEMLMxL6fiPufk +mI4Fa+P4LRkYHZxu/oFBEgMUCI9QE4daxlY5jYou0Z0qhcjt0+wq7wMVAKM1kmqj +GaJ6HQCJamdzpIJ6zaxzBDEDqofKIr6LBTeOscce8yCtdG4dO2KLp5uYWfdB4IJU +KjhVAvJdv1UpbDpUXjhydgq3AjEA////////////////////////////////x2NN +gfQ3Ld9YGg2ySLCneuzsGWrMxSlzAgEBoTQDMgADeGyHPLmHcszPQ9MIIYnznpzi +QbvuJtYSjCqtIGxDfzgcLcc3nCc5tBxo+qX6OJEz +-----END EC PRIVATE KEY----- diff --git a/t/data/openssl_ec1.pub.der b/t/data/openssl_ec1.pub.der new file mode 100644 index 0000000..3ead52f Binary files /dev/null and b/t/data/openssl_ec1.pub.der differ diff --git a/t/data/openssl_ec1.pub.pem b/t/data/openssl_ec1.pub.pem new file mode 100644 index 0000000..e77f041 --- /dev/null +++ b/t/data/openssl_ec1.pub.pem @@ -0,0 +1,12 @@ +-----BEGIN PUBLIC KEY----- +MIIBzDCCAWQGByqGSM49AgEwggFXAgEBMDwGByqGSM49AQECMQD///////////// +/////////////////////////////v////8AAAAAAAAAAP////8wewQw//////// +//////////////////////////////////7/////AAAAAAAAAAD////8BDCzMS+n +4j7n5JiOBWvj+C0ZGB2cbv6BQRIDFAiPUBOHWsZWOY2KLtGdKoXI7dPsKu8DFQCj +NZJqoxmieh0AiWpnc6SCes2scwRhBKqHyiK+iwU3jrHHHvMgrXRuHTtii6ebmFn3 +QeCCVCo4VQLyXb9VKWw6VF44cnYKtzYX3kqWJixvXZ6Yv5KS3Cn49B29KJoUfOna +MRO18LjACmCxzh1+gZ16Qx18kOoOXwIxAP////////////////////////////// +/8djTYH0Ny3fWBoNskiwp3rs7BlqzMUpcwIBAQNiAAR4bIc8uYdyzM9D0wghifOe +nOJBu+4m1hKMKq0gbEN/OBwtxzecJzm0HGj6pfo4kTNxZ0MALRvCmVj71n2MdHfK +U3Ki+Uegrgi11aRU7w0fz1ItJHJW44Xw3m3cIcij3cE= +-----END PUBLIC KEY----- diff --git a/t/data/openssl_ec1.pubc.der b/t/data/openssl_ec1.pubc.der new file mode 100644 index 0000000..e2c7743 Binary files /dev/null and b/t/data/openssl_ec1.pubc.der differ diff --git a/t/data/openssl_ec1.pubc.pem b/t/data/openssl_ec1.pubc.pem new file mode 100644 index 0000000..3c7a592 --- /dev/null +++ b/t/data/openssl_ec1.pubc.pem @@ -0,0 +1,10 @@ +-----BEGIN PUBLIC KEY----- +MIIBbDCCATQGByqGSM49AgEwggEnAgEBMDwGByqGSM49AQECMQD///////////// +/////////////////////////////v////8AAAAAAAAAAP////8wewQw//////// +//////////////////////////////////7/////AAAAAAAAAAD////8BDCzMS+n +4j7n5JiOBWvj+C0ZGB2cbv6BQRIDFAiPUBOHWsZWOY2KLtGdKoXI7dPsKu8DFQCj +NZJqoxmieh0AiWpnc6SCes2scwQxA6qHyiK+iwU3jrHHHvMgrXRuHTtii6ebmFn3 +QeCCVCo4VQLyXb9VKWw6VF44cnYKtwIxAP////////////////////////////// +/8djTYH0Ny3fWBoNskiwp3rs7BlqzMUpcwIBAQMyAAN4bIc8uYdyzM9D0wghifOe +nOJBu+4m1hKMKq0gbEN/OBwtxzecJzm0HGj6pfo4kTM= +-----END PUBLIC KEY----- diff --git a/t/data/openssl_rsa1.der b/t/data/openssl_rsa1.der new file mode 100644 index 0000000..3355722 Binary files /dev/null and b/t/data/openssl_rsa1.der differ diff --git a/t/data/openssl_rsa1.pem b/t/data/openssl_rsa1.pem new file mode 100644 index 0000000..a8be1d3 --- /dev/null +++ b/t/data/openssl_rsa1.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQDV9a3rZ+yTE+cfK7sQJJz3S3nSVuYo73aDY827t4D1ri9AOK2f +Kot/pKKXpCA67rxtGRNdcxl0bQP1UknetqNdDRtE5DSLHbenxTRqbfH4c5SPxUkt +Qj3yKVMguSxaoy0Vdca5mhsvZC4mY9wN5mY+TA/HIpvsoUzTa59T2jw04wIDAQAB +AoGAUPVbT73NGIHpbDQB3kPcWP5oJBzZjhe+Ak1bZXI0C8JTArvvhlB05GGJXFOw +FlyLU8SvPSb2NMWjP8pZRTpaaYQRqneIVCaLgWTIZB+dh8CWDpkF+4vHxJF+D0eu +aT6YPKI6SJxlYOA1MWJ+zdxY/Ml5rvSrWwnqq8+EIOECT5ECQQDs2yJAGPDNipYk +xDaSldw/jMy885CJdmOCMg6/zLMgRIHDF/zpm5iyjwKAh7zc0as66kv2w1X5Ce5P +lygSspCXAkEA50DKXQ3LF7XlYKmXZSkJVLIQtyUl8Wu8uTre6szYiYVV6vocJ0JQ +/pJX5oxed3Q61puY4N/MGUj3yv5mpwb7lQJBALBVqFcd+lCbx5IRvis9hJ6PXXGi +x01/pS+twstKQ2VXe1/agQEORQ1SaON1qsafFiKjgfBxlpT0rsX0W/InnHsCQC8R +Xd7gvtR9nkk1W24okxCdCY/tTLK9pfThiZuqw+wBqoIgE/jdo5Sc/q0bJuMTUiJ6 +GvyyMF15H44+h3A5mJ0CQQDOOXZTDP4qkQG1+UTuztxkNHkwqRizhJOy3MYcVtGd +WtDkziCYuzRh7HNa8yGC/dxP8mLEhBhvs1MAjrLk7rNw +-----END RSA PRIVATE KEY----- diff --git a/t/data/openssl_rsa1.pubonly.der b/t/data/openssl_rsa1.pubonly.der new file mode 100644 index 0000000..b7b827e Binary files /dev/null and b/t/data/openssl_rsa1.pubonly.der differ diff --git a/t/data/openssl_rsa1.pubonly.pem b/t/data/openssl_rsa1.pubonly.pem new file mode 100644 index 0000000..5c511bb --- /dev/null +++ b/t/data/openssl_rsa1.pubonly.pem @@ -0,0 +1,6 @@ +-----BEGIN PUBLIC KEY----- +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDV9a3rZ+yTE+cfK7sQJJz3S3nS +VuYo73aDY827t4D1ri9AOK2fKot/pKKXpCA67rxtGRNdcxl0bQP1UknetqNdDRtE +5DSLHbenxTRqbfH4c5SPxUktQj3yKVMguSxaoy0Vdca5mhsvZC4mY9wN5mY+TA/H +IpvsoUzTa59T2jw04wIDAQAB +-----END PUBLIC KEY----- diff --git a/t/data/openssl_rsa2.der b/t/data/openssl_rsa2.der new file mode 100644 index 0000000..a0d3bc3 Binary files /dev/null and b/t/data/openssl_rsa2.der differ diff --git a/t/data/openssl_rsa2.pem b/t/data/openssl_rsa2.pem new file mode 100644 index 0000000..4fbc2c8 --- /dev/null +++ b/t/data/openssl_rsa2.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXgIBAAKBgQDkfd+59oUInJsIyN+0ac83pvhpAmqUuVfGhIuj3C/E1O9XT//E +JtMHEQp4I7w1jDsOAxuyZk20l9mkN7CuV1u2VlPrPq6kch0YIAJo6UxL8+k9azZ6 +hpjEvj4C9yO/p0XZgOWUGmaqxs5gMpCMeyd35FKZRzdFbewbdcZ99fMyfQIDAQAB +AoGBAOHkC4XW0MilwqPZq0e6f5EecmGmcOYdokhxi3fw3Az1ErW4MjyiwWgwEbCa +a5xoyY1dx0kE2PecVB+EqxiA5vmrDGMnsV3yTpVUnSF5+DjKyU7q1C1T1ikXdRn0 +S5HgjRA66A3aqIY3643S8YXWSvX6G1ynmWL4CLG5NPG94KnlAkEA/LvZh8/9Hk41 +cdAWPc69+IgcswhLJlqWQl2WmNnAcyVps8DIE9/fYnFLvzaZQJmfPfiQx/X08PvL +LiShCdEjMwJBAOdx0jP2Kx6rt7LqmNidLDvo0earYY9FjgNDOXvPYjUfZPyz6sRG +nb8VUNypEbJn1cLgtao9XW0rw4gh5pVtU48CQQDDoQCz4Oo0ECPMcl8U/rgL7ggR +CQVqrcoLmvfcXwlZ2Abm7f2xbKQ0RjB01WVxHLintoUTUy6DbtQKZq4EtE8DAkBT +zmhSPnpgscdj9wT/svIYg3a2MyqxiXsh/U6sYWzrVYHo63FAP13RmnNcY7AvzN+f +oGTHz06sQGOeQMBRLXRLAkEA3Jl+ydtUlDaSmzatMl72PGdWgOmvp6PYIE9S5Exc +S5m2oK8yymRKNUN2SrO2+JnJ5LtqYHbzsoR5jhBoJK9G6w== +-----END RSA PRIVATE KEY----- diff --git a/t/data/openssl_rsa2.pubonly.der b/t/data/openssl_rsa2.pubonly.der new file mode 100644 index 0000000..8b3116f Binary files /dev/null and b/t/data/openssl_rsa2.pubonly.der differ diff --git a/t/data/openssl_rsa2.pubonly.pem b/t/data/openssl_rsa2.pubonly.pem new file mode 100644 index 0000000..d2f2b86 --- /dev/null +++ b/t/data/openssl_rsa2.pubonly.pem @@ -0,0 +1,6 @@ +-----BEGIN PUBLIC KEY----- +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDkfd+59oUInJsIyN+0ac83pvhp +AmqUuVfGhIuj3C/E1O9XT//EJtMHEQp4I7w1jDsOAxuyZk20l9mkN7CuV1u2VlPr +Pq6kch0YIAJo6UxL8+k9azZ6hpjEvj4C9yO/p0XZgOWUGmaqxs5gMpCMeyd35FKZ +RzdFbewbdcZ99fMyfQIDAQAB +-----END PUBLIC KEY----- diff --git a/t/data/pkcs8.ec-priv-nopass.der b/t/data/pkcs8.ec-priv-nopass.der new file mode 100644 index 0000000..4220cef Binary files /dev/null and b/t/data/pkcs8.ec-priv-nopass.der differ diff --git a/t/data/pkcs8.ec-priv-nopass.pem b/t/data/pkcs8.ec-priv-nopass.pem new file mode 100644 index 0000000..945b96f --- /dev/null +++ b/t/data/pkcs8.ec-priv-nopass.pem @@ -0,0 +1,9 @@ +-----BEGIN PRIVATE KEY----- +MIIBMAIBADCB0wYHKoZIzj0CATCBxwIBATAkBgcqhkjOPQEBAhkA//////////// +/////////v//////////MEsEGP////////////////////7//////////AQYIhI9 +wjlaBcqnQj2uzMlHYKfUYiVr1WkWAxUAxGloRDXes3jEtlypWR4qV2MFmi4EMQR9 +KXeBAMZaHaF4NxZYjc4ri0rujiKPGJY4qQ8iY3M3M0tJ3LZqbcj5l4rKdkipQ7AC +GQD///////////////96YtAxyD9ClPZA7BMCAQEEVTBTAgEBBBiKolTGIsTgOCtl +6dpdos0LvuaExCDFyT6hNAMyAAREwaCX0VY1LZxLW3G75tmft4p9uhc0J7/+NGaP +DN3Tr7SXkT9+co2a+8KPJhQy10k= +-----END PRIVATE KEY----- diff --git a/t/data/pkcs8.ec-priv-pass.der b/t/data/pkcs8.ec-priv-pass.der new file mode 100644 index 0000000..174875c Binary files /dev/null and b/t/data/pkcs8.ec-priv-pass.der differ diff --git a/t/data/pkcs8.ec-priv-pass.pem b/t/data/pkcs8.ec-priv-pass.pem new file mode 100644 index 0000000..12ccc5f --- /dev/null +++ b/t/data/pkcs8.ec-priv-pass.pem @@ -0,0 +1,10 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIBWjAcBgoqhkiG9w0BDAEDMA4ECKvdZESlMxWnAgIIAASCATjCay4uTsTVaS2L +d8714Xwv3EWfIFc4+I3dWFQayElm+PNcWIuESk3Pr4VwIUEuLAzo5xCI5G60DnDX +5Bux/FenEbeE4Vi/s8UmUDANGbAZrOzrlEzDKitCuYV77cK8Bkrdu408OqrmNBtn +HTtUX9o+o+fNbqHvrsQwRbBm7BcvG8P83kcMBDDVCgfJHfME4NeFZTFfgG+NOT6f +77jN4ylAac6jEa/lEnYWUn2CorTb/gT/5G/o6KuY7RHIYGQIgkQGGbQBCoUISgi8 +Mk+7012wlXiN+tzeAkvitTvZlVXTHBwnx1iU5cmx+S4VmH2DdZPNq7lbp69uiqzZ +CtFNCAlycZJkf7aiYgDQeimUDIceW+NKSf8PZCgLkvBNAgJ7GvS5SVvQoOrghtEI +5fUFKVAaDkKBGXUgCY8= +-----END ENCRYPTED PRIVATE KEY----- diff --git a/t/data/pkcs8.ec-short-priv-nopass.der b/t/data/pkcs8.ec-short-priv-nopass.der new file mode 100644 index 0000000..ee4786a Binary files /dev/null and b/t/data/pkcs8.ec-short-priv-nopass.der differ diff --git a/t/data/pkcs8.ec-short-priv-nopass.pem b/t/data/pkcs8.ec-short-priv-nopass.pem new file mode 100644 index 0000000..0a6f3f8 --- /dev/null +++ b/t/data/pkcs8.ec-short-priv-nopass.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MG8CAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQMEVTBTAgEBBBjFP/caeQV4WO3fnWWS +f917PGzwtypd/t+hNAMyAATSg6pBT7RO6l/p+aKcrFsGuthUdfwJWS5V3NGcVt1b +lEHQYjWya2YnHaPq/iMFa7A= +-----END PRIVATE KEY----- diff --git a/t/data/pkcs8.ec-short-priv-pass.der b/t/data/pkcs8.ec-short-priv-pass.der new file mode 100644 index 0000000..6b127f8 Binary files /dev/null and b/t/data/pkcs8.ec-short-priv-pass.der differ diff --git a/t/data/pkcs8.ec-short-priv-pass.pem b/t/data/pkcs8.ec-short-priv-pass.pem new file mode 100644 index 0000000..be41bef --- /dev/null +++ b/t/data/pkcs8.ec-short-priv-pass.pem @@ -0,0 +1,6 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIGYMBwGCiqGSIb3DQEMAQMwDgQINApjTa6oFl0CAggABHi+59l4d4e6KtG9yci2 +BSC65LEsQSnrnFAExfKptNU1zMFsDLCRvDeDQDbxc6HlfoxyqFL4SmH1g3RvC/Vv +NfckdL5O2L8MRnM+ljkFtV2Te4fszWcJFdd7KiNOkPpn+7sWLfzQdvhHChLKUzmz +4INKZyMv/G7VpZ0= +-----END ENCRYPTED PRIVATE KEY----- diff --git a/t/data/pkcs8.rsa-priv-nopass.der b/t/data/pkcs8.rsa-priv-nopass.der new file mode 100644 index 0000000..e728bfa Binary files /dev/null and b/t/data/pkcs8.rsa-priv-nopass.der differ diff --git a/t/data/pkcs8.rsa-priv-nopass.pem b/t/data/pkcs8.rsa-priv-nopass.pem new file mode 100644 index 0000000..51a64f8 --- /dev/null +++ b/t/data/pkcs8.rsa-priv-nopass.pem @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBANPN17xW4EkH5PXG +1i/i3rE1EXFcCHyxmz95VRBDs1p3MuYf9mxntbfYAmuzS3KrRWh3IyX/Eh80N/v9 +OXPlwZbVqSTX+L3pCEJtRtsWn0zmswGThjMZiwle0oWuap63L35F1QN8EDaSPSBC +yGELNRr6rwVYq0w5b+LOcaCZ+/H1AgMBAAECgYEApfu3aGpww+rC3HUhX0+ckyTy +cXLdV9LbxidwqRlVEb0+DyfXNucjelp2sy5EHy3na9GJovo8mmWSxhCRGKliRkQ6 +XgrEMZdCSaWI2AazuHAGlUJRFEVkvdla3AuBAn6y0YdDp/3kbg0yahmKyD8Gq74z +nUYbDL3R5JtR2Ad/KlUCQQDvSEICTHbO/BF7hVmlKRYZSNHKEPrv8X/OlppS14Kv +QRwc+CZ5+l6T1Y+l5cHJQUXrXZoWS1K741TXdUhjjUd7AkEA4pod804Ex8sttdWi +pHMfeyj+IbPAk5XnBc91jT7AYIeL8ccjtfl99xhMsGFaxrh3wA/4SGEvwzWkbxcq +H8G5TwJAKNG+0P2SVwURRm0dOdukdXPCtiHnbP9Zujhe4zr4hEUrMpXymmRntfh8 +pORpBpgoAVraams3Fe5WDttnGfSD+QJAOOC6V9HjfUrQhG3FT0XeRwm5EDiQQ/tC +a8DxHqz7mL8tL1ju68ReC+G7jiJBqNOwqzLW/UP3uyYByiikWChGHQJAHUau7jIM +45ErO096n94Vh95p76ANxOroWszOt39TyvJOykIfoPwFagLrBWV9Jjos2/D54KE+ +fyoy4t3yHT+/nw== +-----END PRIVATE KEY----- diff --git a/t/data/pkcs8.rsa-priv-pass.der b/t/data/pkcs8.rsa-priv-pass.der new file mode 100644 index 0000000..a61a423 Binary files /dev/null and b/t/data/pkcs8.rsa-priv-pass.der differ diff --git a/t/data/pkcs8.rsa-priv-pass.pem b/t/data/pkcs8.rsa-priv-pass.pem new file mode 100644 index 0000000..e6854b3 --- /dev/null +++ b/t/data/pkcs8.rsa-priv-pass.pem @@ -0,0 +1,17 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIICojAcBgoqhkiG9w0BDAEDMA4ECCQk+Rr1yzzcAgIIAASCAoD/mgpUFjxxM/Ty +Yt+NeT0Fo4echgoGksqs6+rYhO16oshG664emZfkuNoFGGzJ38X6GVuqIXhlPnYQ +biKvL37dN/KnoGytFHq9Wnk8dDwjGHPtwajhW5WuIV3NuhW/AO1PF/cRZKFjWrPt +NWY5CrpfH6t6zojoe+5uyXpH29lQy4OqvSRdPIt/12UcB+tzV7XzSWEuXh8HAi8a +sYUu6tuCFnq4GrD2ffM4KWFmL5GqBAwN6m0KkyrNni9XT+RaA6zEhv/lVcwg2esa +4/EzRs0ixzzZDKaml8oCMl9RHtFAbQmdlfV7Ip4rGK9BwY6UFiDMIVru6HynOVQK +vvZ+j//bgO+3ubrv7psX+vC9Fy/MoH2Tc7MIwDN/QVTciPZlzjWBnBNxMfeFKtEn +d7NFiapgfLuRQIiDTMrW/clcqvO54NphxhrcgUEoxos4twKZARntqPZHtf8nEM2x +2sEF5kI65aEF/5Yy16qvP0vZAA2B1kcIdXZ8XLZCp4c3olhkIrmgUpo1gyFXdCoC +7dT5Cz7/YLkq5hkcFrtp4V9BZMR24fSttc4p24N5xuZ+JneGnGkLX6B+nJAtm9vw +bZA6P+23GI0qeMzL3HJXwCOTSsWfm/H9W5+2Zmw851aAmE+pZLni/pk3e3iNSWgs +946x/doA5O0uCFsU7oxme+WAIp2SjhxGoe808Lf1CCFMPboFi1O/E0NsX8SIEX+i +U+UHi4kxZqVkr3Q5SB/9kiSv8K1bE787yueQOT/dsTYYaMsjAbkEZo0o/47F32T6 +A2ioXHOV/pr5zNHqE5tL+qKEcLYbAUF1O+WvmdqYz+vHQjRQBatAqTmncvLDYr/j +1HPwZX2d +-----END ENCRYPTED PRIVATE KEY----- diff --git a/t/data/rsa-aes128.pem b/t/data/rsa-aes128.pem new file mode 100644 index 0000000..b3d351f --- /dev/null +++ b/t/data/rsa-aes128.pem @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,2823DCBA91F7DBA2ED920CAEE40F0BB4 + +KAADjca5SzbAbdz2cF567ZO9WjZz+lA1C40gsOBvHB6LjWU32YGW6Hz9a7pwUjOh +E/gGSFkKv6pTJgXfLs/l+pIDGSohhzChw7hkmN1IgVXqDQZw3koW5Yn7bg6xeJoI +JFwIIQhnft6BHG2o/5MzUTRwHpIxRuIaz2FnZtBNbVtQInHtP8LJIAVoyoO4c0ET +IQBDj7dwOAPdxOsrKCRkjI8IBMwWtKBq7XunkE15dZFFZrZOfIaXUqNYF9DlCHBk +eGV2lZoL99pOtJzHTBzv3rtyPYqCNotTNnui2Z0Jzcq8K97XAlzKhL7BFMw5TSUF +Tf9ECgumaRELXDdlUtEiZ7uACBXAW+qTUxOCrp+EeyfUBYPLuiy9KQvJd4C+8QIs +OIYekzfqZfhbhOdb0U7ZRN3KXfuNS70vKfoMyuW4UVx75QZt3CnJL8M6dn+eijjw +mEVCT/a8SLgTgMKtl2AzFiJK4WqvnUs9iOswlaAWCIpvrMQmxltoL34aim55EZKd +gDlEW5zCcjYe8A5d5abd4cX8vVrN57j2O3Dk9Dgyr4ZHPjBMF8b6LnWqBGrgFrbQ +LpjDZRNm4W7JuROL5VtSBEwP5VAMdl56UPlgGmM6K2MgAvkZ99ycffu0vsKOxd1T +5wpY2y5SBOyoex0XPa9woz0GOLjf9ydpVlVikPHk4XX2ts0+L5VttkQ7wO9GLUj0 +OltsrOxscHq3xPYsJgxmmHGmhrlTKIv1YHjzZsteqZLokH3kr1sCEX+vS3lqaQP8 +rmIjf2vAWi3inteZifZ2v48V8XPTOUky/YQvTEGDstHWVd74hhrCVfx+Jk7vjipr +-----END RSA PRIVATE KEY----- diff --git a/t/data/rsa-aes192.pem b/t/data/rsa-aes192.pem new file mode 100644 index 0000000..d3922bc --- /dev/null +++ b/t/data/rsa-aes192.pem @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-192-CBC,BEA13A8B02546A15B7F23ADA71266129 + +7Qv9E1ZLVnTUu7sG+EdRWqDpOo9vr8ro6Mqg1wHqXozx3JuOTbW9QvcVra9vcdfQ +Zk2HC9sDKc44Jjw04zXQ8jUpFbjCtSGYqCp8Vjq/hsDsMwDMwqskq8BAN8G4s7K6 +vkb/RBqbix+Dm3h9AWsh7+x1BNPX6aC8qyH2YZN/IlPfn52Oq8sTIk6w834NifzH +Y87zI+cJ4e8o8XIVIAoRQFiVbLT5DsV8eMKh1jgwS3b5rdAK/GzDgEWwgonb3R2y +8KGrCIAQbkY1j5jNdurhAwJVEPUr9mwv4tPLoj0vFOez87TNh7iyTQwJ7NsDCilQ ++S7xXxaLewKOvVqo9Qf1k8/xTWUtwSbtwA8V/E+8t7Qv1JkcBNGGDCRw8DWKmr3c +q1qjA2yTILFqi+F+5bmpucPA+tm+iJjgo5uPqw0A/CzSI2Y1haXdxf5thf5eHzJW +nGL5e+2muuirsViNRi4bcqaQ6nngWFLpeeySLL2gbgnEe2z7nDfBoN0821j3G8Qt +mb/lW8KBjQVYoPlboW3u/QAy73Md4IGxvowqRQezOuhr6LHXP9UpzH3RfrHykUzx +FhExT3Ke4volyejYZCBMqIL6AEHNjefJsPGRD8Z2Hfvso6EXhOeMV/hcMd+rgy1f +EMV6hBIIkLWWSKU6yu19nd6xdLp6ZJ3pHbuDT/6EHJs7klF/OdvhGRl1icf3Bvmt +Jnsu9OvVPvNfdPb5agjmcXF962xk5ceypfwJguBQVIqw/XHsu7cjU9EKdTIlg5oo +oxDxyLYAdFUMhFiYtvYd4uCOIjIdFlRZYU9Hj+aI/5jGfrHglTRZWukJTtv6Yjpj +-----END RSA PRIVATE KEY----- diff --git a/t/data/rsa-aes256.pem b/t/data/rsa-aes256.pem new file mode 100644 index 0000000..c5a853b --- /dev/null +++ b/t/data/rsa-aes256.pem @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-256-CBC,E4FF35065678C2D4BF54C5F3070797EB + +0u2a9fhgca81gTue3i5W7uT6BDXpNR1SwVR0RyXs3eTKgFrdy0NPxfACIpekTZiD +ZKTpXwM6tbVC5gzsMK1SBeoiiXvDW3lN+nmiWzY9+sVssv0ys+fjq6WwlEbF3tI/ +OflPOb17M50LLFxOlH7bqwzt5fMBHs2XA+ehMdg24ah1f7pSWjuZdjPOEMuV+XZf +wGJTcdJKMZHdGn0hBxItuEQrYrxJloOJgYS5fjKoAGLmS6dKKVQa+nAJKVE24VIj +spngBoB8zD4OW4Q6qFyPqiFjY/A4JgzBnwcKnkRVCbO629zbdvsgZDiHA4OIm3GH +MWfdkDU48hmTriHXQs0dVEmZieRMVIKK0Y4gXXGElQy3w7XTUhvad9o093Ddr1UR +ZktzPumpnnNVnhPdAmVQtENvqdrFvD/FhNpYnP8HeT0CYQf/aQSZs2Te3doWH6Mz +quE6BXCBqJv8C+YKk8ugFmpzX7An9Lc46KA7hAc6eCQNvPPGEvH75IKWULqZYyBG +xpLWow1jNId8zmgTIW+9eOpEroQ9/Lc5/9E/kSyylVfNxXAGmfdG4kzdF2vLyR4r +cnMJfJtHKOx1QJ6nJfa/giuEwTcrJBleDRFslE1zVoNi03PZ9l5LS0YKhGSmLPoj +T6IvAmKDGYuhp1hnO8spN2awqXaUYwrIzsIWKgwUTSvGc4TepWK72qP+h6/TpSq3 +Sp0OhzNWM6YgLi4gchx54CYbsYwf7vhi7qK6ko2sehMJ3UC8rFQzl+OoddbdQ7dI ++ZKzilZ/ppvh4yKdtYWEB/M17GzJHbU9SPCNKv0S+bo1gG5dsQO2Zlh0CvQUwzaG +-----END RSA PRIVATE KEY----- diff --git a/t/data/rsa-camellia128.pem b/t/data/rsa-camellia128.pem new file mode 100644 index 0000000..5862a7b --- /dev/null +++ b/t/data/rsa-camellia128.pem @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: CAMELLIA-128-CBC,E1719CB01F51547E271937E2B3D150F3 + +zzVZcRFkUA1zdt5Cp63erlq8IoL/t4HDDfAVJqQxuU78XB5VFe8BPN6XFedIBYhe +q9s5fG4ULjf8NJtKPZ4Di7T8HZvAn50BJLa0u9HBHZDQiFQNzrt7Tb7MA2ENuqzG +kmzza8wK15Hzri64Dmfq+Tl19fznAHTnawsrHQiahg9ylEPA2ZulDqnGP6ru71mB +ohEIwg1cxJvaEkQUMiPXUirg/o9qeVhXRBT2cNWPa+qn7E/ufNhmvJM219TqzlQg +4+4zTEi8PkZZHeDASZ1Z/XiZHM7Rlm6PT36QqXORhoVAXeK00ErCpv979ljQ6cEP +4xIjRacmbCNrMPdpvggJP/QJdHvvWzZZHiv8BveET9R2RjquFwhRLKIJZ+IR5D/K +Ppb5wQFCyL0cJ3Tv43e7AWO4oH2QZO7qc2lfnriuolbLHBRcYUUe9qbLHuu5rqdj +BG/ZV0eiHVwCj8g0a0TK0fz0jCiKEe52AlEernnIj6/accQsUDuZfkDLmYoK6me0 +SbGAEfrY1jMPuWwSJvCl9UGozJx4lPXB/3qtkEr5656MYHvf0OWpXqWIkcfDwZ5z +QXruOzzF+ynSB8a/RMcrgKMW9l/3Uvgylcwngkgln85lxpSf1U1vRD2jfcmanPxq +WyIgUGFB8yrLYsiWVv3Xtt9UGfa1s+EW5jTA9uYPAXoadD+HWKqCgQCBGLOpPNZl +U6fTHzM42gxd+5kTcy9IZGSn6lB04K1tRNiJyds1OC7Hb/wq+VvZYy6kAx7WaAmz +CSgH1AIz60AKS3ZknZRnz1IZhDT99BB4dc2RYndY7M778D5bQAP5VZ6DIuTL5mGJ +-----END RSA PRIVATE KEY----- diff --git a/t/data/rsa-camellia192.pem b/t/data/rsa-camellia192.pem new file mode 100644 index 0000000..d203ebe --- /dev/null +++ b/t/data/rsa-camellia192.pem @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: CAMELLIA-192-CBC,BA47F350F95736DBA1AFD47D0998C35B + +hTtFvf+yjUz4lhhNLe2voESxZ6ae65dvl3eWtNZmVmnVhArHqDmcak8GleLD1a2a +FfwJGzdhvAQcLtfn1jpdObjwPS8XUQ9PVk3Dbjc5f4nP5f1ThkcewRtpStpc2MHH +KJvXUOrDhcawO5MJ/EjvRCLs5N2Ykzqn/ptuk2xHGu116MFIZDH079iTYv3j/qQD +OgengmO4uBAuQ5x6VMnIRRwF8zKYZH8wvWTD3FKInN/Fy7x8MOW+b6+eq63uD5vO +oPXKaXJKtK1n1JiET5fdb9NJHZ5T4MERou0hFcHxT79TGtXwY2gsZ807sXIHZwIq ++0c/tLEfNIuaGz4pA0s6c1fYbN4cx5dj+oqrsAaP7QazpEtuE1nlnQYCqlOAwEyN ++x4T2fM7P2Vw7DOaLlyDIBXWtSfMhVfF0BXBsMya8BREownyvIt/lsbTv516waNp +pM6Tojekf2E6U4IQlselIHS5N76KJullosymypyFh2y8S+OjUi4ZsstOgI+84aju +F+/QMyW3I8gaFo3hL6y7Xzc5L3woKfHTXul0IyAofmLeUXWAABTY5FIxM5suaGkw +ko7XTq8xVaQufHFxJZyG96epOe7YWgZ9d/t5gUSnK/6S0J7O0fMMn6vKQOCaaNV4 +Xb3QNJb+2zxPtV3p1ZmQy10i61f+X1WfXx53jG2HLIqBdGc0WxApTaVgppYSxaeT +LF8Lc+8lJRgOTidOr/wdWSuYjbbnGlxx+MHSJboljxzB3XAJ5LDQ0taU0IKkdpfD +QV1BDul0tXsAQs7uEp7rqiLmE1kALzU8EE0+d6/VrVmuvLhDAE1arcyPXPIQAKLa +-----END RSA PRIVATE KEY----- diff --git a/t/data/rsa-camellia256.pem b/t/data/rsa-camellia256.pem new file mode 100644 index 0000000..de8ee26 --- /dev/null +++ b/t/data/rsa-camellia256.pem @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: CAMELLIA-256-CBC,A3CE93CC318DCA6C8537B9554149F96F + +uJ1S7ZSrL959vXzFKkzI1vFBHw9n7kH62Zf+iH8gLtLVmMDeIoioX8UGYTvK+jWz +SbZv2e4bIoxufFIPY+lZ+seLTdU4lWpZ6Shc6xHGc7qRjZ+pT5+c0Dm+W7XQLBoQ +Lwrtb3c6mdhVmJBkk0At9XtzWu2WNE8rQtkWl1NvJLpIbmrQ75DTn2WMQXTgE7fo +8jMngWoIyZFwXnWavJLPUq7WkaXfp8AfRiei7riPT35Y98juGc8MMISR9yWhg6Pz +cCMEvHMns/v0aurhmkTHTIbHI8BjbEGJ5hMhJx6CijANvWbh/UCOBx50GZINs0+q +ZZ8Mn5lHPVV1Q6bMEBQvLAbvUrOebxNg7Fljs6KBFoKm9bN6cLX24jNQ+b4c7I7P +FU3fSnvU9taAxrOev2a913Ek28jdwJQE8sZut128VBMvLj9HIb1Lf5jnMkoapH3f +HA57VrPhzNFIR7/tx3jT4clzW3AyyKt1E/7UQkfZjANnKwsL9Ru8Z0X/BLxSQlMp +HsEHVVLGlVZCrNFp0L7ex39JT6WYoRt2YT0HySrDTu8R4Yh8hgBOKTLLtk/2Ubwb +HrEoQc7e71JDHpnwetxZhUWuIg0IJjz8QZSZzxRgY6qoA1FZV4JEExlyqDCeP7EC +MS7Jur3pMhXMga7rmsXxJOs0bf/vyxFmXZCeSWyF2laKBJ7MHnGd1Xc6k70jQdJ0 +wHy4Dwf/6+mgU9zb10NhduXfEEWRvSjc95nwOAdzgvVlTOs0PzECI1BSnFskWG9f +DxjFHpNAvbLq6kY4v/UEf6mCdgKesfsScH6XL5YJbkgT7JA7KUFO13j16d8B5rrW +-----END RSA PRIVATE KEY----- diff --git a/t/data/rsa-des.pem b/t/data/rsa-des.pem new file mode 100644 index 0000000..388eafc --- /dev/null +++ b/t/data/rsa-des.pem @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-CBC,5CA5B2DF978A847C + +fEuYTfFWcMY5GYXLY7+LbmTeKRNyE/NnvHD+Nr0pJdM0Su7o/9emaQ5xMLgpnBEd +P3p4hnU3irTe5OIE6SxEY9P5M3DH6CnX4jdZ27DvBlUGj64lowRi3QoY9V4+FvkC +tqdy9Y5BkK+eyxr7eIgHpebNTLEdd/7SUgJhPpkP1IZGBcY2HfCqrid4ZGPHaENj +1jlVUy2/Uv8qsQzVEB0JchLouZC+B6oRVKOzaEIspQirR+VKC8dE/3k7ss/EaqnV +hss19GOaOLzzmAFJa5aWc0bhLI4NMvzsZKELpnKSkcYT+urT/F+BjKGTNhEW/ky/ +Zy/HcWE3Ql0Jid1kSZqXJm9eesw/SSNn2hTO0hvznRzIFFnI+2GU1EN3PDg6SKQv +QhzqUuKZ79Gb5tBxKgjEUd+vH/piJ87SumgIHce3gWX5nPblvOoa+VvYs+nWkJDU +8GiftUxrc1RTkJRO10L/WDHV8rq9D4/hmBUcSeZRHG1N9AAddx39HUm90T8vxUBI +2y5HdS1ypP30eWy5srk+by1QBcH/s8OHj0uGd8pAcnZS4sMeWyxA1pso3xPG982l +SOEc6BVVACKPp3qqSGZ96sP4g2oa1uY7mon5GbF3GUFu70LfWjshBU2LT1Wuqcm/ +UatR/Wv6PH6JK69Nt9iclGTBSXwC72IscJG1a09fa4fNRN76FOFojB5ZM9RqFccH +cxwIa4W9qbyvTP2uGFRmxB4PnCvgUn5f/BHFsB6QinjRhuLweP31e0CGUM83xE7H +7Ds5QbMVonnFIuURDZKLXisUNArhsGNxj4NLFh654aI= +-----END RSA PRIVATE KEY----- diff --git a/t/data/rsa-des3.pem b/t/data/rsa-des3.pem new file mode 100644 index 0000000..4616384 --- /dev/null +++ b/t/data/rsa-des3.pem @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,C183E11FE570A434 + +8CEARke2e/AzkOk4eB+Kll0Kt2vrxcr1Q5/VN+y0tRRV9fgqYb24PtwRVSA2bOpi +ksC08XsoOq/qRwdE2EWSqsoZ7xM1eRDTl0oYmW5Tzp2qisqw2QMe9urYG7Qo6R41 +rr+DSzBVPJf9EhygeiWaNuqADZWAr5mF+zzHPjkShf/+g3cZ+uUDA0AWHGdlbp3N +08oUnGBKK2jyNX+DVcQrrMTICNzU1YJwznpeY2YgZpaYwWvNTRh7asi6Be2UFxWx +LNALom6LTpL+F611RS9/qOtlfUpWSE7XK5bIQE5j59VR93VxEP58ilU/qNXI6DXO ++LfEiXB98iRux8fQ68Ooqlere7//HxOPLp3KNcxXgHxuRsfWBuAO5qVGQOWhUanB +RiG6/Wq3ONe/PRRkMAme3lxGNpPR8VHw/F6jLhA/cFGV6e3IdwEI7esAnYnJEI0x +5wB9EoG3DhJMdPhULBp3md7oxFip1lxfZmhh1hh84FR3etin7bHHfaz+nWain+RQ +s6uf3yTYnpPjiC/d5WSS2d1sQ5T6DOaXBt9E5O5E9q0vehFHoY+jfwPy7/VOX/LV +l3s3WjaBd4o6M69TNBXSlAlFD0fvfpkaUMSvzVXevMwEl6qWhWkkc9YWt/mmBNRU +2DcIdPOwNtKERcNqxxw5EYoEKGktHfDZtjki1rB7icN/HWU92QujnhoC4PgjAV1p +MU9zOs9xwK05fC4Aowxujoa+hs/BO4Ss7G0oATrdteymOjiVGh9zBfWBlb3szlQG +bQo9UGYcCIpHMJQz4yah5tca+n4II2ICJFRNx5siTqu7iUSOyZ945w== +-----END RSA PRIVATE KEY----- diff --git a/t/data/rsa-seed.pem b/t/data/rsa-seed.pem new file mode 100644 index 0000000..0416fe9 --- /dev/null +++ b/t/data/rsa-seed.pem @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: SEED-CBC,DEDB927E484244917048F7B10B131414 + +uvGL1hXZrBta0ctGaQraLnjRAdCmn/Lxunk/MEGRqqAlF7R3I44YLF/GEhwqrRuW +7qXfOzDqLJQohA/dUq9+6brukMb2E7b+af2BSKYK6fpKF2y84Sq3E/6/mZbEGQje +4fPeG+nt4L8LDza76IRDU1Z5qNXAMfvYj/GopgeIzWTbFwwM8H2rm9U/LwBalPQA +lRvdOLgO0gGnHTA2b3I3APPzWdLwX7vGgczIZCJUSXuGCMQVtNfpM1kAdqttpiyr +Iow2DNnZ7+eA5qlgS2NcgvGb5FIDj43sgzJLRBAXN46Dc5zWI0Wk2i4pBYbJd73i +5qNPRgS2EaSPsPMLBH/3pvRzPI/Bptqz5NzkbJrV5ojppK4pdTJdyOswp73Jr6e+ +Y768RzHcGaNm6TYjHjWg5E3/6wfqlYw1x2BDmcR7ny9VV/GF2pHzJOsU+sb0fTM+ +0OuDARunbDMFl+xjzwvcErSR1cWwxY9M6DMxZmWVFGJD7ovVaKZ1lgwBuEdZh5yo +Rg0RrMFhwB/gZHkMm8xtSHGdCcsjqmixqbm4jxoYwZ8RLoFkMWshFmM+hjvb0SKi +Jxo4qOnS3smWduICjhEedLkwpVmbMzGXnZjVcJpBacV6KrQOa6O2vBSbo4w2ZQM7 +ZeU+CU3p1718GNInt5+H17HeupROk87HnHiDLKuLZw8GLcqSDAHpgSzTHusvM04q +uQt0SrU8KH5oILcj9I6embONOpZR7zY9+eFPGemTrwNFQVSt1L9nuLCUr+ZqmWNl +AqVtOGq9kWSvWUo9URx/Ze7Y0Zs/6DBmn/dMQnWMR75nV/kgE29P35A8vzXPXcaE +-----END RSA PRIVATE KEY----- diff --git a/t/data/ssh/ssh_dsa_1024 b/t/data/ssh/ssh_dsa_1024 new file mode 100644 index 0000000..efd234b --- /dev/null +++ b/t/data/ssh/ssh_dsa_1024 @@ -0,0 +1,12 @@ +-----BEGIN DSA PRIVATE KEY----- +MIIBuwIBAAKBgQClPP2r5pBXhp0qsGBu3WZ0JRvtNUDWsbtxeb9DXC/0kVFuyHaV +KvLdeLIitJgOso6YS4Tn+bfILoExFQZZT/OgDUmxYoB+1jd7+snSVqputKTYTRzf +/+dHJzbSLF28Xqt1bbCOuKZB9TianmQxy5ru95OE9BCjs7MpUnxf8LVQSQIVAKGm +5ssdWLA8H6NK9Rvx7hMdLs8FAoGACQ9TzAokwkGtccg/zQljmowrn0ziMygIZupf +p5QVT4iiPtutl6WLdduynuJjy/FyQYs6E40kDdPLhzIP/C+lv3HTtmmfpoZAZ0tc +QJvNwwMKi6w62kdcP+EERca+VW8svKp3o6z40yaGwTdQRrL/OMB5I5qAp+qRSH5B +mHgE5SYCgYAHYPU1zMVBTDWru7SNC4G2UyWGWYYLjLytBVHfQmBa51CmqrSs2kCf +GLGA1ynfYENsxcJq9nsXrb4i17H5BHJFkH0g7BUDpeBeLr8gsK3WgfqWwtZsDklt +Obw9chUD/siK6q/dk/fSIB2Ho0inev7k68Z5ZkNI4XOwuEssAVhmwAIVAJjBvZ2W +/WS2qshYFM74ef4InjBE +-----END DSA PRIVATE KEY----- diff --git a/t/data/ssh/ssh_dsa_1024.pub b/t/data/ssh/ssh_dsa_1024.pub new file mode 100644 index 0000000..abe606e --- /dev/null +++ b/t/data/ssh/ssh_dsa_1024.pub @@ -0,0 +1 @@ +ssh-dss AAAAB3NzaC1kc3MAAACBAKU8/avmkFeGnSqwYG7dZnQlG+01QNaxu3F5v0NcL/SRUW7IdpUq8t14siK0mA6yjphLhOf5t8gugTEVBllP86ANSbFigH7WN3v6ydJWqm60pNhNHN//50cnNtIsXbxeq3VtsI64pkH1OJqeZDHLmu73k4T0EKOzsylSfF/wtVBJAAAAFQChpubLHViwPB+jSvUb8e4THS7PBQAAAIAJD1PMCiTCQa1xyD/NCWOajCufTOIzKAhm6l+nlBVPiKI+262XpYt127Ke4mPL8XJBizoTjSQN08uHMg/8L6W/cdO2aZ+mhkBnS1xAm83DAwqLrDraR1w/4QRFxr5Vbyy8qnejrPjTJobBN1BGsv84wHkjmoCn6pFIfkGYeATlJgAAAIAHYPU1zMVBTDWru7SNC4G2UyWGWYYLjLytBVHfQmBa51CmqrSs2kCfGLGA1ynfYENsxcJq9nsXrb4i17H5BHJFkH0g7BUDpeBeLr8gsK3WgfqWwtZsDkltObw9chUD/siK6q/dk/fSIB2Ho0inev7k68Z5ZkNI4XOwuEssAVhmwA== comment for dsa/1024 key diff --git a/t/data/ssh/ssh_dsa_1024.pub.pkcs8 b/t/data/ssh/ssh_dsa_1024.pub.pkcs8 new file mode 100644 index 0000000..40b1e3b --- /dev/null +++ b/t/data/ssh/ssh_dsa_1024.pub.pkcs8 @@ -0,0 +1,12 @@ +-----BEGIN PUBLIC KEY----- +MIIBtjCCASsGByqGSM44BAEwggEeAoGBAKU8/avmkFeGnSqwYG7dZnQlG+01QNax +u3F5v0NcL/SRUW7IdpUq8t14siK0mA6yjphLhOf5t8gugTEVBllP86ANSbFigH7W +N3v6ydJWqm60pNhNHN//50cnNtIsXbxeq3VtsI64pkH1OJqeZDHLmu73k4T0EKOz +sylSfF/wtVBJAhUAoabmyx1YsDwfo0r1G/HuEx0uzwUCgYAJD1PMCiTCQa1xyD/N +CWOajCufTOIzKAhm6l+nlBVPiKI+262XpYt127Ke4mPL8XJBizoTjSQN08uHMg/8 +L6W/cdO2aZ+mhkBnS1xAm83DAwqLrDraR1w/4QRFxr5Vbyy8qnejrPjTJobBN1BG +sv84wHkjmoCn6pFIfkGYeATlJgOBhAACgYAHYPU1zMVBTDWru7SNC4G2UyWGWYYL +jLytBVHfQmBa51CmqrSs2kCfGLGA1ynfYENsxcJq9nsXrb4i17H5BHJFkH0g7BUD +peBeLr8gsK3WgfqWwtZsDkltObw9chUD/siK6q/dk/fSIB2Ho0inev7k68Z5ZkNI +4XOwuEssAVhmwA== +-----END PUBLIC KEY----- diff --git a/t/data/ssh/ssh_dsa_1024.pub.rfc4716 b/t/data/ssh/ssh_dsa_1024.pub.rfc4716 new file mode 100644 index 0000000..7a877de --- /dev/null +++ b/t/data/ssh/ssh_dsa_1024.pub.rfc4716 @@ -0,0 +1,12 @@ +---- BEGIN SSH2 PUBLIC KEY ---- +Comment: "1024-bit DSA, converted by miko@HIROKO from OpenSSH" +AAAAB3NzaC1kc3MAAACBAKU8/avmkFeGnSqwYG7dZnQlG+01QNaxu3F5v0NcL/SRUW7Idp +Uq8t14siK0mA6yjphLhOf5t8gugTEVBllP86ANSbFigH7WN3v6ydJWqm60pNhNHN//50cn +NtIsXbxeq3VtsI64pkH1OJqeZDHLmu73k4T0EKOzsylSfF/wtVBJAAAAFQChpubLHViwPB ++jSvUb8e4THS7PBQAAAIAJD1PMCiTCQa1xyD/NCWOajCufTOIzKAhm6l+nlBVPiKI+262X +pYt127Ke4mPL8XJBizoTjSQN08uHMg/8L6W/cdO2aZ+mhkBnS1xAm83DAwqLrDraR1w/4Q +RFxr5Vbyy8qnejrPjTJobBN1BGsv84wHkjmoCn6pFIfkGYeATlJgAAAIAHYPU1zMVBTDWr +u7SNC4G2UyWGWYYLjLytBVHfQmBa51CmqrSs2kCfGLGA1ynfYENsxcJq9nsXrb4i17H5BH +JFkH0g7BUDpeBeLr8gsK3WgfqWwtZsDkltObw9chUD/siK6q/dk/fSIB2Ho0inev7k68Z5 +ZkNI4XOwuEssAVhmwA== +---- END SSH2 PUBLIC KEY ---- diff --git a/t/data/ssh/ssh_ecdsa_256 b/t/data/ssh/ssh_ecdsa_256 new file mode 100644 index 0000000..2a614ea --- /dev/null +++ b/t/data/ssh/ssh_ecdsa_256 @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIGsCiMB7N5OXYUVyHR4APvQupWm4kxvzPl3o67C+JaojoAoGCCqGSM49 +AwEHoUQDQgAEjhAhdfoyDQ1YPo69apv8vzyxOznqGqzmxeQCHq+v02V4VzNqKMJT +Kf/2ovP8J9aDWmqPcqA6IVngHJPfFh8kiw== +-----END EC PRIVATE KEY----- diff --git a/t/data/ssh/ssh_ecdsa_256.pub b/t/data/ssh/ssh_ecdsa_256.pub new file mode 100644 index 0000000..3389687 --- /dev/null +++ b/t/data/ssh/ssh_ecdsa_256.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBI4QIXX6Mg0NWD6OvWqb/L88sTs56hqs5sXkAh6vr9NleFczaijCUyn/9qLz/CfWg1pqj3KgOiFZ4ByT3xYfJIs= comment for esdsa/256 key diff --git a/t/data/ssh/ssh_ecdsa_256.pub.pkcs8 b/t/data/ssh/ssh_ecdsa_256.pub.pkcs8 new file mode 100644 index 0000000..dbbb55d --- /dev/null +++ b/t/data/ssh/ssh_ecdsa_256.pub.pkcs8 @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBSzCCAQMGByqGSM49AgEwgfcCAQEwLAYHKoZIzj0BAQIhAP////8AAAABAAAA +AAAAAAAAAAAA////////////////MFsEIP////8AAAABAAAAAAAAAAAAAAAA//// +///////////8BCBaxjXYqjqT57PrvVV2mIa8ZR0GsMxTsPY7zjw+J9JgSwMVAMSd +NgiG5wSTamZ44ROdJreBn36QBEEEaxfR8uEsQkf4vOblY6RA8ncDfYEt6zOg9KE5 +RdiYwpZP40Li/hp/m47n60p8D54WK84zV2sxXs7LtkBoN79R9QIhAP////8AAAAA +//////////+85vqtpxeehPO5ysL8YyVRAgEBA0IABI4QIXX6Mg0NWD6OvWqb/L88 +sTs56hqs5sXkAh6vr9NleFczaijCUyn/9qLz/CfWg1pqj3KgOiFZ4ByT3xYfJIs= +-----END PUBLIC KEY----- diff --git a/t/data/ssh/ssh_ecdsa_256.pub.rfc4716 b/t/data/ssh/ssh_ecdsa_256.pub.rfc4716 new file mode 100644 index 0000000..8948675 --- /dev/null +++ b/t/data/ssh/ssh_ecdsa_256.pub.rfc4716 @@ -0,0 +1,6 @@ +---- BEGIN SSH2 PUBLIC KEY ---- +Comment: "256-bit ECDSA, converted by miko@HIROKO from OpenSSH" +AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBI4QIXX6Mg0NWD6OvW +qb/L88sTs56hqs5sXkAh6vr9NleFczaijCUyn/9qLz/CfWg1pqj3KgOiFZ4ByT3xYfJIs= + +---- END SSH2 PUBLIC KEY ---- diff --git a/t/data/ssh/ssh_ecdsa_384 b/t/data/ssh/ssh_ecdsa_384 new file mode 100644 index 0000000..651e71f --- /dev/null +++ b/t/data/ssh/ssh_ecdsa_384 @@ -0,0 +1,6 @@ +-----BEGIN EC PRIVATE KEY----- +MIGkAgEBBDD3dcLYMCsBbWxLYEQybGLLM6eUtV3ANwkys6qIxd39ZBIJOXQ6Rh53 +xIuu1X8HFlygBwYFK4EEACKhZANiAASWQhcqgIlNqJCXnzncp4aTBiGpG15JJssG +1M5eI3wHQlGkIPpRQ1azuRkpODZREXfIhak/vv378nbAnNoJE69h+xwi1W4hHsz4 +qlwatHXJMwcpitiwhzPQZCbbjpuIZjQ= +-----END EC PRIVATE KEY----- diff --git a/t/data/ssh/ssh_ecdsa_384.pub b/t/data/ssh/ssh_ecdsa_384.pub new file mode 100644 index 0000000..d144fe2 --- /dev/null +++ b/t/data/ssh/ssh_ecdsa_384.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBJZCFyqAiU2okJefOdynhpMGIakbXkkmywbUzl4jfAdCUaQg+lFDVrO5GSk4NlERd8iFqT++/fvydsCc2gkTr2H7HCLVbiEezPiqXBq0dckzBymK2LCHM9BkJtuOm4hmNA== comment for esdsa/384 key diff --git a/t/data/ssh/ssh_ecdsa_384.pub.pkcs8 b/t/data/ssh/ssh_ecdsa_384.pub.pkcs8 new file mode 100644 index 0000000..cbd4c4c --- /dev/null +++ b/t/data/ssh/ssh_ecdsa_384.pub.pkcs8 @@ -0,0 +1,12 @@ +-----BEGIN PUBLIC KEY----- +MIIBzDCCAWQGByqGSM49AgEwggFXAgEBMDwGByqGSM49AQECMQD///////////// +/////////////////////////////v////8AAAAAAAAAAP////8wewQw//////// +//////////////////////////////////7/////AAAAAAAAAAD////8BDCzMS+n +4j7n5JiOBWvj+C0ZGB2cbv6BQRIDFAiPUBOHWsZWOY2KLtGdKoXI7dPsKu8DFQCj +NZJqoxmieh0AiWpnc6SCes2scwRhBKqHyiK+iwU3jrHHHvMgrXRuHTtii6ebmFn3 +QeCCVCo4VQLyXb9VKWw6VF44cnYKtzYX3kqWJixvXZ6Yv5KS3Cn49B29KJoUfOna +MRO18LjACmCxzh1+gZ16Qx18kOoOXwIxAP////////////////////////////// +/8djTYH0Ny3fWBoNskiwp3rs7BlqzMUpcwIBAQNiAASWQhcqgIlNqJCXnzncp4aT +BiGpG15JJssG1M5eI3wHQlGkIPpRQ1azuRkpODZREXfIhak/vv378nbAnNoJE69h ++xwi1W4hHsz4qlwatHXJMwcpitiwhzPQZCbbjpuIZjQ= +-----END PUBLIC KEY----- diff --git a/t/data/ssh/ssh_ecdsa_384.pub.rfc4716 b/t/data/ssh/ssh_ecdsa_384.pub.rfc4716 new file mode 100644 index 0000000..3140dda --- /dev/null +++ b/t/data/ssh/ssh_ecdsa_384.pub.rfc4716 @@ -0,0 +1,6 @@ +---- BEGIN SSH2 PUBLIC KEY ---- +Comment: "384-bit ECDSA, converted by miko@HIROKO from OpenSSH" +AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBJZCFyqAiU2okJefOd +ynhpMGIakbXkkmywbUzl4jfAdCUaQg+lFDVrO5GSk4NlERd8iFqT++/fvydsCc2gkTr2H7 +HCLVbiEezPiqXBq0dckzBymK2LCHM9BkJtuOm4hmNA== +---- END SSH2 PUBLIC KEY ---- diff --git a/t/data/ssh/ssh_ecdsa_521 b/t/data/ssh/ssh_ecdsa_521 new file mode 100644 index 0000000..bd08ca9 --- /dev/null +++ b/t/data/ssh/ssh_ecdsa_521 @@ -0,0 +1,7 @@ +-----BEGIN EC PRIVATE KEY----- +MIHbAgEBBEHeJefvwF/LJrhUok7XvKgIWcZ2BoXq2ebXKSDC4GyYElLhjLtz4eIx +p0kySKDqvw0RrelJV7dqbiItueACXH5uDqAHBgUrgQQAI6GBiQOBhgAEAWTfmyu1 +4/23ALBgq9T2i8wGLvsN3qUQE+sVowRvQJl1nkwLedKp+UYdFaRJtSmN0907txhA +2kr1hcds1I7mFtTWAVmDKIYXHAlhjPw0CN50FcyDIfglamUrkVCbk/ly9qCUi0L2 +qQqKhReEJzrtgxgG2K9eVR7Q+AirqRsdOptfr7k3 +-----END EC PRIVATE KEY----- diff --git a/t/data/ssh/ssh_ecdsa_521.pub b/t/data/ssh/ssh_ecdsa_521.pub new file mode 100644 index 0000000..c37e28f --- /dev/null +++ b/t/data/ssh/ssh_ecdsa_521.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAFk35srteP9twCwYKvU9ovMBi77Dd6lEBPrFaMEb0CZdZ5MC3nSqflGHRWkSbUpjdPdO7cYQNpK9YXHbNSO5hbU1gFZgyiGFxwJYYz8NAjedBXMgyH4JWplK5FQm5P5cvaglItC9qkKioUXhCc67YMYBtivXlUe0PgIq6kbHTqbX6+5Nw== comment for esdsa/521 key diff --git a/t/data/ssh/ssh_ecdsa_521.pub.pkcs8 b/t/data/ssh/ssh_ecdsa_521.pub.pkcs8 new file mode 100644 index 0000000..36ba67c --- /dev/null +++ b/t/data/ssh/ssh_ecdsa_521.pub.pkcs8 @@ -0,0 +1,15 @@ +-----BEGIN PUBLIC KEY----- +MIICXDCCAc8GByqGSM49AgEwggHCAgEBME0GByqGSM49AQECQgH///////////// +//////////////////////////////////////////////////////////////// +/////////zCBngRCAf////////////////////////////////////////////// +///////////////////////////////////////8BEFRlT65YY4cmh+SmiGgtoVA +7qLacluZsxXzuLSJkY7xCeFWGTlR7H6TexZSwL07sb8HNXPfiD0sNPHvRR/Ua1A/ +AAMVANCeiAApHLhTlsxnFzkyhKqg2mS6BIGFBADGhY4GtwQE6c2ePstmI5W0Qpxk +gTkFP7Uh+CivYGtNPbqhS1537+dZKP4dwSei/6jeM0izwYVqQpv5fn4xwuW9ZgEY +OSlqeJo7wARcil+0LH0b2Zj1RElXm0RoF6+9Fyc+ZiyX7nKZXvQmQMVQuQE/rQdh +NTxwhqJywkCIvpR2n9FmUAJCAf////////////////////////////////////// +////+lGGh4O/L5Zrf8wBSPcJpdA7tcm4iZxHrrtvtx6ROGQJAgEBA4GGAAQBZN+b +K7Xj/bcAsGCr1PaLzAYu+w3epRAT6xWjBG9AmXWeTAt50qn5Rh0VpEm1KY3T3Tu3 +GEDaSvWFx2zUjuYW1NYBWYMohhccCWGM/DQI3nQVzIMh+CVqZSuRUJuT+XL2oJSL +QvapCoqFF4QnOu2DGAbYr15VHtD4CKupGx06m1+vuTc= +-----END PUBLIC KEY----- diff --git a/t/data/ssh/ssh_ecdsa_521.pub.rfc4716 b/t/data/ssh/ssh_ecdsa_521.pub.rfc4716 new file mode 100644 index 0000000..8287ac3 --- /dev/null +++ b/t/data/ssh/ssh_ecdsa_521.pub.rfc4716 @@ -0,0 +1,7 @@ +---- BEGIN SSH2 PUBLIC KEY ---- +Comment: "521-bit ECDSA, converted by miko@HIROKO from OpenSSH" +AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAFk35srteP9twCwYK +vU9ovMBi77Dd6lEBPrFaMEb0CZdZ5MC3nSqflGHRWkSbUpjdPdO7cYQNpK9YXHbNSO5hbU +1gFZgyiGFxwJYYz8NAjedBXMgyH4JWplK5FQm5P5cvaglItC9qkKioUXhCc67YMYBtivXl +Ue0PgIq6kbHTqbX6+5Nw== +---- END SSH2 PUBLIC KEY ---- diff --git a/t/data/ssh/ssh_rsa_1024 b/t/data/ssh/ssh_rsa_1024 new file mode 100644 index 0000000..3843049 --- /dev/null +++ b/t/data/ssh/ssh_rsa_1024 @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICWwIBAAKBgQC458k0igFgcvkrDjUKo0gIgPW0+7QEPck7/DXIpGAkHzHDTQLu +7/IzxBDCL7iQhF2eQwaR/s9SXjs2DV/OT3SXM3QjJO4PS3nHkzfP7Zjqm9LGSicB +gR8x5LPmxoNVA3qOInMP5xhhgbKYYusuBMAlpEgq/T9uCvLIuvRnGhBTDwIDAQAB +AoGAD5UhBLd4pDssOm+pEqtt/6F2k3j+07itQ8vecHlBzOmAFRhhXeeEvs4QJ31E +DZHKHfNCE32o1SUx0j1QTJ+vkIWHcQmLR89cLROlB4cyb+e4ki483ROr6niDNhni +KeaeW9QGMEHIAbf8UbguA2vU4p+9wcemNiFUJcwiQ740zNECQQD2GyyQbzEUbiiw +GjGbH131aVvO2FtYpYWckQhgfrBdwkLECUDRL4ggqGpOgjnF4WFXa2UC/BvLySAE +jfwBhUy3AkEAwFbCKDQWIblrQoCeFHU75fASbCXwEGtMIO/+GT9hcpUAB5iQjwOe +AMQEbs7aezSufGbIyUUL6AJBGoRGRVcEaQJALwEPqOJjyFgl00Sddtgt1OJzk3UF +NVAfzcBxjiSEQNQKdnCh/ZILeNlRvH7o099w/QZY+5H1KR3XzKblm9C+zwJAavKS +6Tn1KHFqg8Lyo1uAn9160OnTb73JyfLIbo+Ahu704kRh9TPEspZMBLU+ZQ2pDAE3 +GjsrYKmIO89bJ4k4KQJADF9+tNJ1xtW1z/wS/u1IGTkMLYApyqUMf2ewf5yvD8yx +H4PEeYEC96+kn6bdEErk6ssOP2O1n9jwIlRyZgcKOg== +-----END RSA PRIVATE KEY----- diff --git a/t/data/ssh/ssh_rsa_1024.pub b/t/data/ssh/ssh_rsa_1024.pub new file mode 100644 index 0000000..1a5f165 --- /dev/null +++ b/t/data/ssh/ssh_rsa_1024.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC458k0igFgcvkrDjUKo0gIgPW0+7QEPck7/DXIpGAkHzHDTQLu7/IzxBDCL7iQhF2eQwaR/s9SXjs2DV/OT3SXM3QjJO4PS3nHkzfP7Zjqm9LGSicBgR8x5LPmxoNVA3qOInMP5xhhgbKYYusuBMAlpEgq/T9uCvLIuvRnGhBTDw== comment for rsa/1024 key diff --git a/t/data/ssh/ssh_rsa_1024.pub.pem b/t/data/ssh/ssh_rsa_1024.pub.pem new file mode 100644 index 0000000..89892c7 --- /dev/null +++ b/t/data/ssh/ssh_rsa_1024.pub.pem @@ -0,0 +1,5 @@ +-----BEGIN RSA PUBLIC KEY----- +MIGJAoGBALjnyTSKAWBy+SsONQqjSAiA9bT7tAQ9yTv8NcikYCQfMcNNAu7v8jPE +EMIvuJCEXZ5DBpH+z1JeOzYNX85PdJczdCMk7g9LeceTN8/tmOqb0sZKJwGBHzHk +s+bGg1UDeo4icw/nGGGBsphi6y4EwCWkSCr9P24K8si69GcaEFMPAgMBAAE= +-----END RSA PUBLIC KEY----- diff --git a/t/data/ssh/ssh_rsa_1024.pub.pkcs8 b/t/data/ssh/ssh_rsa_1024.pub.pkcs8 new file mode 100644 index 0000000..f363b20 --- /dev/null +++ b/t/data/ssh/ssh_rsa_1024.pub.pkcs8 @@ -0,0 +1,6 @@ +-----BEGIN PUBLIC KEY----- +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC458k0igFgcvkrDjUKo0gIgPW0 ++7QEPck7/DXIpGAkHzHDTQLu7/IzxBDCL7iQhF2eQwaR/s9SXjs2DV/OT3SXM3Qj +JO4PS3nHkzfP7Zjqm9LGSicBgR8x5LPmxoNVA3qOInMP5xhhgbKYYusuBMAlpEgq +/T9uCvLIuvRnGhBTDwIDAQAB +-----END PUBLIC KEY----- diff --git a/t/data/ssh/ssh_rsa_1024.pub.rfc4716 b/t/data/ssh/ssh_rsa_1024.pub.rfc4716 new file mode 100644 index 0000000..9ad2906 --- /dev/null +++ b/t/data/ssh/ssh_rsa_1024.pub.rfc4716 @@ -0,0 +1,6 @@ +---- BEGIN SSH2 PUBLIC KEY ---- +Comment: "1024-bit RSA, converted by miko@HIROKO from OpenSSH" +AAAAB3NzaC1yc2EAAAADAQABAAAAgQC458k0igFgcvkrDjUKo0gIgPW0+7QEPck7/DXIpG +AkHzHDTQLu7/IzxBDCL7iQhF2eQwaR/s9SXjs2DV/OT3SXM3QjJO4PS3nHkzfP7Zjqm9LG +SicBgR8x5LPmxoNVA3qOInMP5xhhgbKYYusuBMAlpEgq/T9uCvLIuvRnGhBTDw== +---- END SSH2 PUBLIC KEY ---- diff --git a/t/data/ssh/ssh_rsa_1024_passwd b/t/data/ssh/ssh_rsa_1024_passwd new file mode 100644 index 0000000..ef8b98b --- /dev/null +++ b/t/data/ssh/ssh_rsa_1024_passwd @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,253BAF06E085D30F39C03966F03680E2 + +FmIMXYIseEF2wUqnYcpmDzYWM0jK8QdqJwVpdmTJEKcdlrHAq1Fs8PYzffrutZA7 +JTbwDinajRTK6US2ZQamJhq2iljbv+iR9bqbqIp2Zs8u2PI1KuS/9HJOl+arO3Su +Dt1LhazOs4UWqXa37nTXUizggUqkOU0p0Fl1xydu17NJi18MRLEKzkd922b7Z2GE +WF5VB7w0oXB0MfULnW89nyLXsxni/jGaa/DGm44ERLy9HsdZ1q59HsNuAD3rnVV8 +jabRcCy14urnEiwXw27JSDAnZRIRDmigeYL+AlEE+A900G9S4yXWrcTcf04MvUT3 +cP1pbAGvdx/R2XlXSpbE5vwE0ctHb6Q2K6r47lL+RoU9+qp2CNW/moPlcHMCUFM4 +A01hoWjHWbfPOD+2Ay/lbt43zNviRlIGk8zLVudxn6Z2wfNk/k6+FgeXBzmm9ccq +ZodR8XVnef7zCIyIqLX+UgcTV6DjyM6hRMCscKGHsBeafof8ItRkklDiUzZ5bUef +bIzta7PGbEAgJr/tKcObODZXjkdOkoMlP5xH8X8Datt8SoFU0Se727j+wUPRN0te +NnAe5YGb2GpvzGN2Be1t++GQOc3xUw4c9CDnh+FSxeP45dHA13zBflPy44arDOKz +EdvgefMsPxnjf/qsldiCv0kmke8TJ05BF3GCaxbPSMCfbetKldeBOKxxpQW1PNYg +Zb+t/eZotzPYrHClphUi8Wz4t5P4Gsf2RXeYeOaTkj8S2kS5MWIIVYSsfieXFYsD +mI2FXpQCH0tYDgK1dW36/HGPUqaIBs3gffS6XVMAlwk= +-----END RSA PRIVATE KEY----- diff --git a/t/data/ssh/ssh_rsa_1536 b/t/data/ssh/ssh_rsa_1536 new file mode 100644 index 0000000..7b2451a --- /dev/null +++ b/t/data/ssh/ssh_rsa_1536 @@ -0,0 +1,21 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIDewIBAAKBwQCkYHef/kFhdtEwG4YZfanYY92cmDX9gqw7OE2dxMyQyj5Eyn/z +taIIERJGv2BG7TlEi8Gd83wFvSrqk4diHycQm2FbLtp258buy/PYCY3cvxYL1imU +xt6aPeLphzxQpt2dSwCom6M5Dq/sxB4YV+lvVpWZEuIFzsfGtqiLO7U4x80lXC14 +30MtN5Z6nYTOVtktYkFJCmMSThYice6L4RHdTNejQZlmKGfLEKeR3wTwBIfLO9XF +kSlHz2Uk4q/Clr0CAwEAAQKBwH3dN/wUbe+5UThq+uWt6U2+OkTb8Atr8YFu/U+f +D5yWn9OA0zTDkYxntfziMVBd+QnZkanmdMLYNHJmALZLcFgxAf0WBUYi95qGJPL5 +bdznnHP3yuMW3ABy/rseSDrhaXoOpxFbi2dA3OymRCgHXJkW3QlJyqfiGLlFdZtO +TCdgQVrk89ceKD2VZA07vgsoy1O7t0W6Gjhgnyz77qXI0UkzFQTkZn4cwKKWi8en +g1+AxSEozYMxz6RH6m9j/NKtqQJhAM297KcPFPNcbLZYt66ARzfoUnhHhor9F8/a +3/5nib3EGtQACJwzqFNedRiOXPAe3wzCmNH7Dae9eZMTm+zv0gV04CPbce3KULSW +fVa2Z2vCvmT9HT3d4tWkhJtTvps4RwJhAMyHxvGb6tlUlDcwWht3ZaZo9MJXncox +ikc0g2GJ3Xs3ZqMnmw/ROeJhL/rrZf0ZM+dPEhu8veQgsD5NElLp05H+Mh+Y3ZQV +FbvzjoYxsMt7gEad0Xng/WxyKSzP7EX+2wJgGn/A0E+P+jxIQEAzAEXDZn8EyDsm +KBarD3l4ajL5ubhdYDrU4RGCN6Kt4EjNzZucTO9vcXQtcRJlaz0WUzEcUtmX2OZ1 +yRPKy0eqwxVhQq7liOpU7tf6VFwJPFxP63wXAmBMNfunY5WqzZ08w0OQIHk7/LfX +ApbFFJiV17dszNY+Z3JTMRrSVf/fnp8mPDiQiqeQdSImO7n2G0gQrt85De/L4pAC +vg8ycnjaw/JDhph9+dLefUfkxjUoB5HYJNHBcykCYEZkrc//Bi+o7NQdMXuQDNJY +My9BOxZddy4VrB2W+KqeEXYrXBBZp8i0iHDWMl7wI+UhhrW8KYGWP/8PAvQRYbNr +xig90FpRw5AqTjIKM0bb0BI+zFhJu5fcHY9I6UjISg== +-----END RSA PRIVATE KEY----- diff --git a/t/data/ssh/ssh_rsa_1536.pub b/t/data/ssh/ssh_rsa_1536.pub new file mode 100644 index 0000000..3dc55cd --- /dev/null +++ b/t/data/ssh/ssh_rsa_1536.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAwQCkYHef/kFhdtEwG4YZfanYY92cmDX9gqw7OE2dxMyQyj5Eyn/ztaIIERJGv2BG7TlEi8Gd83wFvSrqk4diHycQm2FbLtp258buy/PYCY3cvxYL1imUxt6aPeLphzxQpt2dSwCom6M5Dq/sxB4YV+lvVpWZEuIFzsfGtqiLO7U4x80lXC1430MtN5Z6nYTOVtktYkFJCmMSThYice6L4RHdTNejQZlmKGfLEKeR3wTwBIfLO9XFkSlHz2Uk4q/Clr0= comment for rsa/1536 key diff --git a/t/data/ssh/ssh_rsa_1536.pub.pem b/t/data/ssh/ssh_rsa_1536.pub.pem new file mode 100644 index 0000000..b6399f2 --- /dev/null +++ b/t/data/ssh/ssh_rsa_1536.pub.pem @@ -0,0 +1,7 @@ +-----BEGIN RSA PUBLIC KEY----- +MIHJAoHBAKRgd5/+QWF20TAbhhl9qdhj3ZyYNf2CrDs4TZ3EzJDKPkTKf/O1oggR +Eka/YEbtOUSLwZ3zfAW9KuqTh2IfJxCbYVsu2nbnxu7L89gJjdy/FgvWKZTG3po9 +4umHPFCm3Z1LAKibozkOr+zEHhhX6W9WlZkS4gXOx8a2qIs7tTjHzSVcLXjfQy03 +lnqdhM5W2S1iQUkKYxJOFiJx7ovhEd1M16NBmWYoZ8sQp5HfBPAEh8s71cWRKUfP +ZSTir8KWvQIDAQAB +-----END RSA PUBLIC KEY----- diff --git a/t/data/ssh/ssh_rsa_1536.pub.pkcs8 b/t/data/ssh/ssh_rsa_1536.pub.pkcs8 new file mode 100644 index 0000000..05df4c6 --- /dev/null +++ b/t/data/ssh/ssh_rsa_1536.pub.pkcs8 @@ -0,0 +1,7 @@ +-----BEGIN PUBLIC KEY----- +MIHfMA0GCSqGSIb3DQEBAQUAA4HNADCByQKBwQCkYHef/kFhdtEwG4YZfanYY92c +mDX9gqw7OE2dxMyQyj5Eyn/ztaIIERJGv2BG7TlEi8Gd83wFvSrqk4diHycQm2Fb +Ltp258buy/PYCY3cvxYL1imUxt6aPeLphzxQpt2dSwCom6M5Dq/sxB4YV+lvVpWZ +EuIFzsfGtqiLO7U4x80lXC1430MtN5Z6nYTOVtktYkFJCmMSThYice6L4RHdTNej +QZlmKGfLEKeR3wTwBIfLO9XFkSlHz2Uk4q/Clr0CAwEAAQ== +-----END PUBLIC KEY----- diff --git a/t/data/ssh/ssh_rsa_1536.pub.rfc4716 b/t/data/ssh/ssh_rsa_1536.pub.rfc4716 new file mode 100644 index 0000000..e3480e0 --- /dev/null +++ b/t/data/ssh/ssh_rsa_1536.pub.rfc4716 @@ -0,0 +1,8 @@ +---- BEGIN SSH2 PUBLIC KEY ---- +Comment: "1536-bit RSA, converted by miko@HIROKO from OpenSSH" +AAAAB3NzaC1yc2EAAAADAQABAAAAwQCkYHef/kFhdtEwG4YZfanYY92cmDX9gqw7OE2dxM +yQyj5Eyn/ztaIIERJGv2BG7TlEi8Gd83wFvSrqk4diHycQm2FbLtp258buy/PYCY3cvxYL +1imUxt6aPeLphzxQpt2dSwCom6M5Dq/sxB4YV+lvVpWZEuIFzsfGtqiLO7U4x80lXC1430 +MtN5Z6nYTOVtktYkFJCmMSThYice6L4RHdTNejQZlmKGfLEKeR3wTwBIfLO9XFkSlHz2Uk +4q/Clr0= +---- END SSH2 PUBLIC KEY ---- diff --git a/t/data/ssh/ssh_rsa_1536_passwd b/t/data/ssh/ssh_rsa_1536_passwd new file mode 100644 index 0000000..342a45b --- /dev/null +++ b/t/data/ssh/ssh_rsa_1536_passwd @@ -0,0 +1,24 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,6724457B0E61D83CACA2F37336709F43 + +cKmWiYITd+9Q2goeFBMEMptmeZfjwp7GA7uH1Pvo3Op2VDDd14q8vg11MLtSE1oV +nAWb0qzraJcXfnANd3+XsmUVh9IMDE4r3dZNgSoIVfGkIUlRNJnXfaFU4OojaWyc +RPOcX9wmulcqE4gBKXBnWYjlsoSo9cdJnn79LejxNvxRoPE5XJ+ANmVfeGtZcvvc +z5Avsm3L7FXFnD8I5cnYugdnmXU/JJAmI4jqd2EbYtOPDDEwP/4oN5nGMCnZPSGV +mAnoBxKH4bWyk2TUfMDHeg8Ma5STuDYmWc5u1/H7Ym5NXxYH7cie6EdhQWw0BMc4 +nZ+R3/5k+Taj9/I5IuB8OcztxnnSYVESHxrBqRTs8qPK7060OojLQ351WJos5wHS +XHWxh7pGOO5It/hYrIhPVrCY0jcYIhHZmwBx6b/frHvYf2t/LLUw/AVNgUwapL2/ +Vv2Et0zZIQHOGZ2VuVDvGWPxjMH8p9+Ql482CrGQ2M2U2DHFcx2uQh1wsmARRhkP +5juYYSYAOGqAkZSR0hmjt1nwnP22WeoWLWUhgNHFrf8qbaQ66dHLnWDSsHlg29du +2Khd4qi8ivpBekFo3PV08Q7rmuhp1wFjrnu+mXhJWh4zp7MQ7XM7UJ5rriAxOBvt +RZuLnPDMTsIMPp53G12FH4LpoSUdNY6YlZC0yXrGdg4af4ukNhLxPH5xaeEsPqqW +nwOI7Wcmf7sXgH/wLlOeSBQ6eHAIhconjKnxhIxR4htnJNtA3D1MBZEaeI5xbvVL +ePSzlvffxjaL0rm76kevWnbKMdwnGGgIvgbT/gYyDmqOD525t4YaiyfC21CUVyZV +FM87TBFnxJlcpgY7ewQTJMrufyPanpqm1XmvnpQrYV7pnPexJCx0g40ZUDaQYtcE +gOwAWqcD2vXuuFK0/H5/M/LXChOcj9JwnmeZRVB6Wc+TPcniusuUoJiYcoTEUThT +8j1odI+zDu2umliDAMMK8ZEvMBiFi4RtL3qijQt2rlZcfT5/B19d3sIL6Oe6/3dS +/lq9/wtCH8Gm2yI2ETKQo90DR90ZD2SxFY80VQhFJgumwTT0FpZJRzOolN9C3opZ +h04n2a7KqplKcqXV/nee+2hzzTXMwCdsDL2qE8tFtjTDRg3leYcZPXqIn4xa2qtq +Yt1D5JuPhVYZI38ZIpfiJbejCOhjofqz0Upzr6/Qwc8= +-----END RSA PRIVATE KEY----- diff --git a/t/data/ssh/ssh_rsa_2048 b/t/data/ssh/ssh_rsa_2048 new file mode 100644 index 0000000..ac227d7 --- /dev/null +++ b/t/data/ssh/ssh_rsa_2048 @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEA3cYzdPtsXO6Xa3gamHP5g0QvDrlq0u8K3uXxFAacpaK0I24b +VFVFPjsf+kUmW23jYNxL3Fk0+zUGO9cOyxkoIjSvW4FNStedes6b2NBdiBoMfcWb +7yCVRC0l0ERYCAUhXrGplWbyUXefrM4KtY5jE4m6PX8jyaGSz8rOUhcTxw3silM/ +Jc2B1ZrjoczoUo0jR0BlT9B6HvDe3UGhVONAPCUrFIeeu74I15bbNdyhKxmgXstu +OKHuCfsZcM1h7IoAI9Q6AhjGg3UkPFnxPwRFCauZjRKfhsUHuIRzMG24NkSWWfJB +USjoglInEJFQhQN8lmqPuaHXIMiNN7Kn564JGwIDAQABAoIBAEN53oYlSV8tKN0F ++fGQt8X8pOSx/ZKYMJKJG8SgDmFHE9AD3ETYfOzmSGB5UaZX1OrPnDU63yffhjoG +wPWCffeKWCBbQw0WdU+8NSbOnuaeJlbOHRewrjnEEtE/OhmWlgSdwZ83Z1rqLqcB +ObjrzbFQIl47pMPgaS7X4daQNvBE9yvygiR/wkffBuTXAaGK2/eJAqxdN0pYJvtU ++Hg/IFoTBPOe3FRDRFiruiZPcM2ZXpNKTeXPCPd3uV2PyQ0ehYXa5N5QzfZJzrUO +vJWVgoUM+TdpL7L2t/UbdcTOBfEhWhygsXvJzAHRQopO7NEkYWSDuefcA/YrmOGG +InN58iECgYEA99pG2fPTX9Znd3EoxWa4Ce+p7QBJSPKr1kKhf4Z9zCdch+UT31w4 +ZD/s3cXK6XOlj8ygDVzxVm4IDPSzPGDeyeeYg7hbrJivBnxUKoHBSxKcHo7Cv6Hh +pzrhV7zYdVQhFbvqMf+j7vKztl81aIkU2TVd1u8vOfsblG0iXOeUsYcCgYEA5RB4 +Q2rAEShRlVOJmyJQEpWCGvuQzLrjFZprs70lgowwpFUl/4aOaqp1aye+BZt9JvPv +sI7nTM43VscQdWO4h62Q+efjQPUzpELNhcW1SgtnNyZWW0vFTBr+U5P9eYjyHApn +ZbCVxS9QU3pXCe2j79V0ejIOOA3nhxQ3z2v9IM0CgYBMdFCWutfhIEoaVhW1jtIG +fp90NDpm/jRzi2o15E65wwqQAOH4bIIYqn9uiazmBn5ztTNJ6/mmJ5rkJDeF0Hvo +3D/3oc7lltOmtINh+VSey8bMxkzcwBrTcx4/6kj7KFBsW+MKOUlgVA2LnCLldCOy +PPwNaQqwX/1J88A92FHN0QKBgDYocbbG24hy9u8OZD+ImlP6g1tr1S2ClkQ6UXKa +qu61xJ5l/2jt4Gg5yy89o0DiJXH7RNWCxA81xoG+6RZIMI3rrJZZjDKEhuQ0YzFY +sGdEUPAKIWrOfGRlEXKjT8/XYB7fGtlBKfgIGr7R8xhG1nbTCgoGIbSBHRej4Roq +lxuVAoGAJB9h+oys2G3mw2WsD2KuwCROWsRXQLmoZ0Jz1rjMxe4JoGI50/BCKnNQ +EfNvS+5D6qjo8QfW7cmlSWk9ZLhT4xOF2i2YCYIARtviN0boJs00hVXmTydH0nfM +h2MGPr8DcdhWAjuY4WMo8/av1rVIvFuWaGdKz+1rk1B3OPXKGoA= +-----END RSA PRIVATE KEY----- diff --git a/t/data/ssh/ssh_rsa_2048.pub b/t/data/ssh/ssh_rsa_2048.pub new file mode 100644 index 0000000..5480350 --- /dev/null +++ b/t/data/ssh/ssh_rsa_2048.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDdxjN0+2xc7pdreBqYc/mDRC8OuWrS7wre5fEUBpylorQjbhtUVUU+Ox/6RSZbbeNg3EvcWTT7NQY71w7LGSgiNK9bgU1K1516zpvY0F2IGgx9xZvvIJVELSXQRFgIBSFesamVZvJRd5+szgq1jmMTibo9fyPJoZLPys5SFxPHDeyKUz8lzYHVmuOhzOhSjSNHQGVP0Hoe8N7dQaFU40A8JSsUh567vgjXlts13KErGaBey244oe4J+xlwzWHsigAj1DoCGMaDdSQ8WfE/BEUJq5mNEp+GxQe4hHMwbbg2RJZZ8kFRKOiCUicQkVCFA3yWao+5odcgyI03sqfnrgkb comment for rsa/2048 key diff --git a/t/data/ssh/ssh_rsa_2048.pub.pem b/t/data/ssh/ssh_rsa_2048.pub.pem new file mode 100644 index 0000000..dc193fa --- /dev/null +++ b/t/data/ssh/ssh_rsa_2048.pub.pem @@ -0,0 +1,8 @@ +-----BEGIN RSA PUBLIC KEY----- +MIIBCgKCAQEA3cYzdPtsXO6Xa3gamHP5g0QvDrlq0u8K3uXxFAacpaK0I24bVFVF +Pjsf+kUmW23jYNxL3Fk0+zUGO9cOyxkoIjSvW4FNStedes6b2NBdiBoMfcWb7yCV +RC0l0ERYCAUhXrGplWbyUXefrM4KtY5jE4m6PX8jyaGSz8rOUhcTxw3silM/Jc2B +1ZrjoczoUo0jR0BlT9B6HvDe3UGhVONAPCUrFIeeu74I15bbNdyhKxmgXstuOKHu +CfsZcM1h7IoAI9Q6AhjGg3UkPFnxPwRFCauZjRKfhsUHuIRzMG24NkSWWfJBUSjo +glInEJFQhQN8lmqPuaHXIMiNN7Kn564JGwIDAQAB +-----END RSA PUBLIC KEY----- diff --git a/t/data/ssh/ssh_rsa_2048.pub.pkcs8 b/t/data/ssh/ssh_rsa_2048.pub.pkcs8 new file mode 100644 index 0000000..9c1695b --- /dev/null +++ b/t/data/ssh/ssh_rsa_2048.pub.pkcs8 @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3cYzdPtsXO6Xa3gamHP5 +g0QvDrlq0u8K3uXxFAacpaK0I24bVFVFPjsf+kUmW23jYNxL3Fk0+zUGO9cOyxko +IjSvW4FNStedes6b2NBdiBoMfcWb7yCVRC0l0ERYCAUhXrGplWbyUXefrM4KtY5j +E4m6PX8jyaGSz8rOUhcTxw3silM/Jc2B1ZrjoczoUo0jR0BlT9B6HvDe3UGhVONA +PCUrFIeeu74I15bbNdyhKxmgXstuOKHuCfsZcM1h7IoAI9Q6AhjGg3UkPFnxPwRF +CauZjRKfhsUHuIRzMG24NkSWWfJBUSjoglInEJFQhQN8lmqPuaHXIMiNN7Kn564J +GwIDAQAB +-----END PUBLIC KEY----- diff --git a/t/data/ssh/ssh_rsa_2048.pub.rfc4716 b/t/data/ssh/ssh_rsa_2048.pub.rfc4716 new file mode 100644 index 0000000..8f7f239 --- /dev/null +++ b/t/data/ssh/ssh_rsa_2048.pub.rfc4716 @@ -0,0 +1,9 @@ +---- BEGIN SSH2 PUBLIC KEY ---- +Comment: "2048-bit RSA, converted by miko@HIROKO from OpenSSH" +AAAAB3NzaC1yc2EAAAADAQABAAABAQDdxjN0+2xc7pdreBqYc/mDRC8OuWrS7wre5fEUBp +ylorQjbhtUVUU+Ox/6RSZbbeNg3EvcWTT7NQY71w7LGSgiNK9bgU1K1516zpvY0F2IGgx9 +xZvvIJVELSXQRFgIBSFesamVZvJRd5+szgq1jmMTibo9fyPJoZLPys5SFxPHDeyKUz8lzY +HVmuOhzOhSjSNHQGVP0Hoe8N7dQaFU40A8JSsUh567vgjXlts13KErGaBey244oe4J+xlw +zWHsigAj1DoCGMaDdSQ8WfE/BEUJq5mNEp+GxQe4hHMwbbg2RJZZ8kFRKOiCUicQkVCFA3 +yWao+5odcgyI03sqfnrgkb +---- END SSH2 PUBLIC KEY ---- diff --git a/t/data/ssh/ssh_rsa_2048_passwd b/t/data/ssh/ssh_rsa_2048_passwd new file mode 100644 index 0000000..1b8ce30 --- /dev/null +++ b/t/data/ssh/ssh_rsa_2048_passwd @@ -0,0 +1,30 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,E752B3536B1560DE39C17E0FB930F635 + +TIgSfwVt7W5mvcono7TZCa9hXimqJv1amcCrD0ePqidHW7x0tLyRq2Lj8vMapv9e +j20NNxjtmtgfcfHBYBQurVSOve4lI2TZtkA7LsGPvilJBhSN7vyZ/NWmwaHPp/up +kfcXe+8R80QI8aGHtennZEnItUDmwwfCY79kctlQfhpWcFox+k6Nodf5im5BABYs +/5Bah4eesBvIiZI1ilkOMJ3kGJiXK6mY8Kvw0j7Kr0PHD8NBpeaibdLZtgvq+tye +VtAYm6ce/BpG2AD0WWaG3b766XXlQEzybwDTjzqoMCtuIaDcKTmywq7Tysl5/Wvh +mj76pRZcsae+7UKr2jZuYXVJZMgJoittg00tSQsV8G39HGtzeDAyEuDP3hffxw0a +aShaMBK5FilpvOUxX8ouSWG+GZ40uWwn+DbumiLXzfbiK3Y5b3s2JLxkUoyxqLO/ +xDK5VEiFy3rII176PWjY4iYKeK5RbDihy4AWLFkLEG6IBbPxD8dHWiCtkrYVtX1m +UAUgotuVa6+RAi/lbhyZzONKrVgks5RsBysNuzwou1jx3v7hzAy+sdhSexzqJFWB +/KU4e/LllX/a2LPRJ3vXpV+S3r5xuR9YmYpwkfeGBdizO8OOthOFrwalDy0ay8h6 +s4bAzw9vgXRXQWG0oncVADEuOeAa/enPTvT3oXSeCdWeAP9AIuk1F96PRPoBRaVJ +UHNB5Dd0LOF2VJ1AI+qhUN09FJpvJ0xeVsiaGr5xgWdAjtLOoEnS6UkYV9L7fvbN +Ix0I4wFGT7msuAMlYe19zakVrZ37YlkQLIV6JUm/xIFjSOsH7SCPmmONh3aiN5Qw +jCNDg7QghkumkIoYkJp42ulESuIx5JMdfqWnxQgUB5iYy2YqXs1Z6xLIvglhPDMT +Xs8yLutppjPqFLO2FKl508u5Am6xPJCP366bZMDpNtlvHZANtwMwKpL1h6PyvqQx +72WktaPVCmrVMIna7dfLRw/p+QwSD0oDuOV6qGVKEgh5Ml+eVnUxCQZxD+ZIdzzp +MkP6GKkM/XEwy8GX/0/Cyn+BerfSSUfryh0rskU9RbtpjnywdaBtyJ6DADHEB3GG +oVx1E/WAj+ab/n8i85ulbMvunstPRoYG8CJt5pQBKCU5qrcaUI3i56HiBCy9Kw3/ +0tSCn0BE73XZvVZhqtkDV1EYaEKOYSuWmAYx9NHcLSKviiX1GV6fLnPIf60Owrl0 +gUewApNsH3WNlpcr6B32xM3R2wh7eW7ClKxrFJZuH3VEt8tuMbgR5kDG1UWB2Cgg +x58yOA/kq3hr4Xfv7hDcGRIQjm+9UdtQVAMBQQPd0nfTQofQBQj/j8xYd1S/t2bI +cr5gAw/HUF7KgFwJ6YhahhylfKIMDX8/fVp384IyK6aaVG1LVDUuzGC27RFc6GYr +MB2rbvok3YDaSaF23oM87hxz3YVGGF+GOhSEWT3lllv1AvH6OruEQkuZOPgJCvXY +IJDXEZO2mA9rtSOwZyGcDf8Pm6LRN8eHmlOtn6GeQw373pLJWmWoRsNVM/rNxDZc +uJGFgG+PVD5Bp13elb/S/uqhDG3PQK7z9AJMVE9sdBulADqxbdlj+LUqDKHfkETh +-----END RSA PRIVATE KEY----- diff --git a/t/data/ssh/ssh_rsa_4096 b/t/data/ssh/ssh_rsa_4096 new file mode 100644 index 0000000..0ec9e29 --- /dev/null +++ b/t/data/ssh/ssh_rsa_4096 @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIJKAIBAAKCAgEAo6FKkV/bSemFY/hO2NA/aMtkglLaC5jaqLzDnP21gfhYPBoB +EDaffV7x+qfv1wyGODJvdUPaNa8nVpwJxyrP/SzskqTlDW235Q7BbLTfGa6qsrj4 +iKGamsEL2HsZNP9GcjXJAPX1gCmQyaJtTeQ7rQSueQ4KuNMh5KQAep5anVi2PCGm +9FeCyk7TQRsna3T0fANdCOeJA5BccfNjTmTSfYau0GGCQ7C+S3v3wfj6iJLD+aqN +pX2jyXvcbce5uPhSCUUEDi6xXn/ytLTtWb9FOXVTR5llockzeLZ8KBF+KWe2JBx3 +pnARYl+Mbe9P86bxuXLiDzMCSAOT+9sOwOYnykqEy65EBsu8lv3s8sa5uNjYOYzU +G/o7IrkIXJ1PyCoqe8TtSts8Uj4XMA0USDxhsJAnzK6+TxuBFZ/TyQnlv8nUKTpu +MrCWsvAGcckKIT9Y0WrLrPqlBqLzhw+q44g64NJQ6SWOwn+hLT1P2dBhcn+VmOPe +dpUYmsCFy4tFTgHsRv7P5/niIsE4hTrZ5lEY0Yyyd05ZFcvwvSMOkwWibBfQ1vzD +eAXmDEgFaHVY6lici0HO7pW8poLjLjZ5IQ40NV0dElzcPX80/ZRPjQvhDsMcrDrv +svRK1epQPJhMcLZrv2vcx1J8rp11M/GVRYeplIT9E3O1/xf0Nl008c8wuI8CAwEA +AQKCAgBwIwwIPqn4qEma7kOSwHyEI8dYrNDzW6iWNO7VuuVWEczeO2/5HYYFlDi+ +77IlLVcaUi4iLgLwAX4zE7J7xLJPLidehBTZNBTvrEIQbo/qeNJQswTYFe/vGFc2 +332x3TP49zUuLGE3mMS5+k9wLvZapzeujFn6ue6jU2Vkovs0k+Qnp2RUVVizrnuG +RcapFLir+F4cyRgT0i4YhZTL17qM/ez1r61nGEwBTQ7I5wlC6VnW0vRJsqW5YeH5 +dgOoaL1Hzv1tfsBdI9A/2TJD7BnTu7z793s3+bwFgQHrL7nHRGUFsGCrNmgjg5mo +iXXAY+uKjNmxUuLAWXtkAYbF2bTwC57/kaNDv7fjlHmzxwgyLq/SguNU3c72Y7rv +oz4jmoi9794NfcUoj8RTyBfvIB6rtRVX3sTOhz8P3d4Lh8xepitE5ysU4TdCMWvs +A0IX/r1yilmj+CPESM3ziSwUd31QHkBgDYFxRfkDp0ildTUfDYf6tLs7k55ejsCF +ddn8PvbzMvhRDLmStjdUBCfGDuOAhjmighuwkS26w/AQ9ndZ6iAAVgDEk1ZgMQhf +V1daWNN5ixh60QVZgXP/c5IpyikPKUMt2qmemmlJDuyuN5rAHnFPnpl/NGvlLaQt +FnFxXn24NsMus3qHSfL8TJkXEV8ZXiBXR7qsaMZ/m5xB/bz9kQKCAQEA02z7kwi4 +/GshGZcSZ5IUk2OnxBnwmImpYocG3kELZAwoLGqYerVw8JFvGmPkGwlXbrHg34tm +OCmPxpcd6A8lBhuTmDO8OW+S1rWqLuYhfV/1PYOWj1YetnKAoRmEqa7PnPZPf2uk +eYq0gDzCOQ4tBwKBqpwa0rrGxahIGwCWh84yKgon/pZ6tjm4hr0GaZF+yK13Cy74 +IiAOVXYoC3qsVvju5Qql6zk4NsX1pj8EkLmQc44T53RBowskBlX/e6/H42zSxbFn +rnZq+cEh9bTYcHZPhyMggzetx18dlZil5B1gKhvDpKo5XYiFGuc8S8/4IXxdsKNw +S2BiKNCB6OsrmQKCAQEAxiCxOfGXLGfNbdakQxDboSZWS7kyOIBBDwspj0Jobyif +o/S9D0hJmaU4QwT7c3zXCBzjicUmjKMgM9feeN7rDOWdBiRkdqOZAGC204Vf9jKm +XAf9gwbs0o/35Xy7t7QZlA+PJQxr56virlsPiENIGcMZhbrC9Pnvpv2dNh8BbBbD +Amif7NNbe6Ry9KvQ0wo5nRI3Bdl2ybFswpnpbTY69ytxHNzYtyqYByT27cYsY+fS +kRfa85e9TcxIC8BPTQToTnm72uh1UNbPy/hmz1/TkiILSQzxNXbxEQ21LUQmM+wa +BeQpvrK+uu7F/naFV0nX9QdfrQaHvACtiqNvTRBeZwKCAQAr5m02UpFWmEf/MEc6 +CjMLh53GMjyq76qkMrVSYN8knwGYd2nB0PrqeMhBCozKsF3fNkAjKqbG8ppP+gDT +tpFRe1hiOhvTMT+kJYR4yIAbsFkTtMcGbDNkXtImoU3SjeG+DcbkBk3Yjtx75CHQ +BwmCcxrJejB3oSC02gRe1vhqqn3wDLvROR2xyLpv/7/dG8DfmmUlhVMwgsd3J1mZ +SJeQV5ADLvrUpMTvWptvMZaZFm7QD6hCXvliCWYpiqHJ5O30YxxAwF1u9FeyFFAg +3LQ0ZdyNitWtaVpEE5PpBBEuFItrMuikwFO5ACfjNjBm7X/wNAqgKs+eVx0KrIDN +BEfBAoIBADsszIIX7CTxI+QodYsqX86z2pZnS96gP840cUc+eF6q7XNUx5rm5kSj +mjg6JrgJk1fy+OrPHYJnvlh9ow7K1b1WXx3UhMUCe9InELQAY/bujc1y/X7C9Ly3 +Dz1VkeN+QR19wC06loftSJj2zZ7PKZu4L8lHTK9Kbw+bM/dUL2KPMdNoWEutnOdC +6Kq3HnnJ1gdZx2FR4C7BdVByE8vwpI/qQ7BxLbEXYazQl4fQ5rU4KiX30AdtTLcN +yn7oA0dnrdKyfS8WuuNYJVwwZtSNNG2zCVfaK7jiO4HybCiG8DoVzHfx+53fWSQP +6Mbls1Gs1nlyqFrPVn8KXMrJoZaMywUCggEBAMJ+udqN5hEiDHE5wMgrI9Dwdn9I +zHFfN9/gn/ffRvsIN9MvYxcK0UhPPQ/PH+GXgPYJDEYrRC9+HJmkIs+x/xzWysft +0+PyFmlA5BEg8tXsPqBpDlKLpd8PWomwfN497ZLdv3geEHzcdZOc+7isX60Q9h0R +J0FH9pCwAXTuhihdbRKnRoFIVySSxYbK644k6TW53LO/jxG6rpRHIzj2n2TMs9kR +wp5A3ON2DM7n9gS7fI8k4+X9YGlTBfsO0VJ2Y4ZSFZbV3cAK6RIU8cpAs/2dwyet +1TjK3J88LTcwrvu4Q5vBRjjyg4t/wRzq+qSCfC1BKvwYo/LTdXL4v0T5oXA= +-----END RSA PRIVATE KEY----- diff --git a/t/data/ssh/ssh_rsa_4096.pub b/t/data/ssh/ssh_rsa_4096.pub new file mode 100644 index 0000000..a9c0029 --- /dev/null +++ b/t/data/ssh/ssh_rsa_4096.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCjoUqRX9tJ6YVj+E7Y0D9oy2SCUtoLmNqovMOc/bWB+Fg8GgEQNp99XvH6p+/XDIY4Mm91Q9o1rydWnAnHKs/9LOySpOUNbbflDsFstN8ZrqqyuPiIoZqawQvYexk0/0ZyNckA9fWAKZDJom1N5DutBK55Dgq40yHkpAB6nlqdWLY8Iab0V4LKTtNBGydrdPR8A10I54kDkFxx82NOZNJ9hq7QYYJDsL5Le/fB+PqIksP5qo2lfaPJe9xtx7m4+FIJRQQOLrFef/K0tO1Zv0U5dVNHmWWhyTN4tnwoEX4pZ7YkHHemcBFiX4xt70/zpvG5cuIPMwJIA5P72w7A5ifKSoTLrkQGy7yW/ezyxrm42Ng5jNQb+jsiuQhcnU/IKip7xO1K2zxSPhcwDRRIPGGwkCfMrr5PG4EVn9PJCeW/ydQpOm4ysJay8AZxyQohP1jRasus+qUGovOHD6rjiDrg0lDpJY7Cf6EtPU/Z0GFyf5WY4952lRiawIXLi0VOAexG/s/n+eIiwTiFOtnmURjRjLJ3TlkVy/C9Iw6TBaJsF9DW/MN4BeYMSAVodVjqWJyLQc7ulbymguMuNnkhDjQ1XR0SXNw9fzT9lE+NC+EOwxysOu+y9ErV6lA8mExwtmu/a9zHUnyunXUz8ZVFh6mUhP0Tc7X/F/Q2XTTxzzC4jw== comment for rsa/4096 key diff --git a/t/data/ssh/ssh_rsa_4096.pub.pem b/t/data/ssh/ssh_rsa_4096.pub.pem new file mode 100644 index 0000000..3d189b1 --- /dev/null +++ b/t/data/ssh/ssh_rsa_4096.pub.pem @@ -0,0 +1,13 @@ +-----BEGIN RSA PUBLIC KEY----- +MIICCgKCAgEAo6FKkV/bSemFY/hO2NA/aMtkglLaC5jaqLzDnP21gfhYPBoBEDaf +fV7x+qfv1wyGODJvdUPaNa8nVpwJxyrP/SzskqTlDW235Q7BbLTfGa6qsrj4iKGa +msEL2HsZNP9GcjXJAPX1gCmQyaJtTeQ7rQSueQ4KuNMh5KQAep5anVi2PCGm9FeC +yk7TQRsna3T0fANdCOeJA5BccfNjTmTSfYau0GGCQ7C+S3v3wfj6iJLD+aqNpX2j +yXvcbce5uPhSCUUEDi6xXn/ytLTtWb9FOXVTR5llockzeLZ8KBF+KWe2JBx3pnAR +Yl+Mbe9P86bxuXLiDzMCSAOT+9sOwOYnykqEy65EBsu8lv3s8sa5uNjYOYzUG/o7 +IrkIXJ1PyCoqe8TtSts8Uj4XMA0USDxhsJAnzK6+TxuBFZ/TyQnlv8nUKTpuMrCW +svAGcckKIT9Y0WrLrPqlBqLzhw+q44g64NJQ6SWOwn+hLT1P2dBhcn+VmOPedpUY +msCFy4tFTgHsRv7P5/niIsE4hTrZ5lEY0Yyyd05ZFcvwvSMOkwWibBfQ1vzDeAXm +DEgFaHVY6lici0HO7pW8poLjLjZ5IQ40NV0dElzcPX80/ZRPjQvhDsMcrDrvsvRK +1epQPJhMcLZrv2vcx1J8rp11M/GVRYeplIT9E3O1/xf0Nl008c8wuI8CAwEAAQ== +-----END RSA PUBLIC KEY----- diff --git a/t/data/ssh/ssh_rsa_4096.pub.pkcs8 b/t/data/ssh/ssh_rsa_4096.pub.pkcs8 new file mode 100644 index 0000000..8cff43f --- /dev/null +++ b/t/data/ssh/ssh_rsa_4096.pub.pkcs8 @@ -0,0 +1,14 @@ +-----BEGIN PUBLIC KEY----- +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAo6FKkV/bSemFY/hO2NA/ +aMtkglLaC5jaqLzDnP21gfhYPBoBEDaffV7x+qfv1wyGODJvdUPaNa8nVpwJxyrP +/SzskqTlDW235Q7BbLTfGa6qsrj4iKGamsEL2HsZNP9GcjXJAPX1gCmQyaJtTeQ7 +rQSueQ4KuNMh5KQAep5anVi2PCGm9FeCyk7TQRsna3T0fANdCOeJA5BccfNjTmTS +fYau0GGCQ7C+S3v3wfj6iJLD+aqNpX2jyXvcbce5uPhSCUUEDi6xXn/ytLTtWb9F +OXVTR5llockzeLZ8KBF+KWe2JBx3pnARYl+Mbe9P86bxuXLiDzMCSAOT+9sOwOYn +ykqEy65EBsu8lv3s8sa5uNjYOYzUG/o7IrkIXJ1PyCoqe8TtSts8Uj4XMA0USDxh +sJAnzK6+TxuBFZ/TyQnlv8nUKTpuMrCWsvAGcckKIT9Y0WrLrPqlBqLzhw+q44g6 +4NJQ6SWOwn+hLT1P2dBhcn+VmOPedpUYmsCFy4tFTgHsRv7P5/niIsE4hTrZ5lEY +0Yyyd05ZFcvwvSMOkwWibBfQ1vzDeAXmDEgFaHVY6lici0HO7pW8poLjLjZ5IQ40 +NV0dElzcPX80/ZRPjQvhDsMcrDrvsvRK1epQPJhMcLZrv2vcx1J8rp11M/GVRYep +lIT9E3O1/xf0Nl008c8wuI8CAwEAAQ== +-----END PUBLIC KEY----- diff --git a/t/data/ssh/ssh_rsa_4096.pub.rfc4716 b/t/data/ssh/ssh_rsa_4096.pub.rfc4716 new file mode 100644 index 0000000..c95c8ae --- /dev/null +++ b/t/data/ssh/ssh_rsa_4096.pub.rfc4716 @@ -0,0 +1,14 @@ +---- BEGIN SSH2 PUBLIC KEY ---- +Comment: "4096-bit RSA, converted by miko@HIROKO from OpenSSH" +AAAAB3NzaC1yc2EAAAADAQABAAACAQCjoUqRX9tJ6YVj+E7Y0D9oy2SCUtoLmNqovMOc/b +WB+Fg8GgEQNp99XvH6p+/XDIY4Mm91Q9o1rydWnAnHKs/9LOySpOUNbbflDsFstN8Zrqqy +uPiIoZqawQvYexk0/0ZyNckA9fWAKZDJom1N5DutBK55Dgq40yHkpAB6nlqdWLY8Iab0V4 +LKTtNBGydrdPR8A10I54kDkFxx82NOZNJ9hq7QYYJDsL5Le/fB+PqIksP5qo2lfaPJe9xt +x7m4+FIJRQQOLrFef/K0tO1Zv0U5dVNHmWWhyTN4tnwoEX4pZ7YkHHemcBFiX4xt70/zpv +G5cuIPMwJIA5P72w7A5ifKSoTLrkQGy7yW/ezyxrm42Ng5jNQb+jsiuQhcnU/IKip7xO1K +2zxSPhcwDRRIPGGwkCfMrr5PG4EVn9PJCeW/ydQpOm4ysJay8AZxyQohP1jRasus+qUGov +OHD6rjiDrg0lDpJY7Cf6EtPU/Z0GFyf5WY4952lRiawIXLi0VOAexG/s/n+eIiwTiFOtnm +URjRjLJ3TlkVy/C9Iw6TBaJsF9DW/MN4BeYMSAVodVjqWJyLQc7ulbymguMuNnkhDjQ1XR +0SXNw9fzT9lE+NC+EOwxysOu+y9ErV6lA8mExwtmu/a9zHUnyunXUz8ZVFh6mUhP0Tc7X/ +F/Q2XTTxzzC4jw== +---- END SSH2 PUBLIC KEY ---- diff --git a/t/data/ssh/ssh_rsa_4096_passwd b/t/data/ssh/ssh_rsa_4096_passwd new file mode 100644 index 0000000..1bb6b34 --- /dev/null +++ b/t/data/ssh/ssh_rsa_4096_passwd @@ -0,0 +1,54 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,A26F7B9DB28D8D9548D32560F7A9C06E + +bhUqLW2ICzS43sFr1IX0dm2RIUEJsGr9xPvRp95wjjf+9ya8xw8EzczETklZqMjV +Tp77QxGxPAgCQSmosJxqTteecS9JugQhZAujXJEpHDnsuts9kpXD8aGm8gsOd0Nk +om4GP/N+uV9ewsJamdNzq0VoH/MSbWNwukoE28+OdMa0Urm9dPea5jl7bI/hAhU2 +uPAg0R3FLSBPWolxmGjKTatBgy5SuFHNP0iUHAhBgY50g8oB6gw4VSLy4SJxSGxS +Y1/biO/cnl2dd23U5+a8r1Akefv/46AD1KYiO2cbokL9pV2NbFQi0FDr24jN0PDh +ru3qMqYTqX2diFUTEHqVivhpaD6Jh9gwhChCh1eJI1BkUQumzF04/KUs6tW0rQ3z +TKDiGDeBhWT6GKc0YN3b8w+QlBP0FrMqgBKfyK2linvsGKIXbCoE5qEBdhC6W8wa +vz3dH0Yez3hPOfN7JI2mHVKnq+agZYKWVkZA84+tSIJBS7iTk+J1XF9aZYn+eo/y +fjCPE+RHBLgE6cxvHwqVzLcDUvLKYxJubOarR/+UFXBY438AcVQgKcSpqUiiH7Nm +n9NtOCufboI9M9MWOt2Lv+jFk/g6t2BKCI5ebe78KV3hS/9bGRj3AqQwSkq3iTAa +ZKcFVqRfXZGcn+0Kfk9GvkKofcro9PJwvHusE3Qsas8sb32R4/RGT2wMKNS7j0yl +0ZODHflwtjU0OepCSxAWzqpCzrD20uMa8FEuYTGs0M9sWQ8Jn83k6bR86ysKIms7 +dh7/oojGmuZfh7JXykK/qRaYdnipSlg3sf26gVTh/rOIpcex+AdGYWiBOCjCxJax +p1ktiZ/A+Q1uqps0WHkPs9b4//92Dcjku6kLXGhJr+oS2OgZ4kRenJo3zVf0mpgD +WJsvST+7oyOpN83y4hrhm7j/AFb0JXiuFEwE3owcP8xt39TJdG67cyMkP9VM/vne +ynO5FaoBjQy+8dn2BmpB91781iXj8JuTGroIUkrNA66ge50I17FPQaH4KpGYTqi7 +wGpJLEecY/7/UUBbeAcjv+UfgbIvrCeZLH4tTDtjL30ky0DU2pLa4OR8VfCd6UMs +5VzfP2zmYGbBdKQHIbszMKagW8lB8jsyGpsJAOrRrqO+NGjwKYS+1gyKbnD2qby9 +Xkfs4td6bGiCg4K+k6y840K0WAn7or/6YrjTR1QmPdvDyFkZmCVDiF/vIbMFCKS2 +gfLnGsvkhBBod4VbxrVza2Fq5pP0d9JV8CM/PKdkH+phzv8G4xz8aEsbduLwS7aL +QNYobW1u3jq3jDstW33z1tPTh7KJWLv9EtBH16chsBnqI4U4paRrrTbCaJFolc9/ +OTRzv3lIb26yvhnU7+O5SmMO1v1UQdD65AFlOwHo6KWOuft4uLblpw9iGaTOhaH3 +KypIdOv2jJUH5Frf1hqrmgR1PUc2GN3wr5K6KQZcsf/gA9A8SB/HTYf7nMGPpcym +PPdk+8qKjrjSpxxJUXOYE9k06au6eMWARRJvdD3fRcNfFWattNFNm8j5YIK2UPeI +GkxnAgtbuEItTt8kRnOYoJYWQI1ifuFeTVrrjy/lv+TM7h5mfIK0kUZecFwnRuFO +fWtk7j29eDlT6Cl5cVWgfvBKxGXEIaKQsKAl0xS+rIIvmqThJkPcGvbDtMdTen91 +kLApeRKvrJjy3xAoRuK4NsPeEuePSBnbW40HwWu9BhF0xlvlcG7t8OQqN7Fqpy0+ +lLzdhKwq9dAldtNRlHHI717nvLsg8Lj72z3zKZLSzBZiyIRJxroU1h0shjOjAsBA +IiR3GbM31Pn/ZBcCl0xyx5nXzaADM8chu8tqb6UBB57J59m0jm3xoZaatUy5TZWK +PsrrCqhXLeg9Yp/acoPh47FhZs24e5VsIrNSqmg2Ta7HopphfiOZlBfcGQ/ihj2C +c8hDyjSCTn7oaHEk3dGP9nxh4EmX3/240ViHuxA19x4VaEofM9HbUDGG359JeEwh +REk8jihb9sJZ8tFamku8Lz+vN9ozK0uQ3Psyug0E6SU8IOdEenDmC8CpVqR1defa +XKJ+LBoP61GWCz1mbE7hOq3BL22b9QFOD+v8RJFXHXXlKZ57YI8aLHWGCYf01S6v +WaahgMCVlFSuNfMyqOIGy0rIQWbGV5wFdSIp5B9y/c+gCyRrlBOZc3MAYvgkWTxf +N+eQXjBZUuj7jZ4rHzy7dC2dHgdEjPTrQIUTqR+zrv2I3pGiG7laE674IpY3V17E +KTy9duBBz7cTF5wNhrET/CzJoMgjbsilzplyKrKSmUu6FbY9dnOMiaE1/M45168/ +dig9cCM/RhnqOWxBSRO73WxKEpv+fXUF68zt9TizVNGBuaqtIscT2ARivfILKiVD +TI3ViUkMddx7a0OgvgMjRN1BG4oXXEe1/3fXztRmi80tymexxdFxFMeGG/Zl8/Sz +p0ZWo96aRRL7htIfE2/MHYQLdbiByLwFAsD/6HgyIWJQuw0mfdha8bqZMDcPAR3E +66oLbwrXLQkSLVOHFbtxetMZfG4W/NV8vP0FvFgMPoybjo+gEpEL142JnqxtuL24 +ZV+amJZbVS3DqZs8yIb31OWFDT9ApZAs3Q7mkcRIa/qRoA4IQLvgLeAiKBxM8R7t +pxObaRBC3R/EU0tWi2V+qAHOQ4QLFX6LQZU9TpnJE2x1aqwGQbaeMNK8gEg+OLGr +n7iKqi+9sm8FwEGKf+bWyaMuCanfSdoSWNl0B0hVYz63BWqqL2VRQbzruD6jmVxp +xEDZQizOWydlSqdIe0irUDb2O28y1droekW3uQc0YyJ/4CAhYpaZMLTioyRMzYYX +eZYFe1HfGcVpQdqNQems6pbwMh46NamH/6UxlgaWt6wQvCP2c5MzasDZGwsaxvKC +5oGewOEr4M2j/ZLuaVB9o3rvrhbJMwBPjCSpeP6lRh9uUrRJqeUlvoHlSbtDZtmd +9s2taSHhn+rkWzZvszwPZ0c4sjQ36MpOb+YUsznFoBOGsh4degq46lP4oatu5Z+i +1hQkPwyFNn/R2tGIOvgXHz32EzK83XVulcXjTkYfIDWwxq/BZ1Sni/LbCw5YDlMP +2RkHKDqTPtTSD+4wL53OQFLREUuvRxHQArYgns4q4vGOI/HUw6Moa32qC4zmtQa8 +-----END RSA PRIVATE KEY----- diff --git a/t/data/ssh/ssh_rsa_768 b/t/data/ssh/ssh_rsa_768 new file mode 100644 index 0000000..021f1b5 --- /dev/null +++ b/t/data/ssh/ssh_rsa_768 @@ -0,0 +1,12 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIBywIBAAJhANh5t4ZAUKeVCI1ETuv1QRuOv4NAxN3DVkcYHbDrEP8PMp6bzvrU +Z0KmqwusZrDYPtpIig/UHlLPzvRihVYefoCjse+bXtXcrF+fgHTUY1BMzn4vbqZ1 +izmIk0a7+W1R1wIDAQABAmEAq8E3Cb+xvqUSmfMeozx+If1Kmjsjd8hqhhHuTNbV +L2nBgfKhcIZiP5G5mJN7Dski77gqXkNk2e4/hXezBRFgW9f+58P77lCziQ2a7f24 +UGJffLaxbwK7JKOyONyBv68BAjEA7uxiVTW//ejJXxCO+pFeCZ4HTC7E4YUibOjH +iw7QcF4DF8LFhxB9mILi5VLEXmCXAjEA5/KZlRMxLcRTSJ6Yco0C8GOFH8+jqWMU +aUez5zzukKy3D8ivg7Xc69oLf2FWPYDBAjAz9+i/ngxfvzWl3uUqrVnl/6CYuoeK +gjnltJBKt/MwrdJAZdYvNbAL71RJC0K5QIsCMQDTAoQv947E6RcvOIDNrXUgBhmk +z/w+7BE0mfOTiX4rBcVgSZ1KwFckBXBySLXxK8ECMASNKoZFnTNjU3NnanGqWk4l +VhPn5x5saUHEJtH4AnX8gWE+LmxA6nw3efM8NtxSog== +-----END RSA PRIVATE KEY----- diff --git a/t/data/ssh/ssh_rsa_768.pub b/t/data/ssh/ssh_rsa_768.pub new file mode 100644 index 0000000..babf946 --- /dev/null +++ b/t/data/ssh/ssh_rsa_768.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAYQDYebeGQFCnlQiNRE7r9UEbjr+DQMTdw1ZHGB2w6xD/DzKem8761GdCpqsLrGaw2D7aSIoP1B5Sz870YoVWHn6Ao7Hvm17V3Kxfn4B01GNQTM5+L26mdYs5iJNGu/ltUdc= comment for rsa/768 key diff --git a/t/data/ssh/ssh_rsa_768.pub.pem b/t/data/ssh/ssh_rsa_768.pub.pem new file mode 100644 index 0000000..9fee219 --- /dev/null +++ b/t/data/ssh/ssh_rsa_768.pub.pem @@ -0,0 +1,5 @@ +-----BEGIN RSA PUBLIC KEY----- +MGgCYQDYebeGQFCnlQiNRE7r9UEbjr+DQMTdw1ZHGB2w6xD/DzKem8761GdCpqsL +rGaw2D7aSIoP1B5Sz870YoVWHn6Ao7Hvm17V3Kxfn4B01GNQTM5+L26mdYs5iJNG +u/ltUdcCAwEAAQ== +-----END RSA PUBLIC KEY----- diff --git a/t/data/ssh/ssh_rsa_768.pub.pkcs8 b/t/data/ssh/ssh_rsa_768.pub.pkcs8 new file mode 100644 index 0000000..d671a61 --- /dev/null +++ b/t/data/ssh/ssh_rsa_768.pub.pkcs8 @@ -0,0 +1,5 @@ +-----BEGIN PUBLIC KEY----- +MHwwDQYJKoZIhvcNAQEBBQADawAwaAJhANh5t4ZAUKeVCI1ETuv1QRuOv4NAxN3D +VkcYHbDrEP8PMp6bzvrUZ0KmqwusZrDYPtpIig/UHlLPzvRihVYefoCjse+bXtXc +rF+fgHTUY1BMzn4vbqZ1izmIk0a7+W1R1wIDAQAB +-----END PUBLIC KEY----- diff --git a/t/data/ssh/ssh_rsa_768.pub.rfc4716 b/t/data/ssh/ssh_rsa_768.pub.rfc4716 new file mode 100644 index 0000000..fb88963 --- /dev/null +++ b/t/data/ssh/ssh_rsa_768.pub.rfc4716 @@ -0,0 +1,6 @@ +---- BEGIN SSH2 PUBLIC KEY ---- +Comment: "768-bit RSA, converted by miko@HIROKO from OpenSSH" +AAAAB3NzaC1yc2EAAAADAQABAAAAYQDYebeGQFCnlQiNRE7r9UEbjr+DQMTdw1ZHGB2w6x +D/DzKem8761GdCpqsLrGaw2D7aSIoP1B5Sz870YoVWHn6Ao7Hvm17V3Kxfn4B01GNQTM5+ +L26mdYs5iJNGu/ltUdc= +---- END SSH2 PUBLIC KEY ---- diff --git a/t/data/ssh/ssh_rsa_768_passwd b/t/data/ssh/ssh_rsa_768_passwd new file mode 100644 index 0000000..3b3590c --- /dev/null +++ b/t/data/ssh/ssh_rsa_768_passwd @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,B8B44B077A4C4A63144875D0A8319272 + +4S9dwwHP6kvCq+PHpCOEuJV9eFZo30ujR4V4ju2GEDxoNzl+RvBurSABRv+MOwOO ++7cXxFOCNFOnhKxvwENLyJ/wvkO7X0al1lF0yFHoF5scWFG1LRxQKp3kpW+k/ncW ++eO72S7Er0fv3DbMC7ZqXXecHc5RauC16quRWqHrYuRHpGj8VqzveEz2r4XAg0zB +OBq+osTF/fxydpncrtChRwcgyCZ7Er9eMEID0T+vlJFmuNEUYvYW9j4BVqMcmoKA +qKr5vr95ss4Hq8lOnha4OQlVzod883QzB3MCMLFkE3e9x3DyvyfGgm0CIIZzz/I4 +3w40pmq1tB/yrp2V8PvdC+ksWHx/2MFuzhcgeugfnrE0my9khsGLkaS2k1fbueBl +s83tIODLBbvjS26KxrADo5vHltwGD9GK6CpnAbL4tS2YVHiOaaI8fqWjNNq8EoXI +tmMve/dEej0HILbjIp0IqKs/rOtrTxf4UBKAhf+j2S8VxDq1gf28YR34zHEpzM3p +bMTPlg0KZRYJ9x7VNz818a4FSBJOWMI8VXBbb7lW/iSQwvQ3orX5rhNrdkHa4B2W +aYaiT78/MwUzjmexGRSgNhymDmHrNx76cg40MeWV6vU= +-----END RSA PRIVATE KEY----- diff --git a/t/data/ssh/ssh_rsa_8192 b/t/data/ssh/ssh_rsa_8192 new file mode 100644 index 0000000..225ee2d --- /dev/null +++ b/t/data/ssh/ssh_rsa_8192 @@ -0,0 +1,99 @@ +-----BEGIN RSA PRIVATE KEY----- +MIISKQIBAAKCBAEAqV97tjVnMe5+B6Hu/wGKiyLWEcHLLW07r3tMk2ehx3MCrOkQ +oQobp0lZ3tn5MXnLi3aYgGTa3Y2u7EMai9MA4vr41rnC5pdIQ0NoqT8uP/OPQ5kH +jVYddaEaFJAOh6SOaEq+S0yRqV4p0/wkTD95VOKDOxl8MjrJRwSbEM98cImYIwvX +bFNOha2S8W8tJ6AeRJBmB1iFO0wAaIFa5fqvGqohSJYuqFFuEBpXn0DW79cp/z9c +ZJPyQ6TewWVu119XGwHNfafjKlbjHpCN+G4xzKFVOXr2OFqprX1kSKKLpwHJQroj +rnv6q2DKF8KOuCazGl9fZyJeuY6w6n4wrUULVquovQ/6Uxdi8xEYBJC1PcVerLSF +ypHKY8hKwa75SpUR3V1oZBjdV6J0yt9hkjzsbA5EbMozgq3zJU5HLjrpyASs6RVh +dDfZuh+o4f5g3Wrb0Nbe9nJYE4ECNa67cYeEc24ik4auxhLkJ+WlY7I/2dKvqnmO +9be5TRdZGmi2uOJD1nJkjKr/brNFPdJoEp/ifyrRZwQQ87OIELJ+eARMmVIRf6jp +eBX6YM0evis3UEX15RmNixR05T23ciZ7AZUbN5Xdlt5YIWzTYuFWbC7dLMg3cmlt +sK92rVpRbKuV8ZBmO/5ckcx5VkQiAG0kmYA8/2lgQXab4OeALSL0ScrDtZ2XXw9G +9TS4w/KBrd4X7VslJ/+v1IoFt+gH6oLCYx5ctpqUlud5WCR5LbKz360AzU9yf0n7 +SqRk41OUcMc+NSUkMBInzOS6JhvzBq8OfpCRnaeBoZUUqn9uZUdwUUo0iOq+6H2D +xjgknPU1o5xIn79R7XB9PJs3fdgbullwlhaV8Xq3/aC0lmJWQy1JfZ8XaXJRmqkM +slV8BViilInrtPsIP7tmK8q0NSYE7AJVhWIfP0qPclsql3MBZCqS9HFn9bEW0U7i +84VCMnN9TDVslTdT/o9RxihL3ilXxk8YmjcfKsRBZbLLDVZhcB7ywe7F+z/ITF42 +cXr03pCi5Ckfv/xBEKfKsIxw5Tj1ptbUD7ijB7Gw3I8cl6hTuhzBCYX3ldDliurQ +TJcqUozPPvH5qhQUoiRplzNUtL//Eug9kP9zq5xQ+VyzrLrm02HkqiTcyGi0jbx7 +xpNbSUanOKkIw0VyPGUPkBmSQZd3ox1DPX9XDTAKQqJuEX3GarytDU3rG+DoRRey +t1fAW+g32Glu+k7SUGLTf7BgMHkq4n812d12gR3pQq4fdZKM8yqxHCWHhrVH0faP +Nt1N6U5OW1+0LxAoC7j+huS/C3OlfFSPIl4VeknxFTfXnMIepy7FB4pqkuSL3cp2 +6kPa49/mYWlUIh5qxdZ9468ZxCGNCFklHVMB+QIDAQABAoIEAEUlMPki9h0hUxxE +lLBQbcH9l80qA4tpE7vBJ3LqFNa68jWq9Fn6KW3y+RiMfjofkeQ+p2WLRvq589aK +UpUQsET51oq6zYGb8ylapKirnXMIOM2M9NNTe7Vg7qfEY9omaOjU0rkk6jZttb/Q +KPVj2GG6E38WGWjcLP2sOK31NsUutwhftjOIEv9p7Bpam+GYcaLmHHEVR1b84RHI +9VX8MG4/VFUw0p1umPND/c+LBfRmL8P/lvWMnJPXBAWKJmUQjBv/cWfCGXBYhmIc ++4iXXAdBOey8cTZydODZ1w38Je0pQoPWP+jkvmImonpuuBsf2XCDzQvqsScpxLoG +iFLEZCue6sU8d6JiYsf+i4KZnRQ5tjvletVHDYwM4dAOYcF7+A4aKxrqN7qmHO4R +oeC0tIQskuyi48KOxzvMqCyMapJ4rip9ywpKHr3oXObeFadvD4xDnESaS7Cyszc9 +PVLM01rYdI8rpcBBSBmtnAaGZ6DCbWq4M4/G0IRTatHoO+hgnvc2PixbRupnj3X8 +pvYrhakKzvAybcU/3uWKKS1P/AF/ypsGV0HqHwxT0SArvmosFYXRF8LWuB46QuD8 +Kq1rtO/NY+hKn0oOBoJQohqKS0sT9ebkeZ5vE5ET1Tf7GLzEiagmYJ45DrQUHplz +9UQhYUWYPG6dQGfhuqcypO5XM+y5Xl3iKTQwh5YAA+mt+LtZdgyFJETyA3wieQSf +NGNV3Ep6i4QoXMUHqNN6yZuaPqr+GXqbDitLug/4n+kRxVlgjcDmK0QM1kZviKKN +fPtoI1bQZ3lNvm8PZgXg5UYXHSkOYmcEIF8uksWAHs+hXHxXZ8Y3MMX3TXlOLYfa +gBHpRjYGe32b2LkNg0z0tHwPBTSjfff64VFqmsCMJyb8bcY5JJRptOLC6mDhbWm3 +5AVcLK6gc+ocuszJPNR71Ltn0mGqxXJRbihMGhEiKtonw4B7zwVGuwhP2UwsaQs3 +6hsLBb8kaqF/+LYwrwr5mdh47pzN0IMVTTTRXz9UrxLmEMvjS5tpKlFA2Rzmw6G1 +3iHX8otLO89ONKBvBJHjUlvl/MkXffALq4sV8WYWT0gs0rBAmEZOtCwfXBXPvnEZ +9MLQJCHmn5VfBsgEUnQeW+mPNr3VH0oRMKKfja+U6KmS+IfywkhjOdH+gHZS7R0B +B4HFgPHB+lJ9+ASqj10J4TION/uT6Ph+TJ4fH4Cuvb+89sC0BmQp2jxLbtA1lsEJ +bS9Wvu/f1lJnsZ4hrqNHhxpfTHScSzrB4zalfArzfbZqJAyzL0TEK5yrXvKUgyBC +M59wPO7iQd25ACsZjiEDlN9zVykLBJ6/RoFEEf3Kk6HxLVI0syr9+nocVAnqdDHS +CCUExLECggIBANP/aI6rw6yeQXfm6Zto14kWuAbiyXvmWvLhV+G6t1mmqsNORFZB +oRysDOpGCVe/mTxwovaAZRABPNFtcJbSE909owK2DgooKqiKnjU4akZAOsxG6w/A +zEXUqbHUJPg3dHd8vg0+pD3yNGNH/xQn3QLfklfljxW3IprDoz0RoGdYPjLMmvn5 +irW0tsRqzQeEob0R7Wd5UtmI/zMdUoj7tX9BgmzYcw7JZkj3U1CPjUDOxP3AWmUb +brcq2WTS6mOea7oH0QyrCBcDYrxCdW9Vhb0sm1BZjPMtRq5weikmPvL98eYc++zj +qRCOHcyr8P/87ILlGhuwB1RkFn8qJpjR0nXDi+/IFCRUWyM147kFOCtu1Cd2s/rj +bCt0xUhNup7YCNb3uexj+fG0b91PqKv137phluoxZPI1qkQoOC1DsL02bCQMYr0n +eEYgaO4WeSozlvOD+TEuMe1PTZJL804UbsyygXN3+FaRU12u0/7XeV+a58zpDlzn +Ax/aOXze/++CNaigwtn77eKik2p+fN/B0DnJUEbR+viHr6IgZTI+z58zCDUNiVsA +Wk9J9j4Cbvy096TSq90tSKwWxBKYQrvKl0uy+QEg+fKZ5Oiywoyaa52x4pgOFP44 +0WhF45TSo31twsepPRhZCBaKR1L8BKLbC3XjoODA3BqdR4vxspNpsdpFAoICAQDM +hzEnPNLT/s9Ntw25QRC1qbOBniavel14BN6DSP6T1kedx8g0kzZ2VutUQC/Gqkor +wUcqY94V4PZ9L70MwwKDEeU+sSBmCTJa0SB6bKa7cF9R0WBCd7lKe12ijyFR3Um7 +8Ju7MsiwmIbQz2h2nejVUfwfm2v5M2YRu1v2mgZ6/6Ye58r8Z8FNCjNCjpJ6aVRA +37hLLCudOMJ/julW2k/QOUjzPFKrWHrx4aFZSIm/a8ZLJI7j6pGPYG+CeSrz6E5M +VCgXRhDQT7hGrO53PgkRPHhLQy/P36Ed0sjgTol4IuNj7M4UGQiw527hO09QTksH +ny9bj4c9w9tqqRKYXT2nONENfeCeamJKRSaVqV+J90mcFtTJ3GMSUnOIeKjnXaB9 +4L7viVZ/R352MVhMYf2smRG/BN1WiM7Tmr2iAqWc0ul9YrfYMruOmeo319Cg3EHz +adfbRRFKxfuRMXO8UeYT/mXBfqHJ3ZtDs5CYENFEX4KJ32rD7x8SdeaSa1Y9abuW +BU26CuF7q3lZVLsxHp1HzEv791IdE+tx05mujiWnZnAy91d/k8wQVhVbyI93ij+w +zcZReA8jWp2ETOXtz7sGnrMbdphLdprwmhlOjf7iTjvX08ZVk5LuaBcIVdCiy6+I +nbpgVQ/9UizVJP2rBCwZN6mdjmIljAqP9bRvF7b+JQKCAgBQ7yU/spuVfyWHXQS6 +bCA9GgtPta0uPBdkulsOtnXhKBvxTCQSuiOECrszhWFzupYJ2QaeDQ6IObC6U4m0 +SqeCw1FEa7SYdBU1GxajQtJv132bF0gOT5Cs6C+Q0Gj8yk8QfvMfo1aYv6r4bDgZ +vc5GlowMOnuR0sTHSQE9A0m1qp60TiCsZnRqQn+0JQH5aM1GnV2BL3RN0Ft9bChi +W5ZC6wOcAlaKwqDmImYQT32hzE6wgYsBJqPyEc3FDDCnr4d5EhrhNzpzbrt3G/gx +dPkF682vs0B4ZkShvBcnNo65vfFn5JDZM2EMDPWbedkcIbc5kbWR9HYX5c4g5jqu +BQzQIMN/22a1J+9TVfOGY1O6YSlll4/GrKRTQtU+cU5Z7igRyamVceWuPTCn0Q2X ++NpdEXzIE+tx/MLwGlq4DSugUPKgIIphpHvqad0laDcBwYhTl4K/H9+3tZrry0sr +9+kFBPEe4CJTClBFZ8VPeXvA4Ca2uBLfrOIoeuuPnKMhERjjM9yv09pRt7eH5JpP +4nJYXV7kaq3hzAtlXfDEae5h3N25Q124/D1+H8J+kfdFSuFwb21llzAzYs2gO7je +cM2p/L3LjIdf8xjNLdHQU/PZ1FupqVaiZ5aqtGPaIUCBVjISf63vaa4IzOnF6Kjs +c6vAahK1O2vMTVdPOgru9F8N8QKCAgEAxPaYnmnTuraT2wqjG7mOJvQjW3r7VFgp +9S/zPUkpaSOdWlQP+JmghDxWao9Zsx9BSHvcVfVQ5Y78sTgs/kI6hBDSzRn00m6e +4Jiuh1dlBfNEyF0zLy9u8Ex3stnVw6mwnV4sCw3v+SkaA7MJrdmKZQyMGcAqLhWS +gRcGjChufzr9NpwQfhxJKjDdhoYYh+wxaDxKlZIW+lSz8fWlvq+E10ijeSKpljsi +Qxf/syTJCt/2WVz+gnzd6s569JJNjBA2fwk4hplCDeoH04AsMgc64i9yxUARpkV9 +OmRIcMMRXfFzPELLfs1Q8lQeEqd0TSjo1pE1IR7Kpe+cuU3TC4oXmpd7s1t62fQn +bdDERLKUwB+18qyGBVPI0Nc4Tb+tIQqoSTELj1CaTP6DybzhhMWFbxcF4QgFQ5WC +YIOPhZq49JqkosxTsc/BkaWlylt6nb8fgBN4/b+41GJvTrbp9vyD7tM6GSojEmzo +Xj1pzRe8//RemPngLop0SOnjvzPBHGlbbjDzVmuuE9Phi+auUrJh0sfqkN7vY/NP +9RFK2bAokNp0yJAr4j9p8H2GGhq+Fue7SEAScViGc4yLTuJjNy6qtMhWQedm6J1y +vqwYHO9f+35N4R4fzT/N6uuw6qUBxBUVmSIUXzrrqA/f/u+dnnjpIuvY21NIL1J6 +xYJgXe/fmUUCggIBAL4Kcka/aAIYxJ2V7Y23CZEE91XpbLPBHUQOxEHG5WpV05Mc +zy+zDHIZr/DqXszGP7vV9K2Pmpl3Yods10sSeo5gkNszE2fmP+e4RVd/5z0zsmG9 +HYqQLKoynMOFGmnFHTRj+/U8VDAkK4lMf4PyB5PSW0fG6LBllvjYptg6Y/PzQGgu +qGi5tAwnwLckfOzwRGenrNCh6Pcy1N+ruIZqHQCN155so63jQ70C7KwJqtlSUp+k +z2DxSA5BcFgdfVLgclDQiBxJpdU9bFzqi/UXht9wmQqrWiZ9LTw5NWTn8siGJiuT +m5jjp92L4FdWCA9BZTm2uedYH7NppJBJxxTXMDPJK/J3IW+O5RbNtbuI33mllT3z +lf2ZwKS8ZzEu0U/0M65rcSB7R5gCLt2IAKKcbhY9D2Ewuo271lPAqvq7j84uKh8Z +jbKwjwhMoRbtt0745xLwu+IYtlUI57vdH8S4E1nG862EG3G51ldziAPF/JEmTt0Q +tkx/PCxEsUk7MG9kybZ7WzvkK/j2guzP3wQy6irTO4WWFQNZXv9q9qBT0gurs3Gz +oXm8H3Otf7bbSkMe8yG30KyCrsdYOT6xrBN6POdObakJgNgyRM3mCKdjQzvCmbaE +nKJS0FlxbsE1MGOtBorSXEsvXW/DSuReSysnVRDNkRu7Y5Y0oGAwQQ4J5Pfj +-----END RSA PRIVATE KEY----- diff --git a/t/data/ssh/ssh_rsa_8192.pub b/t/data/ssh/ssh_rsa_8192.pub new file mode 100644 index 0000000..ec8259b --- /dev/null +++ b/t/data/ssh/ssh_rsa_8192.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAEAQCpX3u2NWcx7n4Hoe7/AYqLItYRwcstbTuve0yTZ6HHcwKs6RChChunSVne2fkxecuLdpiAZNrdja7sQxqL0wDi+vjWucLml0hDQ2ipPy4/849DmQeNVh11oRoUkA6HpI5oSr5LTJGpXinT/CRMP3lU4oM7GXwyOslHBJsQz3xwiZgjC9dsU06FrZLxby0noB5EkGYHWIU7TABogVrl+q8aqiFIli6oUW4QGlefQNbv1yn/P1xkk/JDpN7BZW7XX1cbAc19p+MqVuMekI34bjHMoVU5evY4WqmtfWRIoounAclCuiOue/qrYMoXwo64JrMaX19nIl65jrDqfjCtRQtWq6i9D/pTF2LzERgEkLU9xV6stIXKkcpjyErBrvlKlRHdXWhkGN1XonTK32GSPOxsDkRsyjOCrfMlTkcuOunIBKzpFWF0N9m6H6jh/mDdatvQ1t72clgTgQI1rrtxh4RzbiKThq7GEuQn5aVjsj/Z0q+qeY71t7lNF1kaaLa44kPWcmSMqv9us0U90mgSn+J/KtFnBBDzs4gQsn54BEyZUhF/qOl4FfpgzR6+KzdQRfXlGY2LFHTlPbdyJnsBlRs3ld2W3lghbNNi4VZsLt0syDdyaW2wr3atWlFsq5XxkGY7/lyRzHlWRCIAbSSZgDz/aWBBdpvg54AtIvRJysO1nZdfD0b1NLjD8oGt3hftWyUn/6/UigW36AfqgsJjHly2mpSW53lYJHktsrPfrQDNT3J/SftKpGTjU5Rwxz41JSQwEifM5LomG/MGrw5+kJGdp4GhlRSqf25lR3BRSjSI6r7ofYPGOCSc9TWjnEifv1HtcH08mzd92Bu6WXCWFpXxerf9oLSWYlZDLUl9nxdpclGaqQyyVXwFWKKUieu0+wg/u2YryrQ1JgTsAlWFYh8/So9yWyqXcwFkKpL0cWf1sRbRTuLzhUIyc31MNWyVN1P+j1HGKEveKVfGTxiaNx8qxEFlsssNVmFwHvLB7sX7P8hMXjZxevTekKLkKR+//EEQp8qwjHDlOPWm1tQPuKMHsbDcjxyXqFO6HMEJhfeV0OWK6tBMlypSjM8+8fmqFBSiJGmXM1S0v/8S6D2Q/3OrnFD5XLOsuubTYeSqJNzIaLSNvHvGk1tJRqc4qQjDRXI8ZQ+QGZJBl3ejHUM9f1cNMApCom4RfcZqvK0NTesb4OhFF7K3V8Bb6DfYaW76TtJQYtN/sGAweSrifzXZ3XaBHelCrh91kozzKrEcJYeGtUfR9o823U3pTk5bX7QvECgLuP6G5L8Lc6V8VI8iXhV6SfEVN9ecwh6nLsUHimqS5IvdynbqQ9rj3+ZhaVQiHmrF1n3jrxnEIY0IWSUdUwH5 comment for rsa/8192 key diff --git a/t/data/ssh/ssh_rsa_8192.pub.pem b/t/data/ssh/ssh_rsa_8192.pub.pem new file mode 100644 index 0000000..77db744 --- /dev/null +++ b/t/data/ssh/ssh_rsa_8192.pub.pem @@ -0,0 +1,24 @@ +-----BEGIN RSA PUBLIC KEY----- +MIIECgKCBAEAqV97tjVnMe5+B6Hu/wGKiyLWEcHLLW07r3tMk2ehx3MCrOkQoQob +p0lZ3tn5MXnLi3aYgGTa3Y2u7EMai9MA4vr41rnC5pdIQ0NoqT8uP/OPQ5kHjVYd +daEaFJAOh6SOaEq+S0yRqV4p0/wkTD95VOKDOxl8MjrJRwSbEM98cImYIwvXbFNO +ha2S8W8tJ6AeRJBmB1iFO0wAaIFa5fqvGqohSJYuqFFuEBpXn0DW79cp/z9cZJPy +Q6TewWVu119XGwHNfafjKlbjHpCN+G4xzKFVOXr2OFqprX1kSKKLpwHJQrojrnv6 +q2DKF8KOuCazGl9fZyJeuY6w6n4wrUULVquovQ/6Uxdi8xEYBJC1PcVerLSFypHK +Y8hKwa75SpUR3V1oZBjdV6J0yt9hkjzsbA5EbMozgq3zJU5HLjrpyASs6RVhdDfZ +uh+o4f5g3Wrb0Nbe9nJYE4ECNa67cYeEc24ik4auxhLkJ+WlY7I/2dKvqnmO9be5 +TRdZGmi2uOJD1nJkjKr/brNFPdJoEp/ifyrRZwQQ87OIELJ+eARMmVIRf6jpeBX6 +YM0evis3UEX15RmNixR05T23ciZ7AZUbN5Xdlt5YIWzTYuFWbC7dLMg3cmltsK92 +rVpRbKuV8ZBmO/5ckcx5VkQiAG0kmYA8/2lgQXab4OeALSL0ScrDtZ2XXw9G9TS4 +w/KBrd4X7VslJ/+v1IoFt+gH6oLCYx5ctpqUlud5WCR5LbKz360AzU9yf0n7SqRk +41OUcMc+NSUkMBInzOS6JhvzBq8OfpCRnaeBoZUUqn9uZUdwUUo0iOq+6H2Dxjgk +nPU1o5xIn79R7XB9PJs3fdgbullwlhaV8Xq3/aC0lmJWQy1JfZ8XaXJRmqkMslV8 +BViilInrtPsIP7tmK8q0NSYE7AJVhWIfP0qPclsql3MBZCqS9HFn9bEW0U7i84VC +MnN9TDVslTdT/o9RxihL3ilXxk8YmjcfKsRBZbLLDVZhcB7ywe7F+z/ITF42cXr0 +3pCi5Ckfv/xBEKfKsIxw5Tj1ptbUD7ijB7Gw3I8cl6hTuhzBCYX3ldDliurQTJcq +UozPPvH5qhQUoiRplzNUtL//Eug9kP9zq5xQ+VyzrLrm02HkqiTcyGi0jbx7xpNb +SUanOKkIw0VyPGUPkBmSQZd3ox1DPX9XDTAKQqJuEX3GarytDU3rG+DoRReyt1fA +W+g32Glu+k7SUGLTf7BgMHkq4n812d12gR3pQq4fdZKM8yqxHCWHhrVH0faPNt1N +6U5OW1+0LxAoC7j+huS/C3OlfFSPIl4VeknxFTfXnMIepy7FB4pqkuSL3cp26kPa +49/mYWlUIh5qxdZ9468ZxCGNCFklHVMB+QIDAQAB +-----END RSA PUBLIC KEY----- diff --git a/t/data/ssh/ssh_rsa_8192.pub.pkcs8 b/t/data/ssh/ssh_rsa_8192.pub.pkcs8 new file mode 100644 index 0000000..2996f37 --- /dev/null +++ b/t/data/ssh/ssh_rsa_8192.pub.pkcs8 @@ -0,0 +1,25 @@ +-----BEGIN PUBLIC KEY----- +MIIEIjANBgkqhkiG9w0BAQEFAAOCBA8AMIIECgKCBAEAqV97tjVnMe5+B6Hu/wGK +iyLWEcHLLW07r3tMk2ehx3MCrOkQoQobp0lZ3tn5MXnLi3aYgGTa3Y2u7EMai9MA +4vr41rnC5pdIQ0NoqT8uP/OPQ5kHjVYddaEaFJAOh6SOaEq+S0yRqV4p0/wkTD95 +VOKDOxl8MjrJRwSbEM98cImYIwvXbFNOha2S8W8tJ6AeRJBmB1iFO0wAaIFa5fqv +GqohSJYuqFFuEBpXn0DW79cp/z9cZJPyQ6TewWVu119XGwHNfafjKlbjHpCN+G4x +zKFVOXr2OFqprX1kSKKLpwHJQrojrnv6q2DKF8KOuCazGl9fZyJeuY6w6n4wrUUL +VquovQ/6Uxdi8xEYBJC1PcVerLSFypHKY8hKwa75SpUR3V1oZBjdV6J0yt9hkjzs +bA5EbMozgq3zJU5HLjrpyASs6RVhdDfZuh+o4f5g3Wrb0Nbe9nJYE4ECNa67cYeE +c24ik4auxhLkJ+WlY7I/2dKvqnmO9be5TRdZGmi2uOJD1nJkjKr/brNFPdJoEp/i +fyrRZwQQ87OIELJ+eARMmVIRf6jpeBX6YM0evis3UEX15RmNixR05T23ciZ7AZUb +N5Xdlt5YIWzTYuFWbC7dLMg3cmltsK92rVpRbKuV8ZBmO/5ckcx5VkQiAG0kmYA8 +/2lgQXab4OeALSL0ScrDtZ2XXw9G9TS4w/KBrd4X7VslJ/+v1IoFt+gH6oLCYx5c +tpqUlud5WCR5LbKz360AzU9yf0n7SqRk41OUcMc+NSUkMBInzOS6JhvzBq8OfpCR +naeBoZUUqn9uZUdwUUo0iOq+6H2DxjgknPU1o5xIn79R7XB9PJs3fdgbullwlhaV +8Xq3/aC0lmJWQy1JfZ8XaXJRmqkMslV8BViilInrtPsIP7tmK8q0NSYE7AJVhWIf +P0qPclsql3MBZCqS9HFn9bEW0U7i84VCMnN9TDVslTdT/o9RxihL3ilXxk8Ymjcf +KsRBZbLLDVZhcB7ywe7F+z/ITF42cXr03pCi5Ckfv/xBEKfKsIxw5Tj1ptbUD7ij +B7Gw3I8cl6hTuhzBCYX3ldDliurQTJcqUozPPvH5qhQUoiRplzNUtL//Eug9kP9z +q5xQ+VyzrLrm02HkqiTcyGi0jbx7xpNbSUanOKkIw0VyPGUPkBmSQZd3ox1DPX9X +DTAKQqJuEX3GarytDU3rG+DoRReyt1fAW+g32Glu+k7SUGLTf7BgMHkq4n812d12 +gR3pQq4fdZKM8yqxHCWHhrVH0faPNt1N6U5OW1+0LxAoC7j+huS/C3OlfFSPIl4V +eknxFTfXnMIepy7FB4pqkuSL3cp26kPa49/mYWlUIh5qxdZ9468ZxCGNCFklHVMB ++QIDAQAB +-----END PUBLIC KEY----- diff --git a/t/data/ssh/ssh_rsa_8192.pub.rfc4716 b/t/data/ssh/ssh_rsa_8192.pub.rfc4716 new file mode 100644 index 0000000..3fdbc00 --- /dev/null +++ b/t/data/ssh/ssh_rsa_8192.pub.rfc4716 @@ -0,0 +1,23 @@ +---- BEGIN SSH2 PUBLIC KEY ---- +Comment: "8192-bit RSA, converted by miko@HIROKO from OpenSSH" +AAAAB3NzaC1yc2EAAAADAQABAAAEAQCpX3u2NWcx7n4Hoe7/AYqLItYRwcstbTuve0yTZ6 +HHcwKs6RChChunSVne2fkxecuLdpiAZNrdja7sQxqL0wDi+vjWucLml0hDQ2ipPy4/849D +mQeNVh11oRoUkA6HpI5oSr5LTJGpXinT/CRMP3lU4oM7GXwyOslHBJsQz3xwiZgjC9dsU0 +6FrZLxby0noB5EkGYHWIU7TABogVrl+q8aqiFIli6oUW4QGlefQNbv1yn/P1xkk/JDpN7B +ZW7XX1cbAc19p+MqVuMekI34bjHMoVU5evY4WqmtfWRIoounAclCuiOue/qrYMoXwo64Jr +MaX19nIl65jrDqfjCtRQtWq6i9D/pTF2LzERgEkLU9xV6stIXKkcpjyErBrvlKlRHdXWhk +GN1XonTK32GSPOxsDkRsyjOCrfMlTkcuOunIBKzpFWF0N9m6H6jh/mDdatvQ1t72clgTgQ +I1rrtxh4RzbiKThq7GEuQn5aVjsj/Z0q+qeY71t7lNF1kaaLa44kPWcmSMqv9us0U90mgS +n+J/KtFnBBDzs4gQsn54BEyZUhF/qOl4FfpgzR6+KzdQRfXlGY2LFHTlPbdyJnsBlRs3ld +2W3lghbNNi4VZsLt0syDdyaW2wr3atWlFsq5XxkGY7/lyRzHlWRCIAbSSZgDz/aWBBdpvg +54AtIvRJysO1nZdfD0b1NLjD8oGt3hftWyUn/6/UigW36AfqgsJjHly2mpSW53lYJHktsr +PfrQDNT3J/SftKpGTjU5Rwxz41JSQwEifM5LomG/MGrw5+kJGdp4GhlRSqf25lR3BRSjSI +6r7ofYPGOCSc9TWjnEifv1HtcH08mzd92Bu6WXCWFpXxerf9oLSWYlZDLUl9nxdpclGaqQ +yyVXwFWKKUieu0+wg/u2YryrQ1JgTsAlWFYh8/So9yWyqXcwFkKpL0cWf1sRbRTuLzhUIy +c31MNWyVN1P+j1HGKEveKVfGTxiaNx8qxEFlsssNVmFwHvLB7sX7P8hMXjZxevTekKLkKR ++//EEQp8qwjHDlOPWm1tQPuKMHsbDcjxyXqFO6HMEJhfeV0OWK6tBMlypSjM8+8fmqFBSi +JGmXM1S0v/8S6D2Q/3OrnFD5XLOsuubTYeSqJNzIaLSNvHvGk1tJRqc4qQjDRXI8ZQ+QGZ +JBl3ejHUM9f1cNMApCom4RfcZqvK0NTesb4OhFF7K3V8Bb6DfYaW76TtJQYtN/sGAweSri +fzXZ3XaBHelCrh91kozzKrEcJYeGtUfR9o823U3pTk5bX7QvECgLuP6G5L8Lc6V8VI8iXh +V6SfEVN9ecwh6nLsUHimqS5IvdynbqQ9rj3+ZhaVQiHmrF1n3jrxnEIY0IWSUdUwH5 +---- END SSH2 PUBLIC KEY ---- diff --git a/t/data/ssh/ssh_rsa_8192_passwd b/t/data/ssh/ssh_rsa_8192_passwd new file mode 100644 index 0000000..dab496a --- /dev/null +++ b/t/data/ssh/ssh_rsa_8192_passwd @@ -0,0 +1,102 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,555970539213A18AC076A1D00F0C23B7 + +bt8MfXt/wEkv+nvXRkFxP+IXzwBLUeAc7kYucKR2R9BfkNNnQOJi8FPo4pdRk2IX +PXJgbdLGOuN9HjtSaZ9paLcwBAhCwfQFlZm58fDYgqylVq7e0qTm+CiURTNy1esw +eJec59I2flGAfJQ7oG752v9dfFY2+K9xQkYSeRXj8LtmuOBYMGnmKyakwkKMV09M +kYyK63UYdeuak2509jfe6bPNIChUmmRSQaeTz2vnPY4GQPEPtLq15htrguja++zC +q2WYRpMJAUwzTfo/eBJzZti71GSzhIlRjPDTSFo4Kz7pPNJJowORDZ/WYga7J84S +r9cL2WftJFTUuPzlzJLKHn8cwYlDaH7qGImNE9qKDTzc2/s3Hycp4CE3ZPFMmGqq +CwE3WOW140KMugRDEp89GmXXldbXkpgTEerh9k5o7RkJnZAqOCT8/uVImLsh8cyn +Pd1dYacp6L+Zl/Dvh6N1fEnb8+UWGxG7J64oyBY0EwRDnsuCkI8WZ5gAkqY+K9eB +YOeXMVE4OGnQ2ZvzywoVwHSTDj5j0ecH9VxUxrnyHfaOY45ghzUxApXK3iTxMygG +CHvY6rZDJi2ujckNUrqKELLWWE5WmGyQz7LWe/fSHUjszDckHHcUSAHG0twaOmh1 +T4lCUBYPXCDdcabkT0A6fLL1vPiRU7Q4NOOwwjkIxHRSt2FwZgFN6uDnKFFdMrjK +eP/FbIAdFwp06F0yOZi8/0DteEDqBn6tnxi/8ShKdWeF7IsAe2Hg00DLzGQFGwjx +/jrwdwes6fuBWGu6zEFTNboEYJOA8WULbY8LsXS7Yyz8ISu4RWtZlqcivvOiPEJh +JTwuhRC9r2zIrMBNwQCFYT/ycjcq9eJU+uLol68AzsQsTwdvyV7q+RLVi0WmRvC5 +vIfJHjYhmLNR/Ge+slNVT2R4hiImQQJnBFBVfIvkgLGXzWK6akUdvq4CXnaopfwX +WqhdAa10F0BGWpEvD766mr6/8PNI1XOe8zKltl7vPwJQyDwdX5nN3G53AyL+lpwY +It2O9DcchWQ97jloaHksWvwYfGd34fr2MaeYQ73y/OdriJX6EGDLM6alynt4mAsN +ptjC86+Pmr3r0rrB6LaSPpprBl29hWKStv5BNnbTwfWTcQINUn3tVxbonjAAuXXs +zT+Pwfi7aB5DUtqv5rNWcXpv8JBHJxz/ZN5eNNg4OrWPRp7cXX2QV4l3UKJ53aVO +vci/aKbC5m/G/6oiWRCgXmV5e1C/ZLdldiWApTAEQ4IRPji/FS06Z1pMYv/JKmTb +4FmnAL8QUMXOKWbuPfLR5B9SofcMXSioHM9zoIhwcaQyUaJb4Y3zoUzuccZ162Rs +MMQwSTQHHMJWb1WXexYIxcMx0BJ/3ufYKi1MbRdDuPtynotvlI8kXc2YMR8wC0CQ +bDh5RWho/U5p1305ZD0SizMiBm4J4amL/bqCuu6N08TUVg5+ZkV6ROs2Ki9pCrtF +oCakGa+llFKsqVCBdkiK8wC66bFGeV6y22BtNeZxMg/pS7ze18UFykpCA9BZKX7P +nvmmTNb7Yw6o/IPz5pqvcv0Un6q+wbfFj0MUB/krFBZqW9duSSRQPVls+nv2GQCk +qFFB3Sl8ZQ60oZmFKfzn5lRsUBUyiJ0Rgpi3ZcgWyQqtEQdDbIfqeKPT+kqWpKry +EU2ovpyq4L+un9fzVcXuQpT9dqF34kk31oRiC7XX9uLPcPqAiEN+pzt6lWQ4x9Sr +q3ia/J6KEB6b+nESIxOO7OmSvGipPrhV8HksNMuuxXVM0jqMOzeczzzTdVG2IJMS +VHCDZVctFrTT/VLNoZQ20GL0/6NEInALbsR1a57tlxHi1lGo+XcPWpPvzc5DhhUC +aVuLySNCXXnfJ1zVyoGLnyMlRWXWzqnBwgo8c6KQ4VRF5bk8AHqpHkn43nbSYI0X +1Dwk7Me0lPMA/BmqxuNhD0pnokJ/6yNE2wZ05Fy0IHlN4dRrU4jmMULWqNhNn382 +/hEndmmixwfih0rRwB8vDl2+4V+gcldGdEikEFl9ag2uCSDBs2f9CEoPxRZv5xib +dwxqJDwfye4j1V6wJz8a6uEEgjg/zW8El1eKxD4t3IYP0yWFEbPKnN//FwPilGR9 +A20CzzF1PBywxuu3GGRPTP0u6KWFB8DGxhq6asXs7i2jvD8DHAxaMb2QO0CSoWxc +hQoiZKYyYe+A6bLjmC3bb9u+iFWnpkuFovvX4Xp03tSb3J9NzbOB2WoXt9q0baNy +COPjQvVcdfWYGD7sUV7h/mHZbwzUN1L38RQpgH8L/GVraFo+iG5/r1W78qf3dvw9 +OwPvHwoBwaja4c8Hl4y/cNBdg5lXOT8qXRCwAn2iSuSphGk5BpGsUEyOi5JLsJkK +cE7WSA14tJ3zF1YuvqxbTJXiblLh7gnZOX9xgygHe8zkPCyaw4lbR9Y+HPV3xZGw +esF+w+F4qsoBYA8+Jpf8/wbdSWXrfDiQJoHklAfYNeISvPDUvpjJb1DMDHvJ2X0a +I3/9E8OixyE+qsAvmBKPJzzak8ogblCzBjaYYmk+QWes/jQthZSMI19yA4gsBI0y +RRlaWDxTlGShSGeFl8IZRdEv/9KSi2sJTRQaBrdQC84uKr7tUaydOgM7AZl0hssP +KH1nCabiapEUuCk1tpXgOMm2LFqEEJGAJMnbFB+KHANVFAyNXeWYKHfB6g6DWcCG +pc0Gi5TpoukqOmIFMDUJ42FJfXdh2tY91IsVN9vWXdljhKGM848H0vRqQnH3N5pz +blxVdZjVwQPdWoXHfuXnyzaW1Yjqms2EAhKKJFYDyNMWqe7MzXtdgDHH80HgSWVf +BO2DHzDE4KCXMEPOuh4wooKENEe2x5TjuUj9YxpQw4V2HfFDMAR+FwwlYiNbnTfq +BDjB0FhoAfgioVnZC21OPmebKsegpQcyMPs5Z2TqY+n5xojGv9iQOK0hvRQCTpVY +PVGEwvcjqX7F878BKkqtN/mfWgZQVipXm9y+TztrAVDcbIGJKyafXikhEX4tOiHI +poviDNNVjs9DpZD/nIOwCoqJOYbf3rFe0UEe2QhNiyZPTdWAyd4huss1PUKMhbSe +wBnytt5hKAwM0a0FcPZH4QoLz57Shxuko5hv2/raKdOxa1v8NKI+vhdx3ZLdtlDr +7MJg0sWqHFihjbD8Ctp9a6r+K06fRaV0obQ/PadQ/p+2sO5Ca+ojWmseHPeZz9vM +WZMEzx15AjT7scnZBNpj7b10CjCZd+zeSpZSQoHVHk7SBVTg6RGT/wvodhwcn/eP +u2+2GjiK3A9Y2+GIEqwakTU/Qb2h8PSv3JAX+8CFqcuIA1Cw+NTbHfZ3DxGocmIZ +L45gWjcw5DzJsT5a5LvTAsYGVvTsLBue4MmINnMhw8644grHxeO5OzkCcRv61xLJ +XQ+6eAbf6ZWh7hyCxADD0Yq2KxHxOUV7sseHYrmMFpVXS4mhsH05QrHjWTPyPxgV +i/TvgCynZ5b0Ch/WsmPBrp1rynyYOxHNAdkvi1XY4o87hWkHlQDgQLUfXBW3bVxM +LSWA5Nh5H5tsLvBty8bOSqqoD/9R6nWesE9rMMXeTMP/f4UEzeW+TpRPneKj/9WM +fDVobKw8kwNywf8w0Gb5k/3BEDhEVjKc/bt1g6WQcyWNiflQmfyMLMi+oXefHpJ3 +ek0645un5+dRXdgNFowr/2sM/jxhzOr9JT9ZP1LUVCKgEjXUOXlsKEPGf+5IddVA +KrfQ1saIxFsfCFja7ZZN9mdMdNB86LH1/ORRbIPoo8EQuBAn8coHjeQhJyxDFWRo +VnOm3ug44FbFC5rW1XcnhLEpHLSHZ1ZLacmypVVYHxDDpOe9podO0PJybqWVWo3Z +hJ4b2EFqOsSqS8gLq26vD4033Cw1xjPhN7+oMHvGs3pxgzdRUNRlSzUm8rbdL3hh +Lcs+rhnaT2GXy1jeHvRPY7X20wnhftY3lkhgq7gm03qRTGNJke/H45jYAB0HGmuB +8dRI6+TU9SLo4xZz8kPQcdIN6waxQ8F7Bmp9dQSTDtxw/cLyBUyT0w1V8uwcihAT +Sw0e34XkNxKbF8jXX/xWbEMo5FsBBFrZM0U3YX4rEmyD3bXnUHEr6vMU1qP3N90X +arNEX3q96MkG+aZqd+ZcatRN6y2ENYAgn4+Tqkfro+qmfTqXW31YEA7WlbyDWFVS +1c2InEU8CW/aB/8AafjGqSMWbogIjh3XOMTBsx6x8W5UkV5LhsF/9KAM1JJ66eWD +CtFxsUg7dUkheI6ouHdKgyZvRrrmx8n7ERpV+YJd40zzAwrG+YSQT/UcTHObPzoY +9HdY/wBO2TmwmeUMmYc54a4GaY4W3b80J9B6JE7eDUyaaFOppe1JdV55tFr/HTBr +bGcR+rp8ArmNyaTR1SkRM/c8htGhkFYS+FY+0E3Sc8a6e1QzxA5kGYYP4Tcnufrr +jyxIZL2Si8rzveWlljH4ULqwUD50YWO5jaqbBeYaZ1TYDnDkBgq2JWFMnjPWfKsP +WwwSYLlBpLhZHrMpPwfFWa8qkarY6BVJOkLTfsr6dWTz0UWg3Mmj8N18LYN56XnB +IeGF9f8ILRmrCOvFkpKqjrYIp7zaiABq5nqv468ghnUYapPbbwujf8l/2/0iURKu +6EbMmNkbv1hzK/g8BDNf28m0gmlJmLXdJGkFrG3LxQCUmwO1LcARBj9+370mw8ED +410IB5heUtGl1dduFN4G6qQwhMzSPvbdNs0wFL3B0q8zusr9PK/Tv4fGkPhqJP2i +9defRezsXhh/I1cKG9uf4bFBb7KI3XfNyAID6/8zKCh2KxJ0zUIMZFUVQJqYGyfy +j+EoVJsV0Xbb2C0suX4ASOWVIgGw0j6S/wITTLYaX4CwanRab2S7KvYskGo8T/uj +S5XLVcLl1TfLyOxxODdBrPqf2sXPhxsxTbQVHPotjHRaegCdyGCimth7shdQ/Br3 +Z9afvoD4UjOFNsKgQkFyIDXEFUGJCmXQLjT4DlVIl/fodrpDTwtvocRd4L/tzeeq +AuV2fZcoimWZnRePKaZAbz6pOpiN9hbKXJh9RMHgvtbMCTCP+keWLdYvLwFkamnX +y09wat+tdHLYWdJGN18Vwq4XrD4En/UDJd0ZsK/nIThzvRe3kn3ZKSMbcaaONp59 +BhzqRHb2RSIs+kFTRWryudCNl2mPsN3Tpd6C2LVincE5njEu14ZVKVtwo/xsPxsc +MotgNioEdce4DiMckjxkCgt9pQR6UQpoIep3KytmzT55Huo1gyFRf3EOvQ8+UBQD +ROBJFUhNj6dWOYN2L0CouaHOPxBMUiHxbiLLJo9+kNQlaLHMXIBSo84CnMHZnx5L +B9mob2kmxm3Vc+QJghfGHHadrJ0ec1a45qDpPnYdMw9KK28M649vdi47X1LC8dkH +AJciCH5aKRD4gFpSCGHJmJhMEfXPz3b0mUoWbnaen0yeFuZELHjJBKztFUyxUXZO +V122Su/21ZDcAbfsHreFc10fCNESxeKYus+UNpxL1R+o0K704x+CkazeRWGU6Je5 +FL5wjCxjcuLHdMootgNeGl0Dq4CNQuq4N4tnjQLFU8nIb32LHWeTEgtgZC9y5288 +yQXo3cqw9FjxQZmPtP4BycNGUevNOF1TZkhdiLW6F5GgIU2OjBoT0lYsT1D4BsJc +NUqWE//6qLS/I2G0GxEvp/oOJxL7RQFxGaoFJ+6ANLZYiteSIfoCN4PjSFTwYkCD +LAV7q++pdMRsN6TN1+cvTk76tgPUxJ2VQ3ikXDieZ9dEHK1VWAxMx/H9YtnwVorm +Y4xEeqDqAUS4as18N098bciXK/ujt+lIWuv8be7nvDxQ4FLRXvTUUvBjZN3HfMfR +H0cIR1NsDXr7lcX4eidMqEoZEaDDAYAtsiAHMWK4rvwAS3GWYkXqHywkmZ/W3czR +VzBKCxkXlizi+vwp87qk36bdhifGJFbjnE8/f4S4PNQ4BimAo8afKNMGCaipjyN2 +sJ8XiEgqWqiaxRhSX2+t6yhqRg7IG0MVDBtUzYiK3FE2nMbUH1BX76P6jjhUxhuk +qwmsZeRU7CGW1vnPjKxK9k25uVKC79ZVZiqfqTz2Eigr76Wx33qHEfw+Vz7ELjFj +TBnnwW9dpCPoeSBc5ad/4Okj+/7Bxd0CdCa+qWs8sJG/qWJkFV50F3kW5E3p6F1/ +lXL6NOPjGN+XfnjIrpphILxZg9nwj6EjudP4QX9SRw8GGDRalPnJrezSQk4WSGTw +-----END RSA PRIVATE KEY----- diff --git a/t/data/text-CR.file b/t/data/text-CR.file new file mode 100644 index 0000000..3d3fe1f --- /dev/null +++ b/t/data/text-CR.file @@ -0,0 +1 @@ +line1 line2 line3 line4 line5 line6 line7 line8 line9 line10 line11 line12 line13 line14 line15 line16 line17 line18 line19 \ No newline at end of file diff --git a/t/data/text-CRLF.file b/t/data/text-CRLF.file new file mode 100644 index 0000000..c4e4ba8 --- /dev/null +++ b/t/data/text-CRLF.file @@ -0,0 +1,19 @@ +line1 +line2 +line3 +line4 +line5 +line6 +line7 +line8 +line9 +line10 +line11 +line12 +line13 +line14 +line15 +line16 +line17 +line18 +line19 diff --git a/t/data/text-LF.file b/t/data/text-LF.file new file mode 100644 index 0000000..d68b4ff --- /dev/null +++ b/t/data/text-LF.file @@ -0,0 +1,19 @@ +line1 +line2 +line3 +line4 +line5 +line6 +line7 +line8 +line9 +line10 +line11 +line12 +line13 +line14 +line15 +line16 +line17 +line18 +line19 diff --git a/t/digest_blake2b_160.t b/t/digest_blake2b_160.t new file mode 100644 index 0000000..be06610 --- /dev/null +++ b/t/digest_blake2b_160.t @@ -0,0 +1,105 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::BLAKE2b_160 qw( blake2b_160 blake2b_160_hex blake2b_160_b64 blake2b_160_b64u blake2b_160_file blake2b_160_file_hex blake2b_160_file_b64 blake2b_160_file_b64u ); + +is( Crypt::Digest::hashsize('BLAKE2b_160'), 20, 'hashsize/1'); +is( Crypt::Digest->hashsize('BLAKE2b_160'), 20, 'hashsize/2'); +is( Crypt::Digest::BLAKE2b_160::hashsize, 20, 'hashsize/3'); +is( Crypt::Digest::BLAKE2b_160->hashsize, 20, 'hashsize/4'); +is( Crypt::Digest->new('BLAKE2b_160')->hashsize, 20, 'hashsize/5'); +is( Crypt::Digest::BLAKE2b_160->new->hashsize, 20, 'hashsize/6'); + + +is( blake2b_160(""), pack("H*","3345524abf6bbe1809449224b5972c41790b6cf2"), 'blake2b_160 (raw/1)'); +is( blake2b_160_hex(""), "3345524abf6bbe1809449224b5972c41790b6cf2", 'blake2b_160 (hex/1)'); +is( blake2b_160_b64(""), "M0VSSr9rvhgJRJIktZcsQXkLbPI=", 'blake2b_160 (base64/1)'); +is( digest_data('BLAKE2b_160', ""), pack("H*","3345524abf6bbe1809449224b5972c41790b6cf2"), 'blake2b_160 (digest_data_raw/1)'); +is( digest_data_hex('BLAKE2b_160', ""), "3345524abf6bbe1809449224b5972c41790b6cf2", 'blake2b_160 (digest_data_hex/1)'); +is( digest_data_b64('BLAKE2b_160', ""), "M0VSSr9rvhgJRJIktZcsQXkLbPI=", 'blake2b_160 (digest_data_b64/1)'); +is( digest_data_b64u('BLAKE2b_160', ""), "M0VSSr9rvhgJRJIktZcsQXkLbPI", 'blake2b_160 (digest_data_b64u/1)'); +is( Crypt::Digest::BLAKE2b_160->new->add("")->hexdigest, "3345524abf6bbe1809449224b5972c41790b6cf2", 'blake2b_160 (OO/1)'); + +is( blake2b_160("123"), pack("H*","c018e33a9cf2fea6a3bb41c4c079ea4fbc901d28"), 'blake2b_160 (raw/2)'); +is( blake2b_160_hex("123"), "c018e33a9cf2fea6a3bb41c4c079ea4fbc901d28", 'blake2b_160 (hex/2)'); +is( blake2b_160_b64("123"), "wBjjOpzy/qaju0HEwHnqT7yQHSg=", 'blake2b_160 (base64/2)'); +is( digest_data('BLAKE2b_160', "123"), pack("H*","c018e33a9cf2fea6a3bb41c4c079ea4fbc901d28"), 'blake2b_160 (digest_data_raw/2)'); +is( digest_data_hex('BLAKE2b_160', "123"), "c018e33a9cf2fea6a3bb41c4c079ea4fbc901d28", 'blake2b_160 (digest_data_hex/2)'); +is( digest_data_b64('BLAKE2b_160', "123"), "wBjjOpzy/qaju0HEwHnqT7yQHSg=", 'blake2b_160 (digest_data_b64/2)'); +is( digest_data_b64u('BLAKE2b_160', "123"), "wBjjOpzy_qaju0HEwHnqT7yQHSg", 'blake2b_160 (digest_data_b64u/2)'); +is( Crypt::Digest::BLAKE2b_160->new->add("123")->hexdigest, "c018e33a9cf2fea6a3bb41c4c079ea4fbc901d28", 'blake2b_160 (OO/2)'); + +is( blake2b_160("test\0test\0test\n"), pack("H*","1ccf96de0b2b8d65c6b5be215afc91c1c0526beb"), 'blake2b_160 (raw/3)'); +is( blake2b_160_hex("test\0test\0test\n"), "1ccf96de0b2b8d65c6b5be215afc91c1c0526beb", 'blake2b_160 (hex/3)'); +is( blake2b_160_b64("test\0test\0test\n"), "HM+W3gsrjWXGtb4hWvyRwcBSa+s=", 'blake2b_160 (base64/3)'); +is( digest_data('BLAKE2b_160', "test\0test\0test\n"), pack("H*","1ccf96de0b2b8d65c6b5be215afc91c1c0526beb"), 'blake2b_160 (digest_data_raw/3)'); +is( digest_data_hex('BLAKE2b_160', "test\0test\0test\n"), "1ccf96de0b2b8d65c6b5be215afc91c1c0526beb", 'blake2b_160 (digest_data_hex/3)'); +is( digest_data_b64('BLAKE2b_160', "test\0test\0test\n"), "HM+W3gsrjWXGtb4hWvyRwcBSa+s=", 'blake2b_160 (digest_data_b64/3)'); +is( digest_data_b64u('BLAKE2b_160', "test\0test\0test\n"), "HM-W3gsrjWXGtb4hWvyRwcBSa-s", 'blake2b_160 (digest_data_b64u/3)'); +is( Crypt::Digest::BLAKE2b_160->new->add("test\0test\0test\n")->hexdigest, "1ccf96de0b2b8d65c6b5be215afc91c1c0526beb", 'blake2b_160 (OO/3)'); + + +is( blake2b_160_file('t/data/binary-test.file'), pack("H*","f3ccc92130e0028ebca9a3a50efb2a15578d1b64"), 'blake2b_160 (raw/file/1)'); +is( blake2b_160_file_hex('t/data/binary-test.file'), "f3ccc92130e0028ebca9a3a50efb2a15578d1b64", 'blake2b_160 (hex/file/1)'); +is( blake2b_160_file_b64('t/data/binary-test.file'), "88zJITDgAo68qaOlDvsqFVeNG2Q=", 'blake2b_160 (base64/file/1)'); +is( digest_file('BLAKE2b_160', 't/data/binary-test.file'), pack("H*","f3ccc92130e0028ebca9a3a50efb2a15578d1b64"), 'blake2b_160 (digest_file_raw/file/1)'); +is( digest_file_hex('BLAKE2b_160', 't/data/binary-test.file'), "f3ccc92130e0028ebca9a3a50efb2a15578d1b64", 'blake2b_160 (digest_file_hex/file/1)'); +is( digest_file_b64('BLAKE2b_160', 't/data/binary-test.file'), "88zJITDgAo68qaOlDvsqFVeNG2Q=", 'blake2b_160 (digest_file_b64/file/1)'); +is( digest_file_b64u('BLAKE2b_160', 't/data/binary-test.file'), "88zJITDgAo68qaOlDvsqFVeNG2Q", 'blake2b_160 (digest_file_b64u/file/1)'); +is( Crypt::Digest::BLAKE2b_160->new->addfile('t/data/binary-test.file')->hexdigest, "f3ccc92130e0028ebca9a3a50efb2a15578d1b64", 'blake2b_160 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2b_160->new->addfile($fh)->hexdigest, "f3ccc92130e0028ebca9a3a50efb2a15578d1b64", 'blake2b_160 (OO/filehandle/1)'); + close($fh); +} + +is( blake2b_160_file('t/data/text-CR.file'), pack("H*","206fb81fb94a6738e2829111fbd3deabc34173a3"), 'blake2b_160 (raw/file/2)'); +is( blake2b_160_file_hex('t/data/text-CR.file'), "206fb81fb94a6738e2829111fbd3deabc34173a3", 'blake2b_160 (hex/file/2)'); +is( blake2b_160_file_b64('t/data/text-CR.file'), "IG+4H7lKZzjigpER+9Peq8NBc6M=", 'blake2b_160 (base64/file/2)'); +is( digest_file('BLAKE2b_160', 't/data/text-CR.file'), pack("H*","206fb81fb94a6738e2829111fbd3deabc34173a3"), 'blake2b_160 (digest_file_raw/file/2)'); +is( digest_file_hex('BLAKE2b_160', 't/data/text-CR.file'), "206fb81fb94a6738e2829111fbd3deabc34173a3", 'blake2b_160 (digest_file_hex/file/2)'); +is( digest_file_b64('BLAKE2b_160', 't/data/text-CR.file'), "IG+4H7lKZzjigpER+9Peq8NBc6M=", 'blake2b_160 (digest_file_b64/file/2)'); +is( digest_file_b64u('BLAKE2b_160', 't/data/text-CR.file'), "IG-4H7lKZzjigpER-9Peq8NBc6M", 'blake2b_160 (digest_file_b64u/file/2)'); +is( Crypt::Digest::BLAKE2b_160->new->addfile('t/data/text-CR.file')->hexdigest, "206fb81fb94a6738e2829111fbd3deabc34173a3", 'blake2b_160 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2b_160->new->addfile($fh)->hexdigest, "206fb81fb94a6738e2829111fbd3deabc34173a3", 'blake2b_160 (OO/filehandle/2)'); + close($fh); +} + +is( blake2b_160_file('t/data/text-CRLF.file'), pack("H*","a5e956dde7e949f6467d21bf58f7b26891877805"), 'blake2b_160 (raw/file/3)'); +is( blake2b_160_file_hex('t/data/text-CRLF.file'), "a5e956dde7e949f6467d21bf58f7b26891877805", 'blake2b_160 (hex/file/3)'); +is( blake2b_160_file_b64('t/data/text-CRLF.file'), "pelW3efpSfZGfSG/WPeyaJGHeAU=", 'blake2b_160 (base64/file/3)'); +is( digest_file('BLAKE2b_160', 't/data/text-CRLF.file'), pack("H*","a5e956dde7e949f6467d21bf58f7b26891877805"), 'blake2b_160 (digest_file_raw/file/3)'); +is( digest_file_hex('BLAKE2b_160', 't/data/text-CRLF.file'), "a5e956dde7e949f6467d21bf58f7b26891877805", 'blake2b_160 (digest_file_hex/file/3)'); +is( digest_file_b64('BLAKE2b_160', 't/data/text-CRLF.file'), "pelW3efpSfZGfSG/WPeyaJGHeAU=", 'blake2b_160 (digest_file_b64/file/3)'); +is( digest_file_b64u('BLAKE2b_160', 't/data/text-CRLF.file'), "pelW3efpSfZGfSG_WPeyaJGHeAU", 'blake2b_160 (digest_file_b64u/file/3)'); +is( Crypt::Digest::BLAKE2b_160->new->addfile('t/data/text-CRLF.file')->hexdigest, "a5e956dde7e949f6467d21bf58f7b26891877805", 'blake2b_160 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2b_160->new->addfile($fh)->hexdigest, "a5e956dde7e949f6467d21bf58f7b26891877805", 'blake2b_160 (OO/filehandle/3)'); + close($fh); +} + +is( blake2b_160_file('t/data/text-LF.file'), pack("H*","023cb935a71ee3bf04d1b8b9b7a1d93838826f9a"), 'blake2b_160 (raw/file/4)'); +is( blake2b_160_file_hex('t/data/text-LF.file'), "023cb935a71ee3bf04d1b8b9b7a1d93838826f9a", 'blake2b_160 (hex/file/4)'); +is( blake2b_160_file_b64('t/data/text-LF.file'), "Ajy5Nace478E0bi5t6HZODiCb5o=", 'blake2b_160 (base64/file/4)'); +is( digest_file('BLAKE2b_160', 't/data/text-LF.file'), pack("H*","023cb935a71ee3bf04d1b8b9b7a1d93838826f9a"), 'blake2b_160 (digest_file_raw/file/4)'); +is( digest_file_hex('BLAKE2b_160', 't/data/text-LF.file'), "023cb935a71ee3bf04d1b8b9b7a1d93838826f9a", 'blake2b_160 (digest_file_hex/file/4)'); +is( digest_file_b64('BLAKE2b_160', 't/data/text-LF.file'), "Ajy5Nace478E0bi5t6HZODiCb5o=", 'blake2b_160 (digest_file_b64/file/4)'); +is( digest_file_b64u('BLAKE2b_160', 't/data/text-LF.file'), "Ajy5Nace478E0bi5t6HZODiCb5o", 'blake2b_160 (digest_file_b64u/file/4)'); +is( Crypt::Digest::BLAKE2b_160->new->addfile('t/data/text-LF.file')->hexdigest, "023cb935a71ee3bf04d1b8b9b7a1d93838826f9a", 'blake2b_160 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2b_160->new->addfile($fh)->hexdigest, "023cb935a71ee3bf04d1b8b9b7a1d93838826f9a", 'blake2b_160 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_blake2b_256.t b/t/digest_blake2b_256.t new file mode 100644 index 0000000..1b71737 --- /dev/null +++ b/t/digest_blake2b_256.t @@ -0,0 +1,105 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::BLAKE2b_256 qw( blake2b_256 blake2b_256_hex blake2b_256_b64 blake2b_256_b64u blake2b_256_file blake2b_256_file_hex blake2b_256_file_b64 blake2b_256_file_b64u ); + +is( Crypt::Digest::hashsize('BLAKE2b_256'), 32, 'hashsize/1'); +is( Crypt::Digest->hashsize('BLAKE2b_256'), 32, 'hashsize/2'); +is( Crypt::Digest::BLAKE2b_256::hashsize, 32, 'hashsize/3'); +is( Crypt::Digest::BLAKE2b_256->hashsize, 32, 'hashsize/4'); +is( Crypt::Digest->new('BLAKE2b_256')->hashsize, 32, 'hashsize/5'); +is( Crypt::Digest::BLAKE2b_256->new->hashsize, 32, 'hashsize/6'); + + +is( blake2b_256(""), pack("H*","0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8"), 'blake2b_256 (raw/1)'); +is( blake2b_256_hex(""), "0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8", 'blake2b_256 (hex/1)'); +is( blake2b_256_b64(""), "DldRwCblQ7Loqy6wYJnaodHl30d3j3eH+qtFzfEv46g=", 'blake2b_256 (base64/1)'); +is( digest_data('BLAKE2b_256', ""), pack("H*","0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8"), 'blake2b_256 (digest_data_raw/1)'); +is( digest_data_hex('BLAKE2b_256', ""), "0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8", 'blake2b_256 (digest_data_hex/1)'); +is( digest_data_b64('BLAKE2b_256', ""), "DldRwCblQ7Loqy6wYJnaodHl30d3j3eH+qtFzfEv46g=", 'blake2b_256 (digest_data_b64/1)'); +is( digest_data_b64u('BLAKE2b_256', ""), "DldRwCblQ7Loqy6wYJnaodHl30d3j3eH-qtFzfEv46g", 'blake2b_256 (digest_data_b64u/1)'); +is( Crypt::Digest::BLAKE2b_256->new->add("")->hexdigest, "0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8", 'blake2b_256 (OO/1)'); + +is( blake2b_256("123"), pack("H*","f5d67bae73b0e10d0dfd3043b3f4f100ada014c5c37bd5ce97813b13f5ab2bcf"), 'blake2b_256 (raw/2)'); +is( blake2b_256_hex("123"), "f5d67bae73b0e10d0dfd3043b3f4f100ada014c5c37bd5ce97813b13f5ab2bcf", 'blake2b_256 (hex/2)'); +is( blake2b_256_b64("123"), "9dZ7rnOw4Q0N/TBDs/TxAK2gFMXDe9XOl4E7E/WrK88=", 'blake2b_256 (base64/2)'); +is( digest_data('BLAKE2b_256', "123"), pack("H*","f5d67bae73b0e10d0dfd3043b3f4f100ada014c5c37bd5ce97813b13f5ab2bcf"), 'blake2b_256 (digest_data_raw/2)'); +is( digest_data_hex('BLAKE2b_256', "123"), "f5d67bae73b0e10d0dfd3043b3f4f100ada014c5c37bd5ce97813b13f5ab2bcf", 'blake2b_256 (digest_data_hex/2)'); +is( digest_data_b64('BLAKE2b_256', "123"), "9dZ7rnOw4Q0N/TBDs/TxAK2gFMXDe9XOl4E7E/WrK88=", 'blake2b_256 (digest_data_b64/2)'); +is( digest_data_b64u('BLAKE2b_256', "123"), "9dZ7rnOw4Q0N_TBDs_TxAK2gFMXDe9XOl4E7E_WrK88", 'blake2b_256 (digest_data_b64u/2)'); +is( Crypt::Digest::BLAKE2b_256->new->add("123")->hexdigest, "f5d67bae73b0e10d0dfd3043b3f4f100ada014c5c37bd5ce97813b13f5ab2bcf", 'blake2b_256 (OO/2)'); + +is( blake2b_256("test\0test\0test\n"), pack("H*","22d4e56794002cce9ecc0b1c2a67d41a514024c76a626ba570a5ec0d6c572ee3"), 'blake2b_256 (raw/3)'); +is( blake2b_256_hex("test\0test\0test\n"), "22d4e56794002cce9ecc0b1c2a67d41a514024c76a626ba570a5ec0d6c572ee3", 'blake2b_256 (hex/3)'); +is( blake2b_256_b64("test\0test\0test\n"), "ItTlZ5QALM6ezAscKmfUGlFAJMdqYmulcKXsDWxXLuM=", 'blake2b_256 (base64/3)'); +is( digest_data('BLAKE2b_256', "test\0test\0test\n"), pack("H*","22d4e56794002cce9ecc0b1c2a67d41a514024c76a626ba570a5ec0d6c572ee3"), 'blake2b_256 (digest_data_raw/3)'); +is( digest_data_hex('BLAKE2b_256', "test\0test\0test\n"), "22d4e56794002cce9ecc0b1c2a67d41a514024c76a626ba570a5ec0d6c572ee3", 'blake2b_256 (digest_data_hex/3)'); +is( digest_data_b64('BLAKE2b_256', "test\0test\0test\n"), "ItTlZ5QALM6ezAscKmfUGlFAJMdqYmulcKXsDWxXLuM=", 'blake2b_256 (digest_data_b64/3)'); +is( digest_data_b64u('BLAKE2b_256', "test\0test\0test\n"), "ItTlZ5QALM6ezAscKmfUGlFAJMdqYmulcKXsDWxXLuM", 'blake2b_256 (digest_data_b64u/3)'); +is( Crypt::Digest::BLAKE2b_256->new->add("test\0test\0test\n")->hexdigest, "22d4e56794002cce9ecc0b1c2a67d41a514024c76a626ba570a5ec0d6c572ee3", 'blake2b_256 (OO/3)'); + + +is( blake2b_256_file('t/data/binary-test.file'), pack("H*","34cb287b359b0be0375ab6cfeefac9f87bf5770117cca950a5f2d66e45dbc77b"), 'blake2b_256 (raw/file/1)'); +is( blake2b_256_file_hex('t/data/binary-test.file'), "34cb287b359b0be0375ab6cfeefac9f87bf5770117cca950a5f2d66e45dbc77b", 'blake2b_256 (hex/file/1)'); +is( blake2b_256_file_b64('t/data/binary-test.file'), "NMsoezWbC+A3WrbP7vrJ+Hv1dwEXzKlQpfLWbkXbx3s=", 'blake2b_256 (base64/file/1)'); +is( digest_file('BLAKE2b_256', 't/data/binary-test.file'), pack("H*","34cb287b359b0be0375ab6cfeefac9f87bf5770117cca950a5f2d66e45dbc77b"), 'blake2b_256 (digest_file_raw/file/1)'); +is( digest_file_hex('BLAKE2b_256', 't/data/binary-test.file'), "34cb287b359b0be0375ab6cfeefac9f87bf5770117cca950a5f2d66e45dbc77b", 'blake2b_256 (digest_file_hex/file/1)'); +is( digest_file_b64('BLAKE2b_256', 't/data/binary-test.file'), "NMsoezWbC+A3WrbP7vrJ+Hv1dwEXzKlQpfLWbkXbx3s=", 'blake2b_256 (digest_file_b64/file/1)'); +is( digest_file_b64u('BLAKE2b_256', 't/data/binary-test.file'), "NMsoezWbC-A3WrbP7vrJ-Hv1dwEXzKlQpfLWbkXbx3s", 'blake2b_256 (digest_file_b64u/file/1)'); +is( Crypt::Digest::BLAKE2b_256->new->addfile('t/data/binary-test.file')->hexdigest, "34cb287b359b0be0375ab6cfeefac9f87bf5770117cca950a5f2d66e45dbc77b", 'blake2b_256 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2b_256->new->addfile($fh)->hexdigest, "34cb287b359b0be0375ab6cfeefac9f87bf5770117cca950a5f2d66e45dbc77b", 'blake2b_256 (OO/filehandle/1)'); + close($fh); +} + +is( blake2b_256_file('t/data/text-CR.file'), pack("H*","8dde4e0ca7633499c0913d7d5c6d3524307c4ee381931f4cc2c3d7030ab97ab3"), 'blake2b_256 (raw/file/2)'); +is( blake2b_256_file_hex('t/data/text-CR.file'), "8dde4e0ca7633499c0913d7d5c6d3524307c4ee381931f4cc2c3d7030ab97ab3", 'blake2b_256 (hex/file/2)'); +is( blake2b_256_file_b64('t/data/text-CR.file'), "jd5ODKdjNJnAkT19XG01JDB8TuOBkx9MwsPXAwq5erM=", 'blake2b_256 (base64/file/2)'); +is( digest_file('BLAKE2b_256', 't/data/text-CR.file'), pack("H*","8dde4e0ca7633499c0913d7d5c6d3524307c4ee381931f4cc2c3d7030ab97ab3"), 'blake2b_256 (digest_file_raw/file/2)'); +is( digest_file_hex('BLAKE2b_256', 't/data/text-CR.file'), "8dde4e0ca7633499c0913d7d5c6d3524307c4ee381931f4cc2c3d7030ab97ab3", 'blake2b_256 (digest_file_hex/file/2)'); +is( digest_file_b64('BLAKE2b_256', 't/data/text-CR.file'), "jd5ODKdjNJnAkT19XG01JDB8TuOBkx9MwsPXAwq5erM=", 'blake2b_256 (digest_file_b64/file/2)'); +is( digest_file_b64u('BLAKE2b_256', 't/data/text-CR.file'), "jd5ODKdjNJnAkT19XG01JDB8TuOBkx9MwsPXAwq5erM", 'blake2b_256 (digest_file_b64u/file/2)'); +is( Crypt::Digest::BLAKE2b_256->new->addfile('t/data/text-CR.file')->hexdigest, "8dde4e0ca7633499c0913d7d5c6d3524307c4ee381931f4cc2c3d7030ab97ab3", 'blake2b_256 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2b_256->new->addfile($fh)->hexdigest, "8dde4e0ca7633499c0913d7d5c6d3524307c4ee381931f4cc2c3d7030ab97ab3", 'blake2b_256 (OO/filehandle/2)'); + close($fh); +} + +is( blake2b_256_file('t/data/text-CRLF.file'), pack("H*","3e6dcddb9dbbf1ea39d55c980da01971c6b1bd2076e0bbc8c95ca49836926a22"), 'blake2b_256 (raw/file/3)'); +is( blake2b_256_file_hex('t/data/text-CRLF.file'), "3e6dcddb9dbbf1ea39d55c980da01971c6b1bd2076e0bbc8c95ca49836926a22", 'blake2b_256 (hex/file/3)'); +is( blake2b_256_file_b64('t/data/text-CRLF.file'), "Pm3N25278eo51VyYDaAZccaxvSB24LvIyVykmDaSaiI=", 'blake2b_256 (base64/file/3)'); +is( digest_file('BLAKE2b_256', 't/data/text-CRLF.file'), pack("H*","3e6dcddb9dbbf1ea39d55c980da01971c6b1bd2076e0bbc8c95ca49836926a22"), 'blake2b_256 (digest_file_raw/file/3)'); +is( digest_file_hex('BLAKE2b_256', 't/data/text-CRLF.file'), "3e6dcddb9dbbf1ea39d55c980da01971c6b1bd2076e0bbc8c95ca49836926a22", 'blake2b_256 (digest_file_hex/file/3)'); +is( digest_file_b64('BLAKE2b_256', 't/data/text-CRLF.file'), "Pm3N25278eo51VyYDaAZccaxvSB24LvIyVykmDaSaiI=", 'blake2b_256 (digest_file_b64/file/3)'); +is( digest_file_b64u('BLAKE2b_256', 't/data/text-CRLF.file'), "Pm3N25278eo51VyYDaAZccaxvSB24LvIyVykmDaSaiI", 'blake2b_256 (digest_file_b64u/file/3)'); +is( Crypt::Digest::BLAKE2b_256->new->addfile('t/data/text-CRLF.file')->hexdigest, "3e6dcddb9dbbf1ea39d55c980da01971c6b1bd2076e0bbc8c95ca49836926a22", 'blake2b_256 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2b_256->new->addfile($fh)->hexdigest, "3e6dcddb9dbbf1ea39d55c980da01971c6b1bd2076e0bbc8c95ca49836926a22", 'blake2b_256 (OO/filehandle/3)'); + close($fh); +} + +is( blake2b_256_file('t/data/text-LF.file'), pack("H*","2f103840304609a16bca2c734e3c604b723ff5164579b6a80825f838d7e0c67e"), 'blake2b_256 (raw/file/4)'); +is( blake2b_256_file_hex('t/data/text-LF.file'), "2f103840304609a16bca2c734e3c604b723ff5164579b6a80825f838d7e0c67e", 'blake2b_256 (hex/file/4)'); +is( blake2b_256_file_b64('t/data/text-LF.file'), "LxA4QDBGCaFryixzTjxgS3I/9RZFebaoCCX4ONfgxn4=", 'blake2b_256 (base64/file/4)'); +is( digest_file('BLAKE2b_256', 't/data/text-LF.file'), pack("H*","2f103840304609a16bca2c734e3c604b723ff5164579b6a80825f838d7e0c67e"), 'blake2b_256 (digest_file_raw/file/4)'); +is( digest_file_hex('BLAKE2b_256', 't/data/text-LF.file'), "2f103840304609a16bca2c734e3c604b723ff5164579b6a80825f838d7e0c67e", 'blake2b_256 (digest_file_hex/file/4)'); +is( digest_file_b64('BLAKE2b_256', 't/data/text-LF.file'), "LxA4QDBGCaFryixzTjxgS3I/9RZFebaoCCX4ONfgxn4=", 'blake2b_256 (digest_file_b64/file/4)'); +is( digest_file_b64u('BLAKE2b_256', 't/data/text-LF.file'), "LxA4QDBGCaFryixzTjxgS3I_9RZFebaoCCX4ONfgxn4", 'blake2b_256 (digest_file_b64u/file/4)'); +is( Crypt::Digest::BLAKE2b_256->new->addfile('t/data/text-LF.file')->hexdigest, "2f103840304609a16bca2c734e3c604b723ff5164579b6a80825f838d7e0c67e", 'blake2b_256 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2b_256->new->addfile($fh)->hexdigest, "2f103840304609a16bca2c734e3c604b723ff5164579b6a80825f838d7e0c67e", 'blake2b_256 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_blake2b_384.t b/t/digest_blake2b_384.t new file mode 100644 index 0000000..1ed548b --- /dev/null +++ b/t/digest_blake2b_384.t @@ -0,0 +1,105 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::BLAKE2b_384 qw( blake2b_384 blake2b_384_hex blake2b_384_b64 blake2b_384_b64u blake2b_384_file blake2b_384_file_hex blake2b_384_file_b64 blake2b_384_file_b64u ); + +is( Crypt::Digest::hashsize('BLAKE2b_384'), 48, 'hashsize/1'); +is( Crypt::Digest->hashsize('BLAKE2b_384'), 48, 'hashsize/2'); +is( Crypt::Digest::BLAKE2b_384::hashsize, 48, 'hashsize/3'); +is( Crypt::Digest::BLAKE2b_384->hashsize, 48, 'hashsize/4'); +is( Crypt::Digest->new('BLAKE2b_384')->hashsize, 48, 'hashsize/5'); +is( Crypt::Digest::BLAKE2b_384->new->hashsize, 48, 'hashsize/6'); + + +is( blake2b_384(""), pack("H*","b32811423377f52d7862286ee1a72ee540524380fda1724a6f25d7978c6fd3244a6caf0498812673c5e05ef583825100"), 'blake2b_384 (raw/1)'); +is( blake2b_384_hex(""), "b32811423377f52d7862286ee1a72ee540524380fda1724a6f25d7978c6fd3244a6caf0498812673c5e05ef583825100", 'blake2b_384 (hex/1)'); +is( blake2b_384_b64(""), "sygRQjN39S14Yihu4acu5UBSQ4D9oXJKbyXXl4xv0yRKbK8EmIEmc8XgXvWDglEA", 'blake2b_384 (base64/1)'); +is( digest_data('BLAKE2b_384', ""), pack("H*","b32811423377f52d7862286ee1a72ee540524380fda1724a6f25d7978c6fd3244a6caf0498812673c5e05ef583825100"), 'blake2b_384 (digest_data_raw/1)'); +is( digest_data_hex('BLAKE2b_384', ""), "b32811423377f52d7862286ee1a72ee540524380fda1724a6f25d7978c6fd3244a6caf0498812673c5e05ef583825100", 'blake2b_384 (digest_data_hex/1)'); +is( digest_data_b64('BLAKE2b_384', ""), "sygRQjN39S14Yihu4acu5UBSQ4D9oXJKbyXXl4xv0yRKbK8EmIEmc8XgXvWDglEA", 'blake2b_384 (digest_data_b64/1)'); +is( digest_data_b64u('BLAKE2b_384', ""), "sygRQjN39S14Yihu4acu5UBSQ4D9oXJKbyXXl4xv0yRKbK8EmIEmc8XgXvWDglEA", 'blake2b_384 (digest_data_b64u/1)'); +is( Crypt::Digest::BLAKE2b_384->new->add("")->hexdigest, "b32811423377f52d7862286ee1a72ee540524380fda1724a6f25d7978c6fd3244a6caf0498812673c5e05ef583825100", 'blake2b_384 (OO/1)'); + +is( blake2b_384("123"), pack("H*","50af7f5deca52771b287704c66e79479adc0ec91a380279ab05627eb4c050f13494beb28dfc739a2a1a7194f9d1c30b0"), 'blake2b_384 (raw/2)'); +is( blake2b_384_hex("123"), "50af7f5deca52771b287704c66e79479adc0ec91a380279ab05627eb4c050f13494beb28dfc739a2a1a7194f9d1c30b0", 'blake2b_384 (hex/2)'); +is( blake2b_384_b64("123"), "UK9/XeylJ3Gyh3BMZueUea3A7JGjgCeasFYn60wFDxNJS+so38c5oqGnGU+dHDCw", 'blake2b_384 (base64/2)'); +is( digest_data('BLAKE2b_384', "123"), pack("H*","50af7f5deca52771b287704c66e79479adc0ec91a380279ab05627eb4c050f13494beb28dfc739a2a1a7194f9d1c30b0"), 'blake2b_384 (digest_data_raw/2)'); +is( digest_data_hex('BLAKE2b_384', "123"), "50af7f5deca52771b287704c66e79479adc0ec91a380279ab05627eb4c050f13494beb28dfc739a2a1a7194f9d1c30b0", 'blake2b_384 (digest_data_hex/2)'); +is( digest_data_b64('BLAKE2b_384', "123"), "UK9/XeylJ3Gyh3BMZueUea3A7JGjgCeasFYn60wFDxNJS+so38c5oqGnGU+dHDCw", 'blake2b_384 (digest_data_b64/2)'); +is( digest_data_b64u('BLAKE2b_384', "123"), "UK9_XeylJ3Gyh3BMZueUea3A7JGjgCeasFYn60wFDxNJS-so38c5oqGnGU-dHDCw", 'blake2b_384 (digest_data_b64u/2)'); +is( Crypt::Digest::BLAKE2b_384->new->add("123")->hexdigest, "50af7f5deca52771b287704c66e79479adc0ec91a380279ab05627eb4c050f13494beb28dfc739a2a1a7194f9d1c30b0", 'blake2b_384 (OO/2)'); + +is( blake2b_384("test\0test\0test\n"), pack("H*","42788332987449000fd8deeec86645ed2c2986fc2338f3defdb4dd48681ad5eb6a92823516a74093288673922f19c669"), 'blake2b_384 (raw/3)'); +is( blake2b_384_hex("test\0test\0test\n"), "42788332987449000fd8deeec86645ed2c2986fc2338f3defdb4dd48681ad5eb6a92823516a74093288673922f19c669", 'blake2b_384 (hex/3)'); +is( blake2b_384_b64("test\0test\0test\n"), "QniDMph0SQAP2N7uyGZF7SwphvwjOPPe/bTdSGga1etqkoI1FqdAkyiGc5IvGcZp", 'blake2b_384 (base64/3)'); +is( digest_data('BLAKE2b_384', "test\0test\0test\n"), pack("H*","42788332987449000fd8deeec86645ed2c2986fc2338f3defdb4dd48681ad5eb6a92823516a74093288673922f19c669"), 'blake2b_384 (digest_data_raw/3)'); +is( digest_data_hex('BLAKE2b_384', "test\0test\0test\n"), "42788332987449000fd8deeec86645ed2c2986fc2338f3defdb4dd48681ad5eb6a92823516a74093288673922f19c669", 'blake2b_384 (digest_data_hex/3)'); +is( digest_data_b64('BLAKE2b_384', "test\0test\0test\n"), "QniDMph0SQAP2N7uyGZF7SwphvwjOPPe/bTdSGga1etqkoI1FqdAkyiGc5IvGcZp", 'blake2b_384 (digest_data_b64/3)'); +is( digest_data_b64u('BLAKE2b_384', "test\0test\0test\n"), "QniDMph0SQAP2N7uyGZF7SwphvwjOPPe_bTdSGga1etqkoI1FqdAkyiGc5IvGcZp", 'blake2b_384 (digest_data_b64u/3)'); +is( Crypt::Digest::BLAKE2b_384->new->add("test\0test\0test\n")->hexdigest, "42788332987449000fd8deeec86645ed2c2986fc2338f3defdb4dd48681ad5eb6a92823516a74093288673922f19c669", 'blake2b_384 (OO/3)'); + + +is( blake2b_384_file('t/data/binary-test.file'), pack("H*","8514556a162fbc197d094cb84ebf3a7f65137bcc88e4804631ac32128661f70457407300500cd527e13b30df9a167239"), 'blake2b_384 (raw/file/1)'); +is( blake2b_384_file_hex('t/data/binary-test.file'), "8514556a162fbc197d094cb84ebf3a7f65137bcc88e4804631ac32128661f70457407300500cd527e13b30df9a167239", 'blake2b_384 (hex/file/1)'); +is( blake2b_384_file_b64('t/data/binary-test.file'), "hRRVahYvvBl9CUy4Tr86f2UTe8yI5IBGMawyEoZh9wRXQHMAUAzVJ+E7MN+aFnI5", 'blake2b_384 (base64/file/1)'); +is( digest_file('BLAKE2b_384', 't/data/binary-test.file'), pack("H*","8514556a162fbc197d094cb84ebf3a7f65137bcc88e4804631ac32128661f70457407300500cd527e13b30df9a167239"), 'blake2b_384 (digest_file_raw/file/1)'); +is( digest_file_hex('BLAKE2b_384', 't/data/binary-test.file'), "8514556a162fbc197d094cb84ebf3a7f65137bcc88e4804631ac32128661f70457407300500cd527e13b30df9a167239", 'blake2b_384 (digest_file_hex/file/1)'); +is( digest_file_b64('BLAKE2b_384', 't/data/binary-test.file'), "hRRVahYvvBl9CUy4Tr86f2UTe8yI5IBGMawyEoZh9wRXQHMAUAzVJ+E7MN+aFnI5", 'blake2b_384 (digest_file_b64/file/1)'); +is( digest_file_b64u('BLAKE2b_384', 't/data/binary-test.file'), "hRRVahYvvBl9CUy4Tr86f2UTe8yI5IBGMawyEoZh9wRXQHMAUAzVJ-E7MN-aFnI5", 'blake2b_384 (digest_file_b64u/file/1)'); +is( Crypt::Digest::BLAKE2b_384->new->addfile('t/data/binary-test.file')->hexdigest, "8514556a162fbc197d094cb84ebf3a7f65137bcc88e4804631ac32128661f70457407300500cd527e13b30df9a167239", 'blake2b_384 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2b_384->new->addfile($fh)->hexdigest, "8514556a162fbc197d094cb84ebf3a7f65137bcc88e4804631ac32128661f70457407300500cd527e13b30df9a167239", 'blake2b_384 (OO/filehandle/1)'); + close($fh); +} + +is( blake2b_384_file('t/data/text-CR.file'), pack("H*","dad6684cf65c72b1d44afc2e121542a01954631b039e7fdf663b7976b9539b379ac58003cda88cefacfc87b924241386"), 'blake2b_384 (raw/file/2)'); +is( blake2b_384_file_hex('t/data/text-CR.file'), "dad6684cf65c72b1d44afc2e121542a01954631b039e7fdf663b7976b9539b379ac58003cda88cefacfc87b924241386", 'blake2b_384 (hex/file/2)'); +is( blake2b_384_file_b64('t/data/text-CR.file'), "2tZoTPZccrHUSvwuEhVCoBlUYxsDnn/fZjt5drlTmzeaxYADzaiM76z8h7kkJBOG", 'blake2b_384 (base64/file/2)'); +is( digest_file('BLAKE2b_384', 't/data/text-CR.file'), pack("H*","dad6684cf65c72b1d44afc2e121542a01954631b039e7fdf663b7976b9539b379ac58003cda88cefacfc87b924241386"), 'blake2b_384 (digest_file_raw/file/2)'); +is( digest_file_hex('BLAKE2b_384', 't/data/text-CR.file'), "dad6684cf65c72b1d44afc2e121542a01954631b039e7fdf663b7976b9539b379ac58003cda88cefacfc87b924241386", 'blake2b_384 (digest_file_hex/file/2)'); +is( digest_file_b64('BLAKE2b_384', 't/data/text-CR.file'), "2tZoTPZccrHUSvwuEhVCoBlUYxsDnn/fZjt5drlTmzeaxYADzaiM76z8h7kkJBOG", 'blake2b_384 (digest_file_b64/file/2)'); +is( digest_file_b64u('BLAKE2b_384', 't/data/text-CR.file'), "2tZoTPZccrHUSvwuEhVCoBlUYxsDnn_fZjt5drlTmzeaxYADzaiM76z8h7kkJBOG", 'blake2b_384 (digest_file_b64u/file/2)'); +is( Crypt::Digest::BLAKE2b_384->new->addfile('t/data/text-CR.file')->hexdigest, "dad6684cf65c72b1d44afc2e121542a01954631b039e7fdf663b7976b9539b379ac58003cda88cefacfc87b924241386", 'blake2b_384 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2b_384->new->addfile($fh)->hexdigest, "dad6684cf65c72b1d44afc2e121542a01954631b039e7fdf663b7976b9539b379ac58003cda88cefacfc87b924241386", 'blake2b_384 (OO/filehandle/2)'); + close($fh); +} + +is( blake2b_384_file('t/data/text-CRLF.file'), pack("H*","c27a3e65cc53d2ff5141d7d15918693cba20d8de8b91d075a9c5a066ac81b004e033d05cb4b6c8257db4f7700f321a17"), 'blake2b_384 (raw/file/3)'); +is( blake2b_384_file_hex('t/data/text-CRLF.file'), "c27a3e65cc53d2ff5141d7d15918693cba20d8de8b91d075a9c5a066ac81b004e033d05cb4b6c8257db4f7700f321a17", 'blake2b_384 (hex/file/3)'); +is( blake2b_384_file_b64('t/data/text-CRLF.file'), "wno+ZcxT0v9RQdfRWRhpPLog2N6LkdB1qcWgZqyBsATgM9BctLbIJX2093APMhoX", 'blake2b_384 (base64/file/3)'); +is( digest_file('BLAKE2b_384', 't/data/text-CRLF.file'), pack("H*","c27a3e65cc53d2ff5141d7d15918693cba20d8de8b91d075a9c5a066ac81b004e033d05cb4b6c8257db4f7700f321a17"), 'blake2b_384 (digest_file_raw/file/3)'); +is( digest_file_hex('BLAKE2b_384', 't/data/text-CRLF.file'), "c27a3e65cc53d2ff5141d7d15918693cba20d8de8b91d075a9c5a066ac81b004e033d05cb4b6c8257db4f7700f321a17", 'blake2b_384 (digest_file_hex/file/3)'); +is( digest_file_b64('BLAKE2b_384', 't/data/text-CRLF.file'), "wno+ZcxT0v9RQdfRWRhpPLog2N6LkdB1qcWgZqyBsATgM9BctLbIJX2093APMhoX", 'blake2b_384 (digest_file_b64/file/3)'); +is( digest_file_b64u('BLAKE2b_384', 't/data/text-CRLF.file'), "wno-ZcxT0v9RQdfRWRhpPLog2N6LkdB1qcWgZqyBsATgM9BctLbIJX2093APMhoX", 'blake2b_384 (digest_file_b64u/file/3)'); +is( Crypt::Digest::BLAKE2b_384->new->addfile('t/data/text-CRLF.file')->hexdigest, "c27a3e65cc53d2ff5141d7d15918693cba20d8de8b91d075a9c5a066ac81b004e033d05cb4b6c8257db4f7700f321a17", 'blake2b_384 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2b_384->new->addfile($fh)->hexdigest, "c27a3e65cc53d2ff5141d7d15918693cba20d8de8b91d075a9c5a066ac81b004e033d05cb4b6c8257db4f7700f321a17", 'blake2b_384 (OO/filehandle/3)'); + close($fh); +} + +is( blake2b_384_file('t/data/text-LF.file'), pack("H*","6126cf1669bbd586f549f76bdb5dcf16ab93c3393e4cb712524550c43c10062a22c8179677f463782bcbe302db6afabe"), 'blake2b_384 (raw/file/4)'); +is( blake2b_384_file_hex('t/data/text-LF.file'), "6126cf1669bbd586f549f76bdb5dcf16ab93c3393e4cb712524550c43c10062a22c8179677f463782bcbe302db6afabe", 'blake2b_384 (hex/file/4)'); +is( blake2b_384_file_b64('t/data/text-LF.file'), "YSbPFmm71Yb1Sfdr213PFquTwzk+TLcSUkVQxDwQBioiyBeWd/RjeCvL4wLbavq+", 'blake2b_384 (base64/file/4)'); +is( digest_file('BLAKE2b_384', 't/data/text-LF.file'), pack("H*","6126cf1669bbd586f549f76bdb5dcf16ab93c3393e4cb712524550c43c10062a22c8179677f463782bcbe302db6afabe"), 'blake2b_384 (digest_file_raw/file/4)'); +is( digest_file_hex('BLAKE2b_384', 't/data/text-LF.file'), "6126cf1669bbd586f549f76bdb5dcf16ab93c3393e4cb712524550c43c10062a22c8179677f463782bcbe302db6afabe", 'blake2b_384 (digest_file_hex/file/4)'); +is( digest_file_b64('BLAKE2b_384', 't/data/text-LF.file'), "YSbPFmm71Yb1Sfdr213PFquTwzk+TLcSUkVQxDwQBioiyBeWd/RjeCvL4wLbavq+", 'blake2b_384 (digest_file_b64/file/4)'); +is( digest_file_b64u('BLAKE2b_384', 't/data/text-LF.file'), "YSbPFmm71Yb1Sfdr213PFquTwzk-TLcSUkVQxDwQBioiyBeWd_RjeCvL4wLbavq-", 'blake2b_384 (digest_file_b64u/file/4)'); +is( Crypt::Digest::BLAKE2b_384->new->addfile('t/data/text-LF.file')->hexdigest, "6126cf1669bbd586f549f76bdb5dcf16ab93c3393e4cb712524550c43c10062a22c8179677f463782bcbe302db6afabe", 'blake2b_384 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2b_384->new->addfile($fh)->hexdigest, "6126cf1669bbd586f549f76bdb5dcf16ab93c3393e4cb712524550c43c10062a22c8179677f463782bcbe302db6afabe", 'blake2b_384 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_blake2b_512.t b/t/digest_blake2b_512.t new file mode 100644 index 0000000..02d2a33 --- /dev/null +++ b/t/digest_blake2b_512.t @@ -0,0 +1,105 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::BLAKE2b_512 qw( blake2b_512 blake2b_512_hex blake2b_512_b64 blake2b_512_b64u blake2b_512_file blake2b_512_file_hex blake2b_512_file_b64 blake2b_512_file_b64u ); + +is( Crypt::Digest::hashsize('BLAKE2b_512'), 64, 'hashsize/1'); +is( Crypt::Digest->hashsize('BLAKE2b_512'), 64, 'hashsize/2'); +is( Crypt::Digest::BLAKE2b_512::hashsize, 64, 'hashsize/3'); +is( Crypt::Digest::BLAKE2b_512->hashsize, 64, 'hashsize/4'); +is( Crypt::Digest->new('BLAKE2b_512')->hashsize, 64, 'hashsize/5'); +is( Crypt::Digest::BLAKE2b_512->new->hashsize, 64, 'hashsize/6'); + + +is( blake2b_512(""), pack("H*","786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce"), 'blake2b_512 (raw/1)'); +is( blake2b_512_hex(""), "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce", 'blake2b_512 (hex/1)'); +is( blake2b_512_b64(""), "eGoC90IBWQPGxv2FJVLScpEvR0DhWEdhiobiF/cfVBnSXhAxr+5YUxOJZESTTrBLkDpoWxRIt1XVb3Aa/pvizg==", 'blake2b_512 (base64/1)'); +is( digest_data('BLAKE2b_512', ""), pack("H*","786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce"), 'blake2b_512 (digest_data_raw/1)'); +is( digest_data_hex('BLAKE2b_512', ""), "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce", 'blake2b_512 (digest_data_hex/1)'); +is( digest_data_b64('BLAKE2b_512', ""), "eGoC90IBWQPGxv2FJVLScpEvR0DhWEdhiobiF/cfVBnSXhAxr+5YUxOJZESTTrBLkDpoWxRIt1XVb3Aa/pvizg==", 'blake2b_512 (digest_data_b64/1)'); +is( digest_data_b64u('BLAKE2b_512', ""), "eGoC90IBWQPGxv2FJVLScpEvR0DhWEdhiobiF_cfVBnSXhAxr-5YUxOJZESTTrBLkDpoWxRIt1XVb3Aa_pvizg", 'blake2b_512 (digest_data_b64u/1)'); +is( Crypt::Digest::BLAKE2b_512->new->add("")->hexdigest, "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce", 'blake2b_512 (OO/1)'); + +is( blake2b_512("123"), pack("H*","e64cb91c7c1819bdcda4dca47a2aae98e737df75ddb0287083229dc0695064616df676a0c95ae55109fe0a27ba9dee79ea9a5c9d90cceb0cf8ae80b4f61ab4a3"), 'blake2b_512 (raw/2)'); +is( blake2b_512_hex("123"), "e64cb91c7c1819bdcda4dca47a2aae98e737df75ddb0287083229dc0695064616df676a0c95ae55109fe0a27ba9dee79ea9a5c9d90cceb0cf8ae80b4f61ab4a3", 'blake2b_512 (hex/2)'); +is( blake2b_512_b64("123"), "5ky5HHwYGb3NpNykeiqumOc333XdsChwgyKdwGlQZGFt9nagyVrlUQn+Cie6ne556ppcnZDM6wz4roC09hq0ow==", 'blake2b_512 (base64/2)'); +is( digest_data('BLAKE2b_512', "123"), pack("H*","e64cb91c7c1819bdcda4dca47a2aae98e737df75ddb0287083229dc0695064616df676a0c95ae55109fe0a27ba9dee79ea9a5c9d90cceb0cf8ae80b4f61ab4a3"), 'blake2b_512 (digest_data_raw/2)'); +is( digest_data_hex('BLAKE2b_512', "123"), "e64cb91c7c1819bdcda4dca47a2aae98e737df75ddb0287083229dc0695064616df676a0c95ae55109fe0a27ba9dee79ea9a5c9d90cceb0cf8ae80b4f61ab4a3", 'blake2b_512 (digest_data_hex/2)'); +is( digest_data_b64('BLAKE2b_512', "123"), "5ky5HHwYGb3NpNykeiqumOc333XdsChwgyKdwGlQZGFt9nagyVrlUQn+Cie6ne556ppcnZDM6wz4roC09hq0ow==", 'blake2b_512 (digest_data_b64/2)'); +is( digest_data_b64u('BLAKE2b_512', "123"), "5ky5HHwYGb3NpNykeiqumOc333XdsChwgyKdwGlQZGFt9nagyVrlUQn-Cie6ne556ppcnZDM6wz4roC09hq0ow", 'blake2b_512 (digest_data_b64u/2)'); +is( Crypt::Digest::BLAKE2b_512->new->add("123")->hexdigest, "e64cb91c7c1819bdcda4dca47a2aae98e737df75ddb0287083229dc0695064616df676a0c95ae55109fe0a27ba9dee79ea9a5c9d90cceb0cf8ae80b4f61ab4a3", 'blake2b_512 (OO/2)'); + +is( blake2b_512("test\0test\0test\n"), pack("H*","fd8d99f76c34c8c6ad60d7842ed769a9d32dc619efc8618761db5a8f1851089b8adfaf40f73ac5f0acf75307bbeda9769764c386e715cc758ce0ee6dfe184400"), 'blake2b_512 (raw/3)'); +is( blake2b_512_hex("test\0test\0test\n"), "fd8d99f76c34c8c6ad60d7842ed769a9d32dc619efc8618761db5a8f1851089b8adfaf40f73ac5f0acf75307bbeda9769764c386e715cc758ce0ee6dfe184400", 'blake2b_512 (hex/3)'); +is( blake2b_512_b64("test\0test\0test\n"), "/Y2Z92w0yMatYNeELtdpqdMtxhnvyGGHYdtajxhRCJuK369A9zrF8Kz3Uwe77al2l2TDhucVzHWM4O5t/hhEAA==", 'blake2b_512 (base64/3)'); +is( digest_data('BLAKE2b_512', "test\0test\0test\n"), pack("H*","fd8d99f76c34c8c6ad60d7842ed769a9d32dc619efc8618761db5a8f1851089b8adfaf40f73ac5f0acf75307bbeda9769764c386e715cc758ce0ee6dfe184400"), 'blake2b_512 (digest_data_raw/3)'); +is( digest_data_hex('BLAKE2b_512', "test\0test\0test\n"), "fd8d99f76c34c8c6ad60d7842ed769a9d32dc619efc8618761db5a8f1851089b8adfaf40f73ac5f0acf75307bbeda9769764c386e715cc758ce0ee6dfe184400", 'blake2b_512 (digest_data_hex/3)'); +is( digest_data_b64('BLAKE2b_512', "test\0test\0test\n"), "/Y2Z92w0yMatYNeELtdpqdMtxhnvyGGHYdtajxhRCJuK369A9zrF8Kz3Uwe77al2l2TDhucVzHWM4O5t/hhEAA==", 'blake2b_512 (digest_data_b64/3)'); +is( digest_data_b64u('BLAKE2b_512', "test\0test\0test\n"), "_Y2Z92w0yMatYNeELtdpqdMtxhnvyGGHYdtajxhRCJuK369A9zrF8Kz3Uwe77al2l2TDhucVzHWM4O5t_hhEAA", 'blake2b_512 (digest_data_b64u/3)'); +is( Crypt::Digest::BLAKE2b_512->new->add("test\0test\0test\n")->hexdigest, "fd8d99f76c34c8c6ad60d7842ed769a9d32dc619efc8618761db5a8f1851089b8adfaf40f73ac5f0acf75307bbeda9769764c386e715cc758ce0ee6dfe184400", 'blake2b_512 (OO/3)'); + + +is( blake2b_512_file('t/data/binary-test.file'), pack("H*","4be101a45bde3785c069f79673e1189a8d9dcaa2482a0fde0c2cc75807aa83f3e0d3747692f09b6708ac00a3c642900b0f8bc64f1e7bce40c043eaeae8583c0b"), 'blake2b_512 (raw/file/1)'); +is( blake2b_512_file_hex('t/data/binary-test.file'), "4be101a45bde3785c069f79673e1189a8d9dcaa2482a0fde0c2cc75807aa83f3e0d3747692f09b6708ac00a3c642900b0f8bc64f1e7bce40c043eaeae8583c0b", 'blake2b_512 (hex/file/1)'); +is( blake2b_512_file_b64('t/data/binary-test.file'), "S+EBpFveN4XAafeWc+EYmo2dyqJIKg/eDCzHWAeqg/Pg03R2kvCbZwisAKPGQpALD4vGTx57zkDAQ+rq6Fg8Cw==", 'blake2b_512 (base64/file/1)'); +is( digest_file('BLAKE2b_512', 't/data/binary-test.file'), pack("H*","4be101a45bde3785c069f79673e1189a8d9dcaa2482a0fde0c2cc75807aa83f3e0d3747692f09b6708ac00a3c642900b0f8bc64f1e7bce40c043eaeae8583c0b"), 'blake2b_512 (digest_file_raw/file/1)'); +is( digest_file_hex('BLAKE2b_512', 't/data/binary-test.file'), "4be101a45bde3785c069f79673e1189a8d9dcaa2482a0fde0c2cc75807aa83f3e0d3747692f09b6708ac00a3c642900b0f8bc64f1e7bce40c043eaeae8583c0b", 'blake2b_512 (digest_file_hex/file/1)'); +is( digest_file_b64('BLAKE2b_512', 't/data/binary-test.file'), "S+EBpFveN4XAafeWc+EYmo2dyqJIKg/eDCzHWAeqg/Pg03R2kvCbZwisAKPGQpALD4vGTx57zkDAQ+rq6Fg8Cw==", 'blake2b_512 (digest_file_b64/file/1)'); +is( digest_file_b64u('BLAKE2b_512', 't/data/binary-test.file'), "S-EBpFveN4XAafeWc-EYmo2dyqJIKg_eDCzHWAeqg_Pg03R2kvCbZwisAKPGQpALD4vGTx57zkDAQ-rq6Fg8Cw", 'blake2b_512 (digest_file_b64u/file/1)'); +is( Crypt::Digest::BLAKE2b_512->new->addfile('t/data/binary-test.file')->hexdigest, "4be101a45bde3785c069f79673e1189a8d9dcaa2482a0fde0c2cc75807aa83f3e0d3747692f09b6708ac00a3c642900b0f8bc64f1e7bce40c043eaeae8583c0b", 'blake2b_512 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2b_512->new->addfile($fh)->hexdigest, "4be101a45bde3785c069f79673e1189a8d9dcaa2482a0fde0c2cc75807aa83f3e0d3747692f09b6708ac00a3c642900b0f8bc64f1e7bce40c043eaeae8583c0b", 'blake2b_512 (OO/filehandle/1)'); + close($fh); +} + +is( blake2b_512_file('t/data/text-CR.file'), pack("H*","49a5a632d6e83d3978ee5a583d81af8e9504fae4861f680e5a7258bb2ead5d44c8a0b6b194f21ac68328c1c62b8ed23025e5d64674d052bf9b171e88418ca16c"), 'blake2b_512 (raw/file/2)'); +is( blake2b_512_file_hex('t/data/text-CR.file'), "49a5a632d6e83d3978ee5a583d81af8e9504fae4861f680e5a7258bb2ead5d44c8a0b6b194f21ac68328c1c62b8ed23025e5d64674d052bf9b171e88418ca16c", 'blake2b_512 (hex/file/2)'); +is( blake2b_512_file_b64('t/data/text-CR.file'), "SaWmMtboPTl47lpYPYGvjpUE+uSGH2gOWnJYuy6tXUTIoLaxlPIaxoMowcYrjtIwJeXWRnTQUr+bFx6IQYyhbA==", 'blake2b_512 (base64/file/2)'); +is( digest_file('BLAKE2b_512', 't/data/text-CR.file'), pack("H*","49a5a632d6e83d3978ee5a583d81af8e9504fae4861f680e5a7258bb2ead5d44c8a0b6b194f21ac68328c1c62b8ed23025e5d64674d052bf9b171e88418ca16c"), 'blake2b_512 (digest_file_raw/file/2)'); +is( digest_file_hex('BLAKE2b_512', 't/data/text-CR.file'), "49a5a632d6e83d3978ee5a583d81af8e9504fae4861f680e5a7258bb2ead5d44c8a0b6b194f21ac68328c1c62b8ed23025e5d64674d052bf9b171e88418ca16c", 'blake2b_512 (digest_file_hex/file/2)'); +is( digest_file_b64('BLAKE2b_512', 't/data/text-CR.file'), "SaWmMtboPTl47lpYPYGvjpUE+uSGH2gOWnJYuy6tXUTIoLaxlPIaxoMowcYrjtIwJeXWRnTQUr+bFx6IQYyhbA==", 'blake2b_512 (digest_file_b64/file/2)'); +is( digest_file_b64u('BLAKE2b_512', 't/data/text-CR.file'), "SaWmMtboPTl47lpYPYGvjpUE-uSGH2gOWnJYuy6tXUTIoLaxlPIaxoMowcYrjtIwJeXWRnTQUr-bFx6IQYyhbA", 'blake2b_512 (digest_file_b64u/file/2)'); +is( Crypt::Digest::BLAKE2b_512->new->addfile('t/data/text-CR.file')->hexdigest, "49a5a632d6e83d3978ee5a583d81af8e9504fae4861f680e5a7258bb2ead5d44c8a0b6b194f21ac68328c1c62b8ed23025e5d64674d052bf9b171e88418ca16c", 'blake2b_512 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2b_512->new->addfile($fh)->hexdigest, "49a5a632d6e83d3978ee5a583d81af8e9504fae4861f680e5a7258bb2ead5d44c8a0b6b194f21ac68328c1c62b8ed23025e5d64674d052bf9b171e88418ca16c", 'blake2b_512 (OO/filehandle/2)'); + close($fh); +} + +is( blake2b_512_file('t/data/text-CRLF.file'), pack("H*","5df2606edf6508ae927e6d0fb769abed4c5dc82f99c2e8f9da1c52c0d0bc3c325446b3cb4d47ffc689d01a9676783946dd4a132bce3c31a8fafd2eeb27107a7e"), 'blake2b_512 (raw/file/3)'); +is( blake2b_512_file_hex('t/data/text-CRLF.file'), "5df2606edf6508ae927e6d0fb769abed4c5dc82f99c2e8f9da1c52c0d0bc3c325446b3cb4d47ffc689d01a9676783946dd4a132bce3c31a8fafd2eeb27107a7e", 'blake2b_512 (hex/file/3)'); +is( blake2b_512_file_b64('t/data/text-CRLF.file'), "XfJgbt9lCK6Sfm0Pt2mr7UxdyC+Zwuj52hxSwNC8PDJURrPLTUf/xonQGpZ2eDlG3UoTK848Maj6/S7rJxB6fg==", 'blake2b_512 (base64/file/3)'); +is( digest_file('BLAKE2b_512', 't/data/text-CRLF.file'), pack("H*","5df2606edf6508ae927e6d0fb769abed4c5dc82f99c2e8f9da1c52c0d0bc3c325446b3cb4d47ffc689d01a9676783946dd4a132bce3c31a8fafd2eeb27107a7e"), 'blake2b_512 (digest_file_raw/file/3)'); +is( digest_file_hex('BLAKE2b_512', 't/data/text-CRLF.file'), "5df2606edf6508ae927e6d0fb769abed4c5dc82f99c2e8f9da1c52c0d0bc3c325446b3cb4d47ffc689d01a9676783946dd4a132bce3c31a8fafd2eeb27107a7e", 'blake2b_512 (digest_file_hex/file/3)'); +is( digest_file_b64('BLAKE2b_512', 't/data/text-CRLF.file'), "XfJgbt9lCK6Sfm0Pt2mr7UxdyC+Zwuj52hxSwNC8PDJURrPLTUf/xonQGpZ2eDlG3UoTK848Maj6/S7rJxB6fg==", 'blake2b_512 (digest_file_b64/file/3)'); +is( digest_file_b64u('BLAKE2b_512', 't/data/text-CRLF.file'), "XfJgbt9lCK6Sfm0Pt2mr7UxdyC-Zwuj52hxSwNC8PDJURrPLTUf_xonQGpZ2eDlG3UoTK848Maj6_S7rJxB6fg", 'blake2b_512 (digest_file_b64u/file/3)'); +is( Crypt::Digest::BLAKE2b_512->new->addfile('t/data/text-CRLF.file')->hexdigest, "5df2606edf6508ae927e6d0fb769abed4c5dc82f99c2e8f9da1c52c0d0bc3c325446b3cb4d47ffc689d01a9676783946dd4a132bce3c31a8fafd2eeb27107a7e", 'blake2b_512 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2b_512->new->addfile($fh)->hexdigest, "5df2606edf6508ae927e6d0fb769abed4c5dc82f99c2e8f9da1c52c0d0bc3c325446b3cb4d47ffc689d01a9676783946dd4a132bce3c31a8fafd2eeb27107a7e", 'blake2b_512 (OO/filehandle/3)'); + close($fh); +} + +is( blake2b_512_file('t/data/text-LF.file'), pack("H*","adaa42f339d50111fd407ad5c3f2c27b81d8560eb1283f69a3449a59a801617c98001a54396c095734a229905f2aa4dffaaf5ceca077a3a55960c66089e9309e"), 'blake2b_512 (raw/file/4)'); +is( blake2b_512_file_hex('t/data/text-LF.file'), "adaa42f339d50111fd407ad5c3f2c27b81d8560eb1283f69a3449a59a801617c98001a54396c095734a229905f2aa4dffaaf5ceca077a3a55960c66089e9309e", 'blake2b_512 (hex/file/4)'); +is( blake2b_512_file_b64('t/data/text-LF.file'), "rapC8znVARH9QHrVw/LCe4HYVg6xKD9po0SaWagBYXyYABpUOWwJVzSiKZBfKqTf+q9c7KB3o6VZYMZgiekwng==", 'blake2b_512 (base64/file/4)'); +is( digest_file('BLAKE2b_512', 't/data/text-LF.file'), pack("H*","adaa42f339d50111fd407ad5c3f2c27b81d8560eb1283f69a3449a59a801617c98001a54396c095734a229905f2aa4dffaaf5ceca077a3a55960c66089e9309e"), 'blake2b_512 (digest_file_raw/file/4)'); +is( digest_file_hex('BLAKE2b_512', 't/data/text-LF.file'), "adaa42f339d50111fd407ad5c3f2c27b81d8560eb1283f69a3449a59a801617c98001a54396c095734a229905f2aa4dffaaf5ceca077a3a55960c66089e9309e", 'blake2b_512 (digest_file_hex/file/4)'); +is( digest_file_b64('BLAKE2b_512', 't/data/text-LF.file'), "rapC8znVARH9QHrVw/LCe4HYVg6xKD9po0SaWagBYXyYABpUOWwJVzSiKZBfKqTf+q9c7KB3o6VZYMZgiekwng==", 'blake2b_512 (digest_file_b64/file/4)'); +is( digest_file_b64u('BLAKE2b_512', 't/data/text-LF.file'), "rapC8znVARH9QHrVw_LCe4HYVg6xKD9po0SaWagBYXyYABpUOWwJVzSiKZBfKqTf-q9c7KB3o6VZYMZgiekwng", 'blake2b_512 (digest_file_b64u/file/4)'); +is( Crypt::Digest::BLAKE2b_512->new->addfile('t/data/text-LF.file')->hexdigest, "adaa42f339d50111fd407ad5c3f2c27b81d8560eb1283f69a3449a59a801617c98001a54396c095734a229905f2aa4dffaaf5ceca077a3a55960c66089e9309e", 'blake2b_512 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2b_512->new->addfile($fh)->hexdigest, "adaa42f339d50111fd407ad5c3f2c27b81d8560eb1283f69a3449a59a801617c98001a54396c095734a229905f2aa4dffaaf5ceca077a3a55960c66089e9309e", 'blake2b_512 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_blake2s_128.t b/t/digest_blake2s_128.t new file mode 100644 index 0000000..eafbcf7 --- /dev/null +++ b/t/digest_blake2s_128.t @@ -0,0 +1,105 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::BLAKE2s_128 qw( blake2s_128 blake2s_128_hex blake2s_128_b64 blake2s_128_b64u blake2s_128_file blake2s_128_file_hex blake2s_128_file_b64 blake2s_128_file_b64u ); + +is( Crypt::Digest::hashsize('BLAKE2s_128'), 16, 'hashsize/1'); +is( Crypt::Digest->hashsize('BLAKE2s_128'), 16, 'hashsize/2'); +is( Crypt::Digest::BLAKE2s_128::hashsize, 16, 'hashsize/3'); +is( Crypt::Digest::BLAKE2s_128->hashsize, 16, 'hashsize/4'); +is( Crypt::Digest->new('BLAKE2s_128')->hashsize, 16, 'hashsize/5'); +is( Crypt::Digest::BLAKE2s_128->new->hashsize, 16, 'hashsize/6'); + + +is( blake2s_128(""), pack("H*","64550d6ffe2c0a01a14aba1eade0200c"), 'blake2s_128 (raw/1)'); +is( blake2s_128_hex(""), "64550d6ffe2c0a01a14aba1eade0200c", 'blake2s_128 (hex/1)'); +is( blake2s_128_b64(""), "ZFUNb/4sCgGhSroereAgDA==", 'blake2s_128 (base64/1)'); +is( digest_data('BLAKE2s_128', ""), pack("H*","64550d6ffe2c0a01a14aba1eade0200c"), 'blake2s_128 (digest_data_raw/1)'); +is( digest_data_hex('BLAKE2s_128', ""), "64550d6ffe2c0a01a14aba1eade0200c", 'blake2s_128 (digest_data_hex/1)'); +is( digest_data_b64('BLAKE2s_128', ""), "ZFUNb/4sCgGhSroereAgDA==", 'blake2s_128 (digest_data_b64/1)'); +is( digest_data_b64u('BLAKE2s_128', ""), "ZFUNb_4sCgGhSroereAgDA", 'blake2s_128 (digest_data_b64u/1)'); +is( Crypt::Digest::BLAKE2s_128->new->add("")->hexdigest, "64550d6ffe2c0a01a14aba1eade0200c", 'blake2s_128 (OO/1)'); + +is( blake2s_128("123"), pack("H*","0a0c4b61b07a608b3904949a4998f8b1"), 'blake2s_128 (raw/2)'); +is( blake2s_128_hex("123"), "0a0c4b61b07a608b3904949a4998f8b1", 'blake2s_128 (hex/2)'); +is( blake2s_128_b64("123"), "CgxLYbB6YIs5BJSaSZj4sQ==", 'blake2s_128 (base64/2)'); +is( digest_data('BLAKE2s_128', "123"), pack("H*","0a0c4b61b07a608b3904949a4998f8b1"), 'blake2s_128 (digest_data_raw/2)'); +is( digest_data_hex('BLAKE2s_128', "123"), "0a0c4b61b07a608b3904949a4998f8b1", 'blake2s_128 (digest_data_hex/2)'); +is( digest_data_b64('BLAKE2s_128', "123"), "CgxLYbB6YIs5BJSaSZj4sQ==", 'blake2s_128 (digest_data_b64/2)'); +is( digest_data_b64u('BLAKE2s_128', "123"), "CgxLYbB6YIs5BJSaSZj4sQ", 'blake2s_128 (digest_data_b64u/2)'); +is( Crypt::Digest::BLAKE2s_128->new->add("123")->hexdigest, "0a0c4b61b07a608b3904949a4998f8b1", 'blake2s_128 (OO/2)'); + +is( blake2s_128("test\0test\0test\n"), pack("H*","32aa3dfdb8adb174cab17a2ac7c205a8"), 'blake2s_128 (raw/3)'); +is( blake2s_128_hex("test\0test\0test\n"), "32aa3dfdb8adb174cab17a2ac7c205a8", 'blake2s_128 (hex/3)'); +is( blake2s_128_b64("test\0test\0test\n"), "Mqo9/bitsXTKsXoqx8IFqA==", 'blake2s_128 (base64/3)'); +is( digest_data('BLAKE2s_128', "test\0test\0test\n"), pack("H*","32aa3dfdb8adb174cab17a2ac7c205a8"), 'blake2s_128 (digest_data_raw/3)'); +is( digest_data_hex('BLAKE2s_128', "test\0test\0test\n"), "32aa3dfdb8adb174cab17a2ac7c205a8", 'blake2s_128 (digest_data_hex/3)'); +is( digest_data_b64('BLAKE2s_128', "test\0test\0test\n"), "Mqo9/bitsXTKsXoqx8IFqA==", 'blake2s_128 (digest_data_b64/3)'); +is( digest_data_b64u('BLAKE2s_128', "test\0test\0test\n"), "Mqo9_bitsXTKsXoqx8IFqA", 'blake2s_128 (digest_data_b64u/3)'); +is( Crypt::Digest::BLAKE2s_128->new->add("test\0test\0test\n")->hexdigest, "32aa3dfdb8adb174cab17a2ac7c205a8", 'blake2s_128 (OO/3)'); + + +is( blake2s_128_file('t/data/binary-test.file'), pack("H*","b5a4e21a67fdd4f2d75ab779feb83bfc"), 'blake2s_128 (raw/file/1)'); +is( blake2s_128_file_hex('t/data/binary-test.file'), "b5a4e21a67fdd4f2d75ab779feb83bfc", 'blake2s_128 (hex/file/1)'); +is( blake2s_128_file_b64('t/data/binary-test.file'), "taTiGmf91PLXWrd5/rg7/A==", 'blake2s_128 (base64/file/1)'); +is( digest_file('BLAKE2s_128', 't/data/binary-test.file'), pack("H*","b5a4e21a67fdd4f2d75ab779feb83bfc"), 'blake2s_128 (digest_file_raw/file/1)'); +is( digest_file_hex('BLAKE2s_128', 't/data/binary-test.file'), "b5a4e21a67fdd4f2d75ab779feb83bfc", 'blake2s_128 (digest_file_hex/file/1)'); +is( digest_file_b64('BLAKE2s_128', 't/data/binary-test.file'), "taTiGmf91PLXWrd5/rg7/A==", 'blake2s_128 (digest_file_b64/file/1)'); +is( digest_file_b64u('BLAKE2s_128', 't/data/binary-test.file'), "taTiGmf91PLXWrd5_rg7_A", 'blake2s_128 (digest_file_b64u/file/1)'); +is( Crypt::Digest::BLAKE2s_128->new->addfile('t/data/binary-test.file')->hexdigest, "b5a4e21a67fdd4f2d75ab779feb83bfc", 'blake2s_128 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2s_128->new->addfile($fh)->hexdigest, "b5a4e21a67fdd4f2d75ab779feb83bfc", 'blake2s_128 (OO/filehandle/1)'); + close($fh); +} + +is( blake2s_128_file('t/data/text-CR.file'), pack("H*","b17af4ae04bd7412393fc958bd60fdb6"), 'blake2s_128 (raw/file/2)'); +is( blake2s_128_file_hex('t/data/text-CR.file'), "b17af4ae04bd7412393fc958bd60fdb6", 'blake2s_128 (hex/file/2)'); +is( blake2s_128_file_b64('t/data/text-CR.file'), "sXr0rgS9dBI5P8lYvWD9tg==", 'blake2s_128 (base64/file/2)'); +is( digest_file('BLAKE2s_128', 't/data/text-CR.file'), pack("H*","b17af4ae04bd7412393fc958bd60fdb6"), 'blake2s_128 (digest_file_raw/file/2)'); +is( digest_file_hex('BLAKE2s_128', 't/data/text-CR.file'), "b17af4ae04bd7412393fc958bd60fdb6", 'blake2s_128 (digest_file_hex/file/2)'); +is( digest_file_b64('BLAKE2s_128', 't/data/text-CR.file'), "sXr0rgS9dBI5P8lYvWD9tg==", 'blake2s_128 (digest_file_b64/file/2)'); +is( digest_file_b64u('BLAKE2s_128', 't/data/text-CR.file'), "sXr0rgS9dBI5P8lYvWD9tg", 'blake2s_128 (digest_file_b64u/file/2)'); +is( Crypt::Digest::BLAKE2s_128->new->addfile('t/data/text-CR.file')->hexdigest, "b17af4ae04bd7412393fc958bd60fdb6", 'blake2s_128 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2s_128->new->addfile($fh)->hexdigest, "b17af4ae04bd7412393fc958bd60fdb6", 'blake2s_128 (OO/filehandle/2)'); + close($fh); +} + +is( blake2s_128_file('t/data/text-CRLF.file'), pack("H*","5e7c030d5e05b0c8c34105634417770c"), 'blake2s_128 (raw/file/3)'); +is( blake2s_128_file_hex('t/data/text-CRLF.file'), "5e7c030d5e05b0c8c34105634417770c", 'blake2s_128 (hex/file/3)'); +is( blake2s_128_file_b64('t/data/text-CRLF.file'), "XnwDDV4FsMjDQQVjRBd3DA==", 'blake2s_128 (base64/file/3)'); +is( digest_file('BLAKE2s_128', 't/data/text-CRLF.file'), pack("H*","5e7c030d5e05b0c8c34105634417770c"), 'blake2s_128 (digest_file_raw/file/3)'); +is( digest_file_hex('BLAKE2s_128', 't/data/text-CRLF.file'), "5e7c030d5e05b0c8c34105634417770c", 'blake2s_128 (digest_file_hex/file/3)'); +is( digest_file_b64('BLAKE2s_128', 't/data/text-CRLF.file'), "XnwDDV4FsMjDQQVjRBd3DA==", 'blake2s_128 (digest_file_b64/file/3)'); +is( digest_file_b64u('BLAKE2s_128', 't/data/text-CRLF.file'), "XnwDDV4FsMjDQQVjRBd3DA", 'blake2s_128 (digest_file_b64u/file/3)'); +is( Crypt::Digest::BLAKE2s_128->new->addfile('t/data/text-CRLF.file')->hexdigest, "5e7c030d5e05b0c8c34105634417770c", 'blake2s_128 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2s_128->new->addfile($fh)->hexdigest, "5e7c030d5e05b0c8c34105634417770c", 'blake2s_128 (OO/filehandle/3)'); + close($fh); +} + +is( blake2s_128_file('t/data/text-LF.file'), pack("H*","72a2b42b4c947d3d3c479b3b0e596aae"), 'blake2s_128 (raw/file/4)'); +is( blake2s_128_file_hex('t/data/text-LF.file'), "72a2b42b4c947d3d3c479b3b0e596aae", 'blake2s_128 (hex/file/4)'); +is( blake2s_128_file_b64('t/data/text-LF.file'), "cqK0K0yUfT08R5s7Dllqrg==", 'blake2s_128 (base64/file/4)'); +is( digest_file('BLAKE2s_128', 't/data/text-LF.file'), pack("H*","72a2b42b4c947d3d3c479b3b0e596aae"), 'blake2s_128 (digest_file_raw/file/4)'); +is( digest_file_hex('BLAKE2s_128', 't/data/text-LF.file'), "72a2b42b4c947d3d3c479b3b0e596aae", 'blake2s_128 (digest_file_hex/file/4)'); +is( digest_file_b64('BLAKE2s_128', 't/data/text-LF.file'), "cqK0K0yUfT08R5s7Dllqrg==", 'blake2s_128 (digest_file_b64/file/4)'); +is( digest_file_b64u('BLAKE2s_128', 't/data/text-LF.file'), "cqK0K0yUfT08R5s7Dllqrg", 'blake2s_128 (digest_file_b64u/file/4)'); +is( Crypt::Digest::BLAKE2s_128->new->addfile('t/data/text-LF.file')->hexdigest, "72a2b42b4c947d3d3c479b3b0e596aae", 'blake2s_128 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2s_128->new->addfile($fh)->hexdigest, "72a2b42b4c947d3d3c479b3b0e596aae", 'blake2s_128 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_blake2s_160.t b/t/digest_blake2s_160.t new file mode 100644 index 0000000..e30a01b --- /dev/null +++ b/t/digest_blake2s_160.t @@ -0,0 +1,105 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::BLAKE2s_160 qw( blake2s_160 blake2s_160_hex blake2s_160_b64 blake2s_160_b64u blake2s_160_file blake2s_160_file_hex blake2s_160_file_b64 blake2s_160_file_b64u ); + +is( Crypt::Digest::hashsize('BLAKE2s_160'), 20, 'hashsize/1'); +is( Crypt::Digest->hashsize('BLAKE2s_160'), 20, 'hashsize/2'); +is( Crypt::Digest::BLAKE2s_160::hashsize, 20, 'hashsize/3'); +is( Crypt::Digest::BLAKE2s_160->hashsize, 20, 'hashsize/4'); +is( Crypt::Digest->new('BLAKE2s_160')->hashsize, 20, 'hashsize/5'); +is( Crypt::Digest::BLAKE2s_160->new->hashsize, 20, 'hashsize/6'); + + +is( blake2s_160(""), pack("H*","354c9c33f735962418bdacb9479873429c34916f"), 'blake2s_160 (raw/1)'); +is( blake2s_160_hex(""), "354c9c33f735962418bdacb9479873429c34916f", 'blake2s_160 (hex/1)'); +is( blake2s_160_b64(""), "NUycM/c1liQYvay5R5hzQpw0kW8=", 'blake2s_160 (base64/1)'); +is( digest_data('BLAKE2s_160', ""), pack("H*","354c9c33f735962418bdacb9479873429c34916f"), 'blake2s_160 (digest_data_raw/1)'); +is( digest_data_hex('BLAKE2s_160', ""), "354c9c33f735962418bdacb9479873429c34916f", 'blake2s_160 (digest_data_hex/1)'); +is( digest_data_b64('BLAKE2s_160', ""), "NUycM/c1liQYvay5R5hzQpw0kW8=", 'blake2s_160 (digest_data_b64/1)'); +is( digest_data_b64u('BLAKE2s_160', ""), "NUycM_c1liQYvay5R5hzQpw0kW8", 'blake2s_160 (digest_data_b64u/1)'); +is( Crypt::Digest::BLAKE2s_160->new->add("")->hexdigest, "354c9c33f735962418bdacb9479873429c34916f", 'blake2s_160 (OO/1)'); + +is( blake2s_160("123"), pack("H*","0acf4489ee7548f29fc6f6d58605f8399b69d664"), 'blake2s_160 (raw/2)'); +is( blake2s_160_hex("123"), "0acf4489ee7548f29fc6f6d58605f8399b69d664", 'blake2s_160 (hex/2)'); +is( blake2s_160_b64("123"), "Cs9Eie51SPKfxvbVhgX4OZtp1mQ=", 'blake2s_160 (base64/2)'); +is( digest_data('BLAKE2s_160', "123"), pack("H*","0acf4489ee7548f29fc6f6d58605f8399b69d664"), 'blake2s_160 (digest_data_raw/2)'); +is( digest_data_hex('BLAKE2s_160', "123"), "0acf4489ee7548f29fc6f6d58605f8399b69d664", 'blake2s_160 (digest_data_hex/2)'); +is( digest_data_b64('BLAKE2s_160', "123"), "Cs9Eie51SPKfxvbVhgX4OZtp1mQ=", 'blake2s_160 (digest_data_b64/2)'); +is( digest_data_b64u('BLAKE2s_160', "123"), "Cs9Eie51SPKfxvbVhgX4OZtp1mQ", 'blake2s_160 (digest_data_b64u/2)'); +is( Crypt::Digest::BLAKE2s_160->new->add("123")->hexdigest, "0acf4489ee7548f29fc6f6d58605f8399b69d664", 'blake2s_160 (OO/2)'); + +is( blake2s_160("test\0test\0test\n"), pack("H*","7e496917ea2fdbb95254bfc7e161144b6a106823"), 'blake2s_160 (raw/3)'); +is( blake2s_160_hex("test\0test\0test\n"), "7e496917ea2fdbb95254bfc7e161144b6a106823", 'blake2s_160 (hex/3)'); +is( blake2s_160_b64("test\0test\0test\n"), "fklpF+ov27lSVL/H4WEUS2oQaCM=", 'blake2s_160 (base64/3)'); +is( digest_data('BLAKE2s_160', "test\0test\0test\n"), pack("H*","7e496917ea2fdbb95254bfc7e161144b6a106823"), 'blake2s_160 (digest_data_raw/3)'); +is( digest_data_hex('BLAKE2s_160', "test\0test\0test\n"), "7e496917ea2fdbb95254bfc7e161144b6a106823", 'blake2s_160 (digest_data_hex/3)'); +is( digest_data_b64('BLAKE2s_160', "test\0test\0test\n"), "fklpF+ov27lSVL/H4WEUS2oQaCM=", 'blake2s_160 (digest_data_b64/3)'); +is( digest_data_b64u('BLAKE2s_160', "test\0test\0test\n"), "fklpF-ov27lSVL_H4WEUS2oQaCM", 'blake2s_160 (digest_data_b64u/3)'); +is( Crypt::Digest::BLAKE2s_160->new->add("test\0test\0test\n")->hexdigest, "7e496917ea2fdbb95254bfc7e161144b6a106823", 'blake2s_160 (OO/3)'); + + +is( blake2s_160_file('t/data/binary-test.file'), pack("H*","079c2122db24abfcbb343a2fc4c579c64fb9e534"), 'blake2s_160 (raw/file/1)'); +is( blake2s_160_file_hex('t/data/binary-test.file'), "079c2122db24abfcbb343a2fc4c579c64fb9e534", 'blake2s_160 (hex/file/1)'); +is( blake2s_160_file_b64('t/data/binary-test.file'), "B5whItskq/y7NDovxMV5xk+55TQ=", 'blake2s_160 (base64/file/1)'); +is( digest_file('BLAKE2s_160', 't/data/binary-test.file'), pack("H*","079c2122db24abfcbb343a2fc4c579c64fb9e534"), 'blake2s_160 (digest_file_raw/file/1)'); +is( digest_file_hex('BLAKE2s_160', 't/data/binary-test.file'), "079c2122db24abfcbb343a2fc4c579c64fb9e534", 'blake2s_160 (digest_file_hex/file/1)'); +is( digest_file_b64('BLAKE2s_160', 't/data/binary-test.file'), "B5whItskq/y7NDovxMV5xk+55TQ=", 'blake2s_160 (digest_file_b64/file/1)'); +is( digest_file_b64u('BLAKE2s_160', 't/data/binary-test.file'), "B5whItskq_y7NDovxMV5xk-55TQ", 'blake2s_160 (digest_file_b64u/file/1)'); +is( Crypt::Digest::BLAKE2s_160->new->addfile('t/data/binary-test.file')->hexdigest, "079c2122db24abfcbb343a2fc4c579c64fb9e534", 'blake2s_160 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2s_160->new->addfile($fh)->hexdigest, "079c2122db24abfcbb343a2fc4c579c64fb9e534", 'blake2s_160 (OO/filehandle/1)'); + close($fh); +} + +is( blake2s_160_file('t/data/text-CR.file'), pack("H*","99ecbe30ed4687ed6d8c8acbfc6205a4a3cea1de"), 'blake2s_160 (raw/file/2)'); +is( blake2s_160_file_hex('t/data/text-CR.file'), "99ecbe30ed4687ed6d8c8acbfc6205a4a3cea1de", 'blake2s_160 (hex/file/2)'); +is( blake2s_160_file_b64('t/data/text-CR.file'), "mey+MO1Gh+1tjIrL/GIFpKPOod4=", 'blake2s_160 (base64/file/2)'); +is( digest_file('BLAKE2s_160', 't/data/text-CR.file'), pack("H*","99ecbe30ed4687ed6d8c8acbfc6205a4a3cea1de"), 'blake2s_160 (digest_file_raw/file/2)'); +is( digest_file_hex('BLAKE2s_160', 't/data/text-CR.file'), "99ecbe30ed4687ed6d8c8acbfc6205a4a3cea1de", 'blake2s_160 (digest_file_hex/file/2)'); +is( digest_file_b64('BLAKE2s_160', 't/data/text-CR.file'), "mey+MO1Gh+1tjIrL/GIFpKPOod4=", 'blake2s_160 (digest_file_b64/file/2)'); +is( digest_file_b64u('BLAKE2s_160', 't/data/text-CR.file'), "mey-MO1Gh-1tjIrL_GIFpKPOod4", 'blake2s_160 (digest_file_b64u/file/2)'); +is( Crypt::Digest::BLAKE2s_160->new->addfile('t/data/text-CR.file')->hexdigest, "99ecbe30ed4687ed6d8c8acbfc6205a4a3cea1de", 'blake2s_160 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2s_160->new->addfile($fh)->hexdigest, "99ecbe30ed4687ed6d8c8acbfc6205a4a3cea1de", 'blake2s_160 (OO/filehandle/2)'); + close($fh); +} + +is( blake2s_160_file('t/data/text-CRLF.file'), pack("H*","12fb04520b12fda25ac2845d5a7c8fb962811b0b"), 'blake2s_160 (raw/file/3)'); +is( blake2s_160_file_hex('t/data/text-CRLF.file'), "12fb04520b12fda25ac2845d5a7c8fb962811b0b", 'blake2s_160 (hex/file/3)'); +is( blake2s_160_file_b64('t/data/text-CRLF.file'), "EvsEUgsS/aJawoRdWnyPuWKBGws=", 'blake2s_160 (base64/file/3)'); +is( digest_file('BLAKE2s_160', 't/data/text-CRLF.file'), pack("H*","12fb04520b12fda25ac2845d5a7c8fb962811b0b"), 'blake2s_160 (digest_file_raw/file/3)'); +is( digest_file_hex('BLAKE2s_160', 't/data/text-CRLF.file'), "12fb04520b12fda25ac2845d5a7c8fb962811b0b", 'blake2s_160 (digest_file_hex/file/3)'); +is( digest_file_b64('BLAKE2s_160', 't/data/text-CRLF.file'), "EvsEUgsS/aJawoRdWnyPuWKBGws=", 'blake2s_160 (digest_file_b64/file/3)'); +is( digest_file_b64u('BLAKE2s_160', 't/data/text-CRLF.file'), "EvsEUgsS_aJawoRdWnyPuWKBGws", 'blake2s_160 (digest_file_b64u/file/3)'); +is( Crypt::Digest::BLAKE2s_160->new->addfile('t/data/text-CRLF.file')->hexdigest, "12fb04520b12fda25ac2845d5a7c8fb962811b0b", 'blake2s_160 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2s_160->new->addfile($fh)->hexdigest, "12fb04520b12fda25ac2845d5a7c8fb962811b0b", 'blake2s_160 (OO/filehandle/3)'); + close($fh); +} + +is( blake2s_160_file('t/data/text-LF.file'), pack("H*","72f0b448af483431f552dcd4ba426209f2d0f4dc"), 'blake2s_160 (raw/file/4)'); +is( blake2s_160_file_hex('t/data/text-LF.file'), "72f0b448af483431f552dcd4ba426209f2d0f4dc", 'blake2s_160 (hex/file/4)'); +is( blake2s_160_file_b64('t/data/text-LF.file'), "cvC0SK9INDH1UtzUukJiCfLQ9Nw=", 'blake2s_160 (base64/file/4)'); +is( digest_file('BLAKE2s_160', 't/data/text-LF.file'), pack("H*","72f0b448af483431f552dcd4ba426209f2d0f4dc"), 'blake2s_160 (digest_file_raw/file/4)'); +is( digest_file_hex('BLAKE2s_160', 't/data/text-LF.file'), "72f0b448af483431f552dcd4ba426209f2d0f4dc", 'blake2s_160 (digest_file_hex/file/4)'); +is( digest_file_b64('BLAKE2s_160', 't/data/text-LF.file'), "cvC0SK9INDH1UtzUukJiCfLQ9Nw=", 'blake2s_160 (digest_file_b64/file/4)'); +is( digest_file_b64u('BLAKE2s_160', 't/data/text-LF.file'), "cvC0SK9INDH1UtzUukJiCfLQ9Nw", 'blake2s_160 (digest_file_b64u/file/4)'); +is( Crypt::Digest::BLAKE2s_160->new->addfile('t/data/text-LF.file')->hexdigest, "72f0b448af483431f552dcd4ba426209f2d0f4dc", 'blake2s_160 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2s_160->new->addfile($fh)->hexdigest, "72f0b448af483431f552dcd4ba426209f2d0f4dc", 'blake2s_160 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_blake2s_224.t b/t/digest_blake2s_224.t new file mode 100644 index 0000000..b96349a --- /dev/null +++ b/t/digest_blake2s_224.t @@ -0,0 +1,105 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::BLAKE2s_224 qw( blake2s_224 blake2s_224_hex blake2s_224_b64 blake2s_224_b64u blake2s_224_file blake2s_224_file_hex blake2s_224_file_b64 blake2s_224_file_b64u ); + +is( Crypt::Digest::hashsize('BLAKE2s_224'), 28, 'hashsize/1'); +is( Crypt::Digest->hashsize('BLAKE2s_224'), 28, 'hashsize/2'); +is( Crypt::Digest::BLAKE2s_224::hashsize, 28, 'hashsize/3'); +is( Crypt::Digest::BLAKE2s_224->hashsize, 28, 'hashsize/4'); +is( Crypt::Digest->new('BLAKE2s_224')->hashsize, 28, 'hashsize/5'); +is( Crypt::Digest::BLAKE2s_224->new->hashsize, 28, 'hashsize/6'); + + +is( blake2s_224(""), pack("H*","1fa1291e65248b37b3433475b2a0dd63d54a11ecc4e3e034e7bc1ef4"), 'blake2s_224 (raw/1)'); +is( blake2s_224_hex(""), "1fa1291e65248b37b3433475b2a0dd63d54a11ecc4e3e034e7bc1ef4", 'blake2s_224 (hex/1)'); +is( blake2s_224_b64(""), "H6EpHmUkizezQzR1sqDdY9VKEezE4+A057we9A==", 'blake2s_224 (base64/1)'); +is( digest_data('BLAKE2s_224', ""), pack("H*","1fa1291e65248b37b3433475b2a0dd63d54a11ecc4e3e034e7bc1ef4"), 'blake2s_224 (digest_data_raw/1)'); +is( digest_data_hex('BLAKE2s_224', ""), "1fa1291e65248b37b3433475b2a0dd63d54a11ecc4e3e034e7bc1ef4", 'blake2s_224 (digest_data_hex/1)'); +is( digest_data_b64('BLAKE2s_224', ""), "H6EpHmUkizezQzR1sqDdY9VKEezE4+A057we9A==", 'blake2s_224 (digest_data_b64/1)'); +is( digest_data_b64u('BLAKE2s_224', ""), "H6EpHmUkizezQzR1sqDdY9VKEezE4-A057we9A", 'blake2s_224 (digest_data_b64u/1)'); +is( Crypt::Digest::BLAKE2s_224->new->add("")->hexdigest, "1fa1291e65248b37b3433475b2a0dd63d54a11ecc4e3e034e7bc1ef4", 'blake2s_224 (OO/1)'); + +is( blake2s_224("123"), pack("H*","8b49aa9362d8236d18b52acbcb3a62fa07d2eb9cf007a48d044d94f1"), 'blake2s_224 (raw/2)'); +is( blake2s_224_hex("123"), "8b49aa9362d8236d18b52acbcb3a62fa07d2eb9cf007a48d044d94f1", 'blake2s_224 (hex/2)'); +is( blake2s_224_b64("123"), "i0mqk2LYI20YtSrLyzpi+gfS65zwB6SNBE2U8Q==", 'blake2s_224 (base64/2)'); +is( digest_data('BLAKE2s_224', "123"), pack("H*","8b49aa9362d8236d18b52acbcb3a62fa07d2eb9cf007a48d044d94f1"), 'blake2s_224 (digest_data_raw/2)'); +is( digest_data_hex('BLAKE2s_224', "123"), "8b49aa9362d8236d18b52acbcb3a62fa07d2eb9cf007a48d044d94f1", 'blake2s_224 (digest_data_hex/2)'); +is( digest_data_b64('BLAKE2s_224', "123"), "i0mqk2LYI20YtSrLyzpi+gfS65zwB6SNBE2U8Q==", 'blake2s_224 (digest_data_b64/2)'); +is( digest_data_b64u('BLAKE2s_224', "123"), "i0mqk2LYI20YtSrLyzpi-gfS65zwB6SNBE2U8Q", 'blake2s_224 (digest_data_b64u/2)'); +is( Crypt::Digest::BLAKE2s_224->new->add("123")->hexdigest, "8b49aa9362d8236d18b52acbcb3a62fa07d2eb9cf007a48d044d94f1", 'blake2s_224 (OO/2)'); + +is( blake2s_224("test\0test\0test\n"), pack("H*","fdb36715bc01dc9575ad662a25add0601e8c73fb8b92fd35190c9f6b"), 'blake2s_224 (raw/3)'); +is( blake2s_224_hex("test\0test\0test\n"), "fdb36715bc01dc9575ad662a25add0601e8c73fb8b92fd35190c9f6b", 'blake2s_224 (hex/3)'); +is( blake2s_224_b64("test\0test\0test\n"), "/bNnFbwB3JV1rWYqJa3QYB6Mc/uLkv01GQyfaw==", 'blake2s_224 (base64/3)'); +is( digest_data('BLAKE2s_224', "test\0test\0test\n"), pack("H*","fdb36715bc01dc9575ad662a25add0601e8c73fb8b92fd35190c9f6b"), 'blake2s_224 (digest_data_raw/3)'); +is( digest_data_hex('BLAKE2s_224', "test\0test\0test\n"), "fdb36715bc01dc9575ad662a25add0601e8c73fb8b92fd35190c9f6b", 'blake2s_224 (digest_data_hex/3)'); +is( digest_data_b64('BLAKE2s_224', "test\0test\0test\n"), "/bNnFbwB3JV1rWYqJa3QYB6Mc/uLkv01GQyfaw==", 'blake2s_224 (digest_data_b64/3)'); +is( digest_data_b64u('BLAKE2s_224', "test\0test\0test\n"), "_bNnFbwB3JV1rWYqJa3QYB6Mc_uLkv01GQyfaw", 'blake2s_224 (digest_data_b64u/3)'); +is( Crypt::Digest::BLAKE2s_224->new->add("test\0test\0test\n")->hexdigest, "fdb36715bc01dc9575ad662a25add0601e8c73fb8b92fd35190c9f6b", 'blake2s_224 (OO/3)'); + + +is( blake2s_224_file('t/data/binary-test.file'), pack("H*","1084e796a3f44c7c06c3c89e03701c5c95226f92b01538a05a05eb04"), 'blake2s_224 (raw/file/1)'); +is( blake2s_224_file_hex('t/data/binary-test.file'), "1084e796a3f44c7c06c3c89e03701c5c95226f92b01538a05a05eb04", 'blake2s_224 (hex/file/1)'); +is( blake2s_224_file_b64('t/data/binary-test.file'), "EITnlqP0THwGw8ieA3AcXJUib5KwFTigWgXrBA==", 'blake2s_224 (base64/file/1)'); +is( digest_file('BLAKE2s_224', 't/data/binary-test.file'), pack("H*","1084e796a3f44c7c06c3c89e03701c5c95226f92b01538a05a05eb04"), 'blake2s_224 (digest_file_raw/file/1)'); +is( digest_file_hex('BLAKE2s_224', 't/data/binary-test.file'), "1084e796a3f44c7c06c3c89e03701c5c95226f92b01538a05a05eb04", 'blake2s_224 (digest_file_hex/file/1)'); +is( digest_file_b64('BLAKE2s_224', 't/data/binary-test.file'), "EITnlqP0THwGw8ieA3AcXJUib5KwFTigWgXrBA==", 'blake2s_224 (digest_file_b64/file/1)'); +is( digest_file_b64u('BLAKE2s_224', 't/data/binary-test.file'), "EITnlqP0THwGw8ieA3AcXJUib5KwFTigWgXrBA", 'blake2s_224 (digest_file_b64u/file/1)'); +is( Crypt::Digest::BLAKE2s_224->new->addfile('t/data/binary-test.file')->hexdigest, "1084e796a3f44c7c06c3c89e03701c5c95226f92b01538a05a05eb04", 'blake2s_224 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2s_224->new->addfile($fh)->hexdigest, "1084e796a3f44c7c06c3c89e03701c5c95226f92b01538a05a05eb04", 'blake2s_224 (OO/filehandle/1)'); + close($fh); +} + +is( blake2s_224_file('t/data/text-CR.file'), pack("H*","d1596023cc333044ef7ab85e6686a436f00d1024c3cea980e9fd402c"), 'blake2s_224 (raw/file/2)'); +is( blake2s_224_file_hex('t/data/text-CR.file'), "d1596023cc333044ef7ab85e6686a436f00d1024c3cea980e9fd402c", 'blake2s_224 (hex/file/2)'); +is( blake2s_224_file_b64('t/data/text-CR.file'), "0VlgI8wzMETverheZoakNvANECTDzqmA6f1ALA==", 'blake2s_224 (base64/file/2)'); +is( digest_file('BLAKE2s_224', 't/data/text-CR.file'), pack("H*","d1596023cc333044ef7ab85e6686a436f00d1024c3cea980e9fd402c"), 'blake2s_224 (digest_file_raw/file/2)'); +is( digest_file_hex('BLAKE2s_224', 't/data/text-CR.file'), "d1596023cc333044ef7ab85e6686a436f00d1024c3cea980e9fd402c", 'blake2s_224 (digest_file_hex/file/2)'); +is( digest_file_b64('BLAKE2s_224', 't/data/text-CR.file'), "0VlgI8wzMETverheZoakNvANECTDzqmA6f1ALA==", 'blake2s_224 (digest_file_b64/file/2)'); +is( digest_file_b64u('BLAKE2s_224', 't/data/text-CR.file'), "0VlgI8wzMETverheZoakNvANECTDzqmA6f1ALA", 'blake2s_224 (digest_file_b64u/file/2)'); +is( Crypt::Digest::BLAKE2s_224->new->addfile('t/data/text-CR.file')->hexdigest, "d1596023cc333044ef7ab85e6686a436f00d1024c3cea980e9fd402c", 'blake2s_224 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2s_224->new->addfile($fh)->hexdigest, "d1596023cc333044ef7ab85e6686a436f00d1024c3cea980e9fd402c", 'blake2s_224 (OO/filehandle/2)'); + close($fh); +} + +is( blake2s_224_file('t/data/text-CRLF.file'), pack("H*","c2898409fa3ea3b8e2859b944f89cfb4244ced2063872ebebd536796"), 'blake2s_224 (raw/file/3)'); +is( blake2s_224_file_hex('t/data/text-CRLF.file'), "c2898409fa3ea3b8e2859b944f89cfb4244ced2063872ebebd536796", 'blake2s_224 (hex/file/3)'); +is( blake2s_224_file_b64('t/data/text-CRLF.file'), "womECfo+o7jihZuUT4nPtCRM7SBjhy6+vVNnlg==", 'blake2s_224 (base64/file/3)'); +is( digest_file('BLAKE2s_224', 't/data/text-CRLF.file'), pack("H*","c2898409fa3ea3b8e2859b944f89cfb4244ced2063872ebebd536796"), 'blake2s_224 (digest_file_raw/file/3)'); +is( digest_file_hex('BLAKE2s_224', 't/data/text-CRLF.file'), "c2898409fa3ea3b8e2859b944f89cfb4244ced2063872ebebd536796", 'blake2s_224 (digest_file_hex/file/3)'); +is( digest_file_b64('BLAKE2s_224', 't/data/text-CRLF.file'), "womECfo+o7jihZuUT4nPtCRM7SBjhy6+vVNnlg==", 'blake2s_224 (digest_file_b64/file/3)'); +is( digest_file_b64u('BLAKE2s_224', 't/data/text-CRLF.file'), "womECfo-o7jihZuUT4nPtCRM7SBjhy6-vVNnlg", 'blake2s_224 (digest_file_b64u/file/3)'); +is( Crypt::Digest::BLAKE2s_224->new->addfile('t/data/text-CRLF.file')->hexdigest, "c2898409fa3ea3b8e2859b944f89cfb4244ced2063872ebebd536796", 'blake2s_224 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2s_224->new->addfile($fh)->hexdigest, "c2898409fa3ea3b8e2859b944f89cfb4244ced2063872ebebd536796", 'blake2s_224 (OO/filehandle/3)'); + close($fh); +} + +is( blake2s_224_file('t/data/text-LF.file'), pack("H*","d8fa36e6ed267a07f871d71f50f9dbc48661260a5e6a1cde8c802b89"), 'blake2s_224 (raw/file/4)'); +is( blake2s_224_file_hex('t/data/text-LF.file'), "d8fa36e6ed267a07f871d71f50f9dbc48661260a5e6a1cde8c802b89", 'blake2s_224 (hex/file/4)'); +is( blake2s_224_file_b64('t/data/text-LF.file'), "2Po25u0megf4cdcfUPnbxIZhJgpeahzejIAriQ==", 'blake2s_224 (base64/file/4)'); +is( digest_file('BLAKE2s_224', 't/data/text-LF.file'), pack("H*","d8fa36e6ed267a07f871d71f50f9dbc48661260a5e6a1cde8c802b89"), 'blake2s_224 (digest_file_raw/file/4)'); +is( digest_file_hex('BLAKE2s_224', 't/data/text-LF.file'), "d8fa36e6ed267a07f871d71f50f9dbc48661260a5e6a1cde8c802b89", 'blake2s_224 (digest_file_hex/file/4)'); +is( digest_file_b64('BLAKE2s_224', 't/data/text-LF.file'), "2Po25u0megf4cdcfUPnbxIZhJgpeahzejIAriQ==", 'blake2s_224 (digest_file_b64/file/4)'); +is( digest_file_b64u('BLAKE2s_224', 't/data/text-LF.file'), "2Po25u0megf4cdcfUPnbxIZhJgpeahzejIAriQ", 'blake2s_224 (digest_file_b64u/file/4)'); +is( Crypt::Digest::BLAKE2s_224->new->addfile('t/data/text-LF.file')->hexdigest, "d8fa36e6ed267a07f871d71f50f9dbc48661260a5e6a1cde8c802b89", 'blake2s_224 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2s_224->new->addfile($fh)->hexdigest, "d8fa36e6ed267a07f871d71f50f9dbc48661260a5e6a1cde8c802b89", 'blake2s_224 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_blake2s_256.t b/t/digest_blake2s_256.t new file mode 100644 index 0000000..7441c1b --- /dev/null +++ b/t/digest_blake2s_256.t @@ -0,0 +1,105 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::BLAKE2s_256 qw( blake2s_256 blake2s_256_hex blake2s_256_b64 blake2s_256_b64u blake2s_256_file blake2s_256_file_hex blake2s_256_file_b64 blake2s_256_file_b64u ); + +is( Crypt::Digest::hashsize('BLAKE2s_256'), 32, 'hashsize/1'); +is( Crypt::Digest->hashsize('BLAKE2s_256'), 32, 'hashsize/2'); +is( Crypt::Digest::BLAKE2s_256::hashsize, 32, 'hashsize/3'); +is( Crypt::Digest::BLAKE2s_256->hashsize, 32, 'hashsize/4'); +is( Crypt::Digest->new('BLAKE2s_256')->hashsize, 32, 'hashsize/5'); +is( Crypt::Digest::BLAKE2s_256->new->hashsize, 32, 'hashsize/6'); + + +is( blake2s_256(""), pack("H*","69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9"), 'blake2s_256 (raw/1)'); +is( blake2s_256_hex(""), "69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9", 'blake2s_256 (hex/1)'); +is( blake2s_256_b64(""), "aSF6MHmQgJThESHQQjVKfB9VtkgsoaUeGyUN/R7Q7vk=", 'blake2s_256 (base64/1)'); +is( digest_data('BLAKE2s_256', ""), pack("H*","69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9"), 'blake2s_256 (digest_data_raw/1)'); +is( digest_data_hex('BLAKE2s_256', ""), "69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9", 'blake2s_256 (digest_data_hex/1)'); +is( digest_data_b64('BLAKE2s_256', ""), "aSF6MHmQgJThESHQQjVKfB9VtkgsoaUeGyUN/R7Q7vk=", 'blake2s_256 (digest_data_b64/1)'); +is( digest_data_b64u('BLAKE2s_256', ""), "aSF6MHmQgJThESHQQjVKfB9VtkgsoaUeGyUN_R7Q7vk", 'blake2s_256 (digest_data_b64u/1)'); +is( Crypt::Digest::BLAKE2s_256->new->add("")->hexdigest, "69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9", 'blake2s_256 (OO/1)'); + +is( blake2s_256("123"), pack("H*","e906644ad861b58d47500e6c636ee3bf4cb4bb00016bb352b1d2d03d122c1605"), 'blake2s_256 (raw/2)'); +is( blake2s_256_hex("123"), "e906644ad861b58d47500e6c636ee3bf4cb4bb00016bb352b1d2d03d122c1605", 'blake2s_256 (hex/2)'); +is( blake2s_256_b64("123"), "6QZkSthhtY1HUA5sY27jv0y0uwABa7NSsdLQPRIsFgU=", 'blake2s_256 (base64/2)'); +is( digest_data('BLAKE2s_256', "123"), pack("H*","e906644ad861b58d47500e6c636ee3bf4cb4bb00016bb352b1d2d03d122c1605"), 'blake2s_256 (digest_data_raw/2)'); +is( digest_data_hex('BLAKE2s_256', "123"), "e906644ad861b58d47500e6c636ee3bf4cb4bb00016bb352b1d2d03d122c1605", 'blake2s_256 (digest_data_hex/2)'); +is( digest_data_b64('BLAKE2s_256', "123"), "6QZkSthhtY1HUA5sY27jv0y0uwABa7NSsdLQPRIsFgU=", 'blake2s_256 (digest_data_b64/2)'); +is( digest_data_b64u('BLAKE2s_256', "123"), "6QZkSthhtY1HUA5sY27jv0y0uwABa7NSsdLQPRIsFgU", 'blake2s_256 (digest_data_b64u/2)'); +is( Crypt::Digest::BLAKE2s_256->new->add("123")->hexdigest, "e906644ad861b58d47500e6c636ee3bf4cb4bb00016bb352b1d2d03d122c1605", 'blake2s_256 (OO/2)'); + +is( blake2s_256("test\0test\0test\n"), pack("H*","01f3bf97dce139caa74eb5cb02d2f01e4afac0c49ebf655db3168d1ca7e1442b"), 'blake2s_256 (raw/3)'); +is( blake2s_256_hex("test\0test\0test\n"), "01f3bf97dce139caa74eb5cb02d2f01e4afac0c49ebf655db3168d1ca7e1442b", 'blake2s_256 (hex/3)'); +is( blake2s_256_b64("test\0test\0test\n"), "AfO/l9zhOcqnTrXLAtLwHkr6wMSev2VdsxaNHKfhRCs=", 'blake2s_256 (base64/3)'); +is( digest_data('BLAKE2s_256', "test\0test\0test\n"), pack("H*","01f3bf97dce139caa74eb5cb02d2f01e4afac0c49ebf655db3168d1ca7e1442b"), 'blake2s_256 (digest_data_raw/3)'); +is( digest_data_hex('BLAKE2s_256', "test\0test\0test\n"), "01f3bf97dce139caa74eb5cb02d2f01e4afac0c49ebf655db3168d1ca7e1442b", 'blake2s_256 (digest_data_hex/3)'); +is( digest_data_b64('BLAKE2s_256', "test\0test\0test\n"), "AfO/l9zhOcqnTrXLAtLwHkr6wMSev2VdsxaNHKfhRCs=", 'blake2s_256 (digest_data_b64/3)'); +is( digest_data_b64u('BLAKE2s_256', "test\0test\0test\n"), "AfO_l9zhOcqnTrXLAtLwHkr6wMSev2VdsxaNHKfhRCs", 'blake2s_256 (digest_data_b64u/3)'); +is( Crypt::Digest::BLAKE2s_256->new->add("test\0test\0test\n")->hexdigest, "01f3bf97dce139caa74eb5cb02d2f01e4afac0c49ebf655db3168d1ca7e1442b", 'blake2s_256 (OO/3)'); + + +is( blake2s_256_file('t/data/binary-test.file'), pack("H*","af6e3f1cf2bfbe4be391142609fb16e3c3af494a0852927032a70d587f6865ad"), 'blake2s_256 (raw/file/1)'); +is( blake2s_256_file_hex('t/data/binary-test.file'), "af6e3f1cf2bfbe4be391142609fb16e3c3af494a0852927032a70d587f6865ad", 'blake2s_256 (hex/file/1)'); +is( blake2s_256_file_b64('t/data/binary-test.file'), "r24/HPK/vkvjkRQmCfsW48OvSUoIUpJwMqcNWH9oZa0=", 'blake2s_256 (base64/file/1)'); +is( digest_file('BLAKE2s_256', 't/data/binary-test.file'), pack("H*","af6e3f1cf2bfbe4be391142609fb16e3c3af494a0852927032a70d587f6865ad"), 'blake2s_256 (digest_file_raw/file/1)'); +is( digest_file_hex('BLAKE2s_256', 't/data/binary-test.file'), "af6e3f1cf2bfbe4be391142609fb16e3c3af494a0852927032a70d587f6865ad", 'blake2s_256 (digest_file_hex/file/1)'); +is( digest_file_b64('BLAKE2s_256', 't/data/binary-test.file'), "r24/HPK/vkvjkRQmCfsW48OvSUoIUpJwMqcNWH9oZa0=", 'blake2s_256 (digest_file_b64/file/1)'); +is( digest_file_b64u('BLAKE2s_256', 't/data/binary-test.file'), "r24_HPK_vkvjkRQmCfsW48OvSUoIUpJwMqcNWH9oZa0", 'blake2s_256 (digest_file_b64u/file/1)'); +is( Crypt::Digest::BLAKE2s_256->new->addfile('t/data/binary-test.file')->hexdigest, "af6e3f1cf2bfbe4be391142609fb16e3c3af494a0852927032a70d587f6865ad", 'blake2s_256 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2s_256->new->addfile($fh)->hexdigest, "af6e3f1cf2bfbe4be391142609fb16e3c3af494a0852927032a70d587f6865ad", 'blake2s_256 (OO/filehandle/1)'); + close($fh); +} + +is( blake2s_256_file('t/data/text-CR.file'), pack("H*","4297ddb26371f31bbfb0b4fbbe47ac8c843bef9285f72a9183cffdbd9adc0449"), 'blake2s_256 (raw/file/2)'); +is( blake2s_256_file_hex('t/data/text-CR.file'), "4297ddb26371f31bbfb0b4fbbe47ac8c843bef9285f72a9183cffdbd9adc0449", 'blake2s_256 (hex/file/2)'); +is( blake2s_256_file_b64('t/data/text-CR.file'), "QpfdsmNx8xu/sLT7vkesjIQ775KF9yqRg8/9vZrcBEk=", 'blake2s_256 (base64/file/2)'); +is( digest_file('BLAKE2s_256', 't/data/text-CR.file'), pack("H*","4297ddb26371f31bbfb0b4fbbe47ac8c843bef9285f72a9183cffdbd9adc0449"), 'blake2s_256 (digest_file_raw/file/2)'); +is( digest_file_hex('BLAKE2s_256', 't/data/text-CR.file'), "4297ddb26371f31bbfb0b4fbbe47ac8c843bef9285f72a9183cffdbd9adc0449", 'blake2s_256 (digest_file_hex/file/2)'); +is( digest_file_b64('BLAKE2s_256', 't/data/text-CR.file'), "QpfdsmNx8xu/sLT7vkesjIQ775KF9yqRg8/9vZrcBEk=", 'blake2s_256 (digest_file_b64/file/2)'); +is( digest_file_b64u('BLAKE2s_256', 't/data/text-CR.file'), "QpfdsmNx8xu_sLT7vkesjIQ775KF9yqRg8_9vZrcBEk", 'blake2s_256 (digest_file_b64u/file/2)'); +is( Crypt::Digest::BLAKE2s_256->new->addfile('t/data/text-CR.file')->hexdigest, "4297ddb26371f31bbfb0b4fbbe47ac8c843bef9285f72a9183cffdbd9adc0449", 'blake2s_256 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2s_256->new->addfile($fh)->hexdigest, "4297ddb26371f31bbfb0b4fbbe47ac8c843bef9285f72a9183cffdbd9adc0449", 'blake2s_256 (OO/filehandle/2)'); + close($fh); +} + +is( blake2s_256_file('t/data/text-CRLF.file'), pack("H*","ae9d70301b9f0fce63463a1c3bddc6438c9342b13e670152323ad5026784e267"), 'blake2s_256 (raw/file/3)'); +is( blake2s_256_file_hex('t/data/text-CRLF.file'), "ae9d70301b9f0fce63463a1c3bddc6438c9342b13e670152323ad5026784e267", 'blake2s_256 (hex/file/3)'); +is( blake2s_256_file_b64('t/data/text-CRLF.file'), "rp1wMBufD85jRjocO93GQ4yTQrE+ZwFSMjrVAmeE4mc=", 'blake2s_256 (base64/file/3)'); +is( digest_file('BLAKE2s_256', 't/data/text-CRLF.file'), pack("H*","ae9d70301b9f0fce63463a1c3bddc6438c9342b13e670152323ad5026784e267"), 'blake2s_256 (digest_file_raw/file/3)'); +is( digest_file_hex('BLAKE2s_256', 't/data/text-CRLF.file'), "ae9d70301b9f0fce63463a1c3bddc6438c9342b13e670152323ad5026784e267", 'blake2s_256 (digest_file_hex/file/3)'); +is( digest_file_b64('BLAKE2s_256', 't/data/text-CRLF.file'), "rp1wMBufD85jRjocO93GQ4yTQrE+ZwFSMjrVAmeE4mc=", 'blake2s_256 (digest_file_b64/file/3)'); +is( digest_file_b64u('BLAKE2s_256', 't/data/text-CRLF.file'), "rp1wMBufD85jRjocO93GQ4yTQrE-ZwFSMjrVAmeE4mc", 'blake2s_256 (digest_file_b64u/file/3)'); +is( Crypt::Digest::BLAKE2s_256->new->addfile('t/data/text-CRLF.file')->hexdigest, "ae9d70301b9f0fce63463a1c3bddc6438c9342b13e670152323ad5026784e267", 'blake2s_256 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2s_256->new->addfile($fh)->hexdigest, "ae9d70301b9f0fce63463a1c3bddc6438c9342b13e670152323ad5026784e267", 'blake2s_256 (OO/filehandle/3)'); + close($fh); +} + +is( blake2s_256_file('t/data/text-LF.file'), pack("H*","34c9db81494e888661bda9569d8cac9d2a9104a7ef7e464aabce701e8d9093d8"), 'blake2s_256 (raw/file/4)'); +is( blake2s_256_file_hex('t/data/text-LF.file'), "34c9db81494e888661bda9569d8cac9d2a9104a7ef7e464aabce701e8d9093d8", 'blake2s_256 (hex/file/4)'); +is( blake2s_256_file_b64('t/data/text-LF.file'), "NMnbgUlOiIZhvalWnYysnSqRBKfvfkZKq85wHo2Qk9g=", 'blake2s_256 (base64/file/4)'); +is( digest_file('BLAKE2s_256', 't/data/text-LF.file'), pack("H*","34c9db81494e888661bda9569d8cac9d2a9104a7ef7e464aabce701e8d9093d8"), 'blake2s_256 (digest_file_raw/file/4)'); +is( digest_file_hex('BLAKE2s_256', 't/data/text-LF.file'), "34c9db81494e888661bda9569d8cac9d2a9104a7ef7e464aabce701e8d9093d8", 'blake2s_256 (digest_file_hex/file/4)'); +is( digest_file_b64('BLAKE2s_256', 't/data/text-LF.file'), "NMnbgUlOiIZhvalWnYysnSqRBKfvfkZKq85wHo2Qk9g=", 'blake2s_256 (digest_file_b64/file/4)'); +is( digest_file_b64u('BLAKE2s_256', 't/data/text-LF.file'), "NMnbgUlOiIZhvalWnYysnSqRBKfvfkZKq85wHo2Qk9g", 'blake2s_256 (digest_file_b64u/file/4)'); +is( Crypt::Digest::BLAKE2s_256->new->addfile('t/data/text-LF.file')->hexdigest, "34c9db81494e888661bda9569d8cac9d2a9104a7ef7e464aabce701e8d9093d8", 'blake2s_256 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::BLAKE2s_256->new->addfile($fh)->hexdigest, "34c9db81494e888661bda9569d8cac9d2a9104a7ef7e464aabce701e8d9093d8", 'blake2s_256 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_chaes.t b/t/digest_chaes.t new file mode 100644 index 0000000..82534d1 --- /dev/null +++ b/t/digest_chaes.t @@ -0,0 +1,105 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::CHAES qw( chaes chaes_hex chaes_b64 chaes_b64u chaes_file chaes_file_hex chaes_file_b64 chaes_file_b64u ); + +is( Crypt::Digest::hashsize('CHAES'), 16, 'hashsize/1'); +is( Crypt::Digest->hashsize('CHAES'), 16, 'hashsize/2'); +is( Crypt::Digest::CHAES::hashsize, 16, 'hashsize/3'); +is( Crypt::Digest::CHAES->hashsize, 16, 'hashsize/4'); +is( Crypt::Digest->new('CHAES')->hashsize, 16, 'hashsize/5'); +is( Crypt::Digest::CHAES->new->hashsize, 16, 'hashsize/6'); + + +is( chaes(""), pack("H*","4047929f1f572643b55f829eb3291d11"), 'chaes (raw/1)'); +is( chaes_hex(""), "4047929f1f572643b55f829eb3291d11", 'chaes (hex/1)'); +is( chaes_b64(""), "QEeSnx9XJkO1X4KesykdEQ==", 'chaes (base64/1)'); +is( digest_data('CHAES', ""), pack("H*","4047929f1f572643b55f829eb3291d11"), 'chaes (digest_data_raw/1)'); +is( digest_data_hex('CHAES', ""), "4047929f1f572643b55f829eb3291d11", 'chaes (digest_data_hex/1)'); +is( digest_data_b64('CHAES', ""), "QEeSnx9XJkO1X4KesykdEQ==", 'chaes (digest_data_b64/1)'); +is( digest_data_b64u('CHAES', ""), "QEeSnx9XJkO1X4KesykdEQ", 'chaes (digest_data_b64u/1)'); +is( Crypt::Digest::CHAES->new->add("")->hexdigest, "4047929f1f572643b55f829eb3291d11", 'chaes (OO/1)'); + +is( chaes("123"), pack("H*","fc04dbd92bbb0311c6cfc6cb75d64a7c"), 'chaes (raw/2)'); +is( chaes_hex("123"), "fc04dbd92bbb0311c6cfc6cb75d64a7c", 'chaes (hex/2)'); +is( chaes_b64("123"), "/ATb2Su7AxHGz8bLddZKfA==", 'chaes (base64/2)'); +is( digest_data('CHAES', "123"), pack("H*","fc04dbd92bbb0311c6cfc6cb75d64a7c"), 'chaes (digest_data_raw/2)'); +is( digest_data_hex('CHAES', "123"), "fc04dbd92bbb0311c6cfc6cb75d64a7c", 'chaes (digest_data_hex/2)'); +is( digest_data_b64('CHAES', "123"), "/ATb2Su7AxHGz8bLddZKfA==", 'chaes (digest_data_b64/2)'); +is( digest_data_b64u('CHAES', "123"), "_ATb2Su7AxHGz8bLddZKfA", 'chaes (digest_data_b64u/2)'); +is( Crypt::Digest::CHAES->new->add("123")->hexdigest, "fc04dbd92bbb0311c6cfc6cb75d64a7c", 'chaes (OO/2)'); + +is( chaes("test\0test\0test\n"), pack("H*","b01f0f1c3dbfb727f8e8a1775fcd9dbc"), 'chaes (raw/3)'); +is( chaes_hex("test\0test\0test\n"), "b01f0f1c3dbfb727f8e8a1775fcd9dbc", 'chaes (hex/3)'); +is( chaes_b64("test\0test\0test\n"), "sB8PHD2/tyf46KF3X82dvA==", 'chaes (base64/3)'); +is( digest_data('CHAES', "test\0test\0test\n"), pack("H*","b01f0f1c3dbfb727f8e8a1775fcd9dbc"), 'chaes (digest_data_raw/3)'); +is( digest_data_hex('CHAES', "test\0test\0test\n"), "b01f0f1c3dbfb727f8e8a1775fcd9dbc", 'chaes (digest_data_hex/3)'); +is( digest_data_b64('CHAES', "test\0test\0test\n"), "sB8PHD2/tyf46KF3X82dvA==", 'chaes (digest_data_b64/3)'); +is( digest_data_b64u('CHAES', "test\0test\0test\n"), "sB8PHD2_tyf46KF3X82dvA", 'chaes (digest_data_b64u/3)'); +is( Crypt::Digest::CHAES->new->add("test\0test\0test\n")->hexdigest, "b01f0f1c3dbfb727f8e8a1775fcd9dbc", 'chaes (OO/3)'); + + +is( chaes_file('t/data/binary-test.file'), pack("H*","50390a2472d0dffe0323360b28cf8060"), 'chaes (raw/file/1)'); +is( chaes_file_hex('t/data/binary-test.file'), "50390a2472d0dffe0323360b28cf8060", 'chaes (hex/file/1)'); +is( chaes_file_b64('t/data/binary-test.file'), "UDkKJHLQ3/4DIzYLKM+AYA==", 'chaes (base64/file/1)'); +is( digest_file('CHAES', 't/data/binary-test.file'), pack("H*","50390a2472d0dffe0323360b28cf8060"), 'chaes (digest_file_raw/file/1)'); +is( digest_file_hex('CHAES', 't/data/binary-test.file'), "50390a2472d0dffe0323360b28cf8060", 'chaes (digest_file_hex/file/1)'); +is( digest_file_b64('CHAES', 't/data/binary-test.file'), "UDkKJHLQ3/4DIzYLKM+AYA==", 'chaes (digest_file_b64/file/1)'); +is( digest_file_b64u('CHAES', 't/data/binary-test.file'), "UDkKJHLQ3_4DIzYLKM-AYA", 'chaes (digest_file_b64u/file/1)'); +is( Crypt::Digest::CHAES->new->addfile('t/data/binary-test.file')->hexdigest, "50390a2472d0dffe0323360b28cf8060", 'chaes (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::CHAES->new->addfile($fh)->hexdigest, "50390a2472d0dffe0323360b28cf8060", 'chaes (OO/filehandle/1)'); + close($fh); +} + +is( chaes_file('t/data/text-CR.file'), pack("H*","f08c7838baa3dbdc02b6ac290db47609"), 'chaes (raw/file/2)'); +is( chaes_file_hex('t/data/text-CR.file'), "f08c7838baa3dbdc02b6ac290db47609", 'chaes (hex/file/2)'); +is( chaes_file_b64('t/data/text-CR.file'), "8Ix4OLqj29wCtqwpDbR2CQ==", 'chaes (base64/file/2)'); +is( digest_file('CHAES', 't/data/text-CR.file'), pack("H*","f08c7838baa3dbdc02b6ac290db47609"), 'chaes (digest_file_raw/file/2)'); +is( digest_file_hex('CHAES', 't/data/text-CR.file'), "f08c7838baa3dbdc02b6ac290db47609", 'chaes (digest_file_hex/file/2)'); +is( digest_file_b64('CHAES', 't/data/text-CR.file'), "8Ix4OLqj29wCtqwpDbR2CQ==", 'chaes (digest_file_b64/file/2)'); +is( digest_file_b64u('CHAES', 't/data/text-CR.file'), "8Ix4OLqj29wCtqwpDbR2CQ", 'chaes (digest_file_b64u/file/2)'); +is( Crypt::Digest::CHAES->new->addfile('t/data/text-CR.file')->hexdigest, "f08c7838baa3dbdc02b6ac290db47609", 'chaes (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::CHAES->new->addfile($fh)->hexdigest, "f08c7838baa3dbdc02b6ac290db47609", 'chaes (OO/filehandle/2)'); + close($fh); +} + +is( chaes_file('t/data/text-CRLF.file'), pack("H*","b7874022b1a2558a2ffa384ca83bdd3f"), 'chaes (raw/file/3)'); +is( chaes_file_hex('t/data/text-CRLF.file'), "b7874022b1a2558a2ffa384ca83bdd3f", 'chaes (hex/file/3)'); +is( chaes_file_b64('t/data/text-CRLF.file'), "t4dAIrGiVYov+jhMqDvdPw==", 'chaes (base64/file/3)'); +is( digest_file('CHAES', 't/data/text-CRLF.file'), pack("H*","b7874022b1a2558a2ffa384ca83bdd3f"), 'chaes (digest_file_raw/file/3)'); +is( digest_file_hex('CHAES', 't/data/text-CRLF.file'), "b7874022b1a2558a2ffa384ca83bdd3f", 'chaes (digest_file_hex/file/3)'); +is( digest_file_b64('CHAES', 't/data/text-CRLF.file'), "t4dAIrGiVYov+jhMqDvdPw==", 'chaes (digest_file_b64/file/3)'); +is( digest_file_b64u('CHAES', 't/data/text-CRLF.file'), "t4dAIrGiVYov-jhMqDvdPw", 'chaes (digest_file_b64u/file/3)'); +is( Crypt::Digest::CHAES->new->addfile('t/data/text-CRLF.file')->hexdigest, "b7874022b1a2558a2ffa384ca83bdd3f", 'chaes (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::CHAES->new->addfile($fh)->hexdigest, "b7874022b1a2558a2ffa384ca83bdd3f", 'chaes (OO/filehandle/3)'); + close($fh); +} + +is( chaes_file('t/data/text-LF.file'), pack("H*","e4a2674dc4123b3fa38dc01414ba58aa"), 'chaes (raw/file/4)'); +is( chaes_file_hex('t/data/text-LF.file'), "e4a2674dc4123b3fa38dc01414ba58aa", 'chaes (hex/file/4)'); +is( chaes_file_b64('t/data/text-LF.file'), "5KJnTcQSOz+jjcAUFLpYqg==", 'chaes (base64/file/4)'); +is( digest_file('CHAES', 't/data/text-LF.file'), pack("H*","e4a2674dc4123b3fa38dc01414ba58aa"), 'chaes (digest_file_raw/file/4)'); +is( digest_file_hex('CHAES', 't/data/text-LF.file'), "e4a2674dc4123b3fa38dc01414ba58aa", 'chaes (digest_file_hex/file/4)'); +is( digest_file_b64('CHAES', 't/data/text-LF.file'), "5KJnTcQSOz+jjcAUFLpYqg==", 'chaes (digest_file_b64/file/4)'); +is( digest_file_b64u('CHAES', 't/data/text-LF.file'), "5KJnTcQSOz-jjcAUFLpYqg", 'chaes (digest_file_b64u/file/4)'); +is( Crypt::Digest::CHAES->new->addfile('t/data/text-LF.file')->hexdigest, "e4a2674dc4123b3fa38dc01414ba58aa", 'chaes (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::CHAES->new->addfile($fh)->hexdigest, "e4a2674dc4123b3fa38dc01414ba58aa", 'chaes (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_md2.t b/t/digest_md2.t new file mode 100644 index 0000000..312011d --- /dev/null +++ b/t/digest_md2.t @@ -0,0 +1,105 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::MD2 qw( md2 md2_hex md2_b64 md2_b64u md2_file md2_file_hex md2_file_b64 md2_file_b64u ); + +is( Crypt::Digest::hashsize('MD2'), 16, 'hashsize/1'); +is( Crypt::Digest->hashsize('MD2'), 16, 'hashsize/2'); +is( Crypt::Digest::MD2::hashsize, 16, 'hashsize/3'); +is( Crypt::Digest::MD2->hashsize, 16, 'hashsize/4'); +is( Crypt::Digest->new('MD2')->hashsize, 16, 'hashsize/5'); +is( Crypt::Digest::MD2->new->hashsize, 16, 'hashsize/6'); + + +is( md2(""), pack("H*","8350e5a3e24c153df2275c9f80692773"), 'md2 (raw/1)'); +is( md2_hex(""), "8350e5a3e24c153df2275c9f80692773", 'md2 (hex/1)'); +is( md2_b64(""), "g1Dlo+JMFT3yJ1yfgGkncw==", 'md2 (base64/1)'); +is( digest_data('MD2', ""), pack("H*","8350e5a3e24c153df2275c9f80692773"), 'md2 (digest_data_raw/1)'); +is( digest_data_hex('MD2', ""), "8350e5a3e24c153df2275c9f80692773", 'md2 (digest_data_hex/1)'); +is( digest_data_b64('MD2', ""), "g1Dlo+JMFT3yJ1yfgGkncw==", 'md2 (digest_data_b64/1)'); +is( digest_data_b64u('MD2', ""), "g1Dlo-JMFT3yJ1yfgGkncw", 'md2 (digest_data_b64u/1)'); +is( Crypt::Digest::MD2->new->add("")->hexdigest, "8350e5a3e24c153df2275c9f80692773", 'md2 (OO/1)'); + +is( md2("123"), pack("H*","ef1fedf5d32ead6b7aaf687de4ed1b71"), 'md2 (raw/2)'); +is( md2_hex("123"), "ef1fedf5d32ead6b7aaf687de4ed1b71", 'md2 (hex/2)'); +is( md2_b64("123"), "7x/t9dMurWt6r2h95O0bcQ==", 'md2 (base64/2)'); +is( digest_data('MD2', "123"), pack("H*","ef1fedf5d32ead6b7aaf687de4ed1b71"), 'md2 (digest_data_raw/2)'); +is( digest_data_hex('MD2', "123"), "ef1fedf5d32ead6b7aaf687de4ed1b71", 'md2 (digest_data_hex/2)'); +is( digest_data_b64('MD2', "123"), "7x/t9dMurWt6r2h95O0bcQ==", 'md2 (digest_data_b64/2)'); +is( digest_data_b64u('MD2', "123"), "7x_t9dMurWt6r2h95O0bcQ", 'md2 (digest_data_b64u/2)'); +is( Crypt::Digest::MD2->new->add("123")->hexdigest, "ef1fedf5d32ead6b7aaf687de4ed1b71", 'md2 (OO/2)'); + +is( md2("test\0test\0test\n"), pack("H*","2ab87f6a63c5a8095e4b1207f3ff860c"), 'md2 (raw/3)'); +is( md2_hex("test\0test\0test\n"), "2ab87f6a63c5a8095e4b1207f3ff860c", 'md2 (hex/3)'); +is( md2_b64("test\0test\0test\n"), "Krh/amPFqAleSxIH8/+GDA==", 'md2 (base64/3)'); +is( digest_data('MD2', "test\0test\0test\n"), pack("H*","2ab87f6a63c5a8095e4b1207f3ff860c"), 'md2 (digest_data_raw/3)'); +is( digest_data_hex('MD2', "test\0test\0test\n"), "2ab87f6a63c5a8095e4b1207f3ff860c", 'md2 (digest_data_hex/3)'); +is( digest_data_b64('MD2', "test\0test\0test\n"), "Krh/amPFqAleSxIH8/+GDA==", 'md2 (digest_data_b64/3)'); +is( digest_data_b64u('MD2', "test\0test\0test\n"), "Krh_amPFqAleSxIH8_-GDA", 'md2 (digest_data_b64u/3)'); +is( Crypt::Digest::MD2->new->add("test\0test\0test\n")->hexdigest, "2ab87f6a63c5a8095e4b1207f3ff860c", 'md2 (OO/3)'); + + +is( md2_file('t/data/binary-test.file'), pack("H*","43fa4a403cf2b9826a72154d56bc09a7"), 'md2 (raw/file/1)'); +is( md2_file_hex('t/data/binary-test.file'), "43fa4a403cf2b9826a72154d56bc09a7", 'md2 (hex/file/1)'); +is( md2_file_b64('t/data/binary-test.file'), "Q/pKQDzyuYJqchVNVrwJpw==", 'md2 (base64/file/1)'); +is( digest_file('MD2', 't/data/binary-test.file'), pack("H*","43fa4a403cf2b9826a72154d56bc09a7"), 'md2 (digest_file_raw/file/1)'); +is( digest_file_hex('MD2', 't/data/binary-test.file'), "43fa4a403cf2b9826a72154d56bc09a7", 'md2 (digest_file_hex/file/1)'); +is( digest_file_b64('MD2', 't/data/binary-test.file'), "Q/pKQDzyuYJqchVNVrwJpw==", 'md2 (digest_file_b64/file/1)'); +is( digest_file_b64u('MD2', 't/data/binary-test.file'), "Q_pKQDzyuYJqchVNVrwJpw", 'md2 (digest_file_b64u/file/1)'); +is( Crypt::Digest::MD2->new->addfile('t/data/binary-test.file')->hexdigest, "43fa4a403cf2b9826a72154d56bc09a7", 'md2 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::MD2->new->addfile($fh)->hexdigest, "43fa4a403cf2b9826a72154d56bc09a7", 'md2 (OO/filehandle/1)'); + close($fh); +} + +is( md2_file('t/data/text-CR.file'), pack("H*","aefb6839dad1aa061e231e9c3aeb7ad0"), 'md2 (raw/file/2)'); +is( md2_file_hex('t/data/text-CR.file'), "aefb6839dad1aa061e231e9c3aeb7ad0", 'md2 (hex/file/2)'); +is( md2_file_b64('t/data/text-CR.file'), "rvtoOdrRqgYeIx6cOut60A==", 'md2 (base64/file/2)'); +is( digest_file('MD2', 't/data/text-CR.file'), pack("H*","aefb6839dad1aa061e231e9c3aeb7ad0"), 'md2 (digest_file_raw/file/2)'); +is( digest_file_hex('MD2', 't/data/text-CR.file'), "aefb6839dad1aa061e231e9c3aeb7ad0", 'md2 (digest_file_hex/file/2)'); +is( digest_file_b64('MD2', 't/data/text-CR.file'), "rvtoOdrRqgYeIx6cOut60A==", 'md2 (digest_file_b64/file/2)'); +is( digest_file_b64u('MD2', 't/data/text-CR.file'), "rvtoOdrRqgYeIx6cOut60A", 'md2 (digest_file_b64u/file/2)'); +is( Crypt::Digest::MD2->new->addfile('t/data/text-CR.file')->hexdigest, "aefb6839dad1aa061e231e9c3aeb7ad0", 'md2 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::MD2->new->addfile($fh)->hexdigest, "aefb6839dad1aa061e231e9c3aeb7ad0", 'md2 (OO/filehandle/2)'); + close($fh); +} + +is( md2_file('t/data/text-CRLF.file'), pack("H*","5c32665f8372b97aa1d8ed733d88f50e"), 'md2 (raw/file/3)'); +is( md2_file_hex('t/data/text-CRLF.file'), "5c32665f8372b97aa1d8ed733d88f50e", 'md2 (hex/file/3)'); +is( md2_file_b64('t/data/text-CRLF.file'), "XDJmX4NyuXqh2O1zPYj1Dg==", 'md2 (base64/file/3)'); +is( digest_file('MD2', 't/data/text-CRLF.file'), pack("H*","5c32665f8372b97aa1d8ed733d88f50e"), 'md2 (digest_file_raw/file/3)'); +is( digest_file_hex('MD2', 't/data/text-CRLF.file'), "5c32665f8372b97aa1d8ed733d88f50e", 'md2 (digest_file_hex/file/3)'); +is( digest_file_b64('MD2', 't/data/text-CRLF.file'), "XDJmX4NyuXqh2O1zPYj1Dg==", 'md2 (digest_file_b64/file/3)'); +is( digest_file_b64u('MD2', 't/data/text-CRLF.file'), "XDJmX4NyuXqh2O1zPYj1Dg", 'md2 (digest_file_b64u/file/3)'); +is( Crypt::Digest::MD2->new->addfile('t/data/text-CRLF.file')->hexdigest, "5c32665f8372b97aa1d8ed733d88f50e", 'md2 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::MD2->new->addfile($fh)->hexdigest, "5c32665f8372b97aa1d8ed733d88f50e", 'md2 (OO/filehandle/3)'); + close($fh); +} + +is( md2_file('t/data/text-LF.file'), pack("H*","0e4142ba5bdaa257e4c618f9b309784c"), 'md2 (raw/file/4)'); +is( md2_file_hex('t/data/text-LF.file'), "0e4142ba5bdaa257e4c618f9b309784c", 'md2 (hex/file/4)'); +is( md2_file_b64('t/data/text-LF.file'), "DkFCulvaolfkxhj5swl4TA==", 'md2 (base64/file/4)'); +is( digest_file('MD2', 't/data/text-LF.file'), pack("H*","0e4142ba5bdaa257e4c618f9b309784c"), 'md2 (digest_file_raw/file/4)'); +is( digest_file_hex('MD2', 't/data/text-LF.file'), "0e4142ba5bdaa257e4c618f9b309784c", 'md2 (digest_file_hex/file/4)'); +is( digest_file_b64('MD2', 't/data/text-LF.file'), "DkFCulvaolfkxhj5swl4TA==", 'md2 (digest_file_b64/file/4)'); +is( digest_file_b64u('MD2', 't/data/text-LF.file'), "DkFCulvaolfkxhj5swl4TA", 'md2 (digest_file_b64u/file/4)'); +is( Crypt::Digest::MD2->new->addfile('t/data/text-LF.file')->hexdigest, "0e4142ba5bdaa257e4c618f9b309784c", 'md2 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::MD2->new->addfile($fh)->hexdigest, "0e4142ba5bdaa257e4c618f9b309784c", 'md2 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_md4.t b/t/digest_md4.t new file mode 100644 index 0000000..b83d061 --- /dev/null +++ b/t/digest_md4.t @@ -0,0 +1,105 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::MD4 qw( md4 md4_hex md4_b64 md4_b64u md4_file md4_file_hex md4_file_b64 md4_file_b64u ); + +is( Crypt::Digest::hashsize('MD4'), 16, 'hashsize/1'); +is( Crypt::Digest->hashsize('MD4'), 16, 'hashsize/2'); +is( Crypt::Digest::MD4::hashsize, 16, 'hashsize/3'); +is( Crypt::Digest::MD4->hashsize, 16, 'hashsize/4'); +is( Crypt::Digest->new('MD4')->hashsize, 16, 'hashsize/5'); +is( Crypt::Digest::MD4->new->hashsize, 16, 'hashsize/6'); + + +is( md4(""), pack("H*","31d6cfe0d16ae931b73c59d7e0c089c0"), 'md4 (raw/1)'); +is( md4_hex(""), "31d6cfe0d16ae931b73c59d7e0c089c0", 'md4 (hex/1)'); +is( md4_b64(""), "MdbP4NFq6TG3PFnX4MCJwA==", 'md4 (base64/1)'); +is( digest_data('MD4', ""), pack("H*","31d6cfe0d16ae931b73c59d7e0c089c0"), 'md4 (digest_data_raw/1)'); +is( digest_data_hex('MD4', ""), "31d6cfe0d16ae931b73c59d7e0c089c0", 'md4 (digest_data_hex/1)'); +is( digest_data_b64('MD4', ""), "MdbP4NFq6TG3PFnX4MCJwA==", 'md4 (digest_data_b64/1)'); +is( digest_data_b64u('MD4', ""), "MdbP4NFq6TG3PFnX4MCJwA", 'md4 (digest_data_b64u/1)'); +is( Crypt::Digest::MD4->new->add("")->hexdigest, "31d6cfe0d16ae931b73c59d7e0c089c0", 'md4 (OO/1)'); + +is( md4("123"), pack("H*","c58cda49f00748a3bc0fcfa511d516cb"), 'md4 (raw/2)'); +is( md4_hex("123"), "c58cda49f00748a3bc0fcfa511d516cb", 'md4 (hex/2)'); +is( md4_b64("123"), "xYzaSfAHSKO8D8+lEdUWyw==", 'md4 (base64/2)'); +is( digest_data('MD4', "123"), pack("H*","c58cda49f00748a3bc0fcfa511d516cb"), 'md4 (digest_data_raw/2)'); +is( digest_data_hex('MD4', "123"), "c58cda49f00748a3bc0fcfa511d516cb", 'md4 (digest_data_hex/2)'); +is( digest_data_b64('MD4', "123"), "xYzaSfAHSKO8D8+lEdUWyw==", 'md4 (digest_data_b64/2)'); +is( digest_data_b64u('MD4', "123"), "xYzaSfAHSKO8D8-lEdUWyw", 'md4 (digest_data_b64u/2)'); +is( Crypt::Digest::MD4->new->add("123")->hexdigest, "c58cda49f00748a3bc0fcfa511d516cb", 'md4 (OO/2)'); + +is( md4("test\0test\0test\n"), pack("H*","6c94f5386a75255cb008ea5ef7979eed"), 'md4 (raw/3)'); +is( md4_hex("test\0test\0test\n"), "6c94f5386a75255cb008ea5ef7979eed", 'md4 (hex/3)'); +is( md4_b64("test\0test\0test\n"), "bJT1OGp1JVywCOpe95ee7Q==", 'md4 (base64/3)'); +is( digest_data('MD4', "test\0test\0test\n"), pack("H*","6c94f5386a75255cb008ea5ef7979eed"), 'md4 (digest_data_raw/3)'); +is( digest_data_hex('MD4', "test\0test\0test\n"), "6c94f5386a75255cb008ea5ef7979eed", 'md4 (digest_data_hex/3)'); +is( digest_data_b64('MD4', "test\0test\0test\n"), "bJT1OGp1JVywCOpe95ee7Q==", 'md4 (digest_data_b64/3)'); +is( digest_data_b64u('MD4', "test\0test\0test\n"), "bJT1OGp1JVywCOpe95ee7Q", 'md4 (digest_data_b64u/3)'); +is( Crypt::Digest::MD4->new->add("test\0test\0test\n")->hexdigest, "6c94f5386a75255cb008ea5ef7979eed", 'md4 (OO/3)'); + + +is( md4_file('t/data/binary-test.file'), pack("H*","dc293e17d9dad79a9311a145c6a96b31"), 'md4 (raw/file/1)'); +is( md4_file_hex('t/data/binary-test.file'), "dc293e17d9dad79a9311a145c6a96b31", 'md4 (hex/file/1)'); +is( md4_file_b64('t/data/binary-test.file'), "3Ck+F9na15qTEaFFxqlrMQ==", 'md4 (base64/file/1)'); +is( digest_file('MD4', 't/data/binary-test.file'), pack("H*","dc293e17d9dad79a9311a145c6a96b31"), 'md4 (digest_file_raw/file/1)'); +is( digest_file_hex('MD4', 't/data/binary-test.file'), "dc293e17d9dad79a9311a145c6a96b31", 'md4 (digest_file_hex/file/1)'); +is( digest_file_b64('MD4', 't/data/binary-test.file'), "3Ck+F9na15qTEaFFxqlrMQ==", 'md4 (digest_file_b64/file/1)'); +is( digest_file_b64u('MD4', 't/data/binary-test.file'), "3Ck-F9na15qTEaFFxqlrMQ", 'md4 (digest_file_b64u/file/1)'); +is( Crypt::Digest::MD4->new->addfile('t/data/binary-test.file')->hexdigest, "dc293e17d9dad79a9311a145c6a96b31", 'md4 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::MD4->new->addfile($fh)->hexdigest, "dc293e17d9dad79a9311a145c6a96b31", 'md4 (OO/filehandle/1)'); + close($fh); +} + +is( md4_file('t/data/text-CR.file'), pack("H*","f0060ad3ed8081c8d55ede445cd19133"), 'md4 (raw/file/2)'); +is( md4_file_hex('t/data/text-CR.file'), "f0060ad3ed8081c8d55ede445cd19133", 'md4 (hex/file/2)'); +is( md4_file_b64('t/data/text-CR.file'), "8AYK0+2AgcjVXt5EXNGRMw==", 'md4 (base64/file/2)'); +is( digest_file('MD4', 't/data/text-CR.file'), pack("H*","f0060ad3ed8081c8d55ede445cd19133"), 'md4 (digest_file_raw/file/2)'); +is( digest_file_hex('MD4', 't/data/text-CR.file'), "f0060ad3ed8081c8d55ede445cd19133", 'md4 (digest_file_hex/file/2)'); +is( digest_file_b64('MD4', 't/data/text-CR.file'), "8AYK0+2AgcjVXt5EXNGRMw==", 'md4 (digest_file_b64/file/2)'); +is( digest_file_b64u('MD4', 't/data/text-CR.file'), "8AYK0-2AgcjVXt5EXNGRMw", 'md4 (digest_file_b64u/file/2)'); +is( Crypt::Digest::MD4->new->addfile('t/data/text-CR.file')->hexdigest, "f0060ad3ed8081c8d55ede445cd19133", 'md4 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::MD4->new->addfile($fh)->hexdigest, "f0060ad3ed8081c8d55ede445cd19133", 'md4 (OO/filehandle/2)'); + close($fh); +} + +is( md4_file('t/data/text-CRLF.file'), pack("H*","2c3026b3dea9ef3089d5ff750054b38b"), 'md4 (raw/file/3)'); +is( md4_file_hex('t/data/text-CRLF.file'), "2c3026b3dea9ef3089d5ff750054b38b", 'md4 (hex/file/3)'); +is( md4_file_b64('t/data/text-CRLF.file'), "LDAms96p7zCJ1f91AFSziw==", 'md4 (base64/file/3)'); +is( digest_file('MD4', 't/data/text-CRLF.file'), pack("H*","2c3026b3dea9ef3089d5ff750054b38b"), 'md4 (digest_file_raw/file/3)'); +is( digest_file_hex('MD4', 't/data/text-CRLF.file'), "2c3026b3dea9ef3089d5ff750054b38b", 'md4 (digest_file_hex/file/3)'); +is( digest_file_b64('MD4', 't/data/text-CRLF.file'), "LDAms96p7zCJ1f91AFSziw==", 'md4 (digest_file_b64/file/3)'); +is( digest_file_b64u('MD4', 't/data/text-CRLF.file'), "LDAms96p7zCJ1f91AFSziw", 'md4 (digest_file_b64u/file/3)'); +is( Crypt::Digest::MD4->new->addfile('t/data/text-CRLF.file')->hexdigest, "2c3026b3dea9ef3089d5ff750054b38b", 'md4 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::MD4->new->addfile($fh)->hexdigest, "2c3026b3dea9ef3089d5ff750054b38b", 'md4 (OO/filehandle/3)'); + close($fh); +} + +is( md4_file('t/data/text-LF.file'), pack("H*","3c87e1ed3fb63667f87a3ec8217f20ef"), 'md4 (raw/file/4)'); +is( md4_file_hex('t/data/text-LF.file'), "3c87e1ed3fb63667f87a3ec8217f20ef", 'md4 (hex/file/4)'); +is( md4_file_b64('t/data/text-LF.file'), "PIfh7T+2Nmf4ej7IIX8g7w==", 'md4 (base64/file/4)'); +is( digest_file('MD4', 't/data/text-LF.file'), pack("H*","3c87e1ed3fb63667f87a3ec8217f20ef"), 'md4 (digest_file_raw/file/4)'); +is( digest_file_hex('MD4', 't/data/text-LF.file'), "3c87e1ed3fb63667f87a3ec8217f20ef", 'md4 (digest_file_hex/file/4)'); +is( digest_file_b64('MD4', 't/data/text-LF.file'), "PIfh7T+2Nmf4ej7IIX8g7w==", 'md4 (digest_file_b64/file/4)'); +is( digest_file_b64u('MD4', 't/data/text-LF.file'), "PIfh7T-2Nmf4ej7IIX8g7w", 'md4 (digest_file_b64u/file/4)'); +is( Crypt::Digest::MD4->new->addfile('t/data/text-LF.file')->hexdigest, "3c87e1ed3fb63667f87a3ec8217f20ef", 'md4 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::MD4->new->addfile($fh)->hexdigest, "3c87e1ed3fb63667f87a3ec8217f20ef", 'md4 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_md5.t b/t/digest_md5.t new file mode 100644 index 0000000..c4b2240 --- /dev/null +++ b/t/digest_md5.t @@ -0,0 +1,105 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::MD5 qw( md5 md5_hex md5_b64 md5_b64u md5_file md5_file_hex md5_file_b64 md5_file_b64u ); + +is( Crypt::Digest::hashsize('MD5'), 16, 'hashsize/1'); +is( Crypt::Digest->hashsize('MD5'), 16, 'hashsize/2'); +is( Crypt::Digest::MD5::hashsize, 16, 'hashsize/3'); +is( Crypt::Digest::MD5->hashsize, 16, 'hashsize/4'); +is( Crypt::Digest->new('MD5')->hashsize, 16, 'hashsize/5'); +is( Crypt::Digest::MD5->new->hashsize, 16, 'hashsize/6'); + + +is( md5(""), pack("H*","d41d8cd98f00b204e9800998ecf8427e"), 'md5 (raw/1)'); +is( md5_hex(""), "d41d8cd98f00b204e9800998ecf8427e", 'md5 (hex/1)'); +is( md5_b64(""), "1B2M2Y8AsgTpgAmY7PhCfg==", 'md5 (base64/1)'); +is( digest_data('MD5', ""), pack("H*","d41d8cd98f00b204e9800998ecf8427e"), 'md5 (digest_data_raw/1)'); +is( digest_data_hex('MD5', ""), "d41d8cd98f00b204e9800998ecf8427e", 'md5 (digest_data_hex/1)'); +is( digest_data_b64('MD5', ""), "1B2M2Y8AsgTpgAmY7PhCfg==", 'md5 (digest_data_b64/1)'); +is( digest_data_b64u('MD5', ""), "1B2M2Y8AsgTpgAmY7PhCfg", 'md5 (digest_data_b64u/1)'); +is( Crypt::Digest::MD5->new->add("")->hexdigest, "d41d8cd98f00b204e9800998ecf8427e", 'md5 (OO/1)'); + +is( md5("123"), pack("H*","202cb962ac59075b964b07152d234b70"), 'md5 (raw/2)'); +is( md5_hex("123"), "202cb962ac59075b964b07152d234b70", 'md5 (hex/2)'); +is( md5_b64("123"), "ICy5YqxZB1uWSwcVLSNLcA==", 'md5 (base64/2)'); +is( digest_data('MD5', "123"), pack("H*","202cb962ac59075b964b07152d234b70"), 'md5 (digest_data_raw/2)'); +is( digest_data_hex('MD5', "123"), "202cb962ac59075b964b07152d234b70", 'md5 (digest_data_hex/2)'); +is( digest_data_b64('MD5', "123"), "ICy5YqxZB1uWSwcVLSNLcA==", 'md5 (digest_data_b64/2)'); +is( digest_data_b64u('MD5', "123"), "ICy5YqxZB1uWSwcVLSNLcA", 'md5 (digest_data_b64u/2)'); +is( Crypt::Digest::MD5->new->add("123")->hexdigest, "202cb962ac59075b964b07152d234b70", 'md5 (OO/2)'); + +is( md5("test\0test\0test\n"), pack("H*","38b00a95b30ee620eacd9aa05259a436"), 'md5 (raw/3)'); +is( md5_hex("test\0test\0test\n"), "38b00a95b30ee620eacd9aa05259a436", 'md5 (hex/3)'); +is( md5_b64("test\0test\0test\n"), "OLAKlbMO5iDqzZqgUlmkNg==", 'md5 (base64/3)'); +is( digest_data('MD5', "test\0test\0test\n"), pack("H*","38b00a95b30ee620eacd9aa05259a436"), 'md5 (digest_data_raw/3)'); +is( digest_data_hex('MD5', "test\0test\0test\n"), "38b00a95b30ee620eacd9aa05259a436", 'md5 (digest_data_hex/3)'); +is( digest_data_b64('MD5', "test\0test\0test\n"), "OLAKlbMO5iDqzZqgUlmkNg==", 'md5 (digest_data_b64/3)'); +is( digest_data_b64u('MD5', "test\0test\0test\n"), "OLAKlbMO5iDqzZqgUlmkNg", 'md5 (digest_data_b64u/3)'); +is( Crypt::Digest::MD5->new->add("test\0test\0test\n")->hexdigest, "38b00a95b30ee620eacd9aa05259a436", 'md5 (OO/3)'); + + +is( md5_file('t/data/binary-test.file'), pack("H*","ca56fa983a4b49e81c68167fe4a2e835"), 'md5 (raw/file/1)'); +is( md5_file_hex('t/data/binary-test.file'), "ca56fa983a4b49e81c68167fe4a2e835", 'md5 (hex/file/1)'); +is( md5_file_b64('t/data/binary-test.file'), "ylb6mDpLSegcaBZ/5KLoNQ==", 'md5 (base64/file/1)'); +is( digest_file('MD5', 't/data/binary-test.file'), pack("H*","ca56fa983a4b49e81c68167fe4a2e835"), 'md5 (digest_file_raw/file/1)'); +is( digest_file_hex('MD5', 't/data/binary-test.file'), "ca56fa983a4b49e81c68167fe4a2e835", 'md5 (digest_file_hex/file/1)'); +is( digest_file_b64('MD5', 't/data/binary-test.file'), "ylb6mDpLSegcaBZ/5KLoNQ==", 'md5 (digest_file_b64/file/1)'); +is( digest_file_b64u('MD5', 't/data/binary-test.file'), "ylb6mDpLSegcaBZ_5KLoNQ", 'md5 (digest_file_b64u/file/1)'); +is( Crypt::Digest::MD5->new->addfile('t/data/binary-test.file')->hexdigest, "ca56fa983a4b49e81c68167fe4a2e835", 'md5 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::MD5->new->addfile($fh)->hexdigest, "ca56fa983a4b49e81c68167fe4a2e835", 'md5 (OO/filehandle/1)'); + close($fh); +} + +is( md5_file('t/data/text-CR.file'), pack("H*","9e2beba516f19ee3d2b3cfcbfbf05fc2"), 'md5 (raw/file/2)'); +is( md5_file_hex('t/data/text-CR.file'), "9e2beba516f19ee3d2b3cfcbfbf05fc2", 'md5 (hex/file/2)'); +is( md5_file_b64('t/data/text-CR.file'), "nivrpRbxnuPSs8/L+/Bfwg==", 'md5 (base64/file/2)'); +is( digest_file('MD5', 't/data/text-CR.file'), pack("H*","9e2beba516f19ee3d2b3cfcbfbf05fc2"), 'md5 (digest_file_raw/file/2)'); +is( digest_file_hex('MD5', 't/data/text-CR.file'), "9e2beba516f19ee3d2b3cfcbfbf05fc2", 'md5 (digest_file_hex/file/2)'); +is( digest_file_b64('MD5', 't/data/text-CR.file'), "nivrpRbxnuPSs8/L+/Bfwg==", 'md5 (digest_file_b64/file/2)'); +is( digest_file_b64u('MD5', 't/data/text-CR.file'), "nivrpRbxnuPSs8_L-_Bfwg", 'md5 (digest_file_b64u/file/2)'); +is( Crypt::Digest::MD5->new->addfile('t/data/text-CR.file')->hexdigest, "9e2beba516f19ee3d2b3cfcbfbf05fc2", 'md5 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::MD5->new->addfile($fh)->hexdigest, "9e2beba516f19ee3d2b3cfcbfbf05fc2", 'md5 (OO/filehandle/2)'); + close($fh); +} + +is( md5_file('t/data/text-CRLF.file'), pack("H*","d939ac2b17f6091bb062bb6f9190fc76"), 'md5 (raw/file/3)'); +is( md5_file_hex('t/data/text-CRLF.file'), "d939ac2b17f6091bb062bb6f9190fc76", 'md5 (hex/file/3)'); +is( md5_file_b64('t/data/text-CRLF.file'), "2TmsKxf2CRuwYrtvkZD8dg==", 'md5 (base64/file/3)'); +is( digest_file('MD5', 't/data/text-CRLF.file'), pack("H*","d939ac2b17f6091bb062bb6f9190fc76"), 'md5 (digest_file_raw/file/3)'); +is( digest_file_hex('MD5', 't/data/text-CRLF.file'), "d939ac2b17f6091bb062bb6f9190fc76", 'md5 (digest_file_hex/file/3)'); +is( digest_file_b64('MD5', 't/data/text-CRLF.file'), "2TmsKxf2CRuwYrtvkZD8dg==", 'md5 (digest_file_b64/file/3)'); +is( digest_file_b64u('MD5', 't/data/text-CRLF.file'), "2TmsKxf2CRuwYrtvkZD8dg", 'md5 (digest_file_b64u/file/3)'); +is( Crypt::Digest::MD5->new->addfile('t/data/text-CRLF.file')->hexdigest, "d939ac2b17f6091bb062bb6f9190fc76", 'md5 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::MD5->new->addfile($fh)->hexdigest, "d939ac2b17f6091bb062bb6f9190fc76", 'md5 (OO/filehandle/3)'); + close($fh); +} + +is( md5_file('t/data/text-LF.file'), pack("H*","2c5b1996d510a6cc97fad5fbaa0b313f"), 'md5 (raw/file/4)'); +is( md5_file_hex('t/data/text-LF.file'), "2c5b1996d510a6cc97fad5fbaa0b313f", 'md5 (hex/file/4)'); +is( md5_file_b64('t/data/text-LF.file'), "LFsZltUQpsyX+tX7qgsxPw==", 'md5 (base64/file/4)'); +is( digest_file('MD5', 't/data/text-LF.file'), pack("H*","2c5b1996d510a6cc97fad5fbaa0b313f"), 'md5 (digest_file_raw/file/4)'); +is( digest_file_hex('MD5', 't/data/text-LF.file'), "2c5b1996d510a6cc97fad5fbaa0b313f", 'md5 (digest_file_hex/file/4)'); +is( digest_file_b64('MD5', 't/data/text-LF.file'), "LFsZltUQpsyX+tX7qgsxPw==", 'md5 (digest_file_b64/file/4)'); +is( digest_file_b64u('MD5', 't/data/text-LF.file'), "LFsZltUQpsyX-tX7qgsxPw", 'md5 (digest_file_b64u/file/4)'); +is( Crypt::Digest::MD5->new->addfile('t/data/text-LF.file')->hexdigest, "2c5b1996d510a6cc97fad5fbaa0b313f", 'md5 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::MD5->new->addfile($fh)->hexdigest, "2c5b1996d510a6cc97fad5fbaa0b313f", 'md5 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_ripemd128.t b/t/digest_ripemd128.t new file mode 100644 index 0000000..e655aa2 --- /dev/null +++ b/t/digest_ripemd128.t @@ -0,0 +1,105 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::RIPEMD128 qw( ripemd128 ripemd128_hex ripemd128_b64 ripemd128_b64u ripemd128_file ripemd128_file_hex ripemd128_file_b64 ripemd128_file_b64u ); + +is( Crypt::Digest::hashsize('RIPEMD128'), 16, 'hashsize/1'); +is( Crypt::Digest->hashsize('RIPEMD128'), 16, 'hashsize/2'); +is( Crypt::Digest::RIPEMD128::hashsize, 16, 'hashsize/3'); +is( Crypt::Digest::RIPEMD128->hashsize, 16, 'hashsize/4'); +is( Crypt::Digest->new('RIPEMD128')->hashsize, 16, 'hashsize/5'); +is( Crypt::Digest::RIPEMD128->new->hashsize, 16, 'hashsize/6'); + + +is( ripemd128(""), pack("H*","cdf26213a150dc3ecb610f18f6b38b46"), 'ripemd128 (raw/1)'); +is( ripemd128_hex(""), "cdf26213a150dc3ecb610f18f6b38b46", 'ripemd128 (hex/1)'); +is( ripemd128_b64(""), "zfJiE6FQ3D7LYQ8Y9rOLRg==", 'ripemd128 (base64/1)'); +is( digest_data('RIPEMD128', ""), pack("H*","cdf26213a150dc3ecb610f18f6b38b46"), 'ripemd128 (digest_data_raw/1)'); +is( digest_data_hex('RIPEMD128', ""), "cdf26213a150dc3ecb610f18f6b38b46", 'ripemd128 (digest_data_hex/1)'); +is( digest_data_b64('RIPEMD128', ""), "zfJiE6FQ3D7LYQ8Y9rOLRg==", 'ripemd128 (digest_data_b64/1)'); +is( digest_data_b64u('RIPEMD128', ""), "zfJiE6FQ3D7LYQ8Y9rOLRg", 'ripemd128 (digest_data_b64u/1)'); +is( Crypt::Digest::RIPEMD128->new->add("")->hexdigest, "cdf26213a150dc3ecb610f18f6b38b46", 'ripemd128 (OO/1)'); + +is( ripemd128("123"), pack("H*","781f357c35df1fef3138f6d29670365a"), 'ripemd128 (raw/2)'); +is( ripemd128_hex("123"), "781f357c35df1fef3138f6d29670365a", 'ripemd128 (hex/2)'); +is( ripemd128_b64("123"), "eB81fDXfH+8xOPbSlnA2Wg==", 'ripemd128 (base64/2)'); +is( digest_data('RIPEMD128', "123"), pack("H*","781f357c35df1fef3138f6d29670365a"), 'ripemd128 (digest_data_raw/2)'); +is( digest_data_hex('RIPEMD128', "123"), "781f357c35df1fef3138f6d29670365a", 'ripemd128 (digest_data_hex/2)'); +is( digest_data_b64('RIPEMD128', "123"), "eB81fDXfH+8xOPbSlnA2Wg==", 'ripemd128 (digest_data_b64/2)'); +is( digest_data_b64u('RIPEMD128', "123"), "eB81fDXfH-8xOPbSlnA2Wg", 'ripemd128 (digest_data_b64u/2)'); +is( Crypt::Digest::RIPEMD128->new->add("123")->hexdigest, "781f357c35df1fef3138f6d29670365a", 'ripemd128 (OO/2)'); + +is( ripemd128("test\0test\0test\n"), pack("H*","4910f92c00d56cedde3b8174c456ccbb"), 'ripemd128 (raw/3)'); +is( ripemd128_hex("test\0test\0test\n"), "4910f92c00d56cedde3b8174c456ccbb", 'ripemd128 (hex/3)'); +is( ripemd128_b64("test\0test\0test\n"), "SRD5LADVbO3eO4F0xFbMuw==", 'ripemd128 (base64/3)'); +is( digest_data('RIPEMD128', "test\0test\0test\n"), pack("H*","4910f92c00d56cedde3b8174c456ccbb"), 'ripemd128 (digest_data_raw/3)'); +is( digest_data_hex('RIPEMD128', "test\0test\0test\n"), "4910f92c00d56cedde3b8174c456ccbb", 'ripemd128 (digest_data_hex/3)'); +is( digest_data_b64('RIPEMD128', "test\0test\0test\n"), "SRD5LADVbO3eO4F0xFbMuw==", 'ripemd128 (digest_data_b64/3)'); +is( digest_data_b64u('RIPEMD128', "test\0test\0test\n"), "SRD5LADVbO3eO4F0xFbMuw", 'ripemd128 (digest_data_b64u/3)'); +is( Crypt::Digest::RIPEMD128->new->add("test\0test\0test\n")->hexdigest, "4910f92c00d56cedde3b8174c456ccbb", 'ripemd128 (OO/3)'); + + +is( ripemd128_file('t/data/binary-test.file'), pack("H*","55f625a0de3efa776e784340384bf671"), 'ripemd128 (raw/file/1)'); +is( ripemd128_file_hex('t/data/binary-test.file'), "55f625a0de3efa776e784340384bf671", 'ripemd128 (hex/file/1)'); +is( ripemd128_file_b64('t/data/binary-test.file'), "VfYloN4++ndueENAOEv2cQ==", 'ripemd128 (base64/file/1)'); +is( digest_file('RIPEMD128', 't/data/binary-test.file'), pack("H*","55f625a0de3efa776e784340384bf671"), 'ripemd128 (digest_file_raw/file/1)'); +is( digest_file_hex('RIPEMD128', 't/data/binary-test.file'), "55f625a0de3efa776e784340384bf671", 'ripemd128 (digest_file_hex/file/1)'); +is( digest_file_b64('RIPEMD128', 't/data/binary-test.file'), "VfYloN4++ndueENAOEv2cQ==", 'ripemd128 (digest_file_b64/file/1)'); +is( digest_file_b64u('RIPEMD128', 't/data/binary-test.file'), "VfYloN4--ndueENAOEv2cQ", 'ripemd128 (digest_file_b64u/file/1)'); +is( Crypt::Digest::RIPEMD128->new->addfile('t/data/binary-test.file')->hexdigest, "55f625a0de3efa776e784340384bf671", 'ripemd128 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::RIPEMD128->new->addfile($fh)->hexdigest, "55f625a0de3efa776e784340384bf671", 'ripemd128 (OO/filehandle/1)'); + close($fh); +} + +is( ripemd128_file('t/data/text-CR.file'), pack("H*","4c095a056f2fe18e00719a0209381054"), 'ripemd128 (raw/file/2)'); +is( ripemd128_file_hex('t/data/text-CR.file'), "4c095a056f2fe18e00719a0209381054", 'ripemd128 (hex/file/2)'); +is( ripemd128_file_b64('t/data/text-CR.file'), "TAlaBW8v4Y4AcZoCCTgQVA==", 'ripemd128 (base64/file/2)'); +is( digest_file('RIPEMD128', 't/data/text-CR.file'), pack("H*","4c095a056f2fe18e00719a0209381054"), 'ripemd128 (digest_file_raw/file/2)'); +is( digest_file_hex('RIPEMD128', 't/data/text-CR.file'), "4c095a056f2fe18e00719a0209381054", 'ripemd128 (digest_file_hex/file/2)'); +is( digest_file_b64('RIPEMD128', 't/data/text-CR.file'), "TAlaBW8v4Y4AcZoCCTgQVA==", 'ripemd128 (digest_file_b64/file/2)'); +is( digest_file_b64u('RIPEMD128', 't/data/text-CR.file'), "TAlaBW8v4Y4AcZoCCTgQVA", 'ripemd128 (digest_file_b64u/file/2)'); +is( Crypt::Digest::RIPEMD128->new->addfile('t/data/text-CR.file')->hexdigest, "4c095a056f2fe18e00719a0209381054", 'ripemd128 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::RIPEMD128->new->addfile($fh)->hexdigest, "4c095a056f2fe18e00719a0209381054", 'ripemd128 (OO/filehandle/2)'); + close($fh); +} + +is( ripemd128_file('t/data/text-CRLF.file'), pack("H*","eb35f79787dcd87b1fe02760922b0561"), 'ripemd128 (raw/file/3)'); +is( ripemd128_file_hex('t/data/text-CRLF.file'), "eb35f79787dcd87b1fe02760922b0561", 'ripemd128 (hex/file/3)'); +is( ripemd128_file_b64('t/data/text-CRLF.file'), "6zX3l4fc2Hsf4CdgkisFYQ==", 'ripemd128 (base64/file/3)'); +is( digest_file('RIPEMD128', 't/data/text-CRLF.file'), pack("H*","eb35f79787dcd87b1fe02760922b0561"), 'ripemd128 (digest_file_raw/file/3)'); +is( digest_file_hex('RIPEMD128', 't/data/text-CRLF.file'), "eb35f79787dcd87b1fe02760922b0561", 'ripemd128 (digest_file_hex/file/3)'); +is( digest_file_b64('RIPEMD128', 't/data/text-CRLF.file'), "6zX3l4fc2Hsf4CdgkisFYQ==", 'ripemd128 (digest_file_b64/file/3)'); +is( digest_file_b64u('RIPEMD128', 't/data/text-CRLF.file'), "6zX3l4fc2Hsf4CdgkisFYQ", 'ripemd128 (digest_file_b64u/file/3)'); +is( Crypt::Digest::RIPEMD128->new->addfile('t/data/text-CRLF.file')->hexdigest, "eb35f79787dcd87b1fe02760922b0561", 'ripemd128 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::RIPEMD128->new->addfile($fh)->hexdigest, "eb35f79787dcd87b1fe02760922b0561", 'ripemd128 (OO/filehandle/3)'); + close($fh); +} + +is( ripemd128_file('t/data/text-LF.file'), pack("H*","05863440dba144d5d0fdce73cbc27535"), 'ripemd128 (raw/file/4)'); +is( ripemd128_file_hex('t/data/text-LF.file'), "05863440dba144d5d0fdce73cbc27535", 'ripemd128 (hex/file/4)'); +is( ripemd128_file_b64('t/data/text-LF.file'), "BYY0QNuhRNXQ/c5zy8J1NQ==", 'ripemd128 (base64/file/4)'); +is( digest_file('RIPEMD128', 't/data/text-LF.file'), pack("H*","05863440dba144d5d0fdce73cbc27535"), 'ripemd128 (digest_file_raw/file/4)'); +is( digest_file_hex('RIPEMD128', 't/data/text-LF.file'), "05863440dba144d5d0fdce73cbc27535", 'ripemd128 (digest_file_hex/file/4)'); +is( digest_file_b64('RIPEMD128', 't/data/text-LF.file'), "BYY0QNuhRNXQ/c5zy8J1NQ==", 'ripemd128 (digest_file_b64/file/4)'); +is( digest_file_b64u('RIPEMD128', 't/data/text-LF.file'), "BYY0QNuhRNXQ_c5zy8J1NQ", 'ripemd128 (digest_file_b64u/file/4)'); +is( Crypt::Digest::RIPEMD128->new->addfile('t/data/text-LF.file')->hexdigest, "05863440dba144d5d0fdce73cbc27535", 'ripemd128 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::RIPEMD128->new->addfile($fh)->hexdigest, "05863440dba144d5d0fdce73cbc27535", 'ripemd128 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_ripemd160.t b/t/digest_ripemd160.t new file mode 100644 index 0000000..f290f9e --- /dev/null +++ b/t/digest_ripemd160.t @@ -0,0 +1,105 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::RIPEMD160 qw( ripemd160 ripemd160_hex ripemd160_b64 ripemd160_b64u ripemd160_file ripemd160_file_hex ripemd160_file_b64 ripemd160_file_b64u ); + +is( Crypt::Digest::hashsize('RIPEMD160'), 20, 'hashsize/1'); +is( Crypt::Digest->hashsize('RIPEMD160'), 20, 'hashsize/2'); +is( Crypt::Digest::RIPEMD160::hashsize, 20, 'hashsize/3'); +is( Crypt::Digest::RIPEMD160->hashsize, 20, 'hashsize/4'); +is( Crypt::Digest->new('RIPEMD160')->hashsize, 20, 'hashsize/5'); +is( Crypt::Digest::RIPEMD160->new->hashsize, 20, 'hashsize/6'); + + +is( ripemd160(""), pack("H*","9c1185a5c5e9fc54612808977ee8f548b2258d31"), 'ripemd160 (raw/1)'); +is( ripemd160_hex(""), "9c1185a5c5e9fc54612808977ee8f548b2258d31", 'ripemd160 (hex/1)'); +is( ripemd160_b64(""), "nBGFpcXp/FRhKAiXfuj1SLIljTE=", 'ripemd160 (base64/1)'); +is( digest_data('RIPEMD160', ""), pack("H*","9c1185a5c5e9fc54612808977ee8f548b2258d31"), 'ripemd160 (digest_data_raw/1)'); +is( digest_data_hex('RIPEMD160', ""), "9c1185a5c5e9fc54612808977ee8f548b2258d31", 'ripemd160 (digest_data_hex/1)'); +is( digest_data_b64('RIPEMD160', ""), "nBGFpcXp/FRhKAiXfuj1SLIljTE=", 'ripemd160 (digest_data_b64/1)'); +is( digest_data_b64u('RIPEMD160', ""), "nBGFpcXp_FRhKAiXfuj1SLIljTE", 'ripemd160 (digest_data_b64u/1)'); +is( Crypt::Digest::RIPEMD160->new->add("")->hexdigest, "9c1185a5c5e9fc54612808977ee8f548b2258d31", 'ripemd160 (OO/1)'); + +is( ripemd160("123"), pack("H*","e3431a8e0adbf96fd140103dc6f63a3f8fa343ab"), 'ripemd160 (raw/2)'); +is( ripemd160_hex("123"), "e3431a8e0adbf96fd140103dc6f63a3f8fa343ab", 'ripemd160 (hex/2)'); +is( ripemd160_b64("123"), "40Majgrb+W/RQBA9xvY6P4+jQ6s=", 'ripemd160 (base64/2)'); +is( digest_data('RIPEMD160', "123"), pack("H*","e3431a8e0adbf96fd140103dc6f63a3f8fa343ab"), 'ripemd160 (digest_data_raw/2)'); +is( digest_data_hex('RIPEMD160', "123"), "e3431a8e0adbf96fd140103dc6f63a3f8fa343ab", 'ripemd160 (digest_data_hex/2)'); +is( digest_data_b64('RIPEMD160', "123"), "40Majgrb+W/RQBA9xvY6P4+jQ6s=", 'ripemd160 (digest_data_b64/2)'); +is( digest_data_b64u('RIPEMD160', "123"), "40Majgrb-W_RQBA9xvY6P4-jQ6s", 'ripemd160 (digest_data_b64u/2)'); +is( Crypt::Digest::RIPEMD160->new->add("123")->hexdigest, "e3431a8e0adbf96fd140103dc6f63a3f8fa343ab", 'ripemd160 (OO/2)'); + +is( ripemd160("test\0test\0test\n"), pack("H*","1d3537be9984c77527d16313decc87e376411c8c"), 'ripemd160 (raw/3)'); +is( ripemd160_hex("test\0test\0test\n"), "1d3537be9984c77527d16313decc87e376411c8c", 'ripemd160 (hex/3)'); +is( ripemd160_b64("test\0test\0test\n"), "HTU3vpmEx3Un0WMT3syH43ZBHIw=", 'ripemd160 (base64/3)'); +is( digest_data('RIPEMD160', "test\0test\0test\n"), pack("H*","1d3537be9984c77527d16313decc87e376411c8c"), 'ripemd160 (digest_data_raw/3)'); +is( digest_data_hex('RIPEMD160', "test\0test\0test\n"), "1d3537be9984c77527d16313decc87e376411c8c", 'ripemd160 (digest_data_hex/3)'); +is( digest_data_b64('RIPEMD160', "test\0test\0test\n"), "HTU3vpmEx3Un0WMT3syH43ZBHIw=", 'ripemd160 (digest_data_b64/3)'); +is( digest_data_b64u('RIPEMD160', "test\0test\0test\n"), "HTU3vpmEx3Un0WMT3syH43ZBHIw", 'ripemd160 (digest_data_b64u/3)'); +is( Crypt::Digest::RIPEMD160->new->add("test\0test\0test\n")->hexdigest, "1d3537be9984c77527d16313decc87e376411c8c", 'ripemd160 (OO/3)'); + + +is( ripemd160_file('t/data/binary-test.file'), pack("H*","0bf6636068ef6d6a2af93d8ce220e8324ecdac2f"), 'ripemd160 (raw/file/1)'); +is( ripemd160_file_hex('t/data/binary-test.file'), "0bf6636068ef6d6a2af93d8ce220e8324ecdac2f", 'ripemd160 (hex/file/1)'); +is( ripemd160_file_b64('t/data/binary-test.file'), "C/ZjYGjvbWoq+T2M4iDoMk7NrC8=", 'ripemd160 (base64/file/1)'); +is( digest_file('RIPEMD160', 't/data/binary-test.file'), pack("H*","0bf6636068ef6d6a2af93d8ce220e8324ecdac2f"), 'ripemd160 (digest_file_raw/file/1)'); +is( digest_file_hex('RIPEMD160', 't/data/binary-test.file'), "0bf6636068ef6d6a2af93d8ce220e8324ecdac2f", 'ripemd160 (digest_file_hex/file/1)'); +is( digest_file_b64('RIPEMD160', 't/data/binary-test.file'), "C/ZjYGjvbWoq+T2M4iDoMk7NrC8=", 'ripemd160 (digest_file_b64/file/1)'); +is( digest_file_b64u('RIPEMD160', 't/data/binary-test.file'), "C_ZjYGjvbWoq-T2M4iDoMk7NrC8", 'ripemd160 (digest_file_b64u/file/1)'); +is( Crypt::Digest::RIPEMD160->new->addfile('t/data/binary-test.file')->hexdigest, "0bf6636068ef6d6a2af93d8ce220e8324ecdac2f", 'ripemd160 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::RIPEMD160->new->addfile($fh)->hexdigest, "0bf6636068ef6d6a2af93d8ce220e8324ecdac2f", 'ripemd160 (OO/filehandle/1)'); + close($fh); +} + +is( ripemd160_file('t/data/text-CR.file'), pack("H*","156e131e5e5e8216cad97fa880a7a54273179853"), 'ripemd160 (raw/file/2)'); +is( ripemd160_file_hex('t/data/text-CR.file'), "156e131e5e5e8216cad97fa880a7a54273179853", 'ripemd160 (hex/file/2)'); +is( ripemd160_file_b64('t/data/text-CR.file'), "FW4THl5eghbK2X+ogKelQnMXmFM=", 'ripemd160 (base64/file/2)'); +is( digest_file('RIPEMD160', 't/data/text-CR.file'), pack("H*","156e131e5e5e8216cad97fa880a7a54273179853"), 'ripemd160 (digest_file_raw/file/2)'); +is( digest_file_hex('RIPEMD160', 't/data/text-CR.file'), "156e131e5e5e8216cad97fa880a7a54273179853", 'ripemd160 (digest_file_hex/file/2)'); +is( digest_file_b64('RIPEMD160', 't/data/text-CR.file'), "FW4THl5eghbK2X+ogKelQnMXmFM=", 'ripemd160 (digest_file_b64/file/2)'); +is( digest_file_b64u('RIPEMD160', 't/data/text-CR.file'), "FW4THl5eghbK2X-ogKelQnMXmFM", 'ripemd160 (digest_file_b64u/file/2)'); +is( Crypt::Digest::RIPEMD160->new->addfile('t/data/text-CR.file')->hexdigest, "156e131e5e5e8216cad97fa880a7a54273179853", 'ripemd160 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::RIPEMD160->new->addfile($fh)->hexdigest, "156e131e5e5e8216cad97fa880a7a54273179853", 'ripemd160 (OO/filehandle/2)'); + close($fh); +} + +is( ripemd160_file('t/data/text-CRLF.file'), pack("H*","cb374a83416fe4fc3ae04945b3a796f3b54c3b63"), 'ripemd160 (raw/file/3)'); +is( ripemd160_file_hex('t/data/text-CRLF.file'), "cb374a83416fe4fc3ae04945b3a796f3b54c3b63", 'ripemd160 (hex/file/3)'); +is( ripemd160_file_b64('t/data/text-CRLF.file'), "yzdKg0Fv5Pw64ElFs6eW87VMO2M=", 'ripemd160 (base64/file/3)'); +is( digest_file('RIPEMD160', 't/data/text-CRLF.file'), pack("H*","cb374a83416fe4fc3ae04945b3a796f3b54c3b63"), 'ripemd160 (digest_file_raw/file/3)'); +is( digest_file_hex('RIPEMD160', 't/data/text-CRLF.file'), "cb374a83416fe4fc3ae04945b3a796f3b54c3b63", 'ripemd160 (digest_file_hex/file/3)'); +is( digest_file_b64('RIPEMD160', 't/data/text-CRLF.file'), "yzdKg0Fv5Pw64ElFs6eW87VMO2M=", 'ripemd160 (digest_file_b64/file/3)'); +is( digest_file_b64u('RIPEMD160', 't/data/text-CRLF.file'), "yzdKg0Fv5Pw64ElFs6eW87VMO2M", 'ripemd160 (digest_file_b64u/file/3)'); +is( Crypt::Digest::RIPEMD160->new->addfile('t/data/text-CRLF.file')->hexdigest, "cb374a83416fe4fc3ae04945b3a796f3b54c3b63", 'ripemd160 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::RIPEMD160->new->addfile($fh)->hexdigest, "cb374a83416fe4fc3ae04945b3a796f3b54c3b63", 'ripemd160 (OO/filehandle/3)'); + close($fh); +} + +is( ripemd160_file('t/data/text-LF.file'), pack("H*","34913b1862982366520f5e29d8a0a2d6e3d9a812"), 'ripemd160 (raw/file/4)'); +is( ripemd160_file_hex('t/data/text-LF.file'), "34913b1862982366520f5e29d8a0a2d6e3d9a812", 'ripemd160 (hex/file/4)'); +is( ripemd160_file_b64('t/data/text-LF.file'), "NJE7GGKYI2ZSD14p2KCi1uPZqBI=", 'ripemd160 (base64/file/4)'); +is( digest_file('RIPEMD160', 't/data/text-LF.file'), pack("H*","34913b1862982366520f5e29d8a0a2d6e3d9a812"), 'ripemd160 (digest_file_raw/file/4)'); +is( digest_file_hex('RIPEMD160', 't/data/text-LF.file'), "34913b1862982366520f5e29d8a0a2d6e3d9a812", 'ripemd160 (digest_file_hex/file/4)'); +is( digest_file_b64('RIPEMD160', 't/data/text-LF.file'), "NJE7GGKYI2ZSD14p2KCi1uPZqBI=", 'ripemd160 (digest_file_b64/file/4)'); +is( digest_file_b64u('RIPEMD160', 't/data/text-LF.file'), "NJE7GGKYI2ZSD14p2KCi1uPZqBI", 'ripemd160 (digest_file_b64u/file/4)'); +is( Crypt::Digest::RIPEMD160->new->addfile('t/data/text-LF.file')->hexdigest, "34913b1862982366520f5e29d8a0a2d6e3d9a812", 'ripemd160 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::RIPEMD160->new->addfile($fh)->hexdigest, "34913b1862982366520f5e29d8a0a2d6e3d9a812", 'ripemd160 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_ripemd256.t b/t/digest_ripemd256.t new file mode 100644 index 0000000..6b13664 --- /dev/null +++ b/t/digest_ripemd256.t @@ -0,0 +1,105 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::RIPEMD256 qw( ripemd256 ripemd256_hex ripemd256_b64 ripemd256_b64u ripemd256_file ripemd256_file_hex ripemd256_file_b64 ripemd256_file_b64u ); + +is( Crypt::Digest::hashsize('RIPEMD256'), 32, 'hashsize/1'); +is( Crypt::Digest->hashsize('RIPEMD256'), 32, 'hashsize/2'); +is( Crypt::Digest::RIPEMD256::hashsize, 32, 'hashsize/3'); +is( Crypt::Digest::RIPEMD256->hashsize, 32, 'hashsize/4'); +is( Crypt::Digest->new('RIPEMD256')->hashsize, 32, 'hashsize/5'); +is( Crypt::Digest::RIPEMD256->new->hashsize, 32, 'hashsize/6'); + + +is( ripemd256(""), pack("H*","02ba4c4e5f8ecd1877fc52d64d30e37a2d9774fb1e5d026380ae0168e3c5522d"), 'ripemd256 (raw/1)'); +is( ripemd256_hex(""), "02ba4c4e5f8ecd1877fc52d64d30e37a2d9774fb1e5d026380ae0168e3c5522d", 'ripemd256 (hex/1)'); +is( ripemd256_b64(""), "ArpMTl+OzRh3/FLWTTDjei2XdPseXQJjgK4BaOPFUi0=", 'ripemd256 (base64/1)'); +is( digest_data('RIPEMD256', ""), pack("H*","02ba4c4e5f8ecd1877fc52d64d30e37a2d9774fb1e5d026380ae0168e3c5522d"), 'ripemd256 (digest_data_raw/1)'); +is( digest_data_hex('RIPEMD256', ""), "02ba4c4e5f8ecd1877fc52d64d30e37a2d9774fb1e5d026380ae0168e3c5522d", 'ripemd256 (digest_data_hex/1)'); +is( digest_data_b64('RIPEMD256', ""), "ArpMTl+OzRh3/FLWTTDjei2XdPseXQJjgK4BaOPFUi0=", 'ripemd256 (digest_data_b64/1)'); +is( digest_data_b64u('RIPEMD256', ""), "ArpMTl-OzRh3_FLWTTDjei2XdPseXQJjgK4BaOPFUi0", 'ripemd256 (digest_data_b64u/1)'); +is( Crypt::Digest::RIPEMD256->new->add("")->hexdigest, "02ba4c4e5f8ecd1877fc52d64d30e37a2d9774fb1e5d026380ae0168e3c5522d", 'ripemd256 (OO/1)'); + +is( ripemd256("123"), pack("H*","8536753ad7bface2dba89fb318c95b1b42890016057d4c3a2f351cec3acbb28b"), 'ripemd256 (raw/2)'); +is( ripemd256_hex("123"), "8536753ad7bface2dba89fb318c95b1b42890016057d4c3a2f351cec3acbb28b", 'ripemd256 (hex/2)'); +is( ripemd256_b64("123"), "hTZ1Ote/rOLbqJ+zGMlbG0KJABYFfUw6LzUc7DrLsos=", 'ripemd256 (base64/2)'); +is( digest_data('RIPEMD256', "123"), pack("H*","8536753ad7bface2dba89fb318c95b1b42890016057d4c3a2f351cec3acbb28b"), 'ripemd256 (digest_data_raw/2)'); +is( digest_data_hex('RIPEMD256', "123"), "8536753ad7bface2dba89fb318c95b1b42890016057d4c3a2f351cec3acbb28b", 'ripemd256 (digest_data_hex/2)'); +is( digest_data_b64('RIPEMD256', "123"), "hTZ1Ote/rOLbqJ+zGMlbG0KJABYFfUw6LzUc7DrLsos=", 'ripemd256 (digest_data_b64/2)'); +is( digest_data_b64u('RIPEMD256', "123"), "hTZ1Ote_rOLbqJ-zGMlbG0KJABYFfUw6LzUc7DrLsos", 'ripemd256 (digest_data_b64u/2)'); +is( Crypt::Digest::RIPEMD256->new->add("123")->hexdigest, "8536753ad7bface2dba89fb318c95b1b42890016057d4c3a2f351cec3acbb28b", 'ripemd256 (OO/2)'); + +is( ripemd256("test\0test\0test\n"), pack("H*","31c2bd4e721bb8fa911022bbc51ddc74943772a951f300bd4e4c9dfceddb10e5"), 'ripemd256 (raw/3)'); +is( ripemd256_hex("test\0test\0test\n"), "31c2bd4e721bb8fa911022bbc51ddc74943772a951f300bd4e4c9dfceddb10e5", 'ripemd256 (hex/3)'); +is( ripemd256_b64("test\0test\0test\n"), "McK9TnIbuPqRECK7xR3cdJQ3cqlR8wC9Tkyd/O3bEOU=", 'ripemd256 (base64/3)'); +is( digest_data('RIPEMD256', "test\0test\0test\n"), pack("H*","31c2bd4e721bb8fa911022bbc51ddc74943772a951f300bd4e4c9dfceddb10e5"), 'ripemd256 (digest_data_raw/3)'); +is( digest_data_hex('RIPEMD256', "test\0test\0test\n"), "31c2bd4e721bb8fa911022bbc51ddc74943772a951f300bd4e4c9dfceddb10e5", 'ripemd256 (digest_data_hex/3)'); +is( digest_data_b64('RIPEMD256', "test\0test\0test\n"), "McK9TnIbuPqRECK7xR3cdJQ3cqlR8wC9Tkyd/O3bEOU=", 'ripemd256 (digest_data_b64/3)'); +is( digest_data_b64u('RIPEMD256', "test\0test\0test\n"), "McK9TnIbuPqRECK7xR3cdJQ3cqlR8wC9Tkyd_O3bEOU", 'ripemd256 (digest_data_b64u/3)'); +is( Crypt::Digest::RIPEMD256->new->add("test\0test\0test\n")->hexdigest, "31c2bd4e721bb8fa911022bbc51ddc74943772a951f300bd4e4c9dfceddb10e5", 'ripemd256 (OO/3)'); + + +is( ripemd256_file('t/data/binary-test.file'), pack("H*","04045c33e656c780c9fe908d819322fd031b5fc8e009c2d03bd2ba9fcc1ff8c8"), 'ripemd256 (raw/file/1)'); +is( ripemd256_file_hex('t/data/binary-test.file'), "04045c33e656c780c9fe908d819322fd031b5fc8e009c2d03bd2ba9fcc1ff8c8", 'ripemd256 (hex/file/1)'); +is( ripemd256_file_b64('t/data/binary-test.file'), "BARcM+ZWx4DJ/pCNgZMi/QMbX8jgCcLQO9K6n8wf+Mg=", 'ripemd256 (base64/file/1)'); +is( digest_file('RIPEMD256', 't/data/binary-test.file'), pack("H*","04045c33e656c780c9fe908d819322fd031b5fc8e009c2d03bd2ba9fcc1ff8c8"), 'ripemd256 (digest_file_raw/file/1)'); +is( digest_file_hex('RIPEMD256', 't/data/binary-test.file'), "04045c33e656c780c9fe908d819322fd031b5fc8e009c2d03bd2ba9fcc1ff8c8", 'ripemd256 (digest_file_hex/file/1)'); +is( digest_file_b64('RIPEMD256', 't/data/binary-test.file'), "BARcM+ZWx4DJ/pCNgZMi/QMbX8jgCcLQO9K6n8wf+Mg=", 'ripemd256 (digest_file_b64/file/1)'); +is( digest_file_b64u('RIPEMD256', 't/data/binary-test.file'), "BARcM-ZWx4DJ_pCNgZMi_QMbX8jgCcLQO9K6n8wf-Mg", 'ripemd256 (digest_file_b64u/file/1)'); +is( Crypt::Digest::RIPEMD256->new->addfile('t/data/binary-test.file')->hexdigest, "04045c33e656c780c9fe908d819322fd031b5fc8e009c2d03bd2ba9fcc1ff8c8", 'ripemd256 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::RIPEMD256->new->addfile($fh)->hexdigest, "04045c33e656c780c9fe908d819322fd031b5fc8e009c2d03bd2ba9fcc1ff8c8", 'ripemd256 (OO/filehandle/1)'); + close($fh); +} + +is( ripemd256_file('t/data/text-CR.file'), pack("H*","9f4e9323acd154c0731e7e9f1b0c4af2c37831b1457c591cd4c19b3f79c930d4"), 'ripemd256 (raw/file/2)'); +is( ripemd256_file_hex('t/data/text-CR.file'), "9f4e9323acd154c0731e7e9f1b0c4af2c37831b1457c591cd4c19b3f79c930d4", 'ripemd256 (hex/file/2)'); +is( ripemd256_file_b64('t/data/text-CR.file'), "n06TI6zRVMBzHn6fGwxK8sN4MbFFfFkc1MGbP3nJMNQ=", 'ripemd256 (base64/file/2)'); +is( digest_file('RIPEMD256', 't/data/text-CR.file'), pack("H*","9f4e9323acd154c0731e7e9f1b0c4af2c37831b1457c591cd4c19b3f79c930d4"), 'ripemd256 (digest_file_raw/file/2)'); +is( digest_file_hex('RIPEMD256', 't/data/text-CR.file'), "9f4e9323acd154c0731e7e9f1b0c4af2c37831b1457c591cd4c19b3f79c930d4", 'ripemd256 (digest_file_hex/file/2)'); +is( digest_file_b64('RIPEMD256', 't/data/text-CR.file'), "n06TI6zRVMBzHn6fGwxK8sN4MbFFfFkc1MGbP3nJMNQ=", 'ripemd256 (digest_file_b64/file/2)'); +is( digest_file_b64u('RIPEMD256', 't/data/text-CR.file'), "n06TI6zRVMBzHn6fGwxK8sN4MbFFfFkc1MGbP3nJMNQ", 'ripemd256 (digest_file_b64u/file/2)'); +is( Crypt::Digest::RIPEMD256->new->addfile('t/data/text-CR.file')->hexdigest, "9f4e9323acd154c0731e7e9f1b0c4af2c37831b1457c591cd4c19b3f79c930d4", 'ripemd256 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::RIPEMD256->new->addfile($fh)->hexdigest, "9f4e9323acd154c0731e7e9f1b0c4af2c37831b1457c591cd4c19b3f79c930d4", 'ripemd256 (OO/filehandle/2)'); + close($fh); +} + +is( ripemd256_file('t/data/text-CRLF.file'), pack("H*","687ec071c90af42e551a3df07196e9d27ec5c4e1744fe17a0e2eb27dc9109611"), 'ripemd256 (raw/file/3)'); +is( ripemd256_file_hex('t/data/text-CRLF.file'), "687ec071c90af42e551a3df07196e9d27ec5c4e1744fe17a0e2eb27dc9109611", 'ripemd256 (hex/file/3)'); +is( ripemd256_file_b64('t/data/text-CRLF.file'), "aH7AcckK9C5VGj3wcZbp0n7FxOF0T+F6Di6yfckQlhE=", 'ripemd256 (base64/file/3)'); +is( digest_file('RIPEMD256', 't/data/text-CRLF.file'), pack("H*","687ec071c90af42e551a3df07196e9d27ec5c4e1744fe17a0e2eb27dc9109611"), 'ripemd256 (digest_file_raw/file/3)'); +is( digest_file_hex('RIPEMD256', 't/data/text-CRLF.file'), "687ec071c90af42e551a3df07196e9d27ec5c4e1744fe17a0e2eb27dc9109611", 'ripemd256 (digest_file_hex/file/3)'); +is( digest_file_b64('RIPEMD256', 't/data/text-CRLF.file'), "aH7AcckK9C5VGj3wcZbp0n7FxOF0T+F6Di6yfckQlhE=", 'ripemd256 (digest_file_b64/file/3)'); +is( digest_file_b64u('RIPEMD256', 't/data/text-CRLF.file'), "aH7AcckK9C5VGj3wcZbp0n7FxOF0T-F6Di6yfckQlhE", 'ripemd256 (digest_file_b64u/file/3)'); +is( Crypt::Digest::RIPEMD256->new->addfile('t/data/text-CRLF.file')->hexdigest, "687ec071c90af42e551a3df07196e9d27ec5c4e1744fe17a0e2eb27dc9109611", 'ripemd256 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::RIPEMD256->new->addfile($fh)->hexdigest, "687ec071c90af42e551a3df07196e9d27ec5c4e1744fe17a0e2eb27dc9109611", 'ripemd256 (OO/filehandle/3)'); + close($fh); +} + +is( ripemd256_file('t/data/text-LF.file'), pack("H*","ef8b4d7c754269584403b4672e5abe44972b36a4ddb66a2a489e11041cbe7413"), 'ripemd256 (raw/file/4)'); +is( ripemd256_file_hex('t/data/text-LF.file'), "ef8b4d7c754269584403b4672e5abe44972b36a4ddb66a2a489e11041cbe7413", 'ripemd256 (hex/file/4)'); +is( ripemd256_file_b64('t/data/text-LF.file'), "74tNfHVCaVhEA7RnLlq+RJcrNqTdtmoqSJ4RBBy+dBM=", 'ripemd256 (base64/file/4)'); +is( digest_file('RIPEMD256', 't/data/text-LF.file'), pack("H*","ef8b4d7c754269584403b4672e5abe44972b36a4ddb66a2a489e11041cbe7413"), 'ripemd256 (digest_file_raw/file/4)'); +is( digest_file_hex('RIPEMD256', 't/data/text-LF.file'), "ef8b4d7c754269584403b4672e5abe44972b36a4ddb66a2a489e11041cbe7413", 'ripemd256 (digest_file_hex/file/4)'); +is( digest_file_b64('RIPEMD256', 't/data/text-LF.file'), "74tNfHVCaVhEA7RnLlq+RJcrNqTdtmoqSJ4RBBy+dBM=", 'ripemd256 (digest_file_b64/file/4)'); +is( digest_file_b64u('RIPEMD256', 't/data/text-LF.file'), "74tNfHVCaVhEA7RnLlq-RJcrNqTdtmoqSJ4RBBy-dBM", 'ripemd256 (digest_file_b64u/file/4)'); +is( Crypt::Digest::RIPEMD256->new->addfile('t/data/text-LF.file')->hexdigest, "ef8b4d7c754269584403b4672e5abe44972b36a4ddb66a2a489e11041cbe7413", 'ripemd256 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::RIPEMD256->new->addfile($fh)->hexdigest, "ef8b4d7c754269584403b4672e5abe44972b36a4ddb66a2a489e11041cbe7413", 'ripemd256 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_ripemd320.t b/t/digest_ripemd320.t new file mode 100644 index 0000000..4dc576d --- /dev/null +++ b/t/digest_ripemd320.t @@ -0,0 +1,105 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::RIPEMD320 qw( ripemd320 ripemd320_hex ripemd320_b64 ripemd320_b64u ripemd320_file ripemd320_file_hex ripemd320_file_b64 ripemd320_file_b64u ); + +is( Crypt::Digest::hashsize('RIPEMD320'), 40, 'hashsize/1'); +is( Crypt::Digest->hashsize('RIPEMD320'), 40, 'hashsize/2'); +is( Crypt::Digest::RIPEMD320::hashsize, 40, 'hashsize/3'); +is( Crypt::Digest::RIPEMD320->hashsize, 40, 'hashsize/4'); +is( Crypt::Digest->new('RIPEMD320')->hashsize, 40, 'hashsize/5'); +is( Crypt::Digest::RIPEMD320->new->hashsize, 40, 'hashsize/6'); + + +is( ripemd320(""), pack("H*","22d65d5661536cdc75c1fdf5c6de7b41b9f27325ebc61e8557177d705a0ec880151c3a32a00899b8"), 'ripemd320 (raw/1)'); +is( ripemd320_hex(""), "22d65d5661536cdc75c1fdf5c6de7b41b9f27325ebc61e8557177d705a0ec880151c3a32a00899b8", 'ripemd320 (hex/1)'); +is( ripemd320_b64(""), "ItZdVmFTbNx1wf31xt57QbnycyXrxh6FVxd9cFoOyIAVHDoyoAiZuA==", 'ripemd320 (base64/1)'); +is( digest_data('RIPEMD320', ""), pack("H*","22d65d5661536cdc75c1fdf5c6de7b41b9f27325ebc61e8557177d705a0ec880151c3a32a00899b8"), 'ripemd320 (digest_data_raw/1)'); +is( digest_data_hex('RIPEMD320', ""), "22d65d5661536cdc75c1fdf5c6de7b41b9f27325ebc61e8557177d705a0ec880151c3a32a00899b8", 'ripemd320 (digest_data_hex/1)'); +is( digest_data_b64('RIPEMD320', ""), "ItZdVmFTbNx1wf31xt57QbnycyXrxh6FVxd9cFoOyIAVHDoyoAiZuA==", 'ripemd320 (digest_data_b64/1)'); +is( digest_data_b64u('RIPEMD320', ""), "ItZdVmFTbNx1wf31xt57QbnycyXrxh6FVxd9cFoOyIAVHDoyoAiZuA", 'ripemd320 (digest_data_b64u/1)'); +is( Crypt::Digest::RIPEMD320->new->add("")->hexdigest, "22d65d5661536cdc75c1fdf5c6de7b41b9f27325ebc61e8557177d705a0ec880151c3a32a00899b8", 'ripemd320 (OO/1)'); + +is( ripemd320("123"), pack("H*","bfa11b73ad4e6421a8ba5a1223d9c9f58a5ad456be98bee5bfcd19a3ecdc6140ce4c700be860fda9"), 'ripemd320 (raw/2)'); +is( ripemd320_hex("123"), "bfa11b73ad4e6421a8ba5a1223d9c9f58a5ad456be98bee5bfcd19a3ecdc6140ce4c700be860fda9", 'ripemd320 (hex/2)'); +is( ripemd320_b64("123"), "v6Ebc61OZCGouloSI9nJ9Ypa1Fa+mL7lv80Zo+zcYUDOTHAL6GD9qQ==", 'ripemd320 (base64/2)'); +is( digest_data('RIPEMD320', "123"), pack("H*","bfa11b73ad4e6421a8ba5a1223d9c9f58a5ad456be98bee5bfcd19a3ecdc6140ce4c700be860fda9"), 'ripemd320 (digest_data_raw/2)'); +is( digest_data_hex('RIPEMD320', "123"), "bfa11b73ad4e6421a8ba5a1223d9c9f58a5ad456be98bee5bfcd19a3ecdc6140ce4c700be860fda9", 'ripemd320 (digest_data_hex/2)'); +is( digest_data_b64('RIPEMD320', "123"), "v6Ebc61OZCGouloSI9nJ9Ypa1Fa+mL7lv80Zo+zcYUDOTHAL6GD9qQ==", 'ripemd320 (digest_data_b64/2)'); +is( digest_data_b64u('RIPEMD320', "123"), "v6Ebc61OZCGouloSI9nJ9Ypa1Fa-mL7lv80Zo-zcYUDOTHAL6GD9qQ", 'ripemd320 (digest_data_b64u/2)'); +is( Crypt::Digest::RIPEMD320->new->add("123")->hexdigest, "bfa11b73ad4e6421a8ba5a1223d9c9f58a5ad456be98bee5bfcd19a3ecdc6140ce4c700be860fda9", 'ripemd320 (OO/2)'); + +is( ripemd320("test\0test\0test\n"), pack("H*","efdfb0c3c74bdf938a4845638eb3622e2bdba11a68a4831b8517cb6b827e46a6026419b27003a044"), 'ripemd320 (raw/3)'); +is( ripemd320_hex("test\0test\0test\n"), "efdfb0c3c74bdf938a4845638eb3622e2bdba11a68a4831b8517cb6b827e46a6026419b27003a044", 'ripemd320 (hex/3)'); +is( ripemd320_b64("test\0test\0test\n"), "79+ww8dL35OKSEVjjrNiLivboRpopIMbhRfLa4J+RqYCZBmycAOgRA==", 'ripemd320 (base64/3)'); +is( digest_data('RIPEMD320', "test\0test\0test\n"), pack("H*","efdfb0c3c74bdf938a4845638eb3622e2bdba11a68a4831b8517cb6b827e46a6026419b27003a044"), 'ripemd320 (digest_data_raw/3)'); +is( digest_data_hex('RIPEMD320', "test\0test\0test\n"), "efdfb0c3c74bdf938a4845638eb3622e2bdba11a68a4831b8517cb6b827e46a6026419b27003a044", 'ripemd320 (digest_data_hex/3)'); +is( digest_data_b64('RIPEMD320', "test\0test\0test\n"), "79+ww8dL35OKSEVjjrNiLivboRpopIMbhRfLa4J+RqYCZBmycAOgRA==", 'ripemd320 (digest_data_b64/3)'); +is( digest_data_b64u('RIPEMD320', "test\0test\0test\n"), "79-ww8dL35OKSEVjjrNiLivboRpopIMbhRfLa4J-RqYCZBmycAOgRA", 'ripemd320 (digest_data_b64u/3)'); +is( Crypt::Digest::RIPEMD320->new->add("test\0test\0test\n")->hexdigest, "efdfb0c3c74bdf938a4845638eb3622e2bdba11a68a4831b8517cb6b827e46a6026419b27003a044", 'ripemd320 (OO/3)'); + + +is( ripemd320_file('t/data/binary-test.file'), pack("H*","115b4ee29a7a781323f35de1d9690d1c340f162463726e1b3206c139c700d65c92dc20497026a198"), 'ripemd320 (raw/file/1)'); +is( ripemd320_file_hex('t/data/binary-test.file'), "115b4ee29a7a781323f35de1d9690d1c340f162463726e1b3206c139c700d65c92dc20497026a198", 'ripemd320 (hex/file/1)'); +is( ripemd320_file_b64('t/data/binary-test.file'), "EVtO4pp6eBMj813h2WkNHDQPFiRjcm4bMgbBOccA1lyS3CBJcCahmA==", 'ripemd320 (base64/file/1)'); +is( digest_file('RIPEMD320', 't/data/binary-test.file'), pack("H*","115b4ee29a7a781323f35de1d9690d1c340f162463726e1b3206c139c700d65c92dc20497026a198"), 'ripemd320 (digest_file_raw/file/1)'); +is( digest_file_hex('RIPEMD320', 't/data/binary-test.file'), "115b4ee29a7a781323f35de1d9690d1c340f162463726e1b3206c139c700d65c92dc20497026a198", 'ripemd320 (digest_file_hex/file/1)'); +is( digest_file_b64('RIPEMD320', 't/data/binary-test.file'), "EVtO4pp6eBMj813h2WkNHDQPFiRjcm4bMgbBOccA1lyS3CBJcCahmA==", 'ripemd320 (digest_file_b64/file/1)'); +is( digest_file_b64u('RIPEMD320', 't/data/binary-test.file'), "EVtO4pp6eBMj813h2WkNHDQPFiRjcm4bMgbBOccA1lyS3CBJcCahmA", 'ripemd320 (digest_file_b64u/file/1)'); +is( Crypt::Digest::RIPEMD320->new->addfile('t/data/binary-test.file')->hexdigest, "115b4ee29a7a781323f35de1d9690d1c340f162463726e1b3206c139c700d65c92dc20497026a198", 'ripemd320 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::RIPEMD320->new->addfile($fh)->hexdigest, "115b4ee29a7a781323f35de1d9690d1c340f162463726e1b3206c139c700d65c92dc20497026a198", 'ripemd320 (OO/filehandle/1)'); + close($fh); +} + +is( ripemd320_file('t/data/text-CR.file'), pack("H*","47afeaad7c965e2d4b2e579f33b079d3d9afc3cc910b154002fdf7b44f06ca6ebc746ade992b2645"), 'ripemd320 (raw/file/2)'); +is( ripemd320_file_hex('t/data/text-CR.file'), "47afeaad7c965e2d4b2e579f33b079d3d9afc3cc910b154002fdf7b44f06ca6ebc746ade992b2645", 'ripemd320 (hex/file/2)'); +is( ripemd320_file_b64('t/data/text-CR.file'), "R6/qrXyWXi1LLlefM7B509mvw8yRCxVAAv33tE8Gym68dGremSsmRQ==", 'ripemd320 (base64/file/2)'); +is( digest_file('RIPEMD320', 't/data/text-CR.file'), pack("H*","47afeaad7c965e2d4b2e579f33b079d3d9afc3cc910b154002fdf7b44f06ca6ebc746ade992b2645"), 'ripemd320 (digest_file_raw/file/2)'); +is( digest_file_hex('RIPEMD320', 't/data/text-CR.file'), "47afeaad7c965e2d4b2e579f33b079d3d9afc3cc910b154002fdf7b44f06ca6ebc746ade992b2645", 'ripemd320 (digest_file_hex/file/2)'); +is( digest_file_b64('RIPEMD320', 't/data/text-CR.file'), "R6/qrXyWXi1LLlefM7B509mvw8yRCxVAAv33tE8Gym68dGremSsmRQ==", 'ripemd320 (digest_file_b64/file/2)'); +is( digest_file_b64u('RIPEMD320', 't/data/text-CR.file'), "R6_qrXyWXi1LLlefM7B509mvw8yRCxVAAv33tE8Gym68dGremSsmRQ", 'ripemd320 (digest_file_b64u/file/2)'); +is( Crypt::Digest::RIPEMD320->new->addfile('t/data/text-CR.file')->hexdigest, "47afeaad7c965e2d4b2e579f33b079d3d9afc3cc910b154002fdf7b44f06ca6ebc746ade992b2645", 'ripemd320 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::RIPEMD320->new->addfile($fh)->hexdigest, "47afeaad7c965e2d4b2e579f33b079d3d9afc3cc910b154002fdf7b44f06ca6ebc746ade992b2645", 'ripemd320 (OO/filehandle/2)'); + close($fh); +} + +is( ripemd320_file('t/data/text-CRLF.file'), pack("H*","d400d2ea267ea39dd32b36db198aba246c20e20aa5c314d56d60efc582a10484925497ff428e6b26"), 'ripemd320 (raw/file/3)'); +is( ripemd320_file_hex('t/data/text-CRLF.file'), "d400d2ea267ea39dd32b36db198aba246c20e20aa5c314d56d60efc582a10484925497ff428e6b26", 'ripemd320 (hex/file/3)'); +is( ripemd320_file_b64('t/data/text-CRLF.file'), "1ADS6iZ+o53TKzbbGYq6JGwg4gqlwxTVbWDvxYKhBISSVJf/Qo5rJg==", 'ripemd320 (base64/file/3)'); +is( digest_file('RIPEMD320', 't/data/text-CRLF.file'), pack("H*","d400d2ea267ea39dd32b36db198aba246c20e20aa5c314d56d60efc582a10484925497ff428e6b26"), 'ripemd320 (digest_file_raw/file/3)'); +is( digest_file_hex('RIPEMD320', 't/data/text-CRLF.file'), "d400d2ea267ea39dd32b36db198aba246c20e20aa5c314d56d60efc582a10484925497ff428e6b26", 'ripemd320 (digest_file_hex/file/3)'); +is( digest_file_b64('RIPEMD320', 't/data/text-CRLF.file'), "1ADS6iZ+o53TKzbbGYq6JGwg4gqlwxTVbWDvxYKhBISSVJf/Qo5rJg==", 'ripemd320 (digest_file_b64/file/3)'); +is( digest_file_b64u('RIPEMD320', 't/data/text-CRLF.file'), "1ADS6iZ-o53TKzbbGYq6JGwg4gqlwxTVbWDvxYKhBISSVJf_Qo5rJg", 'ripemd320 (digest_file_b64u/file/3)'); +is( Crypt::Digest::RIPEMD320->new->addfile('t/data/text-CRLF.file')->hexdigest, "d400d2ea267ea39dd32b36db198aba246c20e20aa5c314d56d60efc582a10484925497ff428e6b26", 'ripemd320 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::RIPEMD320->new->addfile($fh)->hexdigest, "d400d2ea267ea39dd32b36db198aba246c20e20aa5c314d56d60efc582a10484925497ff428e6b26", 'ripemd320 (OO/filehandle/3)'); + close($fh); +} + +is( ripemd320_file('t/data/text-LF.file'), pack("H*","ef55690d2ddd04a67763b871a6cce620eb2844583a4433137959cf4b8d7cbacb95d820f74e748055"), 'ripemd320 (raw/file/4)'); +is( ripemd320_file_hex('t/data/text-LF.file'), "ef55690d2ddd04a67763b871a6cce620eb2844583a4433137959cf4b8d7cbacb95d820f74e748055", 'ripemd320 (hex/file/4)'); +is( ripemd320_file_b64('t/data/text-LF.file'), "71VpDS3dBKZ3Y7hxpszmIOsoRFg6RDMTeVnPS418usuV2CD3TnSAVQ==", 'ripemd320 (base64/file/4)'); +is( digest_file('RIPEMD320', 't/data/text-LF.file'), pack("H*","ef55690d2ddd04a67763b871a6cce620eb2844583a4433137959cf4b8d7cbacb95d820f74e748055"), 'ripemd320 (digest_file_raw/file/4)'); +is( digest_file_hex('RIPEMD320', 't/data/text-LF.file'), "ef55690d2ddd04a67763b871a6cce620eb2844583a4433137959cf4b8d7cbacb95d820f74e748055", 'ripemd320 (digest_file_hex/file/4)'); +is( digest_file_b64('RIPEMD320', 't/data/text-LF.file'), "71VpDS3dBKZ3Y7hxpszmIOsoRFg6RDMTeVnPS418usuV2CD3TnSAVQ==", 'ripemd320 (digest_file_b64/file/4)'); +is( digest_file_b64u('RIPEMD320', 't/data/text-LF.file'), "71VpDS3dBKZ3Y7hxpszmIOsoRFg6RDMTeVnPS418usuV2CD3TnSAVQ", 'ripemd320 (digest_file_b64u/file/4)'); +is( Crypt::Digest::RIPEMD320->new->addfile('t/data/text-LF.file')->hexdigest, "ef55690d2ddd04a67763b871a6cce620eb2844583a4433137959cf4b8d7cbacb95d820f74e748055", 'ripemd320 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::RIPEMD320->new->addfile($fh)->hexdigest, "ef55690d2ddd04a67763b871a6cce620eb2844583a4433137959cf4b8d7cbacb95d820f74e748055", 'ripemd320 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_sha1.t b/t/digest_sha1.t new file mode 100644 index 0000000..c042d09 --- /dev/null +++ b/t/digest_sha1.t @@ -0,0 +1,105 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::SHA1 qw( sha1 sha1_hex sha1_b64 sha1_b64u sha1_file sha1_file_hex sha1_file_b64 sha1_file_b64u ); + +is( Crypt::Digest::hashsize('SHA1'), 20, 'hashsize/1'); +is( Crypt::Digest->hashsize('SHA1'), 20, 'hashsize/2'); +is( Crypt::Digest::SHA1::hashsize, 20, 'hashsize/3'); +is( Crypt::Digest::SHA1->hashsize, 20, 'hashsize/4'); +is( Crypt::Digest->new('SHA1')->hashsize, 20, 'hashsize/5'); +is( Crypt::Digest::SHA1->new->hashsize, 20, 'hashsize/6'); + + +is( sha1(""), pack("H*","da39a3ee5e6b4b0d3255bfef95601890afd80709"), 'sha1 (raw/1)'); +is( sha1_hex(""), "da39a3ee5e6b4b0d3255bfef95601890afd80709", 'sha1 (hex/1)'); +is( sha1_b64(""), "2jmj7l5rSw0yVb/vlWAYkK/YBwk=", 'sha1 (base64/1)'); +is( digest_data('SHA1', ""), pack("H*","da39a3ee5e6b4b0d3255bfef95601890afd80709"), 'sha1 (digest_data_raw/1)'); +is( digest_data_hex('SHA1', ""), "da39a3ee5e6b4b0d3255bfef95601890afd80709", 'sha1 (digest_data_hex/1)'); +is( digest_data_b64('SHA1', ""), "2jmj7l5rSw0yVb/vlWAYkK/YBwk=", 'sha1 (digest_data_b64/1)'); +is( digest_data_b64u('SHA1', ""), "2jmj7l5rSw0yVb_vlWAYkK_YBwk", 'sha1 (digest_data_b64u/1)'); +is( Crypt::Digest::SHA1->new->add("")->hexdigest, "da39a3ee5e6b4b0d3255bfef95601890afd80709", 'sha1 (OO/1)'); + +is( sha1("123"), pack("H*","40bd001563085fc35165329ea1ff5c5ecbdbbeef"), 'sha1 (raw/2)'); +is( sha1_hex("123"), "40bd001563085fc35165329ea1ff5c5ecbdbbeef", 'sha1 (hex/2)'); +is( sha1_b64("123"), "QL0AFWMIX8NRZTKeof9cXsvbvu8=", 'sha1 (base64/2)'); +is( digest_data('SHA1', "123"), pack("H*","40bd001563085fc35165329ea1ff5c5ecbdbbeef"), 'sha1 (digest_data_raw/2)'); +is( digest_data_hex('SHA1', "123"), "40bd001563085fc35165329ea1ff5c5ecbdbbeef", 'sha1 (digest_data_hex/2)'); +is( digest_data_b64('SHA1', "123"), "QL0AFWMIX8NRZTKeof9cXsvbvu8=", 'sha1 (digest_data_b64/2)'); +is( digest_data_b64u('SHA1', "123"), "QL0AFWMIX8NRZTKeof9cXsvbvu8", 'sha1 (digest_data_b64u/2)'); +is( Crypt::Digest::SHA1->new->add("123")->hexdigest, "40bd001563085fc35165329ea1ff5c5ecbdbbeef", 'sha1 (OO/2)'); + +is( sha1("test\0test\0test\n"), pack("H*","ea50a3b39d7337f9232e1a89d97919465592f1e2"), 'sha1 (raw/3)'); +is( sha1_hex("test\0test\0test\n"), "ea50a3b39d7337f9232e1a89d97919465592f1e2", 'sha1 (hex/3)'); +is( sha1_b64("test\0test\0test\n"), "6lCjs51zN/kjLhqJ2XkZRlWS8eI=", 'sha1 (base64/3)'); +is( digest_data('SHA1', "test\0test\0test\n"), pack("H*","ea50a3b39d7337f9232e1a89d97919465592f1e2"), 'sha1 (digest_data_raw/3)'); +is( digest_data_hex('SHA1', "test\0test\0test\n"), "ea50a3b39d7337f9232e1a89d97919465592f1e2", 'sha1 (digest_data_hex/3)'); +is( digest_data_b64('SHA1', "test\0test\0test\n"), "6lCjs51zN/kjLhqJ2XkZRlWS8eI=", 'sha1 (digest_data_b64/3)'); +is( digest_data_b64u('SHA1', "test\0test\0test\n"), "6lCjs51zN_kjLhqJ2XkZRlWS8eI", 'sha1 (digest_data_b64u/3)'); +is( Crypt::Digest::SHA1->new->add("test\0test\0test\n")->hexdigest, "ea50a3b39d7337f9232e1a89d97919465592f1e2", 'sha1 (OO/3)'); + + +is( sha1_file('t/data/binary-test.file'), pack("H*","8fde043b787662863a83f0c55f2517ca6b947fdc"), 'sha1 (raw/file/1)'); +is( sha1_file_hex('t/data/binary-test.file'), "8fde043b787662863a83f0c55f2517ca6b947fdc", 'sha1 (hex/file/1)'); +is( sha1_file_b64('t/data/binary-test.file'), "j94EO3h2YoY6g/DFXyUXymuUf9w=", 'sha1 (base64/file/1)'); +is( digest_file('SHA1', 't/data/binary-test.file'), pack("H*","8fde043b787662863a83f0c55f2517ca6b947fdc"), 'sha1 (digest_file_raw/file/1)'); +is( digest_file_hex('SHA1', 't/data/binary-test.file'), "8fde043b787662863a83f0c55f2517ca6b947fdc", 'sha1 (digest_file_hex/file/1)'); +is( digest_file_b64('SHA1', 't/data/binary-test.file'), "j94EO3h2YoY6g/DFXyUXymuUf9w=", 'sha1 (digest_file_b64/file/1)'); +is( digest_file_b64u('SHA1', 't/data/binary-test.file'), "j94EO3h2YoY6g_DFXyUXymuUf9w", 'sha1 (digest_file_b64u/file/1)'); +is( Crypt::Digest::SHA1->new->addfile('t/data/binary-test.file')->hexdigest, "8fde043b787662863a83f0c55f2517ca6b947fdc", 'sha1 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::SHA1->new->addfile($fh)->hexdigest, "8fde043b787662863a83f0c55f2517ca6b947fdc", 'sha1 (OO/filehandle/1)'); + close($fh); +} + +is( sha1_file('t/data/text-CR.file'), pack("H*","db44309786197ba6364b9c7559b6b9d4fea497f7"), 'sha1 (raw/file/2)'); +is( sha1_file_hex('t/data/text-CR.file'), "db44309786197ba6364b9c7559b6b9d4fea497f7", 'sha1 (hex/file/2)'); +is( sha1_file_b64('t/data/text-CR.file'), "20Qwl4YZe6Y2S5x1Wba51P6kl/c=", 'sha1 (base64/file/2)'); +is( digest_file('SHA1', 't/data/text-CR.file'), pack("H*","db44309786197ba6364b9c7559b6b9d4fea497f7"), 'sha1 (digest_file_raw/file/2)'); +is( digest_file_hex('SHA1', 't/data/text-CR.file'), "db44309786197ba6364b9c7559b6b9d4fea497f7", 'sha1 (digest_file_hex/file/2)'); +is( digest_file_b64('SHA1', 't/data/text-CR.file'), "20Qwl4YZe6Y2S5x1Wba51P6kl/c=", 'sha1 (digest_file_b64/file/2)'); +is( digest_file_b64u('SHA1', 't/data/text-CR.file'), "20Qwl4YZe6Y2S5x1Wba51P6kl_c", 'sha1 (digest_file_b64u/file/2)'); +is( Crypt::Digest::SHA1->new->addfile('t/data/text-CR.file')->hexdigest, "db44309786197ba6364b9c7559b6b9d4fea497f7", 'sha1 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::SHA1->new->addfile($fh)->hexdigest, "db44309786197ba6364b9c7559b6b9d4fea497f7", 'sha1 (OO/filehandle/2)'); + close($fh); +} + +is( sha1_file('t/data/text-CRLF.file'), pack("H*","ed4b7fe06d6ea812a998f2fa0f40e10c53a17ebb"), 'sha1 (raw/file/3)'); +is( sha1_file_hex('t/data/text-CRLF.file'), "ed4b7fe06d6ea812a998f2fa0f40e10c53a17ebb", 'sha1 (hex/file/3)'); +is( sha1_file_b64('t/data/text-CRLF.file'), "7Ut/4G1uqBKpmPL6D0DhDFOhfrs=", 'sha1 (base64/file/3)'); +is( digest_file('SHA1', 't/data/text-CRLF.file'), pack("H*","ed4b7fe06d6ea812a998f2fa0f40e10c53a17ebb"), 'sha1 (digest_file_raw/file/3)'); +is( digest_file_hex('SHA1', 't/data/text-CRLF.file'), "ed4b7fe06d6ea812a998f2fa0f40e10c53a17ebb", 'sha1 (digest_file_hex/file/3)'); +is( digest_file_b64('SHA1', 't/data/text-CRLF.file'), "7Ut/4G1uqBKpmPL6D0DhDFOhfrs=", 'sha1 (digest_file_b64/file/3)'); +is( digest_file_b64u('SHA1', 't/data/text-CRLF.file'), "7Ut_4G1uqBKpmPL6D0DhDFOhfrs", 'sha1 (digest_file_b64u/file/3)'); +is( Crypt::Digest::SHA1->new->addfile('t/data/text-CRLF.file')->hexdigest, "ed4b7fe06d6ea812a998f2fa0f40e10c53a17ebb", 'sha1 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::SHA1->new->addfile($fh)->hexdigest, "ed4b7fe06d6ea812a998f2fa0f40e10c53a17ebb", 'sha1 (OO/filehandle/3)'); + close($fh); +} + +is( sha1_file('t/data/text-LF.file'), pack("H*","c12fb4decacf4617b6e9447770d6ef56c507d4ce"), 'sha1 (raw/file/4)'); +is( sha1_file_hex('t/data/text-LF.file'), "c12fb4decacf4617b6e9447770d6ef56c507d4ce", 'sha1 (hex/file/4)'); +is( sha1_file_b64('t/data/text-LF.file'), "wS+03srPRhe26UR3cNbvVsUH1M4=", 'sha1 (base64/file/4)'); +is( digest_file('SHA1', 't/data/text-LF.file'), pack("H*","c12fb4decacf4617b6e9447770d6ef56c507d4ce"), 'sha1 (digest_file_raw/file/4)'); +is( digest_file_hex('SHA1', 't/data/text-LF.file'), "c12fb4decacf4617b6e9447770d6ef56c507d4ce", 'sha1 (digest_file_hex/file/4)'); +is( digest_file_b64('SHA1', 't/data/text-LF.file'), "wS+03srPRhe26UR3cNbvVsUH1M4=", 'sha1 (digest_file_b64/file/4)'); +is( digest_file_b64u('SHA1', 't/data/text-LF.file'), "wS-03srPRhe26UR3cNbvVsUH1M4", 'sha1 (digest_file_b64u/file/4)'); +is( Crypt::Digest::SHA1->new->addfile('t/data/text-LF.file')->hexdigest, "c12fb4decacf4617b6e9447770d6ef56c507d4ce", 'sha1 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::SHA1->new->addfile($fh)->hexdigest, "c12fb4decacf4617b6e9447770d6ef56c507d4ce", 'sha1 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_sha224.t b/t/digest_sha224.t new file mode 100644 index 0000000..7489768 --- /dev/null +++ b/t/digest_sha224.t @@ -0,0 +1,105 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::SHA224 qw( sha224 sha224_hex sha224_b64 sha224_b64u sha224_file sha224_file_hex sha224_file_b64 sha224_file_b64u ); + +is( Crypt::Digest::hashsize('SHA224'), 28, 'hashsize/1'); +is( Crypt::Digest->hashsize('SHA224'), 28, 'hashsize/2'); +is( Crypt::Digest::SHA224::hashsize, 28, 'hashsize/3'); +is( Crypt::Digest::SHA224->hashsize, 28, 'hashsize/4'); +is( Crypt::Digest->new('SHA224')->hashsize, 28, 'hashsize/5'); +is( Crypt::Digest::SHA224->new->hashsize, 28, 'hashsize/6'); + + +is( sha224(""), pack("H*","d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f"), 'sha224 (raw/1)'); +is( sha224_hex(""), "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", 'sha224 (hex/1)'); +is( sha224_b64(""), "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", 'sha224 (base64/1)'); +is( digest_data('SHA224', ""), pack("H*","d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f"), 'sha224 (digest_data_raw/1)'); +is( digest_data_hex('SHA224', ""), "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", 'sha224 (digest_data_hex/1)'); +is( digest_data_b64('SHA224', ""), "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", 'sha224 (digest_data_b64/1)'); +is( digest_data_b64u('SHA224', ""), "0UoCjCo6K8lHYQK7KII0xBWisB-CjqYqxbPkLw", 'sha224 (digest_data_b64u/1)'); +is( Crypt::Digest::SHA224->new->add("")->hexdigest, "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", 'sha224 (OO/1)'); + +is( sha224("123"), pack("H*","78d8045d684abd2eece923758f3cd781489df3a48e1278982466017f"), 'sha224 (raw/2)'); +is( sha224_hex("123"), "78d8045d684abd2eece923758f3cd781489df3a48e1278982466017f", 'sha224 (hex/2)'); +is( sha224_b64("123"), "eNgEXWhKvS7s6SN1jzzXgUid86SOEniYJGYBfw==", 'sha224 (base64/2)'); +is( digest_data('SHA224', "123"), pack("H*","78d8045d684abd2eece923758f3cd781489df3a48e1278982466017f"), 'sha224 (digest_data_raw/2)'); +is( digest_data_hex('SHA224', "123"), "78d8045d684abd2eece923758f3cd781489df3a48e1278982466017f", 'sha224 (digest_data_hex/2)'); +is( digest_data_b64('SHA224', "123"), "eNgEXWhKvS7s6SN1jzzXgUid86SOEniYJGYBfw==", 'sha224 (digest_data_b64/2)'); +is( digest_data_b64u('SHA224', "123"), "eNgEXWhKvS7s6SN1jzzXgUid86SOEniYJGYBfw", 'sha224 (digest_data_b64u/2)'); +is( Crypt::Digest::SHA224->new->add("123")->hexdigest, "78d8045d684abd2eece923758f3cd781489df3a48e1278982466017f", 'sha224 (OO/2)'); + +is( sha224("test\0test\0test\n"), pack("H*","f4304fb326d85e3b19eefc4ecd772d2fa8d5e20cf9b3c30689bf5d1a"), 'sha224 (raw/3)'); +is( sha224_hex("test\0test\0test\n"), "f4304fb326d85e3b19eefc4ecd772d2fa8d5e20cf9b3c30689bf5d1a", 'sha224 (hex/3)'); +is( sha224_b64("test\0test\0test\n"), "9DBPsybYXjsZ7vxOzXctL6jV4gz5s8MGib9dGg==", 'sha224 (base64/3)'); +is( digest_data('SHA224', "test\0test\0test\n"), pack("H*","f4304fb326d85e3b19eefc4ecd772d2fa8d5e20cf9b3c30689bf5d1a"), 'sha224 (digest_data_raw/3)'); +is( digest_data_hex('SHA224', "test\0test\0test\n"), "f4304fb326d85e3b19eefc4ecd772d2fa8d5e20cf9b3c30689bf5d1a", 'sha224 (digest_data_hex/3)'); +is( digest_data_b64('SHA224', "test\0test\0test\n"), "9DBPsybYXjsZ7vxOzXctL6jV4gz5s8MGib9dGg==", 'sha224 (digest_data_b64/3)'); +is( digest_data_b64u('SHA224', "test\0test\0test\n"), "9DBPsybYXjsZ7vxOzXctL6jV4gz5s8MGib9dGg", 'sha224 (digest_data_b64u/3)'); +is( Crypt::Digest::SHA224->new->add("test\0test\0test\n")->hexdigest, "f4304fb326d85e3b19eefc4ecd772d2fa8d5e20cf9b3c30689bf5d1a", 'sha224 (OO/3)'); + + +is( sha224_file('t/data/binary-test.file'), pack("H*","d6fb653a853a333c87bc3e7dbc79ffd62458fb3030f2ef484b252b93"), 'sha224 (raw/file/1)'); +is( sha224_file_hex('t/data/binary-test.file'), "d6fb653a853a333c87bc3e7dbc79ffd62458fb3030f2ef484b252b93", 'sha224 (hex/file/1)'); +is( sha224_file_b64('t/data/binary-test.file'), "1vtlOoU6MzyHvD59vHn/1iRY+zAw8u9ISyUrkw==", 'sha224 (base64/file/1)'); +is( digest_file('SHA224', 't/data/binary-test.file'), pack("H*","d6fb653a853a333c87bc3e7dbc79ffd62458fb3030f2ef484b252b93"), 'sha224 (digest_file_raw/file/1)'); +is( digest_file_hex('SHA224', 't/data/binary-test.file'), "d6fb653a853a333c87bc3e7dbc79ffd62458fb3030f2ef484b252b93", 'sha224 (digest_file_hex/file/1)'); +is( digest_file_b64('SHA224', 't/data/binary-test.file'), "1vtlOoU6MzyHvD59vHn/1iRY+zAw8u9ISyUrkw==", 'sha224 (digest_file_b64/file/1)'); +is( digest_file_b64u('SHA224', 't/data/binary-test.file'), "1vtlOoU6MzyHvD59vHn_1iRY-zAw8u9ISyUrkw", 'sha224 (digest_file_b64u/file/1)'); +is( Crypt::Digest::SHA224->new->addfile('t/data/binary-test.file')->hexdigest, "d6fb653a853a333c87bc3e7dbc79ffd62458fb3030f2ef484b252b93", 'sha224 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::SHA224->new->addfile($fh)->hexdigest, "d6fb653a853a333c87bc3e7dbc79ffd62458fb3030f2ef484b252b93", 'sha224 (OO/filehandle/1)'); + close($fh); +} + +is( sha224_file('t/data/text-CR.file'), pack("H*","80b23d1856d8e5402088373029c50fca51518aa62a08a4ebc5808399"), 'sha224 (raw/file/2)'); +is( sha224_file_hex('t/data/text-CR.file'), "80b23d1856d8e5402088373029c50fca51518aa62a08a4ebc5808399", 'sha224 (hex/file/2)'); +is( sha224_file_b64('t/data/text-CR.file'), "gLI9GFbY5UAgiDcwKcUPylFRiqYqCKTrxYCDmQ==", 'sha224 (base64/file/2)'); +is( digest_file('SHA224', 't/data/text-CR.file'), pack("H*","80b23d1856d8e5402088373029c50fca51518aa62a08a4ebc5808399"), 'sha224 (digest_file_raw/file/2)'); +is( digest_file_hex('SHA224', 't/data/text-CR.file'), "80b23d1856d8e5402088373029c50fca51518aa62a08a4ebc5808399", 'sha224 (digest_file_hex/file/2)'); +is( digest_file_b64('SHA224', 't/data/text-CR.file'), "gLI9GFbY5UAgiDcwKcUPylFRiqYqCKTrxYCDmQ==", 'sha224 (digest_file_b64/file/2)'); +is( digest_file_b64u('SHA224', 't/data/text-CR.file'), "gLI9GFbY5UAgiDcwKcUPylFRiqYqCKTrxYCDmQ", 'sha224 (digest_file_b64u/file/2)'); +is( Crypt::Digest::SHA224->new->addfile('t/data/text-CR.file')->hexdigest, "80b23d1856d8e5402088373029c50fca51518aa62a08a4ebc5808399", 'sha224 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::SHA224->new->addfile($fh)->hexdigest, "80b23d1856d8e5402088373029c50fca51518aa62a08a4ebc5808399", 'sha224 (OO/filehandle/2)'); + close($fh); +} + +is( sha224_file('t/data/text-CRLF.file'), pack("H*","106ce90e12970e2a4a14e690c5d519a144ebecab9b5292f31faf3d6e"), 'sha224 (raw/file/3)'); +is( sha224_file_hex('t/data/text-CRLF.file'), "106ce90e12970e2a4a14e690c5d519a144ebecab9b5292f31faf3d6e", 'sha224 (hex/file/3)'); +is( sha224_file_b64('t/data/text-CRLF.file'), "EGzpDhKXDipKFOaQxdUZoUTr7KubUpLzH689bg==", 'sha224 (base64/file/3)'); +is( digest_file('SHA224', 't/data/text-CRLF.file'), pack("H*","106ce90e12970e2a4a14e690c5d519a144ebecab9b5292f31faf3d6e"), 'sha224 (digest_file_raw/file/3)'); +is( digest_file_hex('SHA224', 't/data/text-CRLF.file'), "106ce90e12970e2a4a14e690c5d519a144ebecab9b5292f31faf3d6e", 'sha224 (digest_file_hex/file/3)'); +is( digest_file_b64('SHA224', 't/data/text-CRLF.file'), "EGzpDhKXDipKFOaQxdUZoUTr7KubUpLzH689bg==", 'sha224 (digest_file_b64/file/3)'); +is( digest_file_b64u('SHA224', 't/data/text-CRLF.file'), "EGzpDhKXDipKFOaQxdUZoUTr7KubUpLzH689bg", 'sha224 (digest_file_b64u/file/3)'); +is( Crypt::Digest::SHA224->new->addfile('t/data/text-CRLF.file')->hexdigest, "106ce90e12970e2a4a14e690c5d519a144ebecab9b5292f31faf3d6e", 'sha224 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::SHA224->new->addfile($fh)->hexdigest, "106ce90e12970e2a4a14e690c5d519a144ebecab9b5292f31faf3d6e", 'sha224 (OO/filehandle/3)'); + close($fh); +} + +is( sha224_file('t/data/text-LF.file'), pack("H*","b854140316344d8f63f90ade619918bddf80a4b46da19f38f55a3d22"), 'sha224 (raw/file/4)'); +is( sha224_file_hex('t/data/text-LF.file'), "b854140316344d8f63f90ade619918bddf80a4b46da19f38f55a3d22", 'sha224 (hex/file/4)'); +is( sha224_file_b64('t/data/text-LF.file'), "uFQUAxY0TY9j+QreYZkYvd+ApLRtoZ849Vo9Ig==", 'sha224 (base64/file/4)'); +is( digest_file('SHA224', 't/data/text-LF.file'), pack("H*","b854140316344d8f63f90ade619918bddf80a4b46da19f38f55a3d22"), 'sha224 (digest_file_raw/file/4)'); +is( digest_file_hex('SHA224', 't/data/text-LF.file'), "b854140316344d8f63f90ade619918bddf80a4b46da19f38f55a3d22", 'sha224 (digest_file_hex/file/4)'); +is( digest_file_b64('SHA224', 't/data/text-LF.file'), "uFQUAxY0TY9j+QreYZkYvd+ApLRtoZ849Vo9Ig==", 'sha224 (digest_file_b64/file/4)'); +is( digest_file_b64u('SHA224', 't/data/text-LF.file'), "uFQUAxY0TY9j-QreYZkYvd-ApLRtoZ849Vo9Ig", 'sha224 (digest_file_b64u/file/4)'); +is( Crypt::Digest::SHA224->new->addfile('t/data/text-LF.file')->hexdigest, "b854140316344d8f63f90ade619918bddf80a4b46da19f38f55a3d22", 'sha224 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::SHA224->new->addfile($fh)->hexdigest, "b854140316344d8f63f90ade619918bddf80a4b46da19f38f55a3d22", 'sha224 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_sha256.t b/t/digest_sha256.t new file mode 100644 index 0000000..c0f79cc --- /dev/null +++ b/t/digest_sha256.t @@ -0,0 +1,105 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::SHA256 qw( sha256 sha256_hex sha256_b64 sha256_b64u sha256_file sha256_file_hex sha256_file_b64 sha256_file_b64u ); + +is( Crypt::Digest::hashsize('SHA256'), 32, 'hashsize/1'); +is( Crypt::Digest->hashsize('SHA256'), 32, 'hashsize/2'); +is( Crypt::Digest::SHA256::hashsize, 32, 'hashsize/3'); +is( Crypt::Digest::SHA256->hashsize, 32, 'hashsize/4'); +is( Crypt::Digest->new('SHA256')->hashsize, 32, 'hashsize/5'); +is( Crypt::Digest::SHA256->new->hashsize, 32, 'hashsize/6'); + + +is( sha256(""), pack("H*","e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"), 'sha256 (raw/1)'); +is( sha256_hex(""), "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 'sha256 (hex/1)'); +is( sha256_b64(""), "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=", 'sha256 (base64/1)'); +is( digest_data('SHA256', ""), pack("H*","e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"), 'sha256 (digest_data_raw/1)'); +is( digest_data_hex('SHA256', ""), "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 'sha256 (digest_data_hex/1)'); +is( digest_data_b64('SHA256', ""), "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=", 'sha256 (digest_data_b64/1)'); +is( digest_data_b64u('SHA256', ""), "47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU", 'sha256 (digest_data_b64u/1)'); +is( Crypt::Digest::SHA256->new->add("")->hexdigest, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 'sha256 (OO/1)'); + +is( sha256("123"), pack("H*","a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"), 'sha256 (raw/2)'); +is( sha256_hex("123"), "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3", 'sha256 (hex/2)'); +is( sha256_b64("123"), "pmWkWSBCL51Bfkhn79xPuKBKHz//H6B+mY6G9/eieuM=", 'sha256 (base64/2)'); +is( digest_data('SHA256', "123"), pack("H*","a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"), 'sha256 (digest_data_raw/2)'); +is( digest_data_hex('SHA256', "123"), "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3", 'sha256 (digest_data_hex/2)'); +is( digest_data_b64('SHA256', "123"), "pmWkWSBCL51Bfkhn79xPuKBKHz//H6B+mY6G9/eieuM=", 'sha256 (digest_data_b64/2)'); +is( digest_data_b64u('SHA256', "123"), "pmWkWSBCL51Bfkhn79xPuKBKHz__H6B-mY6G9_eieuM", 'sha256 (digest_data_b64u/2)'); +is( Crypt::Digest::SHA256->new->add("123")->hexdigest, "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3", 'sha256 (OO/2)'); + +is( sha256("test\0test\0test\n"), pack("H*","6dedffd4eec5795dec92554802efd8b4a7abc7092f774597abc895c9bc528522"), 'sha256 (raw/3)'); +is( sha256_hex("test\0test\0test\n"), "6dedffd4eec5795dec92554802efd8b4a7abc7092f774597abc895c9bc528522", 'sha256 (hex/3)'); +is( sha256_b64("test\0test\0test\n"), "be3/1O7FeV3sklVIAu/YtKerxwkvd0WXq8iVybxShSI=", 'sha256 (base64/3)'); +is( digest_data('SHA256', "test\0test\0test\n"), pack("H*","6dedffd4eec5795dec92554802efd8b4a7abc7092f774597abc895c9bc528522"), 'sha256 (digest_data_raw/3)'); +is( digest_data_hex('SHA256', "test\0test\0test\n"), "6dedffd4eec5795dec92554802efd8b4a7abc7092f774597abc895c9bc528522", 'sha256 (digest_data_hex/3)'); +is( digest_data_b64('SHA256', "test\0test\0test\n"), "be3/1O7FeV3sklVIAu/YtKerxwkvd0WXq8iVybxShSI=", 'sha256 (digest_data_b64/3)'); +is( digest_data_b64u('SHA256', "test\0test\0test\n"), "be3_1O7FeV3sklVIAu_YtKerxwkvd0WXq8iVybxShSI", 'sha256 (digest_data_b64u/3)'); +is( Crypt::Digest::SHA256->new->add("test\0test\0test\n")->hexdigest, "6dedffd4eec5795dec92554802efd8b4a7abc7092f774597abc895c9bc528522", 'sha256 (OO/3)'); + + +is( sha256_file('t/data/binary-test.file'), pack("H*","eefc3172bcb45a8e99233f5f33faea312e50894885d9677d9ef530f734a3b343"), 'sha256 (raw/file/1)'); +is( sha256_file_hex('t/data/binary-test.file'), "eefc3172bcb45a8e99233f5f33faea312e50894885d9677d9ef530f734a3b343", 'sha256 (hex/file/1)'); +is( sha256_file_b64('t/data/binary-test.file'), "7vwxcry0Wo6ZIz9fM/rqMS5QiUiF2Wd9nvUw9zSjs0M=", 'sha256 (base64/file/1)'); +is( digest_file('SHA256', 't/data/binary-test.file'), pack("H*","eefc3172bcb45a8e99233f5f33faea312e50894885d9677d9ef530f734a3b343"), 'sha256 (digest_file_raw/file/1)'); +is( digest_file_hex('SHA256', 't/data/binary-test.file'), "eefc3172bcb45a8e99233f5f33faea312e50894885d9677d9ef530f734a3b343", 'sha256 (digest_file_hex/file/1)'); +is( digest_file_b64('SHA256', 't/data/binary-test.file'), "7vwxcry0Wo6ZIz9fM/rqMS5QiUiF2Wd9nvUw9zSjs0M=", 'sha256 (digest_file_b64/file/1)'); +is( digest_file_b64u('SHA256', 't/data/binary-test.file'), "7vwxcry0Wo6ZIz9fM_rqMS5QiUiF2Wd9nvUw9zSjs0M", 'sha256 (digest_file_b64u/file/1)'); +is( Crypt::Digest::SHA256->new->addfile('t/data/binary-test.file')->hexdigest, "eefc3172bcb45a8e99233f5f33faea312e50894885d9677d9ef530f734a3b343", 'sha256 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::SHA256->new->addfile($fh)->hexdigest, "eefc3172bcb45a8e99233f5f33faea312e50894885d9677d9ef530f734a3b343", 'sha256 (OO/filehandle/1)'); + close($fh); +} + +is( sha256_file('t/data/text-CR.file'), pack("H*","00e46d5084204a794818df06df45e7cc4489fd7ada4762c958b3c19c86409193"), 'sha256 (raw/file/2)'); +is( sha256_file_hex('t/data/text-CR.file'), "00e46d5084204a794818df06df45e7cc4489fd7ada4762c958b3c19c86409193", 'sha256 (hex/file/2)'); +is( sha256_file_b64('t/data/text-CR.file'), "AORtUIQgSnlIGN8G30XnzESJ/XraR2LJWLPBnIZAkZM=", 'sha256 (base64/file/2)'); +is( digest_file('SHA256', 't/data/text-CR.file'), pack("H*","00e46d5084204a794818df06df45e7cc4489fd7ada4762c958b3c19c86409193"), 'sha256 (digest_file_raw/file/2)'); +is( digest_file_hex('SHA256', 't/data/text-CR.file'), "00e46d5084204a794818df06df45e7cc4489fd7ada4762c958b3c19c86409193", 'sha256 (digest_file_hex/file/2)'); +is( digest_file_b64('SHA256', 't/data/text-CR.file'), "AORtUIQgSnlIGN8G30XnzESJ/XraR2LJWLPBnIZAkZM=", 'sha256 (digest_file_b64/file/2)'); +is( digest_file_b64u('SHA256', 't/data/text-CR.file'), "AORtUIQgSnlIGN8G30XnzESJ_XraR2LJWLPBnIZAkZM", 'sha256 (digest_file_b64u/file/2)'); +is( Crypt::Digest::SHA256->new->addfile('t/data/text-CR.file')->hexdigest, "00e46d5084204a794818df06df45e7cc4489fd7ada4762c958b3c19c86409193", 'sha256 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::SHA256->new->addfile($fh)->hexdigest, "00e46d5084204a794818df06df45e7cc4489fd7ada4762c958b3c19c86409193", 'sha256 (OO/filehandle/2)'); + close($fh); +} + +is( sha256_file('t/data/text-CRLF.file'), pack("H*","2c28030d9bd766d6ae023e34b3aa84245993f98436cd36db0f0ab2294ffe7b6f"), 'sha256 (raw/file/3)'); +is( sha256_file_hex('t/data/text-CRLF.file'), "2c28030d9bd766d6ae023e34b3aa84245993f98436cd36db0f0ab2294ffe7b6f", 'sha256 (hex/file/3)'); +is( sha256_file_b64('t/data/text-CRLF.file'), "LCgDDZvXZtauAj40s6qEJFmT+YQ2zTbbDwqyKU/+e28=", 'sha256 (base64/file/3)'); +is( digest_file('SHA256', 't/data/text-CRLF.file'), pack("H*","2c28030d9bd766d6ae023e34b3aa84245993f98436cd36db0f0ab2294ffe7b6f"), 'sha256 (digest_file_raw/file/3)'); +is( digest_file_hex('SHA256', 't/data/text-CRLF.file'), "2c28030d9bd766d6ae023e34b3aa84245993f98436cd36db0f0ab2294ffe7b6f", 'sha256 (digest_file_hex/file/3)'); +is( digest_file_b64('SHA256', 't/data/text-CRLF.file'), "LCgDDZvXZtauAj40s6qEJFmT+YQ2zTbbDwqyKU/+e28=", 'sha256 (digest_file_b64/file/3)'); +is( digest_file_b64u('SHA256', 't/data/text-CRLF.file'), "LCgDDZvXZtauAj40s6qEJFmT-YQ2zTbbDwqyKU_-e28", 'sha256 (digest_file_b64u/file/3)'); +is( Crypt::Digest::SHA256->new->addfile('t/data/text-CRLF.file')->hexdigest, "2c28030d9bd766d6ae023e34b3aa84245993f98436cd36db0f0ab2294ffe7b6f", 'sha256 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::SHA256->new->addfile($fh)->hexdigest, "2c28030d9bd766d6ae023e34b3aa84245993f98436cd36db0f0ab2294ffe7b6f", 'sha256 (OO/filehandle/3)'); + close($fh); +} + +is( sha256_file('t/data/text-LF.file'), pack("H*","f8282483e6c484c95d26581056a406650c94b4cc7649e05beb0660aa578f345b"), 'sha256 (raw/file/4)'); +is( sha256_file_hex('t/data/text-LF.file'), "f8282483e6c484c95d26581056a406650c94b4cc7649e05beb0660aa578f345b", 'sha256 (hex/file/4)'); +is( sha256_file_b64('t/data/text-LF.file'), "+Cgkg+bEhMldJlgQVqQGZQyUtMx2SeBb6wZgqlePNFs=", 'sha256 (base64/file/4)'); +is( digest_file('SHA256', 't/data/text-LF.file'), pack("H*","f8282483e6c484c95d26581056a406650c94b4cc7649e05beb0660aa578f345b"), 'sha256 (digest_file_raw/file/4)'); +is( digest_file_hex('SHA256', 't/data/text-LF.file'), "f8282483e6c484c95d26581056a406650c94b4cc7649e05beb0660aa578f345b", 'sha256 (digest_file_hex/file/4)'); +is( digest_file_b64('SHA256', 't/data/text-LF.file'), "+Cgkg+bEhMldJlgQVqQGZQyUtMx2SeBb6wZgqlePNFs=", 'sha256 (digest_file_b64/file/4)'); +is( digest_file_b64u('SHA256', 't/data/text-LF.file'), "-Cgkg-bEhMldJlgQVqQGZQyUtMx2SeBb6wZgqlePNFs", 'sha256 (digest_file_b64u/file/4)'); +is( Crypt::Digest::SHA256->new->addfile('t/data/text-LF.file')->hexdigest, "f8282483e6c484c95d26581056a406650c94b4cc7649e05beb0660aa578f345b", 'sha256 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::SHA256->new->addfile($fh)->hexdigest, "f8282483e6c484c95d26581056a406650c94b4cc7649e05beb0660aa578f345b", 'sha256 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_sha384.t b/t/digest_sha384.t new file mode 100644 index 0000000..506bb4b --- /dev/null +++ b/t/digest_sha384.t @@ -0,0 +1,105 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::SHA384 qw( sha384 sha384_hex sha384_b64 sha384_b64u sha384_file sha384_file_hex sha384_file_b64 sha384_file_b64u ); + +is( Crypt::Digest::hashsize('SHA384'), 48, 'hashsize/1'); +is( Crypt::Digest->hashsize('SHA384'), 48, 'hashsize/2'); +is( Crypt::Digest::SHA384::hashsize, 48, 'hashsize/3'); +is( Crypt::Digest::SHA384->hashsize, 48, 'hashsize/4'); +is( Crypt::Digest->new('SHA384')->hashsize, 48, 'hashsize/5'); +is( Crypt::Digest::SHA384->new->hashsize, 48, 'hashsize/6'); + + +is( sha384(""), pack("H*","38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b"), 'sha384 (raw/1)'); +is( sha384_hex(""), "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b", 'sha384 (hex/1)'); +is( sha384_b64(""), "OLBgp1GsljhM2TJ+sbHjaiH9txEUvgdDTAzHv2P24donTt6/529l+9Ua0vFImLlb", 'sha384 (base64/1)'); +is( digest_data('SHA384', ""), pack("H*","38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b"), 'sha384 (digest_data_raw/1)'); +is( digest_data_hex('SHA384', ""), "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b", 'sha384 (digest_data_hex/1)'); +is( digest_data_b64('SHA384', ""), "OLBgp1GsljhM2TJ+sbHjaiH9txEUvgdDTAzHv2P24donTt6/529l+9Ua0vFImLlb", 'sha384 (digest_data_b64/1)'); +is( digest_data_b64u('SHA384', ""), "OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb", 'sha384 (digest_data_b64u/1)'); +is( Crypt::Digest::SHA384->new->add("")->hexdigest, "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b", 'sha384 (OO/1)'); + +is( sha384("123"), pack("H*","9a0a82f0c0cf31470d7affede3406cc9aa8410671520b727044eda15b4c25532a9b5cd8aaf9cec4919d76255b6bfb00f"), 'sha384 (raw/2)'); +is( sha384_hex("123"), "9a0a82f0c0cf31470d7affede3406cc9aa8410671520b727044eda15b4c25532a9b5cd8aaf9cec4919d76255b6bfb00f", 'sha384 (hex/2)'); +is( sha384_b64("123"), "mgqC8MDPMUcNev/t40BsyaqEEGcVILcnBE7aFbTCVTKptc2Kr5zsSRnXYlW2v7AP", 'sha384 (base64/2)'); +is( digest_data('SHA384', "123"), pack("H*","9a0a82f0c0cf31470d7affede3406cc9aa8410671520b727044eda15b4c25532a9b5cd8aaf9cec4919d76255b6bfb00f"), 'sha384 (digest_data_raw/2)'); +is( digest_data_hex('SHA384', "123"), "9a0a82f0c0cf31470d7affede3406cc9aa8410671520b727044eda15b4c25532a9b5cd8aaf9cec4919d76255b6bfb00f", 'sha384 (digest_data_hex/2)'); +is( digest_data_b64('SHA384', "123"), "mgqC8MDPMUcNev/t40BsyaqEEGcVILcnBE7aFbTCVTKptc2Kr5zsSRnXYlW2v7AP", 'sha384 (digest_data_b64/2)'); +is( digest_data_b64u('SHA384', "123"), "mgqC8MDPMUcNev_t40BsyaqEEGcVILcnBE7aFbTCVTKptc2Kr5zsSRnXYlW2v7AP", 'sha384 (digest_data_b64u/2)'); +is( Crypt::Digest::SHA384->new->add("123")->hexdigest, "9a0a82f0c0cf31470d7affede3406cc9aa8410671520b727044eda15b4c25532a9b5cd8aaf9cec4919d76255b6bfb00f", 'sha384 (OO/2)'); + +is( sha384("test\0test\0test\n"), pack("H*","3339da627d4b92fd5af59ce0bdabdbdfea3895d2e698322ee49a37b5bd47245fa015d716921ff689dd9e8c02ba02cea8"), 'sha384 (raw/3)'); +is( sha384_hex("test\0test\0test\n"), "3339da627d4b92fd5af59ce0bdabdbdfea3895d2e698322ee49a37b5bd47245fa015d716921ff689dd9e8c02ba02cea8", 'sha384 (hex/3)'); +is( sha384_b64("test\0test\0test\n"), "MznaYn1Lkv1a9Zzgvavb3+o4ldLmmDIu5Jo3tb1HJF+gFdcWkh/2id2ejAK6As6o", 'sha384 (base64/3)'); +is( digest_data('SHA384', "test\0test\0test\n"), pack("H*","3339da627d4b92fd5af59ce0bdabdbdfea3895d2e698322ee49a37b5bd47245fa015d716921ff689dd9e8c02ba02cea8"), 'sha384 (digest_data_raw/3)'); +is( digest_data_hex('SHA384', "test\0test\0test\n"), "3339da627d4b92fd5af59ce0bdabdbdfea3895d2e698322ee49a37b5bd47245fa015d716921ff689dd9e8c02ba02cea8", 'sha384 (digest_data_hex/3)'); +is( digest_data_b64('SHA384', "test\0test\0test\n"), "MznaYn1Lkv1a9Zzgvavb3+o4ldLmmDIu5Jo3tb1HJF+gFdcWkh/2id2ejAK6As6o", 'sha384 (digest_data_b64/3)'); +is( digest_data_b64u('SHA384', "test\0test\0test\n"), "MznaYn1Lkv1a9Zzgvavb3-o4ldLmmDIu5Jo3tb1HJF-gFdcWkh_2id2ejAK6As6o", 'sha384 (digest_data_b64u/3)'); +is( Crypt::Digest::SHA384->new->add("test\0test\0test\n")->hexdigest, "3339da627d4b92fd5af59ce0bdabdbdfea3895d2e698322ee49a37b5bd47245fa015d716921ff689dd9e8c02ba02cea8", 'sha384 (OO/3)'); + + +is( sha384_file('t/data/binary-test.file'), pack("H*","aec56ad72d87f626f2c3fdeca938a83ff4f5184c4eabddcc64ceeec3130d0626c5880ec1a6a7fd1a8c88c7995a45fc49"), 'sha384 (raw/file/1)'); +is( sha384_file_hex('t/data/binary-test.file'), "aec56ad72d87f626f2c3fdeca938a83ff4f5184c4eabddcc64ceeec3130d0626c5880ec1a6a7fd1a8c88c7995a45fc49", 'sha384 (hex/file/1)'); +is( sha384_file_b64('t/data/binary-test.file'), "rsVq1y2H9ibyw/3sqTioP/T1GExOq93MZM7uwxMNBibFiA7Bpqf9GoyIx5laRfxJ", 'sha384 (base64/file/1)'); +is( digest_file('SHA384', 't/data/binary-test.file'), pack("H*","aec56ad72d87f626f2c3fdeca938a83ff4f5184c4eabddcc64ceeec3130d0626c5880ec1a6a7fd1a8c88c7995a45fc49"), 'sha384 (digest_file_raw/file/1)'); +is( digest_file_hex('SHA384', 't/data/binary-test.file'), "aec56ad72d87f626f2c3fdeca938a83ff4f5184c4eabddcc64ceeec3130d0626c5880ec1a6a7fd1a8c88c7995a45fc49", 'sha384 (digest_file_hex/file/1)'); +is( digest_file_b64('SHA384', 't/data/binary-test.file'), "rsVq1y2H9ibyw/3sqTioP/T1GExOq93MZM7uwxMNBibFiA7Bpqf9GoyIx5laRfxJ", 'sha384 (digest_file_b64/file/1)'); +is( digest_file_b64u('SHA384', 't/data/binary-test.file'), "rsVq1y2H9ibyw_3sqTioP_T1GExOq93MZM7uwxMNBibFiA7Bpqf9GoyIx5laRfxJ", 'sha384 (digest_file_b64u/file/1)'); +is( Crypt::Digest::SHA384->new->addfile('t/data/binary-test.file')->hexdigest, "aec56ad72d87f626f2c3fdeca938a83ff4f5184c4eabddcc64ceeec3130d0626c5880ec1a6a7fd1a8c88c7995a45fc49", 'sha384 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::SHA384->new->addfile($fh)->hexdigest, "aec56ad72d87f626f2c3fdeca938a83ff4f5184c4eabddcc64ceeec3130d0626c5880ec1a6a7fd1a8c88c7995a45fc49", 'sha384 (OO/filehandle/1)'); + close($fh); +} + +is( sha384_file('t/data/text-CR.file'), pack("H*","fd1408765c0b42d3d836e945e21ee92fe17bc7f68b23ccfbdaaf3ffd6f6e81732bd8340d1418b18abd2745ef1a0544e6"), 'sha384 (raw/file/2)'); +is( sha384_file_hex('t/data/text-CR.file'), "fd1408765c0b42d3d836e945e21ee92fe17bc7f68b23ccfbdaaf3ffd6f6e81732bd8340d1418b18abd2745ef1a0544e6", 'sha384 (hex/file/2)'); +is( sha384_file_b64('t/data/text-CR.file'), "/RQIdlwLQtPYNulF4h7pL+F7x/aLI8z72q8//W9ugXMr2DQNFBixir0nRe8aBUTm", 'sha384 (base64/file/2)'); +is( digest_file('SHA384', 't/data/text-CR.file'), pack("H*","fd1408765c0b42d3d836e945e21ee92fe17bc7f68b23ccfbdaaf3ffd6f6e81732bd8340d1418b18abd2745ef1a0544e6"), 'sha384 (digest_file_raw/file/2)'); +is( digest_file_hex('SHA384', 't/data/text-CR.file'), "fd1408765c0b42d3d836e945e21ee92fe17bc7f68b23ccfbdaaf3ffd6f6e81732bd8340d1418b18abd2745ef1a0544e6", 'sha384 (digest_file_hex/file/2)'); +is( digest_file_b64('SHA384', 't/data/text-CR.file'), "/RQIdlwLQtPYNulF4h7pL+F7x/aLI8z72q8//W9ugXMr2DQNFBixir0nRe8aBUTm", 'sha384 (digest_file_b64/file/2)'); +is( digest_file_b64u('SHA384', 't/data/text-CR.file'), "_RQIdlwLQtPYNulF4h7pL-F7x_aLI8z72q8__W9ugXMr2DQNFBixir0nRe8aBUTm", 'sha384 (digest_file_b64u/file/2)'); +is( Crypt::Digest::SHA384->new->addfile('t/data/text-CR.file')->hexdigest, "fd1408765c0b42d3d836e945e21ee92fe17bc7f68b23ccfbdaaf3ffd6f6e81732bd8340d1418b18abd2745ef1a0544e6", 'sha384 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::SHA384->new->addfile($fh)->hexdigest, "fd1408765c0b42d3d836e945e21ee92fe17bc7f68b23ccfbdaaf3ffd6f6e81732bd8340d1418b18abd2745ef1a0544e6", 'sha384 (OO/filehandle/2)'); + close($fh); +} + +is( sha384_file('t/data/text-CRLF.file'), pack("H*","f0d643a22c2f25fda36f3f834b05b5c9201c5139b374c4a581328ce52dd9bababcc7017f96b74eff8f66c097c9156373"), 'sha384 (raw/file/3)'); +is( sha384_file_hex('t/data/text-CRLF.file'), "f0d643a22c2f25fda36f3f834b05b5c9201c5139b374c4a581328ce52dd9bababcc7017f96b74eff8f66c097c9156373", 'sha384 (hex/file/3)'); +is( sha384_file_b64('t/data/text-CRLF.file'), "8NZDoiwvJf2jbz+DSwW1ySAcUTmzdMSlgTKM5S3Zurq8xwF/lrdO/49mwJfJFWNz", 'sha384 (base64/file/3)'); +is( digest_file('SHA384', 't/data/text-CRLF.file'), pack("H*","f0d643a22c2f25fda36f3f834b05b5c9201c5139b374c4a581328ce52dd9bababcc7017f96b74eff8f66c097c9156373"), 'sha384 (digest_file_raw/file/3)'); +is( digest_file_hex('SHA384', 't/data/text-CRLF.file'), "f0d643a22c2f25fda36f3f834b05b5c9201c5139b374c4a581328ce52dd9bababcc7017f96b74eff8f66c097c9156373", 'sha384 (digest_file_hex/file/3)'); +is( digest_file_b64('SHA384', 't/data/text-CRLF.file'), "8NZDoiwvJf2jbz+DSwW1ySAcUTmzdMSlgTKM5S3Zurq8xwF/lrdO/49mwJfJFWNz", 'sha384 (digest_file_b64/file/3)'); +is( digest_file_b64u('SHA384', 't/data/text-CRLF.file'), "8NZDoiwvJf2jbz-DSwW1ySAcUTmzdMSlgTKM5S3Zurq8xwF_lrdO_49mwJfJFWNz", 'sha384 (digest_file_b64u/file/3)'); +is( Crypt::Digest::SHA384->new->addfile('t/data/text-CRLF.file')->hexdigest, "f0d643a22c2f25fda36f3f834b05b5c9201c5139b374c4a581328ce52dd9bababcc7017f96b74eff8f66c097c9156373", 'sha384 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::SHA384->new->addfile($fh)->hexdigest, "f0d643a22c2f25fda36f3f834b05b5c9201c5139b374c4a581328ce52dd9bababcc7017f96b74eff8f66c097c9156373", 'sha384 (OO/filehandle/3)'); + close($fh); +} + +is( sha384_file('t/data/text-LF.file'), pack("H*","042e8f361c9fbdb1bf5f9bc254951dca66566196ecaf2df7850c5438338e2c06ea718d8cf3415b77ad56280ba5a3ca1e"), 'sha384 (raw/file/4)'); +is( sha384_file_hex('t/data/text-LF.file'), "042e8f361c9fbdb1bf5f9bc254951dca66566196ecaf2df7850c5438338e2c06ea718d8cf3415b77ad56280ba5a3ca1e", 'sha384 (hex/file/4)'); +is( sha384_file_b64('t/data/text-LF.file'), "BC6PNhyfvbG/X5vCVJUdymZWYZbsry33hQxUODOOLAbqcY2M80Fbd61WKAulo8oe", 'sha384 (base64/file/4)'); +is( digest_file('SHA384', 't/data/text-LF.file'), pack("H*","042e8f361c9fbdb1bf5f9bc254951dca66566196ecaf2df7850c5438338e2c06ea718d8cf3415b77ad56280ba5a3ca1e"), 'sha384 (digest_file_raw/file/4)'); +is( digest_file_hex('SHA384', 't/data/text-LF.file'), "042e8f361c9fbdb1bf5f9bc254951dca66566196ecaf2df7850c5438338e2c06ea718d8cf3415b77ad56280ba5a3ca1e", 'sha384 (digest_file_hex/file/4)'); +is( digest_file_b64('SHA384', 't/data/text-LF.file'), "BC6PNhyfvbG/X5vCVJUdymZWYZbsry33hQxUODOOLAbqcY2M80Fbd61WKAulo8oe", 'sha384 (digest_file_b64/file/4)'); +is( digest_file_b64u('SHA384', 't/data/text-LF.file'), "BC6PNhyfvbG_X5vCVJUdymZWYZbsry33hQxUODOOLAbqcY2M80Fbd61WKAulo8oe", 'sha384 (digest_file_b64u/file/4)'); +is( Crypt::Digest::SHA384->new->addfile('t/data/text-LF.file')->hexdigest, "042e8f361c9fbdb1bf5f9bc254951dca66566196ecaf2df7850c5438338e2c06ea718d8cf3415b77ad56280ba5a3ca1e", 'sha384 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::SHA384->new->addfile($fh)->hexdigest, "042e8f361c9fbdb1bf5f9bc254951dca66566196ecaf2df7850c5438338e2c06ea718d8cf3415b77ad56280ba5a3ca1e", 'sha384 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_sha3_224.t b/t/digest_sha3_224.t new file mode 100644 index 0000000..6e2ecf3 --- /dev/null +++ b/t/digest_sha3_224.t @@ -0,0 +1,105 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::SHA3_224 qw( sha3_224 sha3_224_hex sha3_224_b64 sha3_224_b64u sha3_224_file sha3_224_file_hex sha3_224_file_b64 sha3_224_file_b64u ); + +is( Crypt::Digest::hashsize('SHA3_224'), 28, 'hashsize/1'); +is( Crypt::Digest->hashsize('SHA3_224'), 28, 'hashsize/2'); +is( Crypt::Digest::SHA3_224::hashsize, 28, 'hashsize/3'); +is( Crypt::Digest::SHA3_224->hashsize, 28, 'hashsize/4'); +is( Crypt::Digest->new('SHA3_224')->hashsize, 28, 'hashsize/5'); +is( Crypt::Digest::SHA3_224->new->hashsize, 28, 'hashsize/6'); + + +is( sha3_224(""), pack("H*","6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7"), 'sha3_224 (raw/1)'); +is( sha3_224_hex(""), "6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7", 'sha3_224 (hex/1)'); +is( sha3_224_b64(""), "a04DQjZn27c7bhVFTw6xq9RZf5obB44/W1prxw==", 'sha3_224 (base64/1)'); +is( digest_data('SHA3_224', ""), pack("H*","6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7"), 'sha3_224 (digest_data_raw/1)'); +is( digest_data_hex('SHA3_224', ""), "6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7", 'sha3_224 (digest_data_hex/1)'); +is( digest_data_b64('SHA3_224', ""), "a04DQjZn27c7bhVFTw6xq9RZf5obB44/W1prxw==", 'sha3_224 (digest_data_b64/1)'); +is( digest_data_b64u('SHA3_224', ""), "a04DQjZn27c7bhVFTw6xq9RZf5obB44_W1prxw", 'sha3_224 (digest_data_b64u/1)'); +is( Crypt::Digest::SHA3_224->new->add("")->hexdigest, "6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7", 'sha3_224 (OO/1)'); + +is( sha3_224("123"), pack("H*","602bdc204140db016bee5374895e5568ce422fabe17e064061d80097"), 'sha3_224 (raw/2)'); +is( sha3_224_hex("123"), "602bdc204140db016bee5374895e5568ce422fabe17e064061d80097", 'sha3_224 (hex/2)'); +is( sha3_224_b64("123"), "YCvcIEFA2wFr7lN0iV5VaM5CL6vhfgZAYdgAlw==", 'sha3_224 (base64/2)'); +is( digest_data('SHA3_224', "123"), pack("H*","602bdc204140db016bee5374895e5568ce422fabe17e064061d80097"), 'sha3_224 (digest_data_raw/2)'); +is( digest_data_hex('SHA3_224', "123"), "602bdc204140db016bee5374895e5568ce422fabe17e064061d80097", 'sha3_224 (digest_data_hex/2)'); +is( digest_data_b64('SHA3_224', "123"), "YCvcIEFA2wFr7lN0iV5VaM5CL6vhfgZAYdgAlw==", 'sha3_224 (digest_data_b64/2)'); +is( digest_data_b64u('SHA3_224', "123"), "YCvcIEFA2wFr7lN0iV5VaM5CL6vhfgZAYdgAlw", 'sha3_224 (digest_data_b64u/2)'); +is( Crypt::Digest::SHA3_224->new->add("123")->hexdigest, "602bdc204140db016bee5374895e5568ce422fabe17e064061d80097", 'sha3_224 (OO/2)'); + +is( sha3_224("test\0test\0test\n"), pack("H*","ae786c2326ad35c1d50654029e54c298755324aaa152899efd443654"), 'sha3_224 (raw/3)'); +is( sha3_224_hex("test\0test\0test\n"), "ae786c2326ad35c1d50654029e54c298755324aaa152899efd443654", 'sha3_224 (hex/3)'); +is( sha3_224_b64("test\0test\0test\n"), "rnhsIyatNcHVBlQCnlTCmHVTJKqhUome/UQ2VA==", 'sha3_224 (base64/3)'); +is( digest_data('SHA3_224', "test\0test\0test\n"), pack("H*","ae786c2326ad35c1d50654029e54c298755324aaa152899efd443654"), 'sha3_224 (digest_data_raw/3)'); +is( digest_data_hex('SHA3_224', "test\0test\0test\n"), "ae786c2326ad35c1d50654029e54c298755324aaa152899efd443654", 'sha3_224 (digest_data_hex/3)'); +is( digest_data_b64('SHA3_224', "test\0test\0test\n"), "rnhsIyatNcHVBlQCnlTCmHVTJKqhUome/UQ2VA==", 'sha3_224 (digest_data_b64/3)'); +is( digest_data_b64u('SHA3_224', "test\0test\0test\n"), "rnhsIyatNcHVBlQCnlTCmHVTJKqhUome_UQ2VA", 'sha3_224 (digest_data_b64u/3)'); +is( Crypt::Digest::SHA3_224->new->add("test\0test\0test\n")->hexdigest, "ae786c2326ad35c1d50654029e54c298755324aaa152899efd443654", 'sha3_224 (OO/3)'); + + +is( sha3_224_file('t/data/binary-test.file'), pack("H*","823fba21c0ccbbc12d683cb97707da3a9d8a73f019397d1d61052e85"), 'sha3_224 (raw/file/1)'); +is( sha3_224_file_hex('t/data/binary-test.file'), "823fba21c0ccbbc12d683cb97707da3a9d8a73f019397d1d61052e85", 'sha3_224 (hex/file/1)'); +is( sha3_224_file_b64('t/data/binary-test.file'), "gj+6IcDMu8EtaDy5dwfaOp2Kc/AZOX0dYQUuhQ==", 'sha3_224 (base64/file/1)'); +is( digest_file('SHA3_224', 't/data/binary-test.file'), pack("H*","823fba21c0ccbbc12d683cb97707da3a9d8a73f019397d1d61052e85"), 'sha3_224 (digest_file_raw/file/1)'); +is( digest_file_hex('SHA3_224', 't/data/binary-test.file'), "823fba21c0ccbbc12d683cb97707da3a9d8a73f019397d1d61052e85", 'sha3_224 (digest_file_hex/file/1)'); +is( digest_file_b64('SHA3_224', 't/data/binary-test.file'), "gj+6IcDMu8EtaDy5dwfaOp2Kc/AZOX0dYQUuhQ==", 'sha3_224 (digest_file_b64/file/1)'); +is( digest_file_b64u('SHA3_224', 't/data/binary-test.file'), "gj-6IcDMu8EtaDy5dwfaOp2Kc_AZOX0dYQUuhQ", 'sha3_224 (digest_file_b64u/file/1)'); +is( Crypt::Digest::SHA3_224->new->addfile('t/data/binary-test.file')->hexdigest, "823fba21c0ccbbc12d683cb97707da3a9d8a73f019397d1d61052e85", 'sha3_224 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::SHA3_224->new->addfile($fh)->hexdigest, "823fba21c0ccbbc12d683cb97707da3a9d8a73f019397d1d61052e85", 'sha3_224 (OO/filehandle/1)'); + close($fh); +} + +is( sha3_224_file('t/data/text-CR.file'), pack("H*","2a7677578a2130ff1234c62d459822fe6256e331dc2f92b1de0ff354"), 'sha3_224 (raw/file/2)'); +is( sha3_224_file_hex('t/data/text-CR.file'), "2a7677578a2130ff1234c62d459822fe6256e331dc2f92b1de0ff354", 'sha3_224 (hex/file/2)'); +is( sha3_224_file_b64('t/data/text-CR.file'), "KnZ3V4ohMP8SNMYtRZgi/mJW4zHcL5Kx3g/zVA==", 'sha3_224 (base64/file/2)'); +is( digest_file('SHA3_224', 't/data/text-CR.file'), pack("H*","2a7677578a2130ff1234c62d459822fe6256e331dc2f92b1de0ff354"), 'sha3_224 (digest_file_raw/file/2)'); +is( digest_file_hex('SHA3_224', 't/data/text-CR.file'), "2a7677578a2130ff1234c62d459822fe6256e331dc2f92b1de0ff354", 'sha3_224 (digest_file_hex/file/2)'); +is( digest_file_b64('SHA3_224', 't/data/text-CR.file'), "KnZ3V4ohMP8SNMYtRZgi/mJW4zHcL5Kx3g/zVA==", 'sha3_224 (digest_file_b64/file/2)'); +is( digest_file_b64u('SHA3_224', 't/data/text-CR.file'), "KnZ3V4ohMP8SNMYtRZgi_mJW4zHcL5Kx3g_zVA", 'sha3_224 (digest_file_b64u/file/2)'); +is( Crypt::Digest::SHA3_224->new->addfile('t/data/text-CR.file')->hexdigest, "2a7677578a2130ff1234c62d459822fe6256e331dc2f92b1de0ff354", 'sha3_224 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::SHA3_224->new->addfile($fh)->hexdigest, "2a7677578a2130ff1234c62d459822fe6256e331dc2f92b1de0ff354", 'sha3_224 (OO/filehandle/2)'); + close($fh); +} + +is( sha3_224_file('t/data/text-CRLF.file'), pack("H*","4276e835b367eed68ebe210d28953828d2995c847f1d35de5de57a5c"), 'sha3_224 (raw/file/3)'); +is( sha3_224_file_hex('t/data/text-CRLF.file'), "4276e835b367eed68ebe210d28953828d2995c847f1d35de5de57a5c", 'sha3_224 (hex/file/3)'); +is( sha3_224_file_b64('t/data/text-CRLF.file'), "QnboNbNn7taOviENKJU4KNKZXIR/HTXeXeV6XA==", 'sha3_224 (base64/file/3)'); +is( digest_file('SHA3_224', 't/data/text-CRLF.file'), pack("H*","4276e835b367eed68ebe210d28953828d2995c847f1d35de5de57a5c"), 'sha3_224 (digest_file_raw/file/3)'); +is( digest_file_hex('SHA3_224', 't/data/text-CRLF.file'), "4276e835b367eed68ebe210d28953828d2995c847f1d35de5de57a5c", 'sha3_224 (digest_file_hex/file/3)'); +is( digest_file_b64('SHA3_224', 't/data/text-CRLF.file'), "QnboNbNn7taOviENKJU4KNKZXIR/HTXeXeV6XA==", 'sha3_224 (digest_file_b64/file/3)'); +is( digest_file_b64u('SHA3_224', 't/data/text-CRLF.file'), "QnboNbNn7taOviENKJU4KNKZXIR_HTXeXeV6XA", 'sha3_224 (digest_file_b64u/file/3)'); +is( Crypt::Digest::SHA3_224->new->addfile('t/data/text-CRLF.file')->hexdigest, "4276e835b367eed68ebe210d28953828d2995c847f1d35de5de57a5c", 'sha3_224 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::SHA3_224->new->addfile($fh)->hexdigest, "4276e835b367eed68ebe210d28953828d2995c847f1d35de5de57a5c", 'sha3_224 (OO/filehandle/3)'); + close($fh); +} + +is( sha3_224_file('t/data/text-LF.file'), pack("H*","a5d86974b60e7f6c022f0a7dc6409aabb4c9d21a93665dfe1220802f"), 'sha3_224 (raw/file/4)'); +is( sha3_224_file_hex('t/data/text-LF.file'), "a5d86974b60e7f6c022f0a7dc6409aabb4c9d21a93665dfe1220802f", 'sha3_224 (hex/file/4)'); +is( sha3_224_file_b64('t/data/text-LF.file'), "pdhpdLYOf2wCLwp9xkCaq7TJ0hqTZl3+EiCALw==", 'sha3_224 (base64/file/4)'); +is( digest_file('SHA3_224', 't/data/text-LF.file'), pack("H*","a5d86974b60e7f6c022f0a7dc6409aabb4c9d21a93665dfe1220802f"), 'sha3_224 (digest_file_raw/file/4)'); +is( digest_file_hex('SHA3_224', 't/data/text-LF.file'), "a5d86974b60e7f6c022f0a7dc6409aabb4c9d21a93665dfe1220802f", 'sha3_224 (digest_file_hex/file/4)'); +is( digest_file_b64('SHA3_224', 't/data/text-LF.file'), "pdhpdLYOf2wCLwp9xkCaq7TJ0hqTZl3+EiCALw==", 'sha3_224 (digest_file_b64/file/4)'); +is( digest_file_b64u('SHA3_224', 't/data/text-LF.file'), "pdhpdLYOf2wCLwp9xkCaq7TJ0hqTZl3-EiCALw", 'sha3_224 (digest_file_b64u/file/4)'); +is( Crypt::Digest::SHA3_224->new->addfile('t/data/text-LF.file')->hexdigest, "a5d86974b60e7f6c022f0a7dc6409aabb4c9d21a93665dfe1220802f", 'sha3_224 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::SHA3_224->new->addfile($fh)->hexdigest, "a5d86974b60e7f6c022f0a7dc6409aabb4c9d21a93665dfe1220802f", 'sha3_224 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_sha3_256.t b/t/digest_sha3_256.t new file mode 100644 index 0000000..6c813bd --- /dev/null +++ b/t/digest_sha3_256.t @@ -0,0 +1,105 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::SHA3_256 qw( sha3_256 sha3_256_hex sha3_256_b64 sha3_256_b64u sha3_256_file sha3_256_file_hex sha3_256_file_b64 sha3_256_file_b64u ); + +is( Crypt::Digest::hashsize('SHA3_256'), 32, 'hashsize/1'); +is( Crypt::Digest->hashsize('SHA3_256'), 32, 'hashsize/2'); +is( Crypt::Digest::SHA3_256::hashsize, 32, 'hashsize/3'); +is( Crypt::Digest::SHA3_256->hashsize, 32, 'hashsize/4'); +is( Crypt::Digest->new('SHA3_256')->hashsize, 32, 'hashsize/5'); +is( Crypt::Digest::SHA3_256->new->hashsize, 32, 'hashsize/6'); + + +is( sha3_256(""), pack("H*","a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"), 'sha3_256 (raw/1)'); +is( sha3_256_hex(""), "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a", 'sha3_256 (hex/1)'); +is( sha3_256_b64(""), "p//G+L8e12ZRwUdWoGHWYvWA/03kO0n6gtgKS4D4Q0o=", 'sha3_256 (base64/1)'); +is( digest_data('SHA3_256', ""), pack("H*","a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"), 'sha3_256 (digest_data_raw/1)'); +is( digest_data_hex('SHA3_256', ""), "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a", 'sha3_256 (digest_data_hex/1)'); +is( digest_data_b64('SHA3_256', ""), "p//G+L8e12ZRwUdWoGHWYvWA/03kO0n6gtgKS4D4Q0o=", 'sha3_256 (digest_data_b64/1)'); +is( digest_data_b64u('SHA3_256', ""), "p__G-L8e12ZRwUdWoGHWYvWA_03kO0n6gtgKS4D4Q0o", 'sha3_256 (digest_data_b64u/1)'); +is( Crypt::Digest::SHA3_256->new->add("")->hexdigest, "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a", 'sha3_256 (OO/1)'); + +is( sha3_256("123"), pack("H*","a03ab19b866fc585b5cb1812a2f63ca861e7e7643ee5d43fd7106b623725fd67"), 'sha3_256 (raw/2)'); +is( sha3_256_hex("123"), "a03ab19b866fc585b5cb1812a2f63ca861e7e7643ee5d43fd7106b623725fd67", 'sha3_256 (hex/2)'); +is( sha3_256_b64("123"), "oDqxm4ZvxYW1yxgSovY8qGHn52Q+5dQ/1xBrYjcl/Wc=", 'sha3_256 (base64/2)'); +is( digest_data('SHA3_256', "123"), pack("H*","a03ab19b866fc585b5cb1812a2f63ca861e7e7643ee5d43fd7106b623725fd67"), 'sha3_256 (digest_data_raw/2)'); +is( digest_data_hex('SHA3_256', "123"), "a03ab19b866fc585b5cb1812a2f63ca861e7e7643ee5d43fd7106b623725fd67", 'sha3_256 (digest_data_hex/2)'); +is( digest_data_b64('SHA3_256', "123"), "oDqxm4ZvxYW1yxgSovY8qGHn52Q+5dQ/1xBrYjcl/Wc=", 'sha3_256 (digest_data_b64/2)'); +is( digest_data_b64u('SHA3_256', "123"), "oDqxm4ZvxYW1yxgSovY8qGHn52Q-5dQ_1xBrYjcl_Wc", 'sha3_256 (digest_data_b64u/2)'); +is( Crypt::Digest::SHA3_256->new->add("123")->hexdigest, "a03ab19b866fc585b5cb1812a2f63ca861e7e7643ee5d43fd7106b623725fd67", 'sha3_256 (OO/2)'); + +is( sha3_256("test\0test\0test\n"), pack("H*","fb08b084e0cff0f17d0d7054aaed12269d2fa08e4c770c4ad497d4f0372f7963"), 'sha3_256 (raw/3)'); +is( sha3_256_hex("test\0test\0test\n"), "fb08b084e0cff0f17d0d7054aaed12269d2fa08e4c770c4ad497d4f0372f7963", 'sha3_256 (hex/3)'); +is( sha3_256_b64("test\0test\0test\n"), "+wiwhODP8PF9DXBUqu0SJp0voI5MdwxK1JfU8DcveWM=", 'sha3_256 (base64/3)'); +is( digest_data('SHA3_256', "test\0test\0test\n"), pack("H*","fb08b084e0cff0f17d0d7054aaed12269d2fa08e4c770c4ad497d4f0372f7963"), 'sha3_256 (digest_data_raw/3)'); +is( digest_data_hex('SHA3_256', "test\0test\0test\n"), "fb08b084e0cff0f17d0d7054aaed12269d2fa08e4c770c4ad497d4f0372f7963", 'sha3_256 (digest_data_hex/3)'); +is( digest_data_b64('SHA3_256', "test\0test\0test\n"), "+wiwhODP8PF9DXBUqu0SJp0voI5MdwxK1JfU8DcveWM=", 'sha3_256 (digest_data_b64/3)'); +is( digest_data_b64u('SHA3_256', "test\0test\0test\n"), "-wiwhODP8PF9DXBUqu0SJp0voI5MdwxK1JfU8DcveWM", 'sha3_256 (digest_data_b64u/3)'); +is( Crypt::Digest::SHA3_256->new->add("test\0test\0test\n")->hexdigest, "fb08b084e0cff0f17d0d7054aaed12269d2fa08e4c770c4ad497d4f0372f7963", 'sha3_256 (OO/3)'); + + +is( sha3_256_file('t/data/binary-test.file'), pack("H*","9c5d0157abcd78eb1ee4e8bed8e03b8fae2c9a3f98a09ec28eb76d1ae2a9abd4"), 'sha3_256 (raw/file/1)'); +is( sha3_256_file_hex('t/data/binary-test.file'), "9c5d0157abcd78eb1ee4e8bed8e03b8fae2c9a3f98a09ec28eb76d1ae2a9abd4", 'sha3_256 (hex/file/1)'); +is( sha3_256_file_b64('t/data/binary-test.file'), "nF0BV6vNeOse5Oi+2OA7j64smj+YoJ7CjrdtGuKpq9Q=", 'sha3_256 (base64/file/1)'); +is( digest_file('SHA3_256', 't/data/binary-test.file'), pack("H*","9c5d0157abcd78eb1ee4e8bed8e03b8fae2c9a3f98a09ec28eb76d1ae2a9abd4"), 'sha3_256 (digest_file_raw/file/1)'); +is( digest_file_hex('SHA3_256', 't/data/binary-test.file'), "9c5d0157abcd78eb1ee4e8bed8e03b8fae2c9a3f98a09ec28eb76d1ae2a9abd4", 'sha3_256 (digest_file_hex/file/1)'); +is( digest_file_b64('SHA3_256', 't/data/binary-test.file'), "nF0BV6vNeOse5Oi+2OA7j64smj+YoJ7CjrdtGuKpq9Q=", 'sha3_256 (digest_file_b64/file/1)'); +is( digest_file_b64u('SHA3_256', 't/data/binary-test.file'), "nF0BV6vNeOse5Oi-2OA7j64smj-YoJ7CjrdtGuKpq9Q", 'sha3_256 (digest_file_b64u/file/1)'); +is( Crypt::Digest::SHA3_256->new->addfile('t/data/binary-test.file')->hexdigest, "9c5d0157abcd78eb1ee4e8bed8e03b8fae2c9a3f98a09ec28eb76d1ae2a9abd4", 'sha3_256 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::SHA3_256->new->addfile($fh)->hexdigest, "9c5d0157abcd78eb1ee4e8bed8e03b8fae2c9a3f98a09ec28eb76d1ae2a9abd4", 'sha3_256 (OO/filehandle/1)'); + close($fh); +} + +is( sha3_256_file('t/data/text-CR.file'), pack("H*","56a1545cf3f7c35466f9587ab44569312ae9139724036fc098d716cedfb16475"), 'sha3_256 (raw/file/2)'); +is( sha3_256_file_hex('t/data/text-CR.file'), "56a1545cf3f7c35466f9587ab44569312ae9139724036fc098d716cedfb16475", 'sha3_256 (hex/file/2)'); +is( sha3_256_file_b64('t/data/text-CR.file'), "VqFUXPP3w1Rm+Vh6tEVpMSrpE5ckA2/AmNcWzt+xZHU=", 'sha3_256 (base64/file/2)'); +is( digest_file('SHA3_256', 't/data/text-CR.file'), pack("H*","56a1545cf3f7c35466f9587ab44569312ae9139724036fc098d716cedfb16475"), 'sha3_256 (digest_file_raw/file/2)'); +is( digest_file_hex('SHA3_256', 't/data/text-CR.file'), "56a1545cf3f7c35466f9587ab44569312ae9139724036fc098d716cedfb16475", 'sha3_256 (digest_file_hex/file/2)'); +is( digest_file_b64('SHA3_256', 't/data/text-CR.file'), "VqFUXPP3w1Rm+Vh6tEVpMSrpE5ckA2/AmNcWzt+xZHU=", 'sha3_256 (digest_file_b64/file/2)'); +is( digest_file_b64u('SHA3_256', 't/data/text-CR.file'), "VqFUXPP3w1Rm-Vh6tEVpMSrpE5ckA2_AmNcWzt-xZHU", 'sha3_256 (digest_file_b64u/file/2)'); +is( Crypt::Digest::SHA3_256->new->addfile('t/data/text-CR.file')->hexdigest, "56a1545cf3f7c35466f9587ab44569312ae9139724036fc098d716cedfb16475", 'sha3_256 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::SHA3_256->new->addfile($fh)->hexdigest, "56a1545cf3f7c35466f9587ab44569312ae9139724036fc098d716cedfb16475", 'sha3_256 (OO/filehandle/2)'); + close($fh); +} + +is( sha3_256_file('t/data/text-CRLF.file'), pack("H*","82898a7bd59d89d4f09894d5d33add66ae5c1971c0fe229ca0371d7d22399f72"), 'sha3_256 (raw/file/3)'); +is( sha3_256_file_hex('t/data/text-CRLF.file'), "82898a7bd59d89d4f09894d5d33add66ae5c1971c0fe229ca0371d7d22399f72", 'sha3_256 (hex/file/3)'); +is( sha3_256_file_b64('t/data/text-CRLF.file'), "gomKe9WdidTwmJTV0zrdZq5cGXHA/iKcoDcdfSI5n3I=", 'sha3_256 (base64/file/3)'); +is( digest_file('SHA3_256', 't/data/text-CRLF.file'), pack("H*","82898a7bd59d89d4f09894d5d33add66ae5c1971c0fe229ca0371d7d22399f72"), 'sha3_256 (digest_file_raw/file/3)'); +is( digest_file_hex('SHA3_256', 't/data/text-CRLF.file'), "82898a7bd59d89d4f09894d5d33add66ae5c1971c0fe229ca0371d7d22399f72", 'sha3_256 (digest_file_hex/file/3)'); +is( digest_file_b64('SHA3_256', 't/data/text-CRLF.file'), "gomKe9WdidTwmJTV0zrdZq5cGXHA/iKcoDcdfSI5n3I=", 'sha3_256 (digest_file_b64/file/3)'); +is( digest_file_b64u('SHA3_256', 't/data/text-CRLF.file'), "gomKe9WdidTwmJTV0zrdZq5cGXHA_iKcoDcdfSI5n3I", 'sha3_256 (digest_file_b64u/file/3)'); +is( Crypt::Digest::SHA3_256->new->addfile('t/data/text-CRLF.file')->hexdigest, "82898a7bd59d89d4f09894d5d33add66ae5c1971c0fe229ca0371d7d22399f72", 'sha3_256 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::SHA3_256->new->addfile($fh)->hexdigest, "82898a7bd59d89d4f09894d5d33add66ae5c1971c0fe229ca0371d7d22399f72", 'sha3_256 (OO/filehandle/3)'); + close($fh); +} + +is( sha3_256_file('t/data/text-LF.file'), pack("H*","8218ef6dfb3282fbd0079c1a1d50e689cdf6e3046f2b9219cd21e4d3513048b7"), 'sha3_256 (raw/file/4)'); +is( sha3_256_file_hex('t/data/text-LF.file'), "8218ef6dfb3282fbd0079c1a1d50e689cdf6e3046f2b9219cd21e4d3513048b7", 'sha3_256 (hex/file/4)'); +is( sha3_256_file_b64('t/data/text-LF.file'), "ghjvbfsygvvQB5waHVDmic324wRvK5IZzSHk01EwSLc=", 'sha3_256 (base64/file/4)'); +is( digest_file('SHA3_256', 't/data/text-LF.file'), pack("H*","8218ef6dfb3282fbd0079c1a1d50e689cdf6e3046f2b9219cd21e4d3513048b7"), 'sha3_256 (digest_file_raw/file/4)'); +is( digest_file_hex('SHA3_256', 't/data/text-LF.file'), "8218ef6dfb3282fbd0079c1a1d50e689cdf6e3046f2b9219cd21e4d3513048b7", 'sha3_256 (digest_file_hex/file/4)'); +is( digest_file_b64('SHA3_256', 't/data/text-LF.file'), "ghjvbfsygvvQB5waHVDmic324wRvK5IZzSHk01EwSLc=", 'sha3_256 (digest_file_b64/file/4)'); +is( digest_file_b64u('SHA3_256', 't/data/text-LF.file'), "ghjvbfsygvvQB5waHVDmic324wRvK5IZzSHk01EwSLc", 'sha3_256 (digest_file_b64u/file/4)'); +is( Crypt::Digest::SHA3_256->new->addfile('t/data/text-LF.file')->hexdigest, "8218ef6dfb3282fbd0079c1a1d50e689cdf6e3046f2b9219cd21e4d3513048b7", 'sha3_256 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::SHA3_256->new->addfile($fh)->hexdigest, "8218ef6dfb3282fbd0079c1a1d50e689cdf6e3046f2b9219cd21e4d3513048b7", 'sha3_256 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_sha3_384.t b/t/digest_sha3_384.t new file mode 100644 index 0000000..dadc964 --- /dev/null +++ b/t/digest_sha3_384.t @@ -0,0 +1,105 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::SHA3_384 qw( sha3_384 sha3_384_hex sha3_384_b64 sha3_384_b64u sha3_384_file sha3_384_file_hex sha3_384_file_b64 sha3_384_file_b64u ); + +is( Crypt::Digest::hashsize('SHA3_384'), 48, 'hashsize/1'); +is( Crypt::Digest->hashsize('SHA3_384'), 48, 'hashsize/2'); +is( Crypt::Digest::SHA3_384::hashsize, 48, 'hashsize/3'); +is( Crypt::Digest::SHA3_384->hashsize, 48, 'hashsize/4'); +is( Crypt::Digest->new('SHA3_384')->hashsize, 48, 'hashsize/5'); +is( Crypt::Digest::SHA3_384->new->hashsize, 48, 'hashsize/6'); + + +is( sha3_384(""), pack("H*","0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004"), 'sha3_384 (raw/1)'); +is( sha3_384_hex(""), "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004", 'sha3_384 (hex/1)'); +is( sha3_384_b64(""), "DGOnW4ReT30BEH2FLkwkhcUaUKqqlPxhmV5xu+6YOirDcTgxJkrbR/tr0eBY1fAE", 'sha3_384 (base64/1)'); +is( digest_data('SHA3_384', ""), pack("H*","0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004"), 'sha3_384 (digest_data_raw/1)'); +is( digest_data_hex('SHA3_384', ""), "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004", 'sha3_384 (digest_data_hex/1)'); +is( digest_data_b64('SHA3_384', ""), "DGOnW4ReT30BEH2FLkwkhcUaUKqqlPxhmV5xu+6YOirDcTgxJkrbR/tr0eBY1fAE", 'sha3_384 (digest_data_b64/1)'); +is( digest_data_b64u('SHA3_384', ""), "DGOnW4ReT30BEH2FLkwkhcUaUKqqlPxhmV5xu-6YOirDcTgxJkrbR_tr0eBY1fAE", 'sha3_384 (digest_data_b64u/1)'); +is( Crypt::Digest::SHA3_384->new->add("")->hexdigest, "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004", 'sha3_384 (OO/1)'); + +is( sha3_384("123"), pack("H*","9bd942d1678a25d029b114306f5e1dae49fe8abeeacd03cfab0f156aa2e363c988b1c12803d4a8c9ba38fdc873e5f007"), 'sha3_384 (raw/2)'); +is( sha3_384_hex("123"), "9bd942d1678a25d029b114306f5e1dae49fe8abeeacd03cfab0f156aa2e363c988b1c12803d4a8c9ba38fdc873e5f007", 'sha3_384 (hex/2)'); +is( sha3_384_b64("123"), "m9lC0WeKJdApsRQwb14drkn+ir7qzQPPqw8VaqLjY8mIscEoA9Soybo4/chz5fAH", 'sha3_384 (base64/2)'); +is( digest_data('SHA3_384', "123"), pack("H*","9bd942d1678a25d029b114306f5e1dae49fe8abeeacd03cfab0f156aa2e363c988b1c12803d4a8c9ba38fdc873e5f007"), 'sha3_384 (digest_data_raw/2)'); +is( digest_data_hex('SHA3_384', "123"), "9bd942d1678a25d029b114306f5e1dae49fe8abeeacd03cfab0f156aa2e363c988b1c12803d4a8c9ba38fdc873e5f007", 'sha3_384 (digest_data_hex/2)'); +is( digest_data_b64('SHA3_384', "123"), "m9lC0WeKJdApsRQwb14drkn+ir7qzQPPqw8VaqLjY8mIscEoA9Soybo4/chz5fAH", 'sha3_384 (digest_data_b64/2)'); +is( digest_data_b64u('SHA3_384', "123"), "m9lC0WeKJdApsRQwb14drkn-ir7qzQPPqw8VaqLjY8mIscEoA9Soybo4_chz5fAH", 'sha3_384 (digest_data_b64u/2)'); +is( Crypt::Digest::SHA3_384->new->add("123")->hexdigest, "9bd942d1678a25d029b114306f5e1dae49fe8abeeacd03cfab0f156aa2e363c988b1c12803d4a8c9ba38fdc873e5f007", 'sha3_384 (OO/2)'); + +is( sha3_384("test\0test\0test\n"), pack("H*","69cf4f5bfec6ec9fc866208f6442dd3f140ad87d9b6092ab32624a462a6d3ab219e339b392b18596aec0520f770cd543"), 'sha3_384 (raw/3)'); +is( sha3_384_hex("test\0test\0test\n"), "69cf4f5bfec6ec9fc866208f6442dd3f140ad87d9b6092ab32624a462a6d3ab219e339b392b18596aec0520f770cd543", 'sha3_384 (hex/3)'); +is( sha3_384_b64("test\0test\0test\n"), "ac9PW/7G7J/IZiCPZELdPxQK2H2bYJKrMmJKRiptOrIZ4zmzkrGFlq7AUg93DNVD", 'sha3_384 (base64/3)'); +is( digest_data('SHA3_384', "test\0test\0test\n"), pack("H*","69cf4f5bfec6ec9fc866208f6442dd3f140ad87d9b6092ab32624a462a6d3ab219e339b392b18596aec0520f770cd543"), 'sha3_384 (digest_data_raw/3)'); +is( digest_data_hex('SHA3_384', "test\0test\0test\n"), "69cf4f5bfec6ec9fc866208f6442dd3f140ad87d9b6092ab32624a462a6d3ab219e339b392b18596aec0520f770cd543", 'sha3_384 (digest_data_hex/3)'); +is( digest_data_b64('SHA3_384', "test\0test\0test\n"), "ac9PW/7G7J/IZiCPZELdPxQK2H2bYJKrMmJKRiptOrIZ4zmzkrGFlq7AUg93DNVD", 'sha3_384 (digest_data_b64/3)'); +is( digest_data_b64u('SHA3_384', "test\0test\0test\n"), "ac9PW_7G7J_IZiCPZELdPxQK2H2bYJKrMmJKRiptOrIZ4zmzkrGFlq7AUg93DNVD", 'sha3_384 (digest_data_b64u/3)'); +is( Crypt::Digest::SHA3_384->new->add("test\0test\0test\n")->hexdigest, "69cf4f5bfec6ec9fc866208f6442dd3f140ad87d9b6092ab32624a462a6d3ab219e339b392b18596aec0520f770cd543", 'sha3_384 (OO/3)'); + + +is( sha3_384_file('t/data/binary-test.file'), pack("H*","d350769c1d1847a2ce4539429d06e3b715b5928d48353f7f1eefba6f76ae6299fb1bf36c2c2067ddb9645051a55279bd"), 'sha3_384 (raw/file/1)'); +is( sha3_384_file_hex('t/data/binary-test.file'), "d350769c1d1847a2ce4539429d06e3b715b5928d48353f7f1eefba6f76ae6299fb1bf36c2c2067ddb9645051a55279bd", 'sha3_384 (hex/file/1)'); +is( sha3_384_file_b64('t/data/binary-test.file'), "01B2nB0YR6LORTlCnQbjtxW1ko1INT9/Hu+6b3auYpn7G/NsLCBn3blkUFGlUnm9", 'sha3_384 (base64/file/1)'); +is( digest_file('SHA3_384', 't/data/binary-test.file'), pack("H*","d350769c1d1847a2ce4539429d06e3b715b5928d48353f7f1eefba6f76ae6299fb1bf36c2c2067ddb9645051a55279bd"), 'sha3_384 (digest_file_raw/file/1)'); +is( digest_file_hex('SHA3_384', 't/data/binary-test.file'), "d350769c1d1847a2ce4539429d06e3b715b5928d48353f7f1eefba6f76ae6299fb1bf36c2c2067ddb9645051a55279bd", 'sha3_384 (digest_file_hex/file/1)'); +is( digest_file_b64('SHA3_384', 't/data/binary-test.file'), "01B2nB0YR6LORTlCnQbjtxW1ko1INT9/Hu+6b3auYpn7G/NsLCBn3blkUFGlUnm9", 'sha3_384 (digest_file_b64/file/1)'); +is( digest_file_b64u('SHA3_384', 't/data/binary-test.file'), "01B2nB0YR6LORTlCnQbjtxW1ko1INT9_Hu-6b3auYpn7G_NsLCBn3blkUFGlUnm9", 'sha3_384 (digest_file_b64u/file/1)'); +is( Crypt::Digest::SHA3_384->new->addfile('t/data/binary-test.file')->hexdigest, "d350769c1d1847a2ce4539429d06e3b715b5928d48353f7f1eefba6f76ae6299fb1bf36c2c2067ddb9645051a55279bd", 'sha3_384 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::SHA3_384->new->addfile($fh)->hexdigest, "d350769c1d1847a2ce4539429d06e3b715b5928d48353f7f1eefba6f76ae6299fb1bf36c2c2067ddb9645051a55279bd", 'sha3_384 (OO/filehandle/1)'); + close($fh); +} + +is( sha3_384_file('t/data/text-CR.file'), pack("H*","71245760e067c5f026d7a98e12cd3553e806781c3f5f751ec342af6cf8c12279f1a2cb3f7c3449c1e6f5f7c9d4d8b656"), 'sha3_384 (raw/file/2)'); +is( sha3_384_file_hex('t/data/text-CR.file'), "71245760e067c5f026d7a98e12cd3553e806781c3f5f751ec342af6cf8c12279f1a2cb3f7c3449c1e6f5f7c9d4d8b656", 'sha3_384 (hex/file/2)'); +is( sha3_384_file_b64('t/data/text-CR.file'), "cSRXYOBnxfAm16mOEs01U+gGeBw/X3Uew0KvbPjBInnxoss/fDRJweb198nU2LZW", 'sha3_384 (base64/file/2)'); +is( digest_file('SHA3_384', 't/data/text-CR.file'), pack("H*","71245760e067c5f026d7a98e12cd3553e806781c3f5f751ec342af6cf8c12279f1a2cb3f7c3449c1e6f5f7c9d4d8b656"), 'sha3_384 (digest_file_raw/file/2)'); +is( digest_file_hex('SHA3_384', 't/data/text-CR.file'), "71245760e067c5f026d7a98e12cd3553e806781c3f5f751ec342af6cf8c12279f1a2cb3f7c3449c1e6f5f7c9d4d8b656", 'sha3_384 (digest_file_hex/file/2)'); +is( digest_file_b64('SHA3_384', 't/data/text-CR.file'), "cSRXYOBnxfAm16mOEs01U+gGeBw/X3Uew0KvbPjBInnxoss/fDRJweb198nU2LZW", 'sha3_384 (digest_file_b64/file/2)'); +is( digest_file_b64u('SHA3_384', 't/data/text-CR.file'), "cSRXYOBnxfAm16mOEs01U-gGeBw_X3Uew0KvbPjBInnxoss_fDRJweb198nU2LZW", 'sha3_384 (digest_file_b64u/file/2)'); +is( Crypt::Digest::SHA3_384->new->addfile('t/data/text-CR.file')->hexdigest, "71245760e067c5f026d7a98e12cd3553e806781c3f5f751ec342af6cf8c12279f1a2cb3f7c3449c1e6f5f7c9d4d8b656", 'sha3_384 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::SHA3_384->new->addfile($fh)->hexdigest, "71245760e067c5f026d7a98e12cd3553e806781c3f5f751ec342af6cf8c12279f1a2cb3f7c3449c1e6f5f7c9d4d8b656", 'sha3_384 (OO/filehandle/2)'); + close($fh); +} + +is( sha3_384_file('t/data/text-CRLF.file'), pack("H*","f3277f0def5a52c6237c2911d20ecfa8a434adcce900c70ce06e351d6c0fe08806ae1af0cf994725e08fcc00a33d38a5"), 'sha3_384 (raw/file/3)'); +is( sha3_384_file_hex('t/data/text-CRLF.file'), "f3277f0def5a52c6237c2911d20ecfa8a434adcce900c70ce06e351d6c0fe08806ae1af0cf994725e08fcc00a33d38a5", 'sha3_384 (hex/file/3)'); +is( sha3_384_file_b64('t/data/text-CRLF.file'), "8yd/De9aUsYjfCkR0g7PqKQ0rczpAMcM4G41HWwP4IgGrhrwz5lHJeCPzACjPTil", 'sha3_384 (base64/file/3)'); +is( digest_file('SHA3_384', 't/data/text-CRLF.file'), pack("H*","f3277f0def5a52c6237c2911d20ecfa8a434adcce900c70ce06e351d6c0fe08806ae1af0cf994725e08fcc00a33d38a5"), 'sha3_384 (digest_file_raw/file/3)'); +is( digest_file_hex('SHA3_384', 't/data/text-CRLF.file'), "f3277f0def5a52c6237c2911d20ecfa8a434adcce900c70ce06e351d6c0fe08806ae1af0cf994725e08fcc00a33d38a5", 'sha3_384 (digest_file_hex/file/3)'); +is( digest_file_b64('SHA3_384', 't/data/text-CRLF.file'), "8yd/De9aUsYjfCkR0g7PqKQ0rczpAMcM4G41HWwP4IgGrhrwz5lHJeCPzACjPTil", 'sha3_384 (digest_file_b64/file/3)'); +is( digest_file_b64u('SHA3_384', 't/data/text-CRLF.file'), "8yd_De9aUsYjfCkR0g7PqKQ0rczpAMcM4G41HWwP4IgGrhrwz5lHJeCPzACjPTil", 'sha3_384 (digest_file_b64u/file/3)'); +is( Crypt::Digest::SHA3_384->new->addfile('t/data/text-CRLF.file')->hexdigest, "f3277f0def5a52c6237c2911d20ecfa8a434adcce900c70ce06e351d6c0fe08806ae1af0cf994725e08fcc00a33d38a5", 'sha3_384 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::SHA3_384->new->addfile($fh)->hexdigest, "f3277f0def5a52c6237c2911d20ecfa8a434adcce900c70ce06e351d6c0fe08806ae1af0cf994725e08fcc00a33d38a5", 'sha3_384 (OO/filehandle/3)'); + close($fh); +} + +is( sha3_384_file('t/data/text-LF.file'), pack("H*","06abb535191f6bb863cb800fba87ddd673f1db5bd42faa7851c689246fd6d03d184906e794df9ddbd27dece68c5dd6c9"), 'sha3_384 (raw/file/4)'); +is( sha3_384_file_hex('t/data/text-LF.file'), "06abb535191f6bb863cb800fba87ddd673f1db5bd42faa7851c689246fd6d03d184906e794df9ddbd27dece68c5dd6c9", 'sha3_384 (hex/file/4)'); +is( sha3_384_file_b64('t/data/text-LF.file'), "Bqu1NRkfa7hjy4APuofd1nPx21vUL6p4UcaJJG/W0D0YSQbnlN+d29J97OaMXdbJ", 'sha3_384 (base64/file/4)'); +is( digest_file('SHA3_384', 't/data/text-LF.file'), pack("H*","06abb535191f6bb863cb800fba87ddd673f1db5bd42faa7851c689246fd6d03d184906e794df9ddbd27dece68c5dd6c9"), 'sha3_384 (digest_file_raw/file/4)'); +is( digest_file_hex('SHA3_384', 't/data/text-LF.file'), "06abb535191f6bb863cb800fba87ddd673f1db5bd42faa7851c689246fd6d03d184906e794df9ddbd27dece68c5dd6c9", 'sha3_384 (digest_file_hex/file/4)'); +is( digest_file_b64('SHA3_384', 't/data/text-LF.file'), "Bqu1NRkfa7hjy4APuofd1nPx21vUL6p4UcaJJG/W0D0YSQbnlN+d29J97OaMXdbJ", 'sha3_384 (digest_file_b64/file/4)'); +is( digest_file_b64u('SHA3_384', 't/data/text-LF.file'), "Bqu1NRkfa7hjy4APuofd1nPx21vUL6p4UcaJJG_W0D0YSQbnlN-d29J97OaMXdbJ", 'sha3_384 (digest_file_b64u/file/4)'); +is( Crypt::Digest::SHA3_384->new->addfile('t/data/text-LF.file')->hexdigest, "06abb535191f6bb863cb800fba87ddd673f1db5bd42faa7851c689246fd6d03d184906e794df9ddbd27dece68c5dd6c9", 'sha3_384 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::SHA3_384->new->addfile($fh)->hexdigest, "06abb535191f6bb863cb800fba87ddd673f1db5bd42faa7851c689246fd6d03d184906e794df9ddbd27dece68c5dd6c9", 'sha3_384 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_sha3_512.t b/t/digest_sha3_512.t new file mode 100644 index 0000000..f8ab9aa --- /dev/null +++ b/t/digest_sha3_512.t @@ -0,0 +1,105 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::SHA3_512 qw( sha3_512 sha3_512_hex sha3_512_b64 sha3_512_b64u sha3_512_file sha3_512_file_hex sha3_512_file_b64 sha3_512_file_b64u ); + +is( Crypt::Digest::hashsize('SHA3_512'), 64, 'hashsize/1'); +is( Crypt::Digest->hashsize('SHA3_512'), 64, 'hashsize/2'); +is( Crypt::Digest::SHA3_512::hashsize, 64, 'hashsize/3'); +is( Crypt::Digest::SHA3_512->hashsize, 64, 'hashsize/4'); +is( Crypt::Digest->new('SHA3_512')->hashsize, 64, 'hashsize/5'); +is( Crypt::Digest::SHA3_512->new->hashsize, 64, 'hashsize/6'); + + +is( sha3_512(""), pack("H*","a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26"), 'sha3_512 (raw/1)'); +is( sha3_512_hex(""), "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26", 'sha3_512 (hex/1)'); +is( sha3_512_b64(""), "pp9zzKI6msXItWfcGFp1bpfJghZP4lhZ4NHcwUdcgKYVshI68fX5TBHj6UAsOsVY9QAZnZW20+MBdYWGKB3NJg==", 'sha3_512 (base64/1)'); +is( digest_data('SHA3_512', ""), pack("H*","a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26"), 'sha3_512 (digest_data_raw/1)'); +is( digest_data_hex('SHA3_512', ""), "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26", 'sha3_512 (digest_data_hex/1)'); +is( digest_data_b64('SHA3_512', ""), "pp9zzKI6msXItWfcGFp1bpfJghZP4lhZ4NHcwUdcgKYVshI68fX5TBHj6UAsOsVY9QAZnZW20+MBdYWGKB3NJg==", 'sha3_512 (digest_data_b64/1)'); +is( digest_data_b64u('SHA3_512', ""), "pp9zzKI6msXItWfcGFp1bpfJghZP4lhZ4NHcwUdcgKYVshI68fX5TBHj6UAsOsVY9QAZnZW20-MBdYWGKB3NJg", 'sha3_512 (digest_data_b64u/1)'); +is( Crypt::Digest::SHA3_512->new->add("")->hexdigest, "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26", 'sha3_512 (OO/1)'); + +is( sha3_512("123"), pack("H*","48c8947f69c054a5caa934674ce8881d02bb18fb59d5a63eeaddff735b0e9801e87294783281ae49fc8287a0fd86779b27d7972d3e84f0fa0d826d7cb67dfefc"), 'sha3_512 (raw/2)'); +is( sha3_512_hex("123"), "48c8947f69c054a5caa934674ce8881d02bb18fb59d5a63eeaddff735b0e9801e87294783281ae49fc8287a0fd86779b27d7972d3e84f0fa0d826d7cb67dfefc", 'sha3_512 (hex/2)'); +is( sha3_512_b64("123"), "SMiUf2nAVKXKqTRnTOiIHQK7GPtZ1aY+6t3/c1sOmAHocpR4MoGuSfyCh6D9hnebJ9eXLT6E8PoNgm18tn3+/A==", 'sha3_512 (base64/2)'); +is( digest_data('SHA3_512', "123"), pack("H*","48c8947f69c054a5caa934674ce8881d02bb18fb59d5a63eeaddff735b0e9801e87294783281ae49fc8287a0fd86779b27d7972d3e84f0fa0d826d7cb67dfefc"), 'sha3_512 (digest_data_raw/2)'); +is( digest_data_hex('SHA3_512', "123"), "48c8947f69c054a5caa934674ce8881d02bb18fb59d5a63eeaddff735b0e9801e87294783281ae49fc8287a0fd86779b27d7972d3e84f0fa0d826d7cb67dfefc", 'sha3_512 (digest_data_hex/2)'); +is( digest_data_b64('SHA3_512', "123"), "SMiUf2nAVKXKqTRnTOiIHQK7GPtZ1aY+6t3/c1sOmAHocpR4MoGuSfyCh6D9hnebJ9eXLT6E8PoNgm18tn3+/A==", 'sha3_512 (digest_data_b64/2)'); +is( digest_data_b64u('SHA3_512', "123"), "SMiUf2nAVKXKqTRnTOiIHQK7GPtZ1aY-6t3_c1sOmAHocpR4MoGuSfyCh6D9hnebJ9eXLT6E8PoNgm18tn3-_A", 'sha3_512 (digest_data_b64u/2)'); +is( Crypt::Digest::SHA3_512->new->add("123")->hexdigest, "48c8947f69c054a5caa934674ce8881d02bb18fb59d5a63eeaddff735b0e9801e87294783281ae49fc8287a0fd86779b27d7972d3e84f0fa0d826d7cb67dfefc", 'sha3_512 (OO/2)'); + +is( sha3_512("test\0test\0test\n"), pack("H*","32ae141bb6ed097396f3258e2d4d5b9d03901a1fd09b82ab753027d3f6806763cc50daa3c50ab077e2acb0b792995cb3b539e6ec0171e56b9c6635780e79f693"), 'sha3_512 (raw/3)'); +is( sha3_512_hex("test\0test\0test\n"), "32ae141bb6ed097396f3258e2d4d5b9d03901a1fd09b82ab753027d3f6806763cc50daa3c50ab077e2acb0b792995cb3b539e6ec0171e56b9c6635780e79f693", 'sha3_512 (hex/3)'); +is( sha3_512_b64("test\0test\0test\n"), "Mq4UG7btCXOW8yWOLU1bnQOQGh/Qm4KrdTAn0/aAZ2PMUNqjxQqwd+KssLeSmVyztTnm7AFx5WucZjV4Dnn2kw==", 'sha3_512 (base64/3)'); +is( digest_data('SHA3_512', "test\0test\0test\n"), pack("H*","32ae141bb6ed097396f3258e2d4d5b9d03901a1fd09b82ab753027d3f6806763cc50daa3c50ab077e2acb0b792995cb3b539e6ec0171e56b9c6635780e79f693"), 'sha3_512 (digest_data_raw/3)'); +is( digest_data_hex('SHA3_512', "test\0test\0test\n"), "32ae141bb6ed097396f3258e2d4d5b9d03901a1fd09b82ab753027d3f6806763cc50daa3c50ab077e2acb0b792995cb3b539e6ec0171e56b9c6635780e79f693", 'sha3_512 (digest_data_hex/3)'); +is( digest_data_b64('SHA3_512', "test\0test\0test\n"), "Mq4UG7btCXOW8yWOLU1bnQOQGh/Qm4KrdTAn0/aAZ2PMUNqjxQqwd+KssLeSmVyztTnm7AFx5WucZjV4Dnn2kw==", 'sha3_512 (digest_data_b64/3)'); +is( digest_data_b64u('SHA3_512', "test\0test\0test\n"), "Mq4UG7btCXOW8yWOLU1bnQOQGh_Qm4KrdTAn0_aAZ2PMUNqjxQqwd-KssLeSmVyztTnm7AFx5WucZjV4Dnn2kw", 'sha3_512 (digest_data_b64u/3)'); +is( Crypt::Digest::SHA3_512->new->add("test\0test\0test\n")->hexdigest, "32ae141bb6ed097396f3258e2d4d5b9d03901a1fd09b82ab753027d3f6806763cc50daa3c50ab077e2acb0b792995cb3b539e6ec0171e56b9c6635780e79f693", 'sha3_512 (OO/3)'); + + +is( sha3_512_file('t/data/binary-test.file'), pack("H*","1ac54b7f8bb2e36b90e796fc6435e5a5e97e4884e3e85c75eb51a0c45724843e63a508adc0ffaf3c9998e23de6b38c6293a8deaf9467a6b512b28c38f2801cef"), 'sha3_512 (raw/file/1)'); +is( sha3_512_file_hex('t/data/binary-test.file'), "1ac54b7f8bb2e36b90e796fc6435e5a5e97e4884e3e85c75eb51a0c45724843e63a508adc0ffaf3c9998e23de6b38c6293a8deaf9467a6b512b28c38f2801cef", 'sha3_512 (hex/file/1)'); +is( sha3_512_file_b64('t/data/binary-test.file'), "GsVLf4uy42uQ55b8ZDXlpel+SITj6Fx161GgxFckhD5jpQitwP+vPJmY4j3ms4xik6jer5RnprUSsow48oAc7w==", 'sha3_512 (base64/file/1)'); +is( digest_file('SHA3_512', 't/data/binary-test.file'), pack("H*","1ac54b7f8bb2e36b90e796fc6435e5a5e97e4884e3e85c75eb51a0c45724843e63a508adc0ffaf3c9998e23de6b38c6293a8deaf9467a6b512b28c38f2801cef"), 'sha3_512 (digest_file_raw/file/1)'); +is( digest_file_hex('SHA3_512', 't/data/binary-test.file'), "1ac54b7f8bb2e36b90e796fc6435e5a5e97e4884e3e85c75eb51a0c45724843e63a508adc0ffaf3c9998e23de6b38c6293a8deaf9467a6b512b28c38f2801cef", 'sha3_512 (digest_file_hex/file/1)'); +is( digest_file_b64('SHA3_512', 't/data/binary-test.file'), "GsVLf4uy42uQ55b8ZDXlpel+SITj6Fx161GgxFckhD5jpQitwP+vPJmY4j3ms4xik6jer5RnprUSsow48oAc7w==", 'sha3_512 (digest_file_b64/file/1)'); +is( digest_file_b64u('SHA3_512', 't/data/binary-test.file'), "GsVLf4uy42uQ55b8ZDXlpel-SITj6Fx161GgxFckhD5jpQitwP-vPJmY4j3ms4xik6jer5RnprUSsow48oAc7w", 'sha3_512 (digest_file_b64u/file/1)'); +is( Crypt::Digest::SHA3_512->new->addfile('t/data/binary-test.file')->hexdigest, "1ac54b7f8bb2e36b90e796fc6435e5a5e97e4884e3e85c75eb51a0c45724843e63a508adc0ffaf3c9998e23de6b38c6293a8deaf9467a6b512b28c38f2801cef", 'sha3_512 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::SHA3_512->new->addfile($fh)->hexdigest, "1ac54b7f8bb2e36b90e796fc6435e5a5e97e4884e3e85c75eb51a0c45724843e63a508adc0ffaf3c9998e23de6b38c6293a8deaf9467a6b512b28c38f2801cef", 'sha3_512 (OO/filehandle/1)'); + close($fh); +} + +is( sha3_512_file('t/data/text-CR.file'), pack("H*","2537d084e27c839299a76b7f54e786f13eba94030c4adc5b254106212d2e1db2e6dd2bea0d785e6b3561713fb1677d28a5ec914c9d5360145606054b6576e0c1"), 'sha3_512 (raw/file/2)'); +is( sha3_512_file_hex('t/data/text-CR.file'), "2537d084e27c839299a76b7f54e786f13eba94030c4adc5b254106212d2e1db2e6dd2bea0d785e6b3561713fb1677d28a5ec914c9d5360145606054b6576e0c1", 'sha3_512 (hex/file/2)'); +is( sha3_512_file_b64('t/data/text-CR.file'), "JTfQhOJ8g5KZp2t/VOeG8T66lAMMStxbJUEGIS0uHbLm3SvqDXheazVhcT+xZ30opeyRTJ1TYBRWBgVLZXbgwQ==", 'sha3_512 (base64/file/2)'); +is( digest_file('SHA3_512', 't/data/text-CR.file'), pack("H*","2537d084e27c839299a76b7f54e786f13eba94030c4adc5b254106212d2e1db2e6dd2bea0d785e6b3561713fb1677d28a5ec914c9d5360145606054b6576e0c1"), 'sha3_512 (digest_file_raw/file/2)'); +is( digest_file_hex('SHA3_512', 't/data/text-CR.file'), "2537d084e27c839299a76b7f54e786f13eba94030c4adc5b254106212d2e1db2e6dd2bea0d785e6b3561713fb1677d28a5ec914c9d5360145606054b6576e0c1", 'sha3_512 (digest_file_hex/file/2)'); +is( digest_file_b64('SHA3_512', 't/data/text-CR.file'), "JTfQhOJ8g5KZp2t/VOeG8T66lAMMStxbJUEGIS0uHbLm3SvqDXheazVhcT+xZ30opeyRTJ1TYBRWBgVLZXbgwQ==", 'sha3_512 (digest_file_b64/file/2)'); +is( digest_file_b64u('SHA3_512', 't/data/text-CR.file'), "JTfQhOJ8g5KZp2t_VOeG8T66lAMMStxbJUEGIS0uHbLm3SvqDXheazVhcT-xZ30opeyRTJ1TYBRWBgVLZXbgwQ", 'sha3_512 (digest_file_b64u/file/2)'); +is( Crypt::Digest::SHA3_512->new->addfile('t/data/text-CR.file')->hexdigest, "2537d084e27c839299a76b7f54e786f13eba94030c4adc5b254106212d2e1db2e6dd2bea0d785e6b3561713fb1677d28a5ec914c9d5360145606054b6576e0c1", 'sha3_512 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::SHA3_512->new->addfile($fh)->hexdigest, "2537d084e27c839299a76b7f54e786f13eba94030c4adc5b254106212d2e1db2e6dd2bea0d785e6b3561713fb1677d28a5ec914c9d5360145606054b6576e0c1", 'sha3_512 (OO/filehandle/2)'); + close($fh); +} + +is( sha3_512_file('t/data/text-CRLF.file'), pack("H*","2fceadea90f637c1e09802d9d4bb0799b95c17d51eff2e8db118d1f6fced01f43bdee512d4d6bf58727debcb80331a9939b683cf30496af67aa3095b517f11ed"), 'sha3_512 (raw/file/3)'); +is( sha3_512_file_hex('t/data/text-CRLF.file'), "2fceadea90f637c1e09802d9d4bb0799b95c17d51eff2e8db118d1f6fced01f43bdee512d4d6bf58727debcb80331a9939b683cf30496af67aa3095b517f11ed", 'sha3_512 (hex/file/3)'); +is( sha3_512_file_b64('t/data/text-CRLF.file'), "L86t6pD2N8HgmALZ1LsHmblcF9Ue/y6NsRjR9vztAfQ73uUS1Na/WHJ968uAMxqZObaDzzBJavZ6owlbUX8R7Q==", 'sha3_512 (base64/file/3)'); +is( digest_file('SHA3_512', 't/data/text-CRLF.file'), pack("H*","2fceadea90f637c1e09802d9d4bb0799b95c17d51eff2e8db118d1f6fced01f43bdee512d4d6bf58727debcb80331a9939b683cf30496af67aa3095b517f11ed"), 'sha3_512 (digest_file_raw/file/3)'); +is( digest_file_hex('SHA3_512', 't/data/text-CRLF.file'), "2fceadea90f637c1e09802d9d4bb0799b95c17d51eff2e8db118d1f6fced01f43bdee512d4d6bf58727debcb80331a9939b683cf30496af67aa3095b517f11ed", 'sha3_512 (digest_file_hex/file/3)'); +is( digest_file_b64('SHA3_512', 't/data/text-CRLF.file'), "L86t6pD2N8HgmALZ1LsHmblcF9Ue/y6NsRjR9vztAfQ73uUS1Na/WHJ968uAMxqZObaDzzBJavZ6owlbUX8R7Q==", 'sha3_512 (digest_file_b64/file/3)'); +is( digest_file_b64u('SHA3_512', 't/data/text-CRLF.file'), "L86t6pD2N8HgmALZ1LsHmblcF9Ue_y6NsRjR9vztAfQ73uUS1Na_WHJ968uAMxqZObaDzzBJavZ6owlbUX8R7Q", 'sha3_512 (digest_file_b64u/file/3)'); +is( Crypt::Digest::SHA3_512->new->addfile('t/data/text-CRLF.file')->hexdigest, "2fceadea90f637c1e09802d9d4bb0799b95c17d51eff2e8db118d1f6fced01f43bdee512d4d6bf58727debcb80331a9939b683cf30496af67aa3095b517f11ed", 'sha3_512 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::SHA3_512->new->addfile($fh)->hexdigest, "2fceadea90f637c1e09802d9d4bb0799b95c17d51eff2e8db118d1f6fced01f43bdee512d4d6bf58727debcb80331a9939b683cf30496af67aa3095b517f11ed", 'sha3_512 (OO/filehandle/3)'); + close($fh); +} + +is( sha3_512_file('t/data/text-LF.file'), pack("H*","46e2ef6af9a108abc49d692ca06ec20b136b96cfa0c4dbb9ecfce7d02c5712dbb2cd5f7e8a84b3ff15465e50d1ec6caffe5212749d96a3468e3477c3da877282"), 'sha3_512 (raw/file/4)'); +is( sha3_512_file_hex('t/data/text-LF.file'), "46e2ef6af9a108abc49d692ca06ec20b136b96cfa0c4dbb9ecfce7d02c5712dbb2cd5f7e8a84b3ff15465e50d1ec6caffe5212749d96a3468e3477c3da877282", 'sha3_512 (hex/file/4)'); +is( sha3_512_file_b64('t/data/text-LF.file'), "RuLvavmhCKvEnWksoG7CCxNrls+gxNu57Pzn0CxXEtuyzV9+ioSz/xVGXlDR7Gyv/lISdJ2Wo0aONHfD2odygg==", 'sha3_512 (base64/file/4)'); +is( digest_file('SHA3_512', 't/data/text-LF.file'), pack("H*","46e2ef6af9a108abc49d692ca06ec20b136b96cfa0c4dbb9ecfce7d02c5712dbb2cd5f7e8a84b3ff15465e50d1ec6caffe5212749d96a3468e3477c3da877282"), 'sha3_512 (digest_file_raw/file/4)'); +is( digest_file_hex('SHA3_512', 't/data/text-LF.file'), "46e2ef6af9a108abc49d692ca06ec20b136b96cfa0c4dbb9ecfce7d02c5712dbb2cd5f7e8a84b3ff15465e50d1ec6caffe5212749d96a3468e3477c3da877282", 'sha3_512 (digest_file_hex/file/4)'); +is( digest_file_b64('SHA3_512', 't/data/text-LF.file'), "RuLvavmhCKvEnWksoG7CCxNrls+gxNu57Pzn0CxXEtuyzV9+ioSz/xVGXlDR7Gyv/lISdJ2Wo0aONHfD2odygg==", 'sha3_512 (digest_file_b64/file/4)'); +is( digest_file_b64u('SHA3_512', 't/data/text-LF.file'), "RuLvavmhCKvEnWksoG7CCxNrls-gxNu57Pzn0CxXEtuyzV9-ioSz_xVGXlDR7Gyv_lISdJ2Wo0aONHfD2odygg", 'sha3_512 (digest_file_b64u/file/4)'); +is( Crypt::Digest::SHA3_512->new->addfile('t/data/text-LF.file')->hexdigest, "46e2ef6af9a108abc49d692ca06ec20b136b96cfa0c4dbb9ecfce7d02c5712dbb2cd5f7e8a84b3ff15465e50d1ec6caffe5212749d96a3468e3477c3da877282", 'sha3_512 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::SHA3_512->new->addfile($fh)->hexdigest, "46e2ef6af9a108abc49d692ca06ec20b136b96cfa0c4dbb9ecfce7d02c5712dbb2cd5f7e8a84b3ff15465e50d1ec6caffe5212749d96a3468e3477c3da877282", 'sha3_512 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_sha512.t b/t/digest_sha512.t new file mode 100644 index 0000000..15ce8b1 --- /dev/null +++ b/t/digest_sha512.t @@ -0,0 +1,105 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::SHA512 qw( sha512 sha512_hex sha512_b64 sha512_b64u sha512_file sha512_file_hex sha512_file_b64 sha512_file_b64u ); + +is( Crypt::Digest::hashsize('SHA512'), 64, 'hashsize/1'); +is( Crypt::Digest->hashsize('SHA512'), 64, 'hashsize/2'); +is( Crypt::Digest::SHA512::hashsize, 64, 'hashsize/3'); +is( Crypt::Digest::SHA512->hashsize, 64, 'hashsize/4'); +is( Crypt::Digest->new('SHA512')->hashsize, 64, 'hashsize/5'); +is( Crypt::Digest::SHA512->new->hashsize, 64, 'hashsize/6'); + + +is( sha512(""), pack("H*","cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"), 'sha512 (raw/1)'); +is( sha512_hex(""), "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", 'sha512 (hex/1)'); +is( sha512_b64(""), "z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg==", 'sha512 (base64/1)'); +is( digest_data('SHA512', ""), pack("H*","cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"), 'sha512 (digest_data_raw/1)'); +is( digest_data_hex('SHA512', ""), "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", 'sha512 (digest_data_hex/1)'); +is( digest_data_b64('SHA512', ""), "z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg==", 'sha512 (digest_data_b64/1)'); +is( digest_data_b64u('SHA512', ""), "z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg_SpIdNs6c5H0NE8XYXysP-DGNKHfuwvY7kxvUdBeoGlODJ6-SfaPg", 'sha512 (digest_data_b64u/1)'); +is( Crypt::Digest::SHA512->new->add("")->hexdigest, "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", 'sha512 (OO/1)'); + +is( sha512("123"), pack("H*","3c9909afec25354d551dae21590bb26e38d53f2173b8d3dc3eee4c047e7ab1c1eb8b85103e3be7ba613b31bb5c9c36214dc9f14a42fd7a2fdb84856bca5c44c2"), 'sha512 (raw/2)'); +is( sha512_hex("123"), "3c9909afec25354d551dae21590bb26e38d53f2173b8d3dc3eee4c047e7ab1c1eb8b85103e3be7ba613b31bb5c9c36214dc9f14a42fd7a2fdb84856bca5c44c2", 'sha512 (hex/2)'); +is( sha512_b64("123"), "PJkJr+wlNU1VHa4hWQuybjjVPyFzuNPcPu5MBH56scHri4UQPjvnumE7MbtcnDYhTcnxSkL9ei/bhIVrylxEwg==", 'sha512 (base64/2)'); +is( digest_data('SHA512', "123"), pack("H*","3c9909afec25354d551dae21590bb26e38d53f2173b8d3dc3eee4c047e7ab1c1eb8b85103e3be7ba613b31bb5c9c36214dc9f14a42fd7a2fdb84856bca5c44c2"), 'sha512 (digest_data_raw/2)'); +is( digest_data_hex('SHA512', "123"), "3c9909afec25354d551dae21590bb26e38d53f2173b8d3dc3eee4c047e7ab1c1eb8b85103e3be7ba613b31bb5c9c36214dc9f14a42fd7a2fdb84856bca5c44c2", 'sha512 (digest_data_hex/2)'); +is( digest_data_b64('SHA512', "123"), "PJkJr+wlNU1VHa4hWQuybjjVPyFzuNPcPu5MBH56scHri4UQPjvnumE7MbtcnDYhTcnxSkL9ei/bhIVrylxEwg==", 'sha512 (digest_data_b64/2)'); +is( digest_data_b64u('SHA512', "123"), "PJkJr-wlNU1VHa4hWQuybjjVPyFzuNPcPu5MBH56scHri4UQPjvnumE7MbtcnDYhTcnxSkL9ei_bhIVrylxEwg", 'sha512 (digest_data_b64u/2)'); +is( Crypt::Digest::SHA512->new->add("123")->hexdigest, "3c9909afec25354d551dae21590bb26e38d53f2173b8d3dc3eee4c047e7ab1c1eb8b85103e3be7ba613b31bb5c9c36214dc9f14a42fd7a2fdb84856bca5c44c2", 'sha512 (OO/2)'); + +is( sha512("test\0test\0test\n"), pack("H*","23f26f65ca7b6ba3d254f1e218586d43d5349e1a9c33168a9c3a97d70cd7bc924b28d3ccc41df7939b29ea6807e04d34beed2a89c7c38c2276a47a4c45755699"), 'sha512 (raw/3)'); +is( sha512_hex("test\0test\0test\n"), "23f26f65ca7b6ba3d254f1e218586d43d5349e1a9c33168a9c3a97d70cd7bc924b28d3ccc41df7939b29ea6807e04d34beed2a89c7c38c2276a47a4c45755699", 'sha512 (hex/3)'); +is( sha512_b64("test\0test\0test\n"), "I/JvZcp7a6PSVPHiGFhtQ9U0nhqcMxaKnDqX1wzXvJJLKNPMxB33k5sp6mgH4E00vu0qicfDjCJ2pHpMRXVWmQ==", 'sha512 (base64/3)'); +is( digest_data('SHA512', "test\0test\0test\n"), pack("H*","23f26f65ca7b6ba3d254f1e218586d43d5349e1a9c33168a9c3a97d70cd7bc924b28d3ccc41df7939b29ea6807e04d34beed2a89c7c38c2276a47a4c45755699"), 'sha512 (digest_data_raw/3)'); +is( digest_data_hex('SHA512', "test\0test\0test\n"), "23f26f65ca7b6ba3d254f1e218586d43d5349e1a9c33168a9c3a97d70cd7bc924b28d3ccc41df7939b29ea6807e04d34beed2a89c7c38c2276a47a4c45755699", 'sha512 (digest_data_hex/3)'); +is( digest_data_b64('SHA512', "test\0test\0test\n"), "I/JvZcp7a6PSVPHiGFhtQ9U0nhqcMxaKnDqX1wzXvJJLKNPMxB33k5sp6mgH4E00vu0qicfDjCJ2pHpMRXVWmQ==", 'sha512 (digest_data_b64/3)'); +is( digest_data_b64u('SHA512', "test\0test\0test\n"), "I_JvZcp7a6PSVPHiGFhtQ9U0nhqcMxaKnDqX1wzXvJJLKNPMxB33k5sp6mgH4E00vu0qicfDjCJ2pHpMRXVWmQ", 'sha512 (digest_data_b64u/3)'); +is( Crypt::Digest::SHA512->new->add("test\0test\0test\n")->hexdigest, "23f26f65ca7b6ba3d254f1e218586d43d5349e1a9c33168a9c3a97d70cd7bc924b28d3ccc41df7939b29ea6807e04d34beed2a89c7c38c2276a47a4c45755699", 'sha512 (OO/3)'); + + +is( sha512_file('t/data/binary-test.file'), pack("H*","f631652982f00556324d1fb9078d818efede0f6a3e042c736979543e2b0e4d44e29238fd0d441d4b2c2d16f8597df4912ed752f09438b1dd64efc723204d337a"), 'sha512 (raw/file/1)'); +is( sha512_file_hex('t/data/binary-test.file'), "f631652982f00556324d1fb9078d818efede0f6a3e042c736979543e2b0e4d44e29238fd0d441d4b2c2d16f8597df4912ed752f09438b1dd64efc723204d337a", 'sha512 (hex/file/1)'); +is( sha512_file_b64('t/data/binary-test.file'), "9jFlKYLwBVYyTR+5B42Bjv7eD2o+BCxzaXlUPisOTUTikjj9DUQdSywtFvhZffSRLtdS8JQ4sd1k78cjIE0zeg==", 'sha512 (base64/file/1)'); +is( digest_file('SHA512', 't/data/binary-test.file'), pack("H*","f631652982f00556324d1fb9078d818efede0f6a3e042c736979543e2b0e4d44e29238fd0d441d4b2c2d16f8597df4912ed752f09438b1dd64efc723204d337a"), 'sha512 (digest_file_raw/file/1)'); +is( digest_file_hex('SHA512', 't/data/binary-test.file'), "f631652982f00556324d1fb9078d818efede0f6a3e042c736979543e2b0e4d44e29238fd0d441d4b2c2d16f8597df4912ed752f09438b1dd64efc723204d337a", 'sha512 (digest_file_hex/file/1)'); +is( digest_file_b64('SHA512', 't/data/binary-test.file'), "9jFlKYLwBVYyTR+5B42Bjv7eD2o+BCxzaXlUPisOTUTikjj9DUQdSywtFvhZffSRLtdS8JQ4sd1k78cjIE0zeg==", 'sha512 (digest_file_b64/file/1)'); +is( digest_file_b64u('SHA512', 't/data/binary-test.file'), "9jFlKYLwBVYyTR-5B42Bjv7eD2o-BCxzaXlUPisOTUTikjj9DUQdSywtFvhZffSRLtdS8JQ4sd1k78cjIE0zeg", 'sha512 (digest_file_b64u/file/1)'); +is( Crypt::Digest::SHA512->new->addfile('t/data/binary-test.file')->hexdigest, "f631652982f00556324d1fb9078d818efede0f6a3e042c736979543e2b0e4d44e29238fd0d441d4b2c2d16f8597df4912ed752f09438b1dd64efc723204d337a", 'sha512 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::SHA512->new->addfile($fh)->hexdigest, "f631652982f00556324d1fb9078d818efede0f6a3e042c736979543e2b0e4d44e29238fd0d441d4b2c2d16f8597df4912ed752f09438b1dd64efc723204d337a", 'sha512 (OO/filehandle/1)'); + close($fh); +} + +is( sha512_file('t/data/text-CR.file'), pack("H*","cfea7a1ac356830a4e938f908e29de7efceab2b851f70722a464084ac83148de60f19b0e99de581b2fbb3da97b14cd05f06431d7fa12fe38369f3ffa10944a06"), 'sha512 (raw/file/2)'); +is( sha512_file_hex('t/data/text-CR.file'), "cfea7a1ac356830a4e938f908e29de7efceab2b851f70722a464084ac83148de60f19b0e99de581b2fbb3da97b14cd05f06431d7fa12fe38369f3ffa10944a06", 'sha512 (hex/file/2)'); +is( sha512_file_b64('t/data/text-CR.file'), "z+p6GsNWgwpOk4+QjinefvzqsrhR9wcipGQISsgxSN5g8ZsOmd5YGy+7Pal7FM0F8GQx1/oS/jg2nz/6EJRKBg==", 'sha512 (base64/file/2)'); +is( digest_file('SHA512', 't/data/text-CR.file'), pack("H*","cfea7a1ac356830a4e938f908e29de7efceab2b851f70722a464084ac83148de60f19b0e99de581b2fbb3da97b14cd05f06431d7fa12fe38369f3ffa10944a06"), 'sha512 (digest_file_raw/file/2)'); +is( digest_file_hex('SHA512', 't/data/text-CR.file'), "cfea7a1ac356830a4e938f908e29de7efceab2b851f70722a464084ac83148de60f19b0e99de581b2fbb3da97b14cd05f06431d7fa12fe38369f3ffa10944a06", 'sha512 (digest_file_hex/file/2)'); +is( digest_file_b64('SHA512', 't/data/text-CR.file'), "z+p6GsNWgwpOk4+QjinefvzqsrhR9wcipGQISsgxSN5g8ZsOmd5YGy+7Pal7FM0F8GQx1/oS/jg2nz/6EJRKBg==", 'sha512 (digest_file_b64/file/2)'); +is( digest_file_b64u('SHA512', 't/data/text-CR.file'), "z-p6GsNWgwpOk4-QjinefvzqsrhR9wcipGQISsgxSN5g8ZsOmd5YGy-7Pal7FM0F8GQx1_oS_jg2nz_6EJRKBg", 'sha512 (digest_file_b64u/file/2)'); +is( Crypt::Digest::SHA512->new->addfile('t/data/text-CR.file')->hexdigest, "cfea7a1ac356830a4e938f908e29de7efceab2b851f70722a464084ac83148de60f19b0e99de581b2fbb3da97b14cd05f06431d7fa12fe38369f3ffa10944a06", 'sha512 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::SHA512->new->addfile($fh)->hexdigest, "cfea7a1ac356830a4e938f908e29de7efceab2b851f70722a464084ac83148de60f19b0e99de581b2fbb3da97b14cd05f06431d7fa12fe38369f3ffa10944a06", 'sha512 (OO/filehandle/2)'); + close($fh); +} + +is( sha512_file('t/data/text-CRLF.file'), pack("H*","158f25d015e0295dc1978e0a5ddf981f6f99e62eb5c7b7c5ee9ec63f1e2869d26885e760da913ef608974954ae78ea9fbbeea8ce392162198b0fdcdda989a923"), 'sha512 (raw/file/3)'); +is( sha512_file_hex('t/data/text-CRLF.file'), "158f25d015e0295dc1978e0a5ddf981f6f99e62eb5c7b7c5ee9ec63f1e2869d26885e760da913ef608974954ae78ea9fbbeea8ce392162198b0fdcdda989a923", 'sha512 (hex/file/3)'); +is( sha512_file_b64('t/data/text-CRLF.file'), "FY8l0BXgKV3Bl44KXd+YH2+Z5i61x7fF7p7GPx4oadJohedg2pE+9giXSVSueOqfu+6ozjkhYhmLD9zdqYmpIw==", 'sha512 (base64/file/3)'); +is( digest_file('SHA512', 't/data/text-CRLF.file'), pack("H*","158f25d015e0295dc1978e0a5ddf981f6f99e62eb5c7b7c5ee9ec63f1e2869d26885e760da913ef608974954ae78ea9fbbeea8ce392162198b0fdcdda989a923"), 'sha512 (digest_file_raw/file/3)'); +is( digest_file_hex('SHA512', 't/data/text-CRLF.file'), "158f25d015e0295dc1978e0a5ddf981f6f99e62eb5c7b7c5ee9ec63f1e2869d26885e760da913ef608974954ae78ea9fbbeea8ce392162198b0fdcdda989a923", 'sha512 (digest_file_hex/file/3)'); +is( digest_file_b64('SHA512', 't/data/text-CRLF.file'), "FY8l0BXgKV3Bl44KXd+YH2+Z5i61x7fF7p7GPx4oadJohedg2pE+9giXSVSueOqfu+6ozjkhYhmLD9zdqYmpIw==", 'sha512 (digest_file_b64/file/3)'); +is( digest_file_b64u('SHA512', 't/data/text-CRLF.file'), "FY8l0BXgKV3Bl44KXd-YH2-Z5i61x7fF7p7GPx4oadJohedg2pE-9giXSVSueOqfu-6ozjkhYhmLD9zdqYmpIw", 'sha512 (digest_file_b64u/file/3)'); +is( Crypt::Digest::SHA512->new->addfile('t/data/text-CRLF.file')->hexdigest, "158f25d015e0295dc1978e0a5ddf981f6f99e62eb5c7b7c5ee9ec63f1e2869d26885e760da913ef608974954ae78ea9fbbeea8ce392162198b0fdcdda989a923", 'sha512 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::SHA512->new->addfile($fh)->hexdigest, "158f25d015e0295dc1978e0a5ddf981f6f99e62eb5c7b7c5ee9ec63f1e2869d26885e760da913ef608974954ae78ea9fbbeea8ce392162198b0fdcdda989a923", 'sha512 (OO/filehandle/3)'); + close($fh); +} + +is( sha512_file('t/data/text-LF.file'), pack("H*","e127fc123059f0554dc1917aed076a9c889d171dc9cdbdfd705641fa368fde66af86e0f8d14a7d3e72571d2bfd25a060ef70e4a84c1d3bb1d0d7524ca8bfaa7a"), 'sha512 (raw/file/4)'); +is( sha512_file_hex('t/data/text-LF.file'), "e127fc123059f0554dc1917aed076a9c889d171dc9cdbdfd705641fa368fde66af86e0f8d14a7d3e72571d2bfd25a060ef70e4a84c1d3bb1d0d7524ca8bfaa7a", 'sha512 (hex/file/4)'); +is( sha512_file_b64('t/data/text-LF.file'), "4Sf8EjBZ8FVNwZF67QdqnIidFx3Jzb39cFZB+jaP3mavhuD40Up9PnJXHSv9JaBg73DkqEwdO7HQ11JMqL+qeg==", 'sha512 (base64/file/4)'); +is( digest_file('SHA512', 't/data/text-LF.file'), pack("H*","e127fc123059f0554dc1917aed076a9c889d171dc9cdbdfd705641fa368fde66af86e0f8d14a7d3e72571d2bfd25a060ef70e4a84c1d3bb1d0d7524ca8bfaa7a"), 'sha512 (digest_file_raw/file/4)'); +is( digest_file_hex('SHA512', 't/data/text-LF.file'), "e127fc123059f0554dc1917aed076a9c889d171dc9cdbdfd705641fa368fde66af86e0f8d14a7d3e72571d2bfd25a060ef70e4a84c1d3bb1d0d7524ca8bfaa7a", 'sha512 (digest_file_hex/file/4)'); +is( digest_file_b64('SHA512', 't/data/text-LF.file'), "4Sf8EjBZ8FVNwZF67QdqnIidFx3Jzb39cFZB+jaP3mavhuD40Up9PnJXHSv9JaBg73DkqEwdO7HQ11JMqL+qeg==", 'sha512 (digest_file_b64/file/4)'); +is( digest_file_b64u('SHA512', 't/data/text-LF.file'), "4Sf8EjBZ8FVNwZF67QdqnIidFx3Jzb39cFZB-jaP3mavhuD40Up9PnJXHSv9JaBg73DkqEwdO7HQ11JMqL-qeg", 'sha512 (digest_file_b64u/file/4)'); +is( Crypt::Digest::SHA512->new->addfile('t/data/text-LF.file')->hexdigest, "e127fc123059f0554dc1917aed076a9c889d171dc9cdbdfd705641fa368fde66af86e0f8d14a7d3e72571d2bfd25a060ef70e4a84c1d3bb1d0d7524ca8bfaa7a", 'sha512 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::SHA512->new->addfile($fh)->hexdigest, "e127fc123059f0554dc1917aed076a9c889d171dc9cdbdfd705641fa368fde66af86e0f8d14a7d3e72571d2bfd25a060ef70e4a84c1d3bb1d0d7524ca8bfaa7a", 'sha512 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_sha512_224.t b/t/digest_sha512_224.t new file mode 100644 index 0000000..dc2033d --- /dev/null +++ b/t/digest_sha512_224.t @@ -0,0 +1,105 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::SHA512_224 qw( sha512_224 sha512_224_hex sha512_224_b64 sha512_224_b64u sha512_224_file sha512_224_file_hex sha512_224_file_b64 sha512_224_file_b64u ); + +is( Crypt::Digest::hashsize('SHA512_224'), 28, 'hashsize/1'); +is( Crypt::Digest->hashsize('SHA512_224'), 28, 'hashsize/2'); +is( Crypt::Digest::SHA512_224::hashsize, 28, 'hashsize/3'); +is( Crypt::Digest::SHA512_224->hashsize, 28, 'hashsize/4'); +is( Crypt::Digest->new('SHA512_224')->hashsize, 28, 'hashsize/5'); +is( Crypt::Digest::SHA512_224->new->hashsize, 28, 'hashsize/6'); + + +is( sha512_224(""), pack("H*","6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4"), 'sha512_224 (raw/1)'); +is( sha512_224_hex(""), "6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4", 'sha512_224 (hex/1)'); +is( sha512_224_b64(""), "btDdAoBvqJ4l3gYMGdOshsq7h9ag3dBcMzuE9A==", 'sha512_224 (base64/1)'); +is( digest_data('SHA512_224', ""), pack("H*","6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4"), 'sha512_224 (digest_data_raw/1)'); +is( digest_data_hex('SHA512_224', ""), "6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4", 'sha512_224 (digest_data_hex/1)'); +is( digest_data_b64('SHA512_224', ""), "btDdAoBvqJ4l3gYMGdOshsq7h9ag3dBcMzuE9A==", 'sha512_224 (digest_data_b64/1)'); +is( digest_data_b64u('SHA512_224', ""), "btDdAoBvqJ4l3gYMGdOshsq7h9ag3dBcMzuE9A", 'sha512_224 (digest_data_b64u/1)'); +is( Crypt::Digest::SHA512_224->new->add("")->hexdigest, "6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4", 'sha512_224 (OO/1)'); + +is( sha512_224("123"), pack("H*","10b7064173a090dcf6cdf30a66831fd8aa4162d97d0a14d88f60f95a"), 'sha512_224 (raw/2)'); +is( sha512_224_hex("123"), "10b7064173a090dcf6cdf30a66831fd8aa4162d97d0a14d88f60f95a", 'sha512_224 (hex/2)'); +is( sha512_224_b64("123"), "ELcGQXOgkNz2zfMKZoMf2KpBYtl9ChTYj2D5Wg==", 'sha512_224 (base64/2)'); +is( digest_data('SHA512_224', "123"), pack("H*","10b7064173a090dcf6cdf30a66831fd8aa4162d97d0a14d88f60f95a"), 'sha512_224 (digest_data_raw/2)'); +is( digest_data_hex('SHA512_224', "123"), "10b7064173a090dcf6cdf30a66831fd8aa4162d97d0a14d88f60f95a", 'sha512_224 (digest_data_hex/2)'); +is( digest_data_b64('SHA512_224', "123"), "ELcGQXOgkNz2zfMKZoMf2KpBYtl9ChTYj2D5Wg==", 'sha512_224 (digest_data_b64/2)'); +is( digest_data_b64u('SHA512_224', "123"), "ELcGQXOgkNz2zfMKZoMf2KpBYtl9ChTYj2D5Wg", 'sha512_224 (digest_data_b64u/2)'); +is( Crypt::Digest::SHA512_224->new->add("123")->hexdigest, "10b7064173a090dcf6cdf30a66831fd8aa4162d97d0a14d88f60f95a", 'sha512_224 (OO/2)'); + +is( sha512_224("test\0test\0test\n"), pack("H*","41a0c9115afa481c3afef7b778aac6b647a966947b0e2e559b053caa"), 'sha512_224 (raw/3)'); +is( sha512_224_hex("test\0test\0test\n"), "41a0c9115afa481c3afef7b778aac6b647a966947b0e2e559b053caa", 'sha512_224 (hex/3)'); +is( sha512_224_b64("test\0test\0test\n"), "QaDJEVr6SBw6/ve3eKrGtkepZpR7Di5VmwU8qg==", 'sha512_224 (base64/3)'); +is( digest_data('SHA512_224', "test\0test\0test\n"), pack("H*","41a0c9115afa481c3afef7b778aac6b647a966947b0e2e559b053caa"), 'sha512_224 (digest_data_raw/3)'); +is( digest_data_hex('SHA512_224', "test\0test\0test\n"), "41a0c9115afa481c3afef7b778aac6b647a966947b0e2e559b053caa", 'sha512_224 (digest_data_hex/3)'); +is( digest_data_b64('SHA512_224', "test\0test\0test\n"), "QaDJEVr6SBw6/ve3eKrGtkepZpR7Di5VmwU8qg==", 'sha512_224 (digest_data_b64/3)'); +is( digest_data_b64u('SHA512_224', "test\0test\0test\n"), "QaDJEVr6SBw6_ve3eKrGtkepZpR7Di5VmwU8qg", 'sha512_224 (digest_data_b64u/3)'); +is( Crypt::Digest::SHA512_224->new->add("test\0test\0test\n")->hexdigest, "41a0c9115afa481c3afef7b778aac6b647a966947b0e2e559b053caa", 'sha512_224 (OO/3)'); + + +is( sha512_224_file('t/data/binary-test.file'), pack("H*","8327cf92e064eb8bfe7118a16fdbf608b5d3b3064bd3f270dd875d9d"), 'sha512_224 (raw/file/1)'); +is( sha512_224_file_hex('t/data/binary-test.file'), "8327cf92e064eb8bfe7118a16fdbf608b5d3b3064bd3f270dd875d9d", 'sha512_224 (hex/file/1)'); +is( sha512_224_file_b64('t/data/binary-test.file'), "gyfPkuBk64v+cRihb9v2CLXTswZL0/Jw3YddnQ==", 'sha512_224 (base64/file/1)'); +is( digest_file('SHA512_224', 't/data/binary-test.file'), pack("H*","8327cf92e064eb8bfe7118a16fdbf608b5d3b3064bd3f270dd875d9d"), 'sha512_224 (digest_file_raw/file/1)'); +is( digest_file_hex('SHA512_224', 't/data/binary-test.file'), "8327cf92e064eb8bfe7118a16fdbf608b5d3b3064bd3f270dd875d9d", 'sha512_224 (digest_file_hex/file/1)'); +is( digest_file_b64('SHA512_224', 't/data/binary-test.file'), "gyfPkuBk64v+cRihb9v2CLXTswZL0/Jw3YddnQ==", 'sha512_224 (digest_file_b64/file/1)'); +is( digest_file_b64u('SHA512_224', 't/data/binary-test.file'), "gyfPkuBk64v-cRihb9v2CLXTswZL0_Jw3YddnQ", 'sha512_224 (digest_file_b64u/file/1)'); +is( Crypt::Digest::SHA512_224->new->addfile('t/data/binary-test.file')->hexdigest, "8327cf92e064eb8bfe7118a16fdbf608b5d3b3064bd3f270dd875d9d", 'sha512_224 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::SHA512_224->new->addfile($fh)->hexdigest, "8327cf92e064eb8bfe7118a16fdbf608b5d3b3064bd3f270dd875d9d", 'sha512_224 (OO/filehandle/1)'); + close($fh); +} + +is( sha512_224_file('t/data/text-CR.file'), pack("H*","c02d47280498098260acd1d8e32cdc773cca3df308834186595f752b"), 'sha512_224 (raw/file/2)'); +is( sha512_224_file_hex('t/data/text-CR.file'), "c02d47280498098260acd1d8e32cdc773cca3df308834186595f752b", 'sha512_224 (hex/file/2)'); +is( sha512_224_file_b64('t/data/text-CR.file'), "wC1HKASYCYJgrNHY4yzcdzzKPfMIg0GGWV91Kw==", 'sha512_224 (base64/file/2)'); +is( digest_file('SHA512_224', 't/data/text-CR.file'), pack("H*","c02d47280498098260acd1d8e32cdc773cca3df308834186595f752b"), 'sha512_224 (digest_file_raw/file/2)'); +is( digest_file_hex('SHA512_224', 't/data/text-CR.file'), "c02d47280498098260acd1d8e32cdc773cca3df308834186595f752b", 'sha512_224 (digest_file_hex/file/2)'); +is( digest_file_b64('SHA512_224', 't/data/text-CR.file'), "wC1HKASYCYJgrNHY4yzcdzzKPfMIg0GGWV91Kw==", 'sha512_224 (digest_file_b64/file/2)'); +is( digest_file_b64u('SHA512_224', 't/data/text-CR.file'), "wC1HKASYCYJgrNHY4yzcdzzKPfMIg0GGWV91Kw", 'sha512_224 (digest_file_b64u/file/2)'); +is( Crypt::Digest::SHA512_224->new->addfile('t/data/text-CR.file')->hexdigest, "c02d47280498098260acd1d8e32cdc773cca3df308834186595f752b", 'sha512_224 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::SHA512_224->new->addfile($fh)->hexdigest, "c02d47280498098260acd1d8e32cdc773cca3df308834186595f752b", 'sha512_224 (OO/filehandle/2)'); + close($fh); +} + +is( sha512_224_file('t/data/text-CRLF.file'), pack("H*","b0a9b9f3c5b0ade5d8caf501a92e1292fc144733fff6d2799ec4fc60"), 'sha512_224 (raw/file/3)'); +is( sha512_224_file_hex('t/data/text-CRLF.file'), "b0a9b9f3c5b0ade5d8caf501a92e1292fc144733fff6d2799ec4fc60", 'sha512_224 (hex/file/3)'); +is( sha512_224_file_b64('t/data/text-CRLF.file'), "sKm588WwreXYyvUBqS4SkvwURzP/9tJ5nsT8YA==", 'sha512_224 (base64/file/3)'); +is( digest_file('SHA512_224', 't/data/text-CRLF.file'), pack("H*","b0a9b9f3c5b0ade5d8caf501a92e1292fc144733fff6d2799ec4fc60"), 'sha512_224 (digest_file_raw/file/3)'); +is( digest_file_hex('SHA512_224', 't/data/text-CRLF.file'), "b0a9b9f3c5b0ade5d8caf501a92e1292fc144733fff6d2799ec4fc60", 'sha512_224 (digest_file_hex/file/3)'); +is( digest_file_b64('SHA512_224', 't/data/text-CRLF.file'), "sKm588WwreXYyvUBqS4SkvwURzP/9tJ5nsT8YA==", 'sha512_224 (digest_file_b64/file/3)'); +is( digest_file_b64u('SHA512_224', 't/data/text-CRLF.file'), "sKm588WwreXYyvUBqS4SkvwURzP_9tJ5nsT8YA", 'sha512_224 (digest_file_b64u/file/3)'); +is( Crypt::Digest::SHA512_224->new->addfile('t/data/text-CRLF.file')->hexdigest, "b0a9b9f3c5b0ade5d8caf501a92e1292fc144733fff6d2799ec4fc60", 'sha512_224 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::SHA512_224->new->addfile($fh)->hexdigest, "b0a9b9f3c5b0ade5d8caf501a92e1292fc144733fff6d2799ec4fc60", 'sha512_224 (OO/filehandle/3)'); + close($fh); +} + +is( sha512_224_file('t/data/text-LF.file'), pack("H*","0e402b1b9ee3cda0e28b97a14aae91f5dbe2721ae469089988ab904d"), 'sha512_224 (raw/file/4)'); +is( sha512_224_file_hex('t/data/text-LF.file'), "0e402b1b9ee3cda0e28b97a14aae91f5dbe2721ae469089988ab904d", 'sha512_224 (hex/file/4)'); +is( sha512_224_file_b64('t/data/text-LF.file'), "DkArG57jzaDii5ehSq6R9dvichrkaQiZiKuQTQ==", 'sha512_224 (base64/file/4)'); +is( digest_file('SHA512_224', 't/data/text-LF.file'), pack("H*","0e402b1b9ee3cda0e28b97a14aae91f5dbe2721ae469089988ab904d"), 'sha512_224 (digest_file_raw/file/4)'); +is( digest_file_hex('SHA512_224', 't/data/text-LF.file'), "0e402b1b9ee3cda0e28b97a14aae91f5dbe2721ae469089988ab904d", 'sha512_224 (digest_file_hex/file/4)'); +is( digest_file_b64('SHA512_224', 't/data/text-LF.file'), "DkArG57jzaDii5ehSq6R9dvichrkaQiZiKuQTQ==", 'sha512_224 (digest_file_b64/file/4)'); +is( digest_file_b64u('SHA512_224', 't/data/text-LF.file'), "DkArG57jzaDii5ehSq6R9dvichrkaQiZiKuQTQ", 'sha512_224 (digest_file_b64u/file/4)'); +is( Crypt::Digest::SHA512_224->new->addfile('t/data/text-LF.file')->hexdigest, "0e402b1b9ee3cda0e28b97a14aae91f5dbe2721ae469089988ab904d", 'sha512_224 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::SHA512_224->new->addfile($fh)->hexdigest, "0e402b1b9ee3cda0e28b97a14aae91f5dbe2721ae469089988ab904d", 'sha512_224 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_sha512_256.t b/t/digest_sha512_256.t new file mode 100644 index 0000000..d5412c2 --- /dev/null +++ b/t/digest_sha512_256.t @@ -0,0 +1,105 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::SHA512_256 qw( sha512_256 sha512_256_hex sha512_256_b64 sha512_256_b64u sha512_256_file sha512_256_file_hex sha512_256_file_b64 sha512_256_file_b64u ); + +is( Crypt::Digest::hashsize('SHA512_256'), 32, 'hashsize/1'); +is( Crypt::Digest->hashsize('SHA512_256'), 32, 'hashsize/2'); +is( Crypt::Digest::SHA512_256::hashsize, 32, 'hashsize/3'); +is( Crypt::Digest::SHA512_256->hashsize, 32, 'hashsize/4'); +is( Crypt::Digest->new('SHA512_256')->hashsize, 32, 'hashsize/5'); +is( Crypt::Digest::SHA512_256->new->hashsize, 32, 'hashsize/6'); + + +is( sha512_256(""), pack("H*","c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a"), 'sha512_256 (raw/1)'); +is( sha512_256_hex(""), "c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a", 'sha512_256 (hex/1)'); +is( sha512_256_b64(""), "xnK40e9W7Sirh8NiLFEUBpvdOte4+XN0mNDAHs7wlno=", 'sha512_256 (base64/1)'); +is( digest_data('SHA512_256', ""), pack("H*","c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a"), 'sha512_256 (digest_data_raw/1)'); +is( digest_data_hex('SHA512_256', ""), "c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a", 'sha512_256 (digest_data_hex/1)'); +is( digest_data_b64('SHA512_256', ""), "xnK40e9W7Sirh8NiLFEUBpvdOte4+XN0mNDAHs7wlno=", 'sha512_256 (digest_data_b64/1)'); +is( digest_data_b64u('SHA512_256', ""), "xnK40e9W7Sirh8NiLFEUBpvdOte4-XN0mNDAHs7wlno", 'sha512_256 (digest_data_b64u/1)'); +is( Crypt::Digest::SHA512_256->new->add("")->hexdigest, "c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a", 'sha512_256 (OO/1)'); + +is( sha512_256("123"), pack("H*","f5182c34f66c46ba5c185fbad8f71db1c8da173b6f6c4c1bc8ecfcfdd426fd10"), 'sha512_256 (raw/2)'); +is( sha512_256_hex("123"), "f5182c34f66c46ba5c185fbad8f71db1c8da173b6f6c4c1bc8ecfcfdd426fd10", 'sha512_256 (hex/2)'); +is( sha512_256_b64("123"), "9RgsNPZsRrpcGF+62PcdscjaFztvbEwbyOz8/dQm/RA=", 'sha512_256 (base64/2)'); +is( digest_data('SHA512_256', "123"), pack("H*","f5182c34f66c46ba5c185fbad8f71db1c8da173b6f6c4c1bc8ecfcfdd426fd10"), 'sha512_256 (digest_data_raw/2)'); +is( digest_data_hex('SHA512_256', "123"), "f5182c34f66c46ba5c185fbad8f71db1c8da173b6f6c4c1bc8ecfcfdd426fd10", 'sha512_256 (digest_data_hex/2)'); +is( digest_data_b64('SHA512_256', "123"), "9RgsNPZsRrpcGF+62PcdscjaFztvbEwbyOz8/dQm/RA=", 'sha512_256 (digest_data_b64/2)'); +is( digest_data_b64u('SHA512_256', "123"), "9RgsNPZsRrpcGF-62PcdscjaFztvbEwbyOz8_dQm_RA", 'sha512_256 (digest_data_b64u/2)'); +is( Crypt::Digest::SHA512_256->new->add("123")->hexdigest, "f5182c34f66c46ba5c185fbad8f71db1c8da173b6f6c4c1bc8ecfcfdd426fd10", 'sha512_256 (OO/2)'); + +is( sha512_256("test\0test\0test\n"), pack("H*","a6a117dcf996903422e8daee13ea130e7192d055bf07e4b534f9ed1df9167264"), 'sha512_256 (raw/3)'); +is( sha512_256_hex("test\0test\0test\n"), "a6a117dcf996903422e8daee13ea130e7192d055bf07e4b534f9ed1df9167264", 'sha512_256 (hex/3)'); +is( sha512_256_b64("test\0test\0test\n"), "pqEX3PmWkDQi6NruE+oTDnGS0FW/B+S1NPntHfkWcmQ=", 'sha512_256 (base64/3)'); +is( digest_data('SHA512_256', "test\0test\0test\n"), pack("H*","a6a117dcf996903422e8daee13ea130e7192d055bf07e4b534f9ed1df9167264"), 'sha512_256 (digest_data_raw/3)'); +is( digest_data_hex('SHA512_256', "test\0test\0test\n"), "a6a117dcf996903422e8daee13ea130e7192d055bf07e4b534f9ed1df9167264", 'sha512_256 (digest_data_hex/3)'); +is( digest_data_b64('SHA512_256', "test\0test\0test\n"), "pqEX3PmWkDQi6NruE+oTDnGS0FW/B+S1NPntHfkWcmQ=", 'sha512_256 (digest_data_b64/3)'); +is( digest_data_b64u('SHA512_256', "test\0test\0test\n"), "pqEX3PmWkDQi6NruE-oTDnGS0FW_B-S1NPntHfkWcmQ", 'sha512_256 (digest_data_b64u/3)'); +is( Crypt::Digest::SHA512_256->new->add("test\0test\0test\n")->hexdigest, "a6a117dcf996903422e8daee13ea130e7192d055bf07e4b534f9ed1df9167264", 'sha512_256 (OO/3)'); + + +is( sha512_256_file('t/data/binary-test.file'), pack("H*","0b73f578749b73675a98d3d8daf3457c326db775b87a483d0c1245ede48467af"), 'sha512_256 (raw/file/1)'); +is( sha512_256_file_hex('t/data/binary-test.file'), "0b73f578749b73675a98d3d8daf3457c326db775b87a483d0c1245ede48467af", 'sha512_256 (hex/file/1)'); +is( sha512_256_file_b64('t/data/binary-test.file'), "C3P1eHSbc2damNPY2vNFfDJtt3W4ekg9DBJF7eSEZ68=", 'sha512_256 (base64/file/1)'); +is( digest_file('SHA512_256', 't/data/binary-test.file'), pack("H*","0b73f578749b73675a98d3d8daf3457c326db775b87a483d0c1245ede48467af"), 'sha512_256 (digest_file_raw/file/1)'); +is( digest_file_hex('SHA512_256', 't/data/binary-test.file'), "0b73f578749b73675a98d3d8daf3457c326db775b87a483d0c1245ede48467af", 'sha512_256 (digest_file_hex/file/1)'); +is( digest_file_b64('SHA512_256', 't/data/binary-test.file'), "C3P1eHSbc2damNPY2vNFfDJtt3W4ekg9DBJF7eSEZ68=", 'sha512_256 (digest_file_b64/file/1)'); +is( digest_file_b64u('SHA512_256', 't/data/binary-test.file'), "C3P1eHSbc2damNPY2vNFfDJtt3W4ekg9DBJF7eSEZ68", 'sha512_256 (digest_file_b64u/file/1)'); +is( Crypt::Digest::SHA512_256->new->addfile('t/data/binary-test.file')->hexdigest, "0b73f578749b73675a98d3d8daf3457c326db775b87a483d0c1245ede48467af", 'sha512_256 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::SHA512_256->new->addfile($fh)->hexdigest, "0b73f578749b73675a98d3d8daf3457c326db775b87a483d0c1245ede48467af", 'sha512_256 (OO/filehandle/1)'); + close($fh); +} + +is( sha512_256_file('t/data/text-CR.file'), pack("H*","8f6b6338b4656ed2b71f044d1fddbc2e1d0470b328e1962f9cdb1152bdb33fbb"), 'sha512_256 (raw/file/2)'); +is( sha512_256_file_hex('t/data/text-CR.file'), "8f6b6338b4656ed2b71f044d1fddbc2e1d0470b328e1962f9cdb1152bdb33fbb", 'sha512_256 (hex/file/2)'); +is( sha512_256_file_b64('t/data/text-CR.file'), "j2tjOLRlbtK3HwRNH928Lh0EcLMo4ZYvnNsRUr2zP7s=", 'sha512_256 (base64/file/2)'); +is( digest_file('SHA512_256', 't/data/text-CR.file'), pack("H*","8f6b6338b4656ed2b71f044d1fddbc2e1d0470b328e1962f9cdb1152bdb33fbb"), 'sha512_256 (digest_file_raw/file/2)'); +is( digest_file_hex('SHA512_256', 't/data/text-CR.file'), "8f6b6338b4656ed2b71f044d1fddbc2e1d0470b328e1962f9cdb1152bdb33fbb", 'sha512_256 (digest_file_hex/file/2)'); +is( digest_file_b64('SHA512_256', 't/data/text-CR.file'), "j2tjOLRlbtK3HwRNH928Lh0EcLMo4ZYvnNsRUr2zP7s=", 'sha512_256 (digest_file_b64/file/2)'); +is( digest_file_b64u('SHA512_256', 't/data/text-CR.file'), "j2tjOLRlbtK3HwRNH928Lh0EcLMo4ZYvnNsRUr2zP7s", 'sha512_256 (digest_file_b64u/file/2)'); +is( Crypt::Digest::SHA512_256->new->addfile('t/data/text-CR.file')->hexdigest, "8f6b6338b4656ed2b71f044d1fddbc2e1d0470b328e1962f9cdb1152bdb33fbb", 'sha512_256 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::SHA512_256->new->addfile($fh)->hexdigest, "8f6b6338b4656ed2b71f044d1fddbc2e1d0470b328e1962f9cdb1152bdb33fbb", 'sha512_256 (OO/filehandle/2)'); + close($fh); +} + +is( sha512_256_file('t/data/text-CRLF.file'), pack("H*","432c9ddcbf8deb5ca160e3a0a7e06606b3baae39d6662b456ae3c36304eaed18"), 'sha512_256 (raw/file/3)'); +is( sha512_256_file_hex('t/data/text-CRLF.file'), "432c9ddcbf8deb5ca160e3a0a7e06606b3baae39d6662b456ae3c36304eaed18", 'sha512_256 (hex/file/3)'); +is( sha512_256_file_b64('t/data/text-CRLF.file'), "Qyyd3L+N61yhYOOgp+BmBrO6rjnWZitFauPDYwTq7Rg=", 'sha512_256 (base64/file/3)'); +is( digest_file('SHA512_256', 't/data/text-CRLF.file'), pack("H*","432c9ddcbf8deb5ca160e3a0a7e06606b3baae39d6662b456ae3c36304eaed18"), 'sha512_256 (digest_file_raw/file/3)'); +is( digest_file_hex('SHA512_256', 't/data/text-CRLF.file'), "432c9ddcbf8deb5ca160e3a0a7e06606b3baae39d6662b456ae3c36304eaed18", 'sha512_256 (digest_file_hex/file/3)'); +is( digest_file_b64('SHA512_256', 't/data/text-CRLF.file'), "Qyyd3L+N61yhYOOgp+BmBrO6rjnWZitFauPDYwTq7Rg=", 'sha512_256 (digest_file_b64/file/3)'); +is( digest_file_b64u('SHA512_256', 't/data/text-CRLF.file'), "Qyyd3L-N61yhYOOgp-BmBrO6rjnWZitFauPDYwTq7Rg", 'sha512_256 (digest_file_b64u/file/3)'); +is( Crypt::Digest::SHA512_256->new->addfile('t/data/text-CRLF.file')->hexdigest, "432c9ddcbf8deb5ca160e3a0a7e06606b3baae39d6662b456ae3c36304eaed18", 'sha512_256 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::SHA512_256->new->addfile($fh)->hexdigest, "432c9ddcbf8deb5ca160e3a0a7e06606b3baae39d6662b456ae3c36304eaed18", 'sha512_256 (OO/filehandle/3)'); + close($fh); +} + +is( sha512_256_file('t/data/text-LF.file'), pack("H*","26ce04b3a529a52b1435a348175723b78885b35e9805acb09bd433e163a0b8c2"), 'sha512_256 (raw/file/4)'); +is( sha512_256_file_hex('t/data/text-LF.file'), "26ce04b3a529a52b1435a348175723b78885b35e9805acb09bd433e163a0b8c2", 'sha512_256 (hex/file/4)'); +is( sha512_256_file_b64('t/data/text-LF.file'), "Js4Es6UppSsUNaNIF1cjt4iFs16YBaywm9Qz4WOguMI=", 'sha512_256 (base64/file/4)'); +is( digest_file('SHA512_256', 't/data/text-LF.file'), pack("H*","26ce04b3a529a52b1435a348175723b78885b35e9805acb09bd433e163a0b8c2"), 'sha512_256 (digest_file_raw/file/4)'); +is( digest_file_hex('SHA512_256', 't/data/text-LF.file'), "26ce04b3a529a52b1435a348175723b78885b35e9805acb09bd433e163a0b8c2", 'sha512_256 (digest_file_hex/file/4)'); +is( digest_file_b64('SHA512_256', 't/data/text-LF.file'), "Js4Es6UppSsUNaNIF1cjt4iFs16YBaywm9Qz4WOguMI=", 'sha512_256 (digest_file_b64/file/4)'); +is( digest_file_b64u('SHA512_256', 't/data/text-LF.file'), "Js4Es6UppSsUNaNIF1cjt4iFs16YBaywm9Qz4WOguMI", 'sha512_256 (digest_file_b64u/file/4)'); +is( Crypt::Digest::SHA512_256->new->addfile('t/data/text-LF.file')->hexdigest, "26ce04b3a529a52b1435a348175723b78885b35e9805acb09bd433e163a0b8c2", 'sha512_256 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::SHA512_256->new->addfile($fh)->hexdigest, "26ce04b3a529a52b1435a348175723b78885b35e9805acb09bd433e163a0b8c2", 'sha512_256 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_shake.t b/t/digest_shake.t new file mode 100644 index 0000000..dd39dc5 --- /dev/null +++ b/t/digest_shake.t @@ -0,0 +1,53 @@ +use strict; +use warnings; + +use Test::More tests => 16; + +use Crypt::Digest::SHAKE; + + +my $sh128 = Crypt::Digest::SHAKE->new(128); +ok($sh128, "Crypt::Digest::SHAKE->new(128)"); + +my $sh256 = Crypt::Digest::SHAKE->new(256); +ok($sh256, "Crypt::Digest::SHAKE->new(256)"); + +is(unpack("H*", $sh128->add("")->done(32)), "7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef26"); +is(unpack("H*", $sh256->add("")->done(64)), "46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762fd75dc4ddd8c0f200cb05019d67b592f6fc821c49479ab48640292eacb3b7c4be"); + +is(unpack("H*", Crypt::Digest::SHAKE->new(128)->add("The quick brown fox jumps over the lazy dog")->done(32)), + "f4202e3c5852f9182a0430fd8144f0a74b95e7417ecae17db0f8cfeed0e3e66e"); +is(unpack("H*", Crypt::Digest::SHAKE->new(128)->add("The quick brown fox jumps over the lazy dof")->done(32)), + "853f4538be0db9621a6cea659a06c1107b1f83f02b13d18297bd39d7411cf10c"); + +{ + my $sh128 = Crypt::Digest::SHAKE->new(128); + $sh128->add("The qui"); + $sh128->add("ck bro"); + $sh128->add("wn fox j"); + $sh128->add("umps o"); + $sh128->add("ver the l"); + $sh128->add("azy dof"); + my $res = $sh128->done(5); + $res .= $sh128->done(7); + $res .= $sh128->done(8); + $res .= $sh128->done(12); + is(unpack("H*", $res), "853f4538be0db9621a6cea659a06c1107b1f83f02b13d18297bd39d7411cf10c"); +} + +is(unpack("H*", Crypt::Digest::SHAKE->new(256)->add("A" x 307)->done(9)), "dbf9928a270d58ed5a"); +is(unpack("H*", Crypt::Digest::SHAKE->new(256)->add("A" x 307)->done(19)), "dbf9928a270d58ed5a6c00f2f849cac54aef8c"); +is(unpack("H*", Crypt::Digest::SHAKE->new(256)->add("A" x 307)->done(29)), "dbf9928a270d58ed5a6c00f2f849cac54aef8c917698bcc971fe6b973e"); +is(unpack("H*", Crypt::Digest::SHAKE->new(256)->add("A" x 307)->done(39)), "dbf9928a270d58ed5a6c00f2f849cac54aef8c917698bcc971fe6b973ec8aac9666a6f6829c58a"); +is(unpack("H*", Crypt::Digest::SHAKE->new(256)->add("A" x 307)->done(49)), "dbf9928a270d58ed5a6c00f2f849cac54aef8c917698bcc971fe6b973ec8aac9666a6f6829c58aba66ebbb34dbd7acab94"); +is(unpack("H*", Crypt::Digest::SHAKE->new(256)->add("A" x 307)->done(59)), "dbf9928a270d58ed5a6c00f2f849cac54aef8c917698bcc971fe6b973ec8aac9666a6f6829c58aba66ebbb34dbd7acab94cd20c6de1916fc29a890"); +is(unpack("H*", Crypt::Digest::SHAKE->new(256)->add("A" x 307)->done(69)), "dbf9928a270d58ed5a6c00f2f849cac54aef8c917698bcc971fe6b973ec8aac9666a6f6829c58aba66ebbb34dbd7acab94cd20c6de1916fc29a890ad14e4f95af8c3c20147"); + +{ + my $hex = substr(unpack("H*", Crypt::Digest::SHAKE->new(256)->add("A" x 307)->done(999)), -100); + is($hex, "e8e5fc62297c4ce6f915d79148470b87f539f2806160e3114ae210a3c4707e73adcdb33410606aad260c4f5dbb1575fa3d1e"); +} +{ + my $hex = substr(unpack("H*", Crypt::Digest::SHAKE->new(128)->add("A" x 307)->done(999)), -100); + is($hex, "868064bc8e37bd63713aa58ee7dae1c8d022aab26f079b13dfbc6c986a2d0200b046a99ed716380f691b7d15689236a0a8e6"); +} diff --git a/t/digest_test_vectors_ltc.t b/t/digest_test_vectors_ltc.t new file mode 100644 index 0000000..da12c44 --- /dev/null +++ b/t/digest_test_vectors_ltc.t @@ -0,0 +1,1815 @@ +use strict; +use warnings; + +use Test::More tests => 1739; +use Crypt::Digest; + +my $trans = { + "chc_hash" => "CHAES", + "md2" => "MD2", + "md4" => "MD4", + "md5" => "MD5", + "rmd128" => "RIPEMD128", + "rmd160" => "RIPEMD160", + "sha1" => "SHA1", + "sha224" => "SHA224", + "sha256" => "SHA256", + "sha384" => "SHA384", + "sha512" => "SHA512", + "tiger" => "Tiger192", + "whirlpool" => "Whirlpool", +}; +my $tv; +my $hash; + +while (my $l = ) { + $l =~ s/[\r\n]*$//; + $l =~ s/^[\s]*([^\s\r\n]+).*?/$1/; + $l =~ s/\s+//; + my ($k, $v) = split /:/, $l; + next unless defined $k && defined $v; + $hash = $v if lc($k) eq 'hash'; + $tv->{$hash}->{$k} = $v if $hash && $k =~ /\d+/; +} + +my $bytes = ''; +for my $i (0..255) { + for my $h (keys %$tv) { + next unless $tv->{$h}->{$i}; + my $H = $trans->{$h} || die "FATAL: unknown hash function '$h'"; + is(Crypt::Digest->new($H)->add($bytes)->hexdigest, lc($tv->{$h}->{$i}), "$H/$i"); + } + $bytes .= pack('C', $i); +} + +__DATA__ +Hash Test Vectors: + +These are the hashes of nn bytes '00 01 02 03 .. (nn-1)' + +Hash: tiger + 0: 3293AC630C13F0245F92BBB1766E16167A4E58492DDE73F3 + 1: 5D9ED00A030E638BDB753A6A24FB900E5A63B8E73E6C25B6 + 2: 65B0E1EA36CA17EDE2F055E67EAD67B1C282A11A5BA3A8E0 + 3: AB7FB8D21CE3D8D9BB5F1AF1F2FA0D3C277906160DB8D226 + 4: FE2E9D43F74B199D91B9291D73CCFCA0BEA5F068FBA244FF + 5: 3DF6D672FE9DAAB21523EB04705D8A8B72B78B00AD465D1C + 6: E05724353FE29957C3E8DEBAA21D0C2DD49CCA22191D5AD3 + 7: 4056DDBF82AE74AB56720DEAF079ACA2F076ED046D044DE5 + 8: 801FB9BE1A9AC7337A81345B3845E4E7C13AF1FBADB73723 + 9: 430156547A82492CA859385304748F65F2D4A7E2664AE2B1 + 10: FC435137CD652D720A11EDF47ABE4680BA4AD5BD810C9835 + 11: 20A8143DF47F5715FA0905FE6F9D1D2B5B2D4E26FA98930B + 12: E4A2063019FBC034DEB01E2A95296042319CBC039DA69A91 + 13: B5F0FA570C4CD69A3C68448BE42C865BDF77ED68B93875E7 + 14: 802BE6EA2CE86A0B371F2354944B19CB3231AF7FB4F00FF8 + 15: D7C08863B5E5E3D69B5404A116315A698E128EBAF8636B70 + 16: 5C5288CB0E4E533056BA5293440D9BE6F3C461233BF1ED51 + 17: 88D3A94F3820E4087DA69D8BBE2CF415466063709C450C4D + 18: C07B4B155F9F75805D9D087087FCDD28D08A9D022192447E + 19: EE473E569FF3E092CF8996B31CE665EA7D61520D42E27395 + 20: E13DAE8098139CFCEA755D2060F107E3C7581EDF9F4B3B85 + 21: B48A9C09F26B379AA28FBC750B50CEF69D0D0EE37FF765F7 + 22: 574A01456373014F4179CDA14541E2E3C5A1CDDA9F9D071C + 23: F2E2831E5BB4AF05914C4BA61BB8D600D1EF071C5DF02269 + 24: B7808A5B6258CBE718EDA938978C69D3FFC45A222E9DBF4C + 25: D8E4E076DDE78950D51EAC9F97D2D1916A0910465D45A55C + 26: 4EDECFAAE1DE98B7E056E64CA24003422BBE6F048129B24C + 27: 0DE283B5A4953EAAEC6F3FDE50D7875C8EE57FA79BDC70FC + 28: ECDD4BA1936DB9E6F83E2BD7F39D23927A1A17B2D52A8649 + 29: BE11893460E49659F7DF3FB3BD5E3E9A319F85FD3496E26C + 30: AEC0DA0F2CC0646325CC03319A0E080F68B46B33F81920D6 + 31: 8824FD39984F6A52FFFF19016E27C594921452086373F2EE + 32: 8B6592AFBB02E227AA451B5CFDC821B84245D34B96BF4F13 + 33: 960DF9C349EC6619FF37E3F0F4832E19CC6A4E4D68962651 + 34: F4E2B7AA72BC7D6E0CF6DA1094BEEFAA9C55610327C62900 + 35: 05FD1B80CA4C7C14FE5BF0ACBD0EA3DAE498DC391DCF2277 + 36: C5E95F953898C68355B591507BB714F0E5DAB9989D083900 + 37: B2D4E286CF7EA8AB6ECD650C9E48CA23497EADE55485DB1E + 38: 9D51657E11C54FFDF205DBB435097A2BC6F93C4BE8D6180B + 39: 3C6AE3911356A343AE3113735F07FCFB5E046ACD47B00FBB + 40: 664342CDECC825ED340A7FFE2E57107DD0B5F24C24B2C3F0 + 41: 4EF7FCA13CE684D81DE4F566D2897CEB407FBB3DDE81FD64 + 42: 54689FECED63F297B13CD494B85E686680F4F78DE7EC81D5 + 43: AF434BDBDC7EF90BE03E40A033F16E8A57B41840E1E8AB59 + 44: A32DB678F44905C18968F5D898CA7992EBE2E4CC3318B96C + 45: DEE9D519A12ACFB8A0935A368D6E6C75EEEEE6F2B0D5D191 + 46: CBC74863472D1C9D23C526F4908BD4D4234E00CBCC99A9E9 + 47: 6C228A1D4871E802E035C9BB16C5187354841FB6BE3C69B6 + 48: CAA755C55AA869E633CB3C6D93A561944AC7418154E2B0F0 + 49: A6835F7C0C6CA8F4A45787BAFA77478AE9ADDBEFBC3052D3 + 50: E406755957EC21BA6A64B5D3AAF31749CF98DF92F1B1FFE0 + 51: 0C2D4A44A803DBA99B7A467553C9293B46A538558BD77DD4 + 52: F04F011B09D275A185528CC040EB719649C8471A87B259B3 + 53: 3DA8B57FF52FCAE7C32636EC6C80708189CED8113C5CDE1E + 54: 6C6C88B8E18DF5CB22EDB61A2D3ED74741A708BC46576FB7 + 55: 2D48EE2BF85DE234754BECF3C6F5B0E62988B5BF24AEA5BB + 56: 0D17702DDCA078ED1CC51B95DF29EA1053CE97F69395C613 + 57: 9D8C2AD327DE43D5782D5F20881F4A8C433BA19AFC8C15AD + 58: 227BA419B760D9D10DBB09585EDD475AC2734FD4539F8275 + 59: 2F5220A828EF94E327BD51D4DF5C58609F8A93B9FE01FFF6 + 60: 0EED9F91E1A33A50B8E913DBA0B5E248D263E1FC72C6A449 + 61: 766B707E999FF3C51EE01168513BA0DCEFEAB222DD1F69F6 + 62: 85E6710694E7C36A2340DA6A371C0560450F3D44D35AD98C + 63: D401F9B13D39C24477C0AE6971C705C63C067F29508C29C9 + 64: 212DF89C57155270344ACCB19027B0B26B104FA0FBBE0FE4 + 65: 3BEDE767AA4A7507DBEFF83D1BC33F67EBA9C64945066227 + 66: 79FED1FB9F17C4980108E8605C10D9E176AC8FE4F6A65064 + 67: 48D9B7622AB7F8968ED926255F78E8CE461E4C9162FFE8B7 + 68: 6638C83837297B3F53B0F824C087D9A0B8D9FC6265683B8F + 69: 174421CF6D331FF51924F8946E8244555C9020D38E31B6DB + 70: 03E42AFB5FFF9B9C3794A3DBEC99FA7E3F7305EF07BD29EF + 71: CCAFC68D4B3ED889DC9F28CB9225808A40AA8E0D5CA343FF + 72: E824F93B4022011886EFC54539D4D5D51863ADA329FB4E22 + 73: 7CF0DC01B326687530F42040BA0D0CE93174455E8A990D14 + 74: 7A8E619479F4F5C418EC041806850E6723CA56AFBC3D32CC + 75: 083C5CA90F4B296C42040559C8296149D4EEBAB5EF2CB82D + 76: 3581B7AC32FA8A0986FD14F277FB106E112B92D18CD689BD + 77: 258E822D9CC1ECA8B55D925BA361BA2D9FC27AF181F138B4 + 78: A86C1E88A64515FA281A462D467458231494F16E835DF873 + 79: 76E7F06FE9B8B388DB012F8B4BE2FB343F95913EDDE47A27 + 80: 00278B4E5690E729EC7118B5BF63C9D1EB1268960893CA75 + 81: 8DE70E64A31BA1AF4F5C23CF774CCA32FE952D76C3FDD1B7 + 82: BBEA72C840749BABAF1415FEAC343411B89515B87848A09A + 83: C6C3CCAC1B338DF117A61ECF9A280E9BA709784C72B76771 + 84: AE9813EF4429EAE73EA9FDB5E23D263AF1BB87928CF5F048 + 85: 68647CD7BFFB8E530D28C86685A8D2F657EE4CD64EDD7E66 + 86: AA8C35B0E746AF56435F6C711AD0423966EA459087409713 + 87: AAD5C0D5E980B29BC88985C544717B81F58CDB923A3468E0 + 88: F60929D14781DE44EA607AAFC0D25FA1B6EF3C6AA0F8B3D7 + 89: C48087DC75EC43A54A593F24E1B359BB75C581A65C3170D0 + 90: 11D1372FBDFD9FF514611AB20D31BA62F18856C8D6AE3AD7 + 91: F2A8076B9017EDADEED41F409C9E32EB3BC090EAE89F855D + 92: 702FA47E5BD35E344B5B87C0082106337206CADD3D4D5014 + 93: B9E03FED752A560C3B0365EDF5BFC4DC7EAC5E4BBB93738D + 94: 3C84C52BF51077A5819F56E5A5C1C06209181579393220C7 + 95: F8ECCA28A525594E138B55C06617A063DF74FE3469D98381 + 96: 1081C3BAEEC0ADF4980C2EA6593B0906DCBEDE4805754774 + 97: B5152E39DE0BFE8982D783FC4F0CB7160EB2D69F6F3B3E5B + 98: 6A6B760BFB1965C72AC793F9C02FA21B0F1C34BD2640BB6B + 99: 1E6DCBFA8BA8D96C29101768A6A39433D5AD5A50E0970730 +100: 733222D3A033351FAFD68C5CE8A4D833BA7420D44103CB6B +101: E4CD7DA59B215F1DEAA8FBBA850F2C1A7F4C3D495FE6804A +102: 7BE78C790713545754D4C78A9318ACA4AA058C5C23540131 +103: B71C3809A504BE2F57AE9E25BDCC3921DC665C65289EA55A +104: 2B8CA39977535EB692EFBF0DECDA8971A8604F7FCBAE75DD +105: 3CC48B51E4C5DE4F0C2ABE0BE6EE4B63CC564A87C01943CD +106: 157ACDF7B59FC25966F9783207554364882840E7251ED6C1 +107: DEA1CFAECF18D3611CCD0517131A16DDBC97A12902DD8BAB +108: 2AD2E990BCF6481284DF44B961632687C2E64DFAE2AE16C2 +109: 838F3A3B28A50A12B5707490A66080DCFA0230E583B6EB14 +110: C8B20315121CDFB3A91BC0EDF11886F283CF6C480F498627 +111: 2B0FB04F100BE9AD51B7D64C76651BAB4B7D31D1D9195711 +112: B6495B6256FF464EC409A4098B622E8BDBB1003411854FD7 +113: 1741A789472E20E1CC89869A2477E4F2807C22182EA5B221 +114: 07ADC82CB3F27389A12B6B9C2B268BDDFD1D9478D9EDA0D7 +115: D9BD6760FB819A8A3CEE75303F8208FCA3E138B517DAB934 +116: 9FCF21A9236C2C12861FD20F1FB15A187CD7EE7821F72BE7 +117: 73D165769B34DA6F151464E61115D0E09A66F8D0FA049726 +118: 74580BFA88EEA03C0EAE722F81997E400D9CC25FA0311DFA +119: E3C6A369820E267C938D276A858928040C7C25A826501DC7 +120: C20AD90DB0B8BEE0335D069259991060969EEC9F939E4CA7 +121: F3746F4CD6A19CC137C5FCC8F60A4C0A7F56D97190B7A9C2 +122: 63A3B79EAF3DF35180960465059C0ADEE06D45179A56284F +123: 606AFD833D082628D58672403EE6DB348E6F68D8CD1947F8 +124: 7567EA8E10CBF312F8478B7C51D87B00B6CF3DE82B03DCE7 +125: DBCDC2B9B8589F6C7616B55B059B3B3E38D97A9E6DF1F29A +126: 15D9909F8D69689E7E78A0DB928194A59623E7253AA9D400 +127: DE39589DCC0C654867943801946B9888B347526279CA15BD +128: 34FA7C74EE67C1F92C0BE1CFD4B2F46A14FFB999604925F6 + +Hash: md2 + 0: 8350E5A3E24C153DF2275C9F80692773 + 1: EE8DBAE3BC62BDC94EA63F69C1BC26C9 + 2: 1EAA4F494D81BC570FED4440EF3AC1C3 + 3: 54CDB6D1BF893171E7814DB84DF63A3A + 4: F71A82F8083CD9ABA3D0D651E2577EDA + 5: 2F708334DBD1FE8F71CEE77E54B470F9 + 6: E014DF2DF43498495056E7A437476A34 + 7: 9C410644446400B0F2C1B4697C443E19 + 8: 0944DEC40367AC855117012204018C9F + 9: CE8A6E797AC79D82D2C6D151F740CB33 + 10: 06DB4C310570268754114F747E1F0946 + 11: 9F323D5FC6DA86307BEBC0371A733787 + 12: 3C1C7E741794D3D4022DE17FCE72B283 + 13: 035D71AA96F782A9EB8D431E431672EE + 14: 7ABE4067ED6CA42C79B542829434559C + 15: 5E8D0D6F6F8E07C226AE9DD32609035A + 16: 2B1632FF487D6C98AA3773B9D3FCD2AB + 17: D3D894482F7541BC0948B19842B479D9 + 18: CFE6B872AC98304524CC6A88B6C45881 + 19: 1573DD015C8629DE9664CA0721473888 + 20: ACFE2D3BB3CCAD8AEF6E37D0D8FBD634 + 21: F5F83499AA172BE8344F7F39BA708AAA + 22: 1D1C71FF6321B685D26F7FA620DA6C22 + 23: 4D7E74B6C8321775A34F7EFF38AAE5DF + 24: 351A988C86AC5A10D0AB8E9071795181 + 25: 970F511C12E9CCD526EFF8574CF1467F + 26: 0A68F53A476F7499EF79278A4EE8DAA3 + 27: D458CF9C8CD0ABA23BD9A8C5ABE495CE + 28: C8002E85C3AD9B8B4AFD23378165C54B + 29: 0B4788B157ED150A34D0E6E96BB4789C + 30: B14F4E31DE09281E07248A17939BE5B9 + 31: 803EEB99231526D6A33C8D4FCA537A6F + 32: 51FE5D6637D2F0F09E48CE2A7F5030EA + +Hash: md4 + 0: 31D6CFE0D16AE931B73C59D7E0C089C0 + 1: 47C61A0FA8738BA77308A8A600F88E4B + 2: 9E7A1DDE4D280E7F389018A5CCC3ABF2 + 3: E9A4DB2923FAF634CBB12CC1F8AC5C66 + 4: DF8FA069C6121801FFC539DADD33FCB9 + 5: 4B3511308F7E71BF6462CF18F1184C61 + 6: 075582A51F87682919E733C84C9FD998 + 7: 20DDA7535A464D13E1763BA61BDC12AC + 8: 66AE1E305BED186780BB60328D3CCBC5 + 9: 503E90BF2375627262E58D90177220F8 + 10: AEC6B48C10659E3D6E18A2CDE8F8D3A0 + 11: 45EFB3704B6684B0750E3DEDBB2BCDA9 + 12: 7C9443DBCD858138E32604E0D288F7B8 + 13: 95E5B93F4EA79C082BA1745D3026D70A + 14: C913D5DE0BBD1C2F2838E46363732D97 + 15: ABE357BDC413C82C8BBAA380C39CB5F9 + 16: 22F840370EBB1DDBEA4FA3A40243391E + 17: 0A289FEC69AF967988FA40C47960060B + 18: B63D3ADF13B509C95C088F909A0B356E + 19: 36E8E07E3202E6F4F7E885853C9735C7 + 20: 1D363AFD1208A7B8BD486D51AEBFAEB8 + 21: 75E36A5445AD72CF5BF47301EBED1FDF + 22: DA7979688F48A6606D86C762DF0D8850 + 23: 6ACB325CE624372873CC01A4AA053F8E + 24: 94F9BFD6503DBDC58C163E33504B7EDB + 25: 3702CB296784290FC46B82445BF7EB17 + 26: 903510251E7A00415EA21B6AC268A92D + 27: 6DF08DB9C33C86CFE8DAF5E5BB865ECE + 28: C29C5223D89A6589DE9253AF050D3449 + 29: 16B935ACC3EC6C016CA1BBF727C272B9 + 30: 644C01B157A24584B02A32119A424C01 + 31: 4A3C6C73634759420C419426F7D43E67 + 32: 7BD627A6B82FF3D797FFF130D8956391 + 33: 811A69D6A8AFE3C4FE5B4EFD73804F6E + 34: 721BE5F4BDDED885BFF842868F62F4ED + 35: 76956871B22D5BECAD3E9A459B4A448B + 36: 4F2CF372771A13B4C0C1A589F0EDCF87 + 37: 084AFBAE8D22DF83CC760A61138E560A + 38: E1CA123EBA05CC4899731A593833F372 + 39: 9D9E277FA61993C018C1C61AE09588BC + 40: 85E0D0316F0B76578948810039EDE2BA + 41: 27736345D0F2B0A1A9576D17C47D0202 + 42: DC9F788BE7C97BB5E0D2DD49B9F1D2DC + 43: 27F1A9A0D166C495493877DF06E9C104 + 44: D1ACA7951866F58773CD4AFA3D2F5C2E + 45: 5204BE3729BD7D318EA8127BED82D5CC + 46: 10258B7939D81F5F8E0EA70EE6500B08 + 47: 4E699952169098ED3084DC2EEE7BC488 + 48: DF6ED8D604512088FCEAFB21808BF7D0 + 49: 904D0667C94C9C981D59BE80DEEEE628 + 50: D83483A47B64D74F9DED5278EE462404 + 51: 490EC8799A9DE3BDE8708DAF68E6888E + 52: 443E4D2D5F800C22D818927A29A38490 + 53: 48E82AA772E111FCBE393177F3123963 + 54: B72685D042162D5F30472281278C42F7 + 55: CC8A7F2BD608E3EEECB7F121D13BEA55 + 56: B8E94B6408BBFA6EC9805BF21BC05CBD + 57: 6AEC85410412FF54078A9FC72A55ACE5 + 58: 3E69F792BE88478883E46E867F3C93EB + 59: 3B057FC41BA700F0E46740B8FF391F52 + 60: 3E3C6DF9500BFF8404486A3AEFC6F16D + 61: F5AD65BA970ACBBB8335F9C0B9D7139F + 62: 75D45F8E48406E32ABF94D07FF9B9C84 + 63: 54BA4472FCD03E99CF28F90EED9F2AE0 + 64: 2DE6578F0E7898FA17ACD84B79685D3A + 65: 3A4F2CA37EEBDF6DC99A6155517B74FC + 66: E19DC463C01E1B712B9415202A2B5505 + 67: 61D8AA0838DEAEEADE2F26156AF58761 + 68: BE294AFF81BFEA3159564B8B61844EFE + 69: BB943319320EE7B3A029D7BCD101F92F + 70: 36239791A7BE33AD46F668B51D724481 + 71: 21DCC9A32031428B7B02F68E1450A0F3 + 72: 95C1B0832575E21982B17CCCCAF54556 + 73: 24939E25985A3B5620B19D7889E5E153 + 74: 3029C8B005386705FE7E4CBAA060E987 + 75: E8BD97C5C1A0CC9AD1F1BEB3913B22FF + 76: 808EBCA0B0E6FD1B30E4BA499C05EF9B + 77: 55BD20AB87DE2E536DDE22286D0922D9 + 78: 2B2E45FA5628F29DA06462378D17DD12 + 79: B90F1709241EF59F78666AEBB3D5607C + 80: 37854275343F079BCE1639C84D74AE1C + 81: 444AB5A4F39B765C5D67BB433D4CF0B1 + 82: 7E30CFA6363F9AC96607783710E151B9 + 83: 9D9252DFFB2D5023CFE34873EA6C43AE + 84: 49A70634AFCED27DC2DF2EB079F7A1E6 + 85: 4C976C9EF13716CCB468D82BD8C56FE2 + 86: 4EB382D16DDC18C31E6DBAC6CA83247D + 87: B16112D0FF3C6A8ADB19C13DF742F5D1 + 88: F703DC6100AE23D194E01EAC433CF28B + 89: A6527B1B907218063BF196AA91C73F47 + 90: 61F1A1E947F3F542FCF85AC758BA5D14 + 91: 12ADDEDCE418E9444AE34A40353ED0EB + 92: D1C35142C475D44A52CEB0A8FAEA7AAB + 93: 1F89912C1FC59AAB53C983B035661269 + 94: 2E7E19A4A6635AB5958DDA70B415EB06 + 95: B700B6739C0AF162D246AF07284A1AE8 + 96: E2B95AC9F876A38D33CCBBD7FA92D67E + 97: AEB4849953750A10BB236BAC8D5AB487 + 98: 82D738AF18FD4B26FFF61377EE921E62 + 99: 0E1451640E59CE0461A46934F174E237 +100: AE06EA64074E8C07116563E8E0893BDC +101: 562DCEB678FBFAB24141E591FFD471B1 +102: 7DD6C3C2884E483E8CA572C471B2D812 +103: 2A4C8E4EC2672C1D54A8DA8F32F04783 +104: 2BFED22E8810A4658060B95B0ADB60BC +105: 214D8F2DD099BAB68EC17189BFF8A8EF +106: 98E4EB29797C8E631CD4317AF422FB05 +107: 241A0F826F359A21CA0E6D9154D1E291 +108: A3398C0118A3605E7A7794B8DF7CA152 +109: 5B0A6FC8721F14EB8A03E9A5D87F173B +110: D93ABEC3EBD5672350C3C36F8FB00E53 +111: 659905751D1F614A78ECBB56D4398D06 +112: 594691B38126E028352DA5B28ADFD416 +113: 7533FBD1FD58C85D54A712EF218A9D53 +114: 654796E7D2F9F2C2D166F23B5AB18812 +115: 5D25B604FB75727AE7EBFF980F54D96A +116: 426A7709CD61EB6ECF4034EC83E073EC +117: 62E21CA2F8E39C03BFF56C8265ACB60A +118: B7C9DAAA89A29F2805DEDE790DCB9575 +119: 9C1067170940CE8F8E4745D362675FAB +120: C5BB35660E3D0A286A96EA3AA4922B3C +121: 8F3B6351623A0E482B57525474DC703A +122: CCC34CC280340681CA5117477DD86AE8 +123: 2F5FB6B41301F87A0490035DE4C1BB99 +124: A16E28DB3F331091E928F9AE3F1ACEB6 +125: 7D2259C98085B9BF7F5E36B29DF8384A +126: BDDA1266FF3E8FFBA1DE1B2759B58BCC +127: 2067886DA4BDE10A94B971CD740B0AAB +128: E1275970EB67D2D996E6E658270AA149 + +Hash: md5 + 0: D41D8CD98F00B204E9800998ECF8427E + 1: 93B885ADFE0DA089CDF634904FD59F71 + 2: 441077CC9E57554DD476BDFB8B8B8102 + 3: B95F67F61EBB03619622D798F45FC2D3 + 4: 37B59AFD592725F9305E484A5D7F5168 + 5: D05374DC381D9B52806446A71C8E79B1 + 6: D15AE53931880FD7B724DD7888B4B4ED + 7: 9AA461E1ECA4086F9230AA49C90B0C61 + 8: 3677509751CCF61539174D2B9635A7BF + 9: A6E7D3B46FDFAF0BDE2A1F832A00D2DE + 10: C56BD5480F6E5413CB62A0AD9666613A + 11: 5B86FA8AD8F4357EA417214182177BE8 + 12: 50A73D7013E9803E3B20888F8FCAFB15 + 13: B20D4797E23EEA3EA5778970D2E226F3 + 14: AA541E601B7B9DDD0504D19866350D4E + 15: 58B7CE493AC99C66058538DACB1E3C94 + 16: 1AC1EF01E96CAF1BE0D329331A4FC2A8 + 17: 1BDD36B0A024C90DB383512607293692 + 18: 633AB81AEA5942052B794524E1A28477 + 19: 2D325313EB5DF436C078435FA0F5EFF1 + 20: 1549D1AAE20214E065AB4B76AAAC89A8 + 21: 7E437C81824D3982E70C88B5DA8EA94B + 22: 2F5F7E7216832AE19C353023618A35A8 + 23: 6535E52506C27EAA1033891FF4F3A74E + 24: 8BD9C8EFBBAC58748951CA5A45CFD386 + 25: D983C63BF41853056787FE1BB764DBFF + 26: B4F24C1219FB00D081C4020C56263451 + 27: B0AE6708C5E1BE10668F57D3916CF423 + 28: BA7BB5AD4DBA5BDE028703007969CB25 + 29: EA880E16EAC1B1488AFF8A25D11D6271 + 30: C7172F0903C4919EB232F18AB7A30C42 + 31: E9E77893BA926E732F483282F416FFAC + 32: B4FFCB23737CEC315A4A4D1AA2A620CE + 33: 5506A276A0A9ACC3093F9169C73CF8C5 + 34: E5A849897D9CC0B25B286C1F0BFB50E3 + 35: F54FA30EA7B26D3E11C54D3C8451BCF0 + 36: 07602FE0229E486957081A49E3F06F83 + 37: 7C4BBA98253CA834BF9ED43FD8B2F959 + 38: CF8DF427548BBFDB1E11143FDF008B85 + 39: 1431A6895A8F435755395F9BA83E76BF + 40: 30DD5E4CAE35BA892CC66D7736723980 + 41: 8EE247A1063931BEDAF4C2FA3E4E261A + 42: C32CEEE2D2245DF8589F94FCDA0C9F2C + 43: F25FA0E071D1F1CDC6632C6B673BCCD5 + 44: 370491B643E97577F4F74BD88576D1EC + 45: B292BF16E3AAFAF41F19C921068214F8 + 46: 52921AAE5CCC9B6E8E45853419D0C80F + 47: F1375BE31969155EF76F04741CD861D7 + 48: 04605CA542B2D82B9886A4B4B9ACFB1C + 49: FA887BA0FA491FAAACBB82BC5FEFCD5B + 50: 06470E932AD7C7CEDF548B5CCB9D4806 + 51: AD130B245E2DD894267CB0DDC532D169 + 52: A9EEB95053682248608E97D79E89CA82 + 53: CC26A3DC608268B98ECD1F3946C4B718 + 54: 33DD62A2DF6538DAF1CF821D9CDE61F9 + 55: 6912EE65FFF2D9F9CE2508CDDF8BCDA0 + 56: 51FDD1ACDA72405DFDFA03FCB85896D7 + 57: 5320EF4C17EF34A0CF2DB763338D25EB + 58: 9F4F41B5CDE885F94CFC0E06E78F929D + 59: E39965BC00ECACD90FD875F77EFF499A + 60: 63ED72093AE09E2C8553EE069E63D702 + 61: 0D08FC14AC5BAA37792377355DBAD0AE + 62: F3CDFFE2E160A061754A06DAFCFD688B + 63: 48A6295221902E8E0938F773A7185E72 + 64: B2D3F56BC197FD985D5965079B5E7148 + 65: 8BD7053801C768420FAF816FADBA971C + 66: E58B3261A467F02BA51B215C013DF4C3 + 67: 73062234B55754C3383480D5EF70DCE5 + 68: F752EBD79A813EF27C35BED69E2EE69F + 69: 10907846EB89EF5DC5D4935A09DAD0E7 + 70: 5F1F5F64B84400FB9AD6D8ECD9C142A0 + 71: 3157D7BB98A202B50CF0C437AA216C39 + 72: 70E7ADE70281B0AFCB1D4ED13EFC2E25 + 73: 0BB96A503B1626C9AB16C1291C663E75 + 74: 5BED4126B3C973F685FCF92A738D4DAB + 75: 7523C240F2A44E86DD22504CA49F098D + 76: 6710949ED8AE17C44FB77496BEDCB2AB + 77: 4A4C43373B9E40035E6E40CBA227CE0B + 78: 91977CBCC32CDEAEC7A0FA24BB948D6A + 79: A6A0F1373CF3DBEE116DF2738D6F544D + 80: 761F6D007F6E5C64C8D161A5CED4E0AA + 81: D44EA4D5A7074B88883A82F2B4CFBE67 + 82: 3097EDA5666E2B2723E8949FCFF2F244 + 83: AB247A3D9BC600F594D5A6C50B80583F + 84: B229430E3DB2DFDD13AA1DA1BAC14D5C + 85: BEFEF62987C6DCDF24FEBD0BB7CD3678 + 86: BFC3E5C7C461500FF085A66548378E0E + 87: A5712194537C75F0DD5A5AB3E9EBAF03 + 88: 8DAAC097E9044B85B75999D6C3BCCD24 + 89: B8124DF21129685597C53A3F606FFD28 + 90: 8FBC4D795C22D958248582A8DF7332ED + 91: 36D217135DB136B2BDF1617D7E9C79CE + 92: 1B3E6271A3A4B663C509A1255027CA99 + 93: A25F596574031FF9C34314C1B1F6BF34 + 94: ACA7017E5BB62BFDD5BBFDED78C8987A + 95: 8129E53A694ADD0560B1534B32FE5912 + 96: DA0E48224106C7535A4CD8DB2AC7B8E3 + 97: CBD4ACE3D766D8E44F63E0DE8F110F04 + 98: BDC17A0EF2777512CB402C90E9D13E31 + 99: 47695AD6AF968D6F1CDD2D8C5C87A466 +100: 7ACEDD1A84A4CFCB6E7A16003242945E +101: 225489D3D073AC705F7B3AD358EABAB2 +102: 301DA87A7B2EC27514C3A2789D5DBE49 +103: 16222C503718F1420958133C330FE3F8 +104: D778CE7F642AA23355948477DA4CC11C +105: E873C37F8977E200A594B815E1A87EF3 +106: E8F8F41528D4F855D8FDF4055BBABE2F +107: CACF3D3D1E7D21C97D265F64D9864B75 +108: 6BF48F161EFF9F7005BD6667F30A5C27 +109: 42E7BB8E780B3B26616ECBCACE81FA1A +110: 225AFD8EC21F86F66211ADF54AFC2E86 +111: 4FAD3AB7D8546851EC1BB63EA7E6F5A8 +112: D1FEC2AC3715E791CA5F489F300381B3 +113: F62807C995735B44699BB8179100CE87 +114: 54050B090344E3284F390806FF716371 +115: 50482241280543B88F7AF3FC13D65C65 +116: 4C36F27D4786FE2FB8CAAC690B6D62F7 +117: 5A0EDF0B97977EE5AFB3D185B64FB610 +118: 4541055C6675B614D27C537C3BB15675 +119: 1C772251899A7FF007400B888D6B2042 +120: B7BA1EFC6022E9ED272F00B8831E26E6 +121: B0B2D719A838DB877B6D6571A39A1CDC +122: 800AA956EC16F603ECDBA66C2DC6E4CF +123: 8827D2778287C58A242ACD4C549BEB31 +124: CFBC5AA0B61103C1A982D8927B26F575 +125: A1F5B691F74F566A2BE1765731084F8A +126: 80749BE03F5724FA4CA0AEF8909379B7 +127: 8402B21E7BC7906493BAE0DAC017F1F9 +128: 37EFF01866BA3F538421B30B7CBEFCAC + +Hash: sha1 + 0: DA39A3EE5E6B4B0D3255BFEF95601890AFD80709 + 1: 5BA93C9DB0CFF93F52B521D7420E43F6EDA2784F + 2: 3F29546453678B855931C174A97D6C0894B8F546 + 3: 0C7A623FD2BBC05B06423BE359E4021D36E721AD + 4: A02A05B025B928C039CF1AE7E8EE04E7C190C0DB + 5: 1CF251472D59F8FADEB3AB258E90999D8491BE19 + 6: 868460D98D09D8BBB93D7B6CDD15CC7FBEC676B9 + 7: 6DC86F11B8CDBE879BF8BA3832499C2F93C729BA + 8: 67423EBFA8454F19AC6F4686D6C0DC731A3DDD6B + 9: 63BF60C7105A07A2B125BBF89E61ABDABC6978C2 + 10: 494179714A6CD627239DFEDEDF2DE9EF994CAF03 + 11: 2C7E7C384F7829694282B1E3A6216DEF8082D055 + 12: CFF9611CB9AA422A16D9BEEE3A75319CE5395912 + 13: E51F9799C4A21BBA255CF473BAF95A89E1B86180 + 14: F741644BA6E1BCF5FEE6D3C1B6177B78468ECE99 + 15: FB1D9241F67827CE6DD7AC55F1E3C4E4F50CAA03 + 16: 56178B86A57FAC22899A9964185C2CC96E7DA589 + 17: 0A0315EC7B1E22A79FC862EDF79BDA2FC01669E3 + 18: 32AF8A619C2566222BB0BA0689DABCC480C381D5 + 19: D35B5AFBC48A696897C084E6E71AAE67C7CD9417 + 20: 602C63D2F3D13CA3206CDF204CDE24E7D8F4266C + 21: A3C6FBE5C13E8B41FADC204C0CF26F3F214189F4 + 22: 25E480E9E0CA2B610105CD1424B8A35F63FB3981 + 23: 45412D51D3CA7BCF452D1612720EE88F9D2427C3 + 24: ED6A95036E3E046931597A457DB7A78B7309C4C0 + 25: B4FE0256D346700783420E08A4A6F7992B1E36C9 + 26: 33E1799E98280E5A9ACE5509477A2048607C5537 + 27: CF193837F6DE43F8E38000ACFCF764FA8D8FDE22 + 28: 7C8DE247DDA83599AF2EC2EE2D29E20583DAC34B + 29: F38A076F70613FC251C4D21E6435AD08341A8A99 + 30: DCD68E6174BD74BA180DA047A7345E8D111F85FD + 31: 43BBACB5F62A0482CBDB564171B04365CA6E27C0 + 32: AE5BD8EFEA5322C4D9986D06680A781392F9A642 + 33: EB90BCE364635C4C23B49F493F0043579BC85C17 + 34: 2942C7AFA65444C43D0592D0DC73CA71DB729205 + 35: ABF726F5FDA729FB7F3F0484D7C94B3107AA02AE + 36: 75DB4F6BCC05A781DDA9D17C46717286DD53654B + 37: A82CB42D89DAF5FBC1D4A48476229C495782F98D + 38: FC1A69683744AF823CD69E8A1E3F460591714028 + 39: DC68DB44B48521B0700A864896A00E17777AEA83 + 40: CC9AD99E917042381B0F99588896CBF236AA8ED3 + 41: EC7A68484A749C7065C6B746F9C465DCB414F370 + 42: C627C449DEFF14AE7ED807293D30846F061DA5B8 + 43: 4782F2A19B6DBB0882D656DE86C3D21A7317F768 + 44: 02D4EED99E7307BEA39AF5330BF7FB388D48B496 + 45: B3D99B9D90A69E50FD4365704F5AB2EAB7BC9763 + 46: 9B1C07176BB227F73E8A4E173071D39302061DE2 + 47: D79097DDAC552A6E02A52CE7AAF494D2D73B2557 + 48: DF7F23B160E75B9BAE5EA1E62B43A5A34A260127 + 49: F598F3780D8C374D97957B9B62D56106E9E0B2D2 + 50: 0BD98598F9AB29C1359EF5460A206DD1370515E3 + 51: E6C320834F69D81689E1ECD5ABC808D49D9C4E07 + 52: FD5EE7588CD129E12B886974621FD29FACC78E19 + 53: 2A9C28EF61EB536D3BBDA64AD95A132554BE3D6B + 54: CFAE6D86A767B9C700B5081A54265FB2FE0F6FD9 + 55: 8AE2D46729CFE68FF927AF5EEC9C7D1B66D65AC2 + 56: 636E2EC698DAC903498E648BD2F3AF641D3C88CB + 57: 7CB1330F35244B57437539253304EA78A6B7C443 + 58: 2E780486F64BC91FBFA2785EC1CA5C9E3CC07939 + 59: 4A7713D44E97D9F09AE1D786199C58AE2BFAF3EB + 60: C98714B16F92C8A770E9FC229DF834D1688E282F + 61: AACE3DD6F54A2A255ABA920F5FFC8CF04B85A69A + 62: CF8563896A3B0A0775985D8289444C4BBC478DA7 + 63: 6D942DA0C4392B123528F2905C713A3CE28364BD + 64: C6138D514FFA2135BFCE0ED0B8FAC65669917EC7 + 65: 69BD728AD6E13CD76FF19751FDE427B00E395746 + 66: CE705B7C60D46E7E36FE073DB8822698579CA410 + 67: C717EBBF6A2BF1BB33DA6257352D5085BEE218B3 + 68: 86151D140AAFC9A4B5877D3FBB49014FE5906E57 + 69: 7446B5A6BBCC58BC9662451A0A747D7D031F9A7D + 70: C24887924F92ADAC5AE367995D12691C662B7362 + 71: 5AF83CFD42D61967778889CA911CFB6C14339BA7 + 72: 587D4F6E6B4E21343423E434679009CBD3D24DCF + 73: AC65DD946C5CC432D4D624CAEB53C7363F96B7AF + 74: FA71E70750674C0F6B4AA19D0BE717B2936C83FD + 75: C9EFE6DD0A019315F73F3962DE38B6C848A1705B + 76: D1D05649B952C8F6EB016BE08FE1544AAC5D5925 + 77: CC3081AC1D695BAE51CFD5B44B9FB3A230733CC3 + 78: EB9DE332558953792687D9A7F598B5D84BF0A46B + 79: 39DE5EFDC92E3D3678F24D2CF545BA4D172D003D + 80: 399DBC9F721E44A992A0DEF42D999B32AF449ADC + 81: 996A2817C8ACBC667E1C4C27B8F4E9952736DD7A + 82: 3EF8189CE1BCC0D65AA182B1A81534635EDFDF2B + 83: D676714C6A6FF4E17A60C0511C25AA8B164FA606 + 84: 4DB6E3381E1B9290267C1539E1053793C8B81FA1 + 85: 3A34D35B0296FE4D83EDA39B742A9D8F4B13A958 + 86: 54F3B45304EF1287F54B877FCCE3285E154F9D6C + 87: B1EA96216E025377AB5AA845238FC8BC65DD60E1 + 88: BC6C7488145485DEDE1AE1D43B594F0046BCDA0F + 89: 3D9A0619ECF88C84CE86213E9AA91D9A252CBC32 + 90: 92CCAA0B4CE89E2BD80A61B9BAFD5AC58AB7B588 + 91: 3EB326B5BF4440FB3A88E3DCB05C1DB5EA01AC5C + 92: 989C63E819B13D4CADFB33F8DEAFBC57C1992A12 + 93: AE944552C20CF16F07A5C357713832C9D72D0C6B + 94: 46723E982569A1E2D9EDCED5498FC1F46F7D63FC + 95: 3BC5DAE7907C83A0693F87FD8372EFDD1DF53E09 + 96: 96D281BA44EB21ECFB1663C8AC5752C48686A927 + 97: FA0EF18178880A72B51C26555C10F5210DAB4390 + 98: 0C7ECAC32B8ED6D9835D381BF069568722A276E1 + 99: 649E44ECBA85C0938EC09229CEE4BB69388EC642 +100: 1E6634BFAEBC0348298105923D0F26E47AA33FF5 +101: AF2AF2734BB2BAA288940CB62109F4849DAA347F +102: 22D14BC045CC9A3794C99BEEE7ABE278BF24D6D8 +103: C3164CCBED75B82ED3F59F4A47FE09B256025549 +104: C27B5BC7CD24DE4913614A769A442E9CC9FB0E08 +105: F44D48D98CAC77522FF6B9E1B9CBB8489E58E588 +106: EA19A71FFBEC9572F6CD65523ACAF865EC05AB52 +107: CDA0EB9D310247BD1E8B3EA10D9B9DEFF6FBABA9 +108: 449DFCE971B9D65D69FBC72940E9A885E8DDE9CE +109: 96EEBB6B95A9DA99C58190CBD77CD6FBCF638A79 +110: 670F7A869E90CE86E0A18232A9D4B1F97C1C77D0 +111: BC544E24573D592290FDAFF8ECF3F7F2B00CD483 +112: E4CE142D09A84A8645338DD6535CBFAAF800D320 +113: 1C26461E26EB697CCC36A98714EE70CAAA87A84E +114: 51C5B1C25A71FF00394A84AB48B5733C8955551E +115: 84803504181C0AE33A511C49AF5015A5B1892BFD +116: 7CC8BCA120C2635ABFEA82DD203112B5C7E165DA +117: 44E2519A529D7261F1BEBEDC8ED95E1182CAE0DC +118: 2A81372DA39C1DF4251539A9922717B7CF5F0334 +119: 41C89D06001BAB4AB78736B44EFE7CE18CE6AE08 +120: D3DBD653BD8597B7475321B60A36891278E6A04A +121: 3723F8AB857804F89F80970E9FC88CF8F890ADC2 +122: D031C9FB7AF0A461241E539E10DB62ED28F7033B +123: E0B550438E794B65D89B9EE5C8F836AE737DECF0 +124: FB3998281C31D1A8EEA2EA737AFFD0B4D6AB6AC2 +125: 7A914D8B86A534581AA71EC61912BA3F5B478698 +126: A271F71547442DEA7B2EDF65CD5FBD5C751710AA +127: 89D7312A903F65CD2B3E34A975E55DBEA9033353 +128: E6434BC401F98603D7EDA504790C98C67385D535 + +Hash: sha224 + 0: D14A028C2A3A2BC9476102BB288234C415A2B01F828EA62AC5B3E42F + 1: FFF9292B4201617BDC4D3053FCE02734166A683D7D858A7F5F59B073 + 2: 00AC60F30E9BD1956F914C8E5125B69DCC31A179734E6A85B3F702BA + 3: E615202185AABE2ACA924BEC29E5A12384F8339EAE4E64C9CBA9F1DA + 4: D70DA0705EAE42A5C596D92F331DDA2421B4E14F8B3035FB73B8B700 + 5: 98029CB458A39A16355963922D32DACD9439F90E9FD106D42A0D123C + 6: 7D92E7F1CAD1818ED1D13AB41F04EBABFE1FEF6BB4CBEEBAC34C29BC + 7: DDD5BABB1B05D8BCCD644ADC393A9E2303C850DA31922C4DA07574F9 + 8: 4C07070802E21052FB0295AC0571CAEDF219143ADAE0627E2850EDAA + 9: 5D3CA3BFE738D33F841069ADF6DD79B987351CE580ACA23326B3A7E7 + 10: 6B5373C535A4FA5D56D6C4953575CE64968031BB019B909F8F2DB904 + 11: 767D0CDC11079BA8DCA276DF5C4B85507DE67DCE47EDA4CD9196D312 + 12: 02C513977B6242D2FAAC094CAE3C247C6E2745F8A71494A60535A2EA + 13: 1F39482310E2209C10A88C7FD7FC1FD567F36789808C37D30045A82B + 14: 55BA81EBA644183AB2460C234BB95ABDA898E980BA976584E2977231 + 15: 2522E2B35A835436C80A122E4676DE64690C81440D42DBDA40EF2151 + 16: 529D656A8BC413FEF58DA82E1BF0308DCFE0429DCD80687E69C94633 + 17: A153F81C68D9FFFD4DE0AB9111C2FA86E8EDCA9B294376083077A135 + 18: 1EC706AEB2227B263A105EDBE2562E0521C96420DA4558012327661B + 19: 4904ADADF19D088911EE0EFD20A9AB511F2786C8FD43F1E5E8BE2AC6 + 20: 6CE245C296289A32F661986FF1C80E893BBD35EB0B182EDC14AB3A7D + 21: 33831C459A43CBF8BEB6DD50039750F1EA3688A7EAEF68CB2F095E16 + 22: EB4BC2EA1F7146E8274A96E874585C401256FB921FFC7E935DDC7FFF + 23: 09A266C98019B6B2A4318FBEDBEA5481AF01F0AD2AD16F09991A3C3A + 24: 7AF2814CD6105473EE530F2B3DAE992ABB6C801428F33430501F09A6 + 25: C5BD6127243049C4D5E9E3B391E12BDA86DC7A9856910A757004486F + 26: FCA06DDE2DCD212E6C1C11BB22B18B4F5582202655DFB9B6C9960C57 + 27: 0851998120F8CE47482DA5B2EB21BADF73C9F145921EEFD33459D49F + 28: ED36A2092538C5D4769917953E7355A13072DDAD8A6E5E2AF1DE96F6 + 29: 2C4A89C05BFD09B7068BAFDA37B0314EFCE02AFAE1B2C25DCE337326 + 30: 1D552A4D06BB8A0827BFE8DA2B6EE56ADBD17CE4810908D572076F6E + 31: 997D180912E0655445B07259278AAAD424633F5FF6BD0AFECD4F15DA + 32: 71446EA93381BA091F94AFCDC5B938323290A1A027C22A75E88A04D0 + 33: F77087D6F4AE34E88C62597CEC06220F4C694D2E0EB704820035AE6A + 34: 64EE78B0A6C116380A4C16F24489C1E94A578E558453537A9819A2E6 + 35: F39C1C862FDC9AB4ACFA50FE283CB7595C608F8C521BB7898CF71D34 + 36: DB482A26C9488A963359D145914612E34B821CC6CDC11113B73BDE2F + 37: C7C45F3AA5EEDE664D6CCD510F628D4DC3C67F93973FE05B0163CA13 + 38: 7F230E3E597845DB9F8D61B44740968FF55F2DF28CA538A68927F130 + 39: EA52362A9C66B6A5FF3B642FCFEBBF54F793B088D29E6840D7A5CF56 + 40: 84B064EF9C13F1ED54AD0B8FC0CC28F9BCE5009500E1CD92CA2BAE04 + 41: A2702281BD63CA745553CB18693DD70AC9A70CD73C01783727707C97 + 42: 89231FCFFC7022DF20B1846285FAACE44AFCC677685DA55EE02D94EA + 43: 4C5B01C50907D097DDBF0923B885A26B58DFF5761C1AEDFB8D5353F5 + 44: 84E0CF33A7E1C0EAA46F37E99CE5C8B292E81AD61318796D1A9A90C3 + 45: 27E59A0B6E7B9125D4CAA658810AE5054CE40A9A0A0FFE6E36435EBC + 46: C7F21E2B4C89B2A6E64D92F93FC4146EB5886503C1231EE6924B4E13 + 47: 653CAFF50E077A855992990F0C5F89C75FA18D1CC147F685AF2EA993 + 48: 6A7BDEA7E456D5339B7D9C244E246AD65B18BA95E0518E201AAA7889 + 49: 837ADE7F298F8159E6E2408751B0C480648CB6FD6D26C551983F3176 + 50: BEEF3F6AC40A9DED345BE41242BB2CF924B457A45CACC68379B1DC4A + 51: 6D2908EB3B6C8952346E0B65B9406D949B5A340123DB83B151DF5F81 + 52: 9E75A1D6B4A4D1A9F5AA6F8A48AFD6F3FD360D2D8723B53DBB63208E + 53: 436E3BFE94A39359CDF47D35395D34C0435018C88B4E96E68C22645A + 54: C209DF2E99E03D679FBA9E14AAF958AC1B0A22076BB3B532A0D7F092 + 55: 8991DFBA74284E04DC7581C7C3E4068FF6CB7A63733361429834BB56 + 56: 2B2CD637C16AD7290BB067AD7D8FD04E204FA43A84366AFC7130F4EF + 57: E87F5BC938C3B981C197D4B163C635A5049FAC81C4C6467E1251BE48 + 58: FD9BDAF5CC288A603D1623651D5BA3B8801D1602B0B9221C0B48435D + 59: 87F207D9D870EDD7DA61753473A51FC386E2792A3861F949BEA05CFE + 60: C9EFF79F4412CE49296C082DC777118F92C9AC4136D4EB32621E942C + 61: DDBC76D25D9819693F3597D6F09044F8D6CCBD12F081156F1090AF7D + 62: 6411AD13AA3654302BAC8E2BFD1CE76F37E3B3394014BBE260062CFC + 63: 049E8DD7EAB3378CE9F823BFB569E5B270235D4B7F9623606971998F + 64: C37B88A3522DBF7AC30D1C68EA397AC11D4773571AED01DDAB73531E + 65: 114B5FD665736A96585C5D5837D35250AED73C725252CBF7F8B121F6 + 66: 7D9B844CAAC9EC93AE2159ED3D336C55396216DAC6AC5DC5DECC11C9 + 67: E1C799109DEEA117F68DD1826B38B514E1D265F11A8B60B24630FF8E + 68: 029A0D024B6C0B63E1586F3D34111727E37D49CA12E7F520FA91A926 + 69: 2EA94F04A72C770A98E2A495D886EE674B7D0FB987B7B5C2217A8773 + 70: FAF445688FFCA34ED783F948B8F74578503D4845836CAF69DBD5EB51 + 71: 91EC59AC7C98F9DFB869E11C80027F8A4D311324597E6FC6135224D3 + 72: 190DFC9C7BDD954E415E543F99B00B5110ED6A12182BFFDCAA77D8B9 + 73: 8C3AA805FA75625476F3267C211B1DDA52E1810B058EF804E34BEE58 + 74: BFD0E517E4A340A4E0EF1AC306EE2C6DD1288C77531EF0FD5ACB73FA + 75: C621A18D7E09976296CBC39761B020E7E346042FC735FDF106148F3F + 76: 27EE5F7E3FE49EAEC0AE0A93FD971EDF0304A4C0513BCF43424C95A2 + 77: BD9D42F293DA572219F08D4A38081D203E44F612EEDEF93CE0DAF6D4 + 78: 374CFB6FB12768717EFED2681718C11B22588C429DB9C71AFB5EB562 + 79: 1CFB1037FC3943559E9F913183DB71392CD4BC68CDFD47D7DEC9C9AD + 80: 2537E015D5945E0541BC48320AE4DFF7FEAB911227AE0D579DA1CD05 + 81: 012B34E1A530B6889E87863A59645EE4FFEB292A33815D2CE11918EA + 82: 5242DD4DFEE389E668D8FF78DA9B2D85AAE12D0C220E8D1BADBBA845 + 83: 4813D70E1D6BB6232CD9257B5132FDBA05E1A4A858E237C303CFA052 + 84: 0530BBA43AE6393655F21F7EEA67F8E8E819BA225AED78CA8BDE075F + 85: 4F7EAF4A9D0000B0E957DFE46DB304EBB2664A32AF4142EC74BE18D8 + 86: 68CF23B9DC4DC3430835B484648CBF126940AF6BAE51431A66D7F0E6 + 87: A093D2119C7076259F194F107077061C61C792DC5326C3A4D3A63BA6 + 88: F4E883F7FD12ACD36E3891986E4D7FF03F3E150F09CD4FB58A023A04 + 89: 0816862C59CE35E0D78834A221D3BABE21987FDAA81F20ED61D9DA84 + 90: F415933677BB364C589722E30B958F2BEF8670A10F1F5082F79FDB4F + 91: E40C5632490BB8DAD2283B6DBDCA870F4B5AB4271C61127DE999BDF0 + 92: B2D4E6CD7AFC35A475620EA1446B9024D767890B8593AB50275F370D + 93: 948616FD7828F09E8A57F986589948085D18EC3550E0ADA8E0127665 + 94: 2B115E930333A355A82F074EF261DE6BB2942D9DD64F98BA12D92DDE + 95: 6EEAB864B5AD618CDB1AE79C7B1DE31020966A02350AEF71088E6876 + 96: 676AD81F213E037F3C9BA2310F49DDDA4D6476C28A8EFC0046D3F55C + 97: 03A28C9068BC10A6FD87A1E53F00415F8CE994C968DD9CFF60D6B0A2 + 98: 01D91D084F400C591EDD750B66EC2482C834CE0E140A37E6E142CFEC + 99: BCAD899E7C771764CB91FF60AD79BFD629F4803A05FCBCC24E8F3E79 +100: 6E08215B5470DDEB67E44A494E52E259A9C2C4FBED4AF5DC6DB3E92A +101: E5C45BED6F8BFC487FF7190B108AF5C5B66F6D55D365B5A1BA156914 +102: 0DB55D83B38D42D229CA42D001B09758B5F3F032109F2F999C553655 +103: AD4DF1AF973A2747568A1B8DEF15E34A350A93F45BA84596580D11F0 +104: D4905849C8C4EA32159A431B52BAAC092F90037093E200A0C46611F9 +105: A936D0AA091B827BAD86644C94603068AB34A5B59E29D1E3BAB13039 +106: 46D214E9FA8C877C2791CC8E6716868713CB5B677CC4D838242C9B18 +107: AE8D3EB227AA3558101D5E5A2BF6C862C9F7297A31A3DF24E4502257 +108: 4462C366B10326D4FEF46E71930BCF93713F7D45FAC9963520FF5FE8 +109: 05EFC35781E413ECBCC763AE13D5A37C159CE5CCEE6EAA1CFF7CA516 +110: CDDBA09D7FE081E7A39C4017B3EDF7A9138D1CB857559BA9AD2C939E +111: 1AEEF583C448A9AE00FBC931B50BC0DA5BB8323E616B11076CEE8B44 +112: 01E5ABF50619B5C2078E754EDDEDCF4DE8D31185A2219313CB91A8C9 +113: B7FF114CA77757CAD67801E6761AF20F4CBB8328AEF290F77EB612C3 +114: 08F43DF4547732424AC7D0390AD8AB3D4978826462446D13B2B468D6 +115: AC3799ED09E3BD9E770FD3A0073E371FE9A3D4E3D464C3A7023CC72D +116: 795F160C275FF6B575031D4053BA1D1C32744D09F005B3BF10BDD1F7 +117: D2EFD4AC8ABA33151D0399E2893769A6D8BBFBA7B128388BFA65B841 +118: F85910F64FEE2B8F91DEC8064F75CB97E1FFC895AEE912DD3945F839 +119: 762F18C0DF65C3D0EA64126C8A6E51DB4425E76D4D969ED0F83899BE +120: D022DEB78772A77E8B91D68F90CA1F636E8FE047AE219434CED18EEF +121: A802D8B618A503352CDBCC1FBEF04EA36499EA72D0E32D314CAF83E5 +122: 6DE1088DD95C9535849294A8635A44084BA36E4EEF81C6D67B98CE90 +123: 6AA11591302A30EFACF874F40AA017F8545D3D9EA68D479965AC0B3E +124: 3288A475A4817D2E42830C709C1DC18A4BBD59DBD903B43CA702F275 +125: CCEEE7F6EFA60B2F2CE1090FB929D6068F7EE301E7A84072FD163F7E +126: A45B0FCFAC3F05279B7E8278AED93E37B225E6A997664F92C7555447 +127: 554C9C3F7E92B80F4121E00CC147535D377EAEB4FB1FA8E25C7F81C1 +128: 67D88DA33FD632D8742424791DFACE672FF59D597FE38B3F2A998386 + +Hash: sha256 + 0: E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 + 1: 6E340B9CFFB37A989CA544E6BB780A2C78901D3FB33738768511A30617AFA01D + 2: B413F47D13EE2FE6C845B2EE141AF81DE858DF4EC549A58B7970BB96645BC8D2 + 3: AE4B3280E56E2FAF83F414A6E3DABE9D5FBE18976544C05FED121ACCB85B53FC + 4: 054EDEC1D0211F624FED0CBCA9D4F9400B0E491C43742AF2C5B0ABEBF0C990D8 + 5: 08BB5E5D6EAAC1049EDE0893D30ED022B1A4D9B5B48DB414871F51C9CB35283D + 6: 17E88DB187AFD62C16E5DEBF3E6527CD006BC012BC90B51A810CD80C2D511F43 + 7: 57355AC3303C148F11AEF7CB179456B9232CDE33A818DFDA2C2FCB9325749A6B + 8: 8A851FF82EE7048AD09EC3847F1DDF44944104D2CBD17EF4E3DB22C6785A0D45 + 9: F8348E0B1DF00833CBBBD08F07ABDECC10C0EFB78829D7828C62A7F36D0CC549 + 10: 1F825AA2F0020EF7CF91DFA30DA4668D791C5D4824FC8E41354B89EC05795AB3 + 11: 78A6273103D17C39A0B6126E226CEC70E33337F4BC6A38067401B54A33E78EAD + 12: FFF3A9BCDD37363D703C1C4F9512533686157868F0D4F16A0F02D0F1DA24F9A2 + 13: 86EBA947D50C2C01570FE1BB5CA552958DABBDBB59B0657F0F26E21FF011E5C7 + 14: AB107F1BD632D3C3F5C724A99D024F7FAA033F33C07696384B604BFE78AC352D + 15: 7071FC3188FDE7E7E500D4768F1784BEDE1A22E991648DCAB9DC3219ACFF1D4C + 16: BE45CB2605BF36BEBDE684841A28F0FD43C69850A3DCE5FEDBA69928EE3A8991 + 17: 3E5718FEA51A8F3F5BACA61C77AFAB473C1810F8B9DB330273B4011CE92C787E + 18: 7A096CC12702BCFA647EE070D4F3BA4C2D1D715B484B55B825D0EDBA6545803B + 19: 5F9A753613D87B8A17302373C4AEE56FAA310D3B24B6AE1862D673AA22E1790F + 20: E7AEBF577F60412F0312D442C70A1FA6148C090BF5BAB404CAEC29482AE779E8 + 21: 75AEE9DCC9FBE7DDC9394F5BC5D38D9F5AD361F0520F7CEAB59616E38F5950B5 + 22: 22CB4DF00CDDD6067AD5CFA2BBA9857F21A06843E1A6E39AD1A68CB9A45AB8B7 + 23: F6A954A68555187D88CD9A026940D15AB2A7E24C7517D21CEEB028E93C96F318 + 24: 1D64ADD2A6388367C9BC2D1F1B384B069A6EF382CDAAA89771DD103E28613A25 + 25: B729CE724D9A48D3884DBFCBEE1D3793D922B29FA9D639E7290AF4978263772B + 26: B858DA80D8A57DC546905FD147612EBDDD3C9188620405D058F9EE5AB1E6BC52 + 27: D78750726155A89C9131D0ECF2704B973B8710865BF9E831845DE4F2DCBC19DA + 28: DC27F8E8EE2D08A2BCCBB2DBD6C8E07FFBA194101FC3458C34DED55F72C0971A + 29: D09BEA65DFF48928A14B79741DE3274B646F55AC898B71A66FA3EAE2D9FACD77 + 30: F2192584B67DA35DFC26F743E5F53BB0376046F899DC6DABD5E7B541AE86C32F + 31: 4F23C2CA8C5C962E50CD31E221BFB6D0ADCA19111DCA8E0C62598FF146DD19C4 + 32: 630DCD2966C4336691125448BBB25B4FF412A49C732DB2C8ABC1B8581BD710DD + 33: 5D8FCFEFA9AEEB711FB8ED1E4B7D5C8A9BAFA46E8E76E68AA18ADCE5A10DF6AB + 34: 14CDBF171499F86BD18B262243D669067EFBDBB5431A48289CF02F2B5448B3D4 + 35: F12DD12340CB84E4D0D9958D62BE7C59BB8F7243A7420FD043177AC542A26AAA + 36: 5D7E2D9B1DCBC85E7C890036A2CF2F9FE7B66554F2DF08CEC6AA9C0A25C99C21 + 37: F4D285F47A1E4959A445EA6528E5DF3EFAB041FA15AAD94DB1E2600B3F395518 + 38: A2FD0E15D72C9D18F383E40016F9DDC706673C54252084285AAA47A812552577 + 39: 4ABA23AEA5E2A91B7807CF3026CDD10A1C38533CE55332683D4CCB88456E0703 + 40: 5FAA4EEC3611556812C2D74B437C8C49ADD3F910F10063D801441F7D75CD5E3B + 41: 753629A6117F5A25D338DFF10F4DD3D07E63EECC2EAF8EABE773F6399706FE67 + 42: 40A1ED73B46030C8D7E88682078C5AB1AE5A2E524E066E8C8743C484DE0E21E5 + 43: C033843682818C475E187D260D5E2EDF0469862DFA3BB0C116F6816A29EDBF60 + 44: 17619EC4250EF65F083E2314EF30AF796B6F1198D0FDDFBB0F272930BF9BB991 + 45: A8E960C769A9508D098451E3D74DD5A2AC6C861EB0341AE94E9FC273597278C9 + 46: 8EBFEB2E3A159E9F39AD7CC040E6678DADE70D4F59A67D529FA76AF301AB2946 + 47: EF8A7781A95C32FA02EBF511EDA3DC6E273BE59CB0F9E20A4F84D54F41427791 + 48: 4DBDC2B2B62CB00749785BC84202236DBC3777D74660611B8E58812F0CFDE6C3 + 49: 7509FE148E2C426ED16C990F22FE8116905C82C561756E723F63223ACE0E147E + 50: A622E13829E488422EE72A5FC92CB11D25C3D0F185A1384B8138DF5074C983BF + 51: 3309847CEE454B4F99DCFE8FDC5511A7BA168CE0B6E5684EF73F9030D009B8B5 + 52: C4C6540A15FC140A784056FE6D9E13566FB614ECB2D9AC0331E264C386442ACD + 53: 90962CC12AE9CDAE32D7C33C4B93194B11FAC835942EE41B98770C6141C66795 + 54: 675F28ACC0B90A72D1C3A570FE83AC565555DB358CF01826DC8EEFB2BF7CA0F3 + 55: 463EB28E72F82E0A96C0A4CC53690C571281131F672AA229E0D45AE59B598B59 + 56: DA2AE4D6B36748F2A318F23E7AB1DFDF45ACDC9D049BD80E59DE82A60895F562 + 57: 2FE741AF801CC238602AC0EC6A7B0C3A8A87C7FC7D7F02A3FE03D1C12EAC4D8F + 58: E03B18640C635B338A92B82CCE4FF072F9F1ABA9AC5261EE1340F592F35C0499 + 59: BD2DE8F5DD15C73F68DFD26A614080C2E323B2B51B1B5ED9D7933E535D223BDA + 60: 0DDDE28E40838EF6F9853E887F597D6ADB5F40EB35D5763C52E1E64D8BA3BFFF + 61: 4B5C2783C91CECCB7C839213BCBB6A902D7FE8C2EC866877A51F433EA17F3E85 + 62: C89DA82CBCD76DDF220E4E9091019B9866FFDA72BEE30DE1EFFE6C99701A2221 + 63: 29AF2686FD53374A36B0846694CC342177E428D1647515F078784D69CDB9E488 + 64: FDEAB9ACF3710362BD2658CDC9A29E8F9C757FCF9811603A8C447CD1D9151108 + 65: 4BFD2C8B6F1EEC7A2AFEB48B934EE4B2694182027E6D0FC075074F2FABB31781 + 66: B6DFD259F6E0D07DEB658A88148F8253F9BBBB74DDD6DB3EDBE159A56BC35073 + 67: 8FA5913B62847D42BB4B464E00A72C612D2AB0DF2AF0B9A96AF8D323FA509077 + 68: 7DED979C0153EBB9EF28A15A314D0B27B41C4F8EED700B54974B48EB3ECAF91C + 69: 1CF3AA651DCF35DBFE296E770AD7EBC4E00BCCCD0224DB296183DC952D0008C9 + 70: 5767D69A906D4860DB9079EB7E90AB4A543E5CB032FCE846554AEF6CEB600E1D + 71: 8189E3D54767D51E8D1942659A9E2905F9EC3AE72860C16A66E75B8CC9BD2087 + 72: 107DE2BC788E11029F7851F8E1B0B5AFB4E34379C709FC840689EBD3D1F51B5B + 73: 169F6F093A9BE82FEBE1A6A4471425697EC25D5040B472C5B1822AEEA2625988 + 74: 2087EBD358AE3EA2A092FC19C2DFEE57C5F0860296BC7B057C14E1227C5CB9D1 + 75: 182AB56F7739E43CEE0B9BA1E92C4B2A81B088705516A5243910159744F21BE9 + 76: 081F6C68899A48A1BE455A55416104921D2FE4BDAE696F4B72F9D9626A47915E + 77: 5CE02376CC256861B78F87E34783814BA1AEC6D09AB500D579ED8EE95C8AFCC8 + 78: B93E407404E3E95F20FD647365E0E7F46AFABE9AF1FF083AF996135E00D54009 + 79: E81FA832B37BE8ED8F79DA29987AA4D61310DCB14B2859DEDF8FB1DAA2541FD3 + 80: C56705FEA5B110B8DC63688533CED21167E628017387C885423B835A55EDD5EF + 81: C2226285D08A245A17058ED2D24AD095B714F608AE364FDDF119E0A7DF890540 + 82: F9C270DA8793221A6809AC685FDD4F5387E0FE1EE6AAF01C74F1E0A719621614 + 83: E69BEFD6EF7F685C36E343AC1702D87AD6A0E4AC8C0D5C521D04AAD4EF0B7458 + 84: 4E3033562AD74A7D43EB5FF5FC2382622C6307CB10E245AD62DA77C4C63CB178 + 85: 2EA17629472564A59E5EB845A2CDD04F442DF2FF26BCC866E400F77158D612A1 + 86: B90223DF74DD49A8A1461F340F2D7A90F96903CCBB5BC3C74EA3658FC8948B20 + 87: E0209F42B927EC9C0F6D6A76007ED540E9BDD6E427B3368A1EA6C5E7565972DD + 88: 10D9BD424114319C0999ADF6288F74060CD8918EF1228827A6269B2BF0F0880C + 89: 7D1978A65AC94DBBCDC62E3D81850299FE157DD9B7BD9E01B170156210D2815A + 90: E052DFF9E1C94AAA49556F86FAD55029A4875839FDA57F5005F4C4403876B256 + 91: 58D29459B2130A2E151252D408B95E6DAC424C564062EB911CC76440CB926CA0 + 92: 4E4530C392316F598E1BD07F32166380A8F712A33A48E9EB4247131EC5DC05D3 + 93: A09C9D3E42342C7DEA44EDB4AEB48CF6727CACD8032A12CF77A25829FC249D32 + 94: EB978D0F1AC03CE5C3510B5F4A16073A7A2BDC15C4AB7777DCF01030CC316667 + 95: 7D1905A3ACE827EA1AC51C4FA08C281ED3BE87E7F4E928D696BFDE35C8F2DC0F + 96: 08359B108FA567F5DCF319FA3434DA6ABBC1D595F426372666447F09CC5A87DC + 97: A7B3830FFAB0F2BBABBEF6DF0B169A7917008BF238880BBF8C20B8E000077312 + 98: B4F5D9B1555994C5EBAEBD82918D560A3BF82962A171A1614E7551939E943366 + 99: 014ECAEA1B378900F1212898C6DDB01565D81AF1D0EF78DF5E28D46E9CAF7CFC +100: BCE0AFF19CF5AA6A7469A30D61D04E4376E4BBF6381052EE9E7F33925C954D52 +101: 4565D7B898CCEA3139AD260F9273115F806B30079D7683218C4E3ECD43AF3B33 +102: DDADEB660FE8902C9FB2DB9B6CF237C9CE5B31753398085C4367EB5910B9CC13 +103: C15A8928131F6687DD10F3C115DDF8D7C8F2DF7E18D12C08C4FD16F666CE60BA +104: AE8E3D799B1353A39815F90ECEEBEFA265CC448FE39FAF2008CB20784CB2DF9F +105: 98545371A3D9981ABE5AB4A32A1D7B2FADD9801D89DA52A94A4F78A42740D21C +106: 6323DCE2F8B3A04DCEA8D205602348C40403CB200C677EB1A1C0FE37EDB6EB2F +107: 8150F7C5DA910D709FF02DDF85DD293C6A2672633DE8CDA30F2E0AA58B14B0C4 +108: 44D21DB70716BD7644CB0D819FA6791805EBC526EA32996A60E41DC753FCFAFC +109: B9B7C375CCA45DB19466EBD0FE7C9E147948CC42C1C90F0579728CFB2651956D +110: A47A551B01E55AAAA015531A4FA26A666F1EBD4BA4573898DE712B8B5E0CA7E9 +111: 60780E9451BDC43CF4530FFC95CBB0C4EB24DAE2C39F55F334D679E076C08065 +112: 09373F127D34E61DBBAA8BC4499C87074F2DDB10E1B465F506D7D70A15011979 +113: 13AAA9B5FB739CDB0E2AF99D9AC0A409390ADC4D1CB9B41F1EF94F8552060E92 +114: 5B0A32F1219524F5D72B00BA1A1B1C09A05FF10C83BB7A86042E42988F2AFC06 +115: 32796A0A246EA67EB785EDA2E045192B9D6E40B9FE2047B21EF0CEE929039651 +116: DA9AB8930992A9F65ECCEC4C310882CAB428A708E6C899181046A8C73AF00855 +117: 9C94557382C966753C8CAB0957EAEDBE1D737B5FCB35C56C220DDD36F8A2D351 +118: D32AB00929CB935B79D44E74C5A745DB460FF794DEA3B79BE40C1CC5CF5388EF +119: DA18797ED7C3A777F0847F429724A2D8CD5138E6ED2895C3FA1A6D39D18F7EC6 +120: F52B23DB1FBB6DED89EF42A23CE0C8922C45F25C50B568A93BF1C075420BBB7C +121: 335A461692B30BBA1D647CC71604E88E676C90E4C22455D0B8C83F4BD7C8AC9B +122: 3D08C4D7BDDA7EC922B0741DF357DE46E7BD102F9AB7A5C67624AB58DA6D9D75 +123: CC63BE92E3A900CD067DA89473B61B40579B54EF54F8305C2FFCC893743792E9 +124: 865447FC4FAE01471F2FC973BFB448DE00217521EF02E3214D5177EA89C3EF31 +125: 3DAA582F9563601E290F3CD6D304BFF7E25A9EE42A34FFBAC5CF2BF40134E0D4 +126: 5DDA7CB7C2282A55676F8AD5C448092F4A9EBD65338B07ED224FCD7B6C73F5EF +127: 92CA0FA6651EE2F97B884B7246A562FA71250FEDEFE5EBF270D31C546BFEA976 +128: 471FB943AA23C511F6F72F8D1652D9C880CFA392AD80503120547703E56A2BE5 + +Hash: sha384 + 0: 38B060A751AC96384CD9327EB1B1E36A21FDB71114BE07434C0CC7BF63F6E1DA274EDEBFE76F65FBD51AD2F14898B95B + 1: BEC021B4F368E3069134E012C2B4307083D3A9BDD206E24E5F0D86E13D6636655933EC2B413465966817A9C208A11717 + 2: 5D13BB39A64C4EE16E0E8D2E1C13EC4731FF1AC69652C072D0CDC355EB9E0EC41B08AEF3DD6FE0541E9FA9E3DCC80F7B + 3: 4F895854C1A4FC5AA2E0456EAF8D0ECAA70C196BD901153861D76B8FA3CD95CEEA29EAB6A279F8B08437703CE0B4B91A + 4: 80AE432E757826025095CA1FA4F89C06C8BA6754B1D883A8E31A1E65FCFB820BD74ACFACA3D939A574EA408A74162D1D + 5: 561C16404A1B592406301780C0C2DF6AA0555F504F35BFBEAC810AE36A343B776858C5E0DE56BB79607A34D2F67108F2 + 6: 79F4738706FCE9650AC60266675C3CD07298B09923850D525604D040E6E448ADC7DC22780D7E1B95BFEAA86A678E4552 + 7: E6CE1896C9783A70AC4C90276CC37B37687D7E30C753975762F961AE37118D9A610242716E8359EFC4975AA98C632DCF + 8: CFB18F81F4BB672B03214F1FEDE456F882A0DE40120212A1FEBA8FDC48F763C86ACBBFB684D34B70F99F4D8D81FE3A28 + 9: D075AE1178210804635AC02C656309311527FC8190835C8AD8196577C3332AF4D87F056023F235DB893C69AA87B0CFB9 + 10: 182E95266ADFF49059E706C61483478FE0688150C8D08B95FAB5CFDE961F12D903AAF44104AF4CE72BA6A4BF20302B2E + 11: 89BFCF569AE4AF718510DA78C67414109F5739BB5C40D51C9C8C50E2B2CEE86F2F80C8B9D68F7C01201A0714572FE602 + 12: B635441A3721CF190B39D23703C5B77018FF1A56C94F8252EE95C217E3477F093E8EC65C6AE767179A7872C8DB9B2141 + 13: 48DEBF56626CC86DFA47AD6FDEC73FD182434621DA8BC6DB23AFF067BC36DC8244D3071B1F57DE4B716F63D9820DFB23 + 14: 58475B7CF93FECCB2C02B588F1552A359E7EE9AC45D9AE50B2D7C22021466677D70EF24EFA5C492515164458E9A24744 + 15: 0AA75534F0F58756A01E3366F78E7611BC7F432364C649C3F50547F7BCA3E5489531B8AB129495FEAC834FF0A0B45DB6 + 16: C81DF98D9E6DE9B858A1E6EBA0F1A3A399D98C441E67E1062601806485BB89125EFD54CC78DF5FBCEABC93CD7C7BA13B + 17: FDD3C4C0F87EEC0CADD73028A06B01E67696C7E04960936B30C73F004CF6B595D644533F8B473C8E63B02D593A64B041 + 18: 445E4CCA1A03480D149F38014C14D28DF8288F2C6CFF047F45D4F2580AE85EFFB3BE009C9D2ACC54B51467F83A09FBE2 + 19: 8305DC56172245B82AEDCE7F9C7DC88C0E62CBF835A2AA133EB579F415FFD15BABBC30BB98E55DFDA0F9E80275C92BC4 + 20: 8A48240E1C85E80651EDDC88599273444839A952CACA2BEF4400576E65B1EB6C19C47A3067B63AF7CDC4238ADB9A8DAD + 21: 8F2F7669C27A7CB1CF7A84A2C4F050D7141852D8B429291956B85E2DB5287741A3104E7E99CA5D23A5EEA59A68A4DDB1 + 22: 32CF04AE2A4A326FDE2FBB887F47FB7A2C486E56088D85B45F0C7587591F44797FE0A67E36F571809695E05F254884B2 + 23: 713A04A3A6BA8D2FD821F1CDF9FACAF42795E4247C9A26F0ADC5E0E6AACBAFFD8F4E02563733C6BDF1A863A787949B35 + 24: 35D8A5AA0DC9AB4C9A4C62B36E0E1013977C198B05CF6B92CEA25C08309DAFD282AA9A4862958593C06BA46919EA8019 + 25: D3FB60C2E981A5C82F1B1BCB3D4D7AF62C9A32A9F0D87E0532C9D3AAC083D70133EFF63A1E2CCB87360BF032C25FE9E1 + 26: B119F9AC74E58BD081E24C0CC1E090012C192996EED67A8ECA33794FE7E1920E26C0EFAEB866EB5AB82FCA3188A3B05A + 27: 5B29543AB0F76F246B7FDE6E8E5D3DF6017A39342BB08351A4EF609AE00A91ACB7C5D0487B3760B34CEF326F63C84572 + 28: F8E1FAA657BF829C9D2E4811805238CCCD11F0C1AB7619058241BA5606E7BD5E4816163E6E8E82E62A43CB4943A41006 + 29: 0855B919786B5E5C87B85A6C17A46C550B2BA81B3724389088E2B54BA89D82B8F9841FF442DA5DB8D54C9B2AC108DC3C + 30: 7DEF8CAB7C80CEF90FB38989ABEF6F1A5EC18379681E484A1B4DB6624818D2E486FB9C245C1F0DDD85A846D4268344B1 + 31: 04AAA180C2CD24F0FB150B1AA360F445344150DCA13E1ABB8117D42E25DF7FE29246D9F00C7473D20CEC32A71E64E1F5 + 32: E7112491FAEEFD57786DA73F367B25A6F5769F5C98FA7B704D8D37747724A647371989E8B0FE8D3CB23F9EEDD528456B + 33: EA27126D0B96E00E428943EA94F4B03FD22D56C4FF4636EED139D027E6D45EF57AB86093A7342B3B3851FD3BFD1DDA23 + 34: B2BD337A4BDD48D25A5E3FCE3E0948EC67829B835A8E3DD0D9F4881D10C766369B079028C6060B7263603288D8FA4BBA + 35: A9E940504AE6B137BB1BC88CE3A9AE53DCB63AFDFE5FA0C652003A921F582C08662425C7FBD5B1E1422E39E645D4A757 + 36: F033150D7464D49A076C7D4BB9E2A5488132786CB4851A4C81DA5B0FCE66D775D3C1766094AD6CA9482DD9539F28ED9A + 37: E64D999E7258ABBB4CFF6F74AF7D6A1E9B044C17E1ACE0FC61B29E7732763755A9C1D3A380B080AD968D2228DB731DE7 + 38: 9030D47B57ABEA93B51162556FF352DA61FDF501132A9FD94E6CB56690E7A805CDB290FB4ADE36BF90A53F20922C9B6E + 39: 4473396BB0461EDB4712880810A3F7252725AD4FD6092021A40559F453A1C63ACFFA8A02C85CC8DB86560323DA0A0FD9 + 40: 095FDD130278B3C8F574D17283611E4D6199EA63A0F1599E01ED070CD0B115296FE353477582BF279D622355C89A23E4 + 41: 7EE600CEE8437531C6A5BEC313D53371F9B56425D5662C104624D83D51111E5C9F4B83000B8A3EF150E04AEDCF67C237 + 42: 676D2BD2500BC527DCB51968FE8742E40D2965047478E69155AAB9201E0C9B0F6BA9BE85C4734B0DD556B5FA7608BE83 + 43: 09F5FE433D1FB8F62A76E5654B54CB6A9EF505D2465A49DCB9669EAC9A30B2532505E4500F842EC9FBE79A382C8C2F4D + 44: 075821CA8C547E66AD94F4C4ADF866A2A7554E08D2B0F0B3576801773EDC85DF76107E6912904E9757EBA753A77CD0FF + 45: 2172C22E7E48BD0B4A73FF02803D6FCE776CECBD95DFC43CA0763A0B375D57030000B12E59F9CDE81DE58E17489B2C41 + 46: B9A15689BA4F41BE46855775B46A5DB9D6826E0CBDBC3B292DA6D57B2A179A3D393A8E1B55DE79438E5221580C604EAD + 47: EBFA57C946831E2E370A6B1BE46E27C95C512297499B8BD15722622178E00599DEEADD48F1B4B08EB649A137805CB786 + 48: 25866C8288F9FA319FA9AA2470B4FC2595DFFA9154E607444EA3247E81D74A2AE0957D6B7E050F8C96AA7577BEDCABB5 + 49: 3D28682B90022C873CEC78C3A47FD45B5124E49ED07E2F0FB41A112A63AACC9E7614ADBB007D129C0673B08C51210839 + 50: F76D9B7ED868085905AE806CFC5C6DE994999E379922AC003D53F00B65467AACEF3929392F1F2F56C621D2F552544A22 + 51: 324951FA2432B63D1765C21F98325BC4AE2FFB25F411047C53ED5A3D550B50E2B8F6E79BBE65F2C686A5132E5B982AC7 + 52: 320CB033AD533AF8EDB3E664E34BB85B2327AFCFC583CE9202C0B11F16425A58FD895D7435E8953F9506A25DE7BE6EF3 + 53: 6065D55530ED8339B09D7A4D9CB1919004F69ED9D6B119E78E1C39C7AD2AAC029A3F266F7E48350966B845C4D7D92A72 + 54: EB6E866BDC0B5089301D89B870B75056ABA6D5FA6C7406A8D6D97CE5175102479647D3F93325A2CB648A3F40CCE38542 + 55: DCEDB6B590EDB4EFA849C801E6B6490657A5C1E64F69269F5F63C9267F6223DE24CEA7AAA6B267D9BCECC15147B6C875 + 56: 7B9132D597B8873AD55BBC30F18ED3F2C9F340E7DE69FB5774056C71A06D9BC2B14137E9E1C68B6B645FED28B188249D + 57: 0901B1E5B13FCE000486BDA64FBE45C79FCE15F38A4DDD9335A521D98829D267ABCCD84284BEF1EA3C2D4E4687C6D3B8 + 58: 4A9375DBAA878E2C1C7BFB977989E6D39CC00F890ADC425F7084AE3761BAEFCB9384C8B9EB3ADD4C3C838A6D560DF788 + 59: 908682C3E0D97A4943063EA9DD0A0F55EFCA203ACA3004010D3D7EF94593592729B523EAAE4160C3EA2241EBA236FD65 + 60: 24586F75A43A08D6CF116B87B86CC43300FC4132523CC4824B7FBB3F54A5B41C7D598B40639B25A99732D575A5CFD355 + 61: 7B4CFB73E247E941570E70C7308ACC5166F123187F003B1CAA9BCD17DDA8ED5535ACAE443C9ADE93C5567090EACE29AA + 62: E97EF4578822DDC79AF60514A188F8C719E4133B58E5EB134261AA7E89C402EA7219129A06B395E5E1D2738AC23FC876 + 63: DD66B519F51A925814407A449C60B34C553D7652D41783EE903A810A4C9F833B8181C91C7F12283EACD6A5F8A2639DDF + 64: 9F2C9EB7116B3D7A4BA84A74A4D4EFF8A5EFCF54B6D7B662693C38577914C73A214766F0A175339BB0895A863824FC0A + 65: 14B0A9FFCE149426BF5045FFC24C057451D2473186DEB4F150117B855911A7641651FB1E15DF406EB373D71151C46F25 + 66: 286505FF7A9EF81224988A8FF1E423A2AD21F6B339E91B89F7F1540F14CC9A603952564539167465CA70FF0B523BECF9 + 67: 8CAB08A79BA16F3D7CBEB942C7D8676F8D0295B5FAA01F3C850DC4B5FE913AF00F2E938BE0B442187B135BEF1A36C34C + 68: 4D12FFBCE2E770ECA1104BD2F29C65FE95534E390A138C30CB0ECB6436A971116D82C6321D2EA2C0A735AF34E5E3E3B2 + 69: F8617A35FE9116A719441F82F21C79B8868E5FFFC2EA737FDC821246DB7610E9868D870575F19B29F2FD259D9242A497 + 70: 932FC435B590B1E1D49C34EB3B627DAD5476216518250B1FBFE772476437872B8DA6CAF6D2F33CE7AF8648D956CF717F + 71: 3F63DF48C2D87CEB2168BEFBF6B857A415D8BFB7062251E8E1AB0487483EEBDE5E8E8B8B0E3AD81ED4AB15E81FD5E448 + 72: 4A71E4E737DE74F78E72ECB9DDB580EA5AC96E5BBD5E52E11D4A41AB3B8303E3AF3458A8AD89B39CD9F4A6D5DB3C9E2A + 73: CAC3A81A98103BBF08C440F6C8F61AC010DF8AC05FDA77E2ED8660AB73A978B9428BA0458A5C64DFCE35D87F0DAA2A6F + 74: 6E5D162C60A451B6257781FA0E36B3BDD9BC42A7BCFEAEB75C18E541A4DE00967E6BF575CB32374C1E9FE7B36D92048B + 75: 04DDFD71893D0F4AD2A0B672A057ED2795D6811AEAFDB7136BC8C20A55DABB3AE4B62B8A2C722C1F53E18FFA5771610F + 76: 555D5B51C2EA17659516A67D31CE2CB302979F80BD7056908C1A152403FD902EAEBABDD066AB3F7834E7213A6CE99EEB + 77: 44797CE4FEC66B26B52A4249C2B267AF891C912E55221EDB6CAFC4E2F022A40E8231931DF0B19321D5CCB2AB8A4F256A + 78: 51D7AC85289FE7E4D9431414B2BF3760BE65FEDD1A0B34BED0E1562A73495EE10971B5141835DB454C865039154BEA15 + 79: 2E31DAE50A484B7E11E2E621D0552803791E07279752E09EDF4C884EF24C79C33D9572AE0DE6E0B6A20271F1F7AB98FF + 80: DDC65ED22CAE4D159D35E129A1602D8FA50D7AA53E209B0D5442BB121DB0D5D102441054B2B321675F3722669FECD06E + 81: 200E0BC495311E2FE524A1579490D843011A592E4E9B927DEB0727E5481898C557CB2941F18AF0F2725A1B19DE045BA5 + 82: 561E1875B31DEAEC4DB2FF5BFA7856A6F0ABE1294CDCCA1DA12CCB1786D9556881A768ABAE50F7243921ACF993AAF18C + 83: F6B88007732D5B9F75209F9FE107B9917010D5960184FD239854AB4611CC788D1455B113A5565A87326B3CE6CA190DB8 + 84: B4E703169169B07AC61E76A75ED4AACEE4115F6A43842BF136B514824A05F5C5ADB68F2E525D8C9E8BDB20D3BCA21155 + 85: F72E2083B296EB7468C97749D3AA1B08F418EBCD9A2E5CB4117C5A034BBEA5E2004EE1E43E26A98E4F25AD4306AF3A57 + 86: B1DE9ED0D5E5F7FDCDF530041D7320CA7376A64590F6679971F84061C42AA03F0B07C7EBCB806EC8380D9FF0E182293F + 87: 30ACC02AECEA9B91F3C6BB0F4CA8EEA1B84A0BA6BBB8F7749FD29C9BE5C5E28AFAE5A33617DFE3FC28CE3A78D1A19CDD + 88: 5B2DABAF662B86DC4B1DF6A2EBDEB5CFF1F63C65ACE5E1237DB507DD3FA2C27FF46517B0FCD6F32F25DCD55ACDC07FA0 + 89: 33BE80B29355AB16AA0F05A45A8DC15A5EF7F9FEE60BCBE05E106BF6FA0F196BFD9CBB8D79298360F760DA7B05135F83 + 90: 048C648A525FAB61CF81E087047044130E407B71DDD27293119689C8516B19DDC4F276E3B4E93E6AB80A79BB2700DE68 + 91: BF18EA9E00E6C2262D802FB66E04FFA21DC5C13640BBF27B2C22592DE4AFE31C18147E6EBD2D45669C36F9432494A000 + 92: 0A1A114981A785C399E2B21871A532B2A747FC67B4DAA287C14F2F449FC6F7C6925DB5E884E6E041D08BF6BC69295124 + 93: AC6705C373300FCC09A291CFF1834401FC30FAD512569848A05171AA02426B7034EA2E4777AAC2DDFF48089226A4884C + 94: B7B08352FF8988C0FFE3FE0E27278F068BDC88AECBA8D7ACD8919850D7400A2C0A0A8519B264F61102290C9AAAD3C2DD + 95: 8F78C56A93B3DC69ECC5827F8D591195FB683A9951175754926A8E19F81FF859DC1904DE12BC8482A760E998552D28E6 + 96: E606004ECDC6878B5EC15F4554017CCF962E92CC6EAEBE4997BA34EC0E53C67D564C8461C013701A401FE347EC0F721E + 97: AB7D7116F436ECB13ED2EC42347DDF902E0FD766EA8978CF93625F56B2164E2E630D6383EB03602A8DF27F28F580E3C7 + 98: D716BE6974E46F19A606486BE576AC6E250AAE6AC2ACE7CA9A924C874790E6B4C94670FD884A6EF770EC5E5F3F264306 + 99: 746EEE51375E6695BC4B66190172DC6E86C18E144267C7B0133D6C2ECE05F75B862E4C4EA5F813DD927D60C46E2C554F +100: 3D20E33BA4D52A8C374878F1A624A907132264D0C831C64FC51ED8E1CDB75D11C3FC78D4C3CFBF99D7F0BEA9829B725C +101: FE6A6EBBE30EEA13CE04B1C8FA4199331B77566D2AF420D4EACEDCF22C23B3D7AD2313175389A0765AD60A79C0AA85C4 +102: 1806469C58C028D7FBE80F219DD45333D440A824032778DEFC0A89CF704D40745F0F449F7DF82D228E1718391C85F318 +103: 20CD15E37F6371020B78579210FFD7756B42BD01EB829C1320C59AC382781AC4224439F1F820E215EE907091EE4F028B +104: 7967636E73E440EF1F8751441ADE0F4D169167AC270949A758FE0FFE0B90C2773435623160E4BEA5F23DBE0678E95ED2 +105: 754F6D73A11693E07A2E5F05FBE13514C52F04F904131E0544202354D30917C333DC649FF7C33557005BB19B64DB777D +106: 358D83F883166A6D2972C63F2A46EF893D2FF0F577A53830B3B8E2CB28D1EFE8405084C145EE4E0BEE5DFA9AEF739263 +107: D74B6FD707BCEC9419F032A9C21A7C79CD38F42D564057CDB956485FC5C2ACAECE9D86BE8E12B9181018EA7871343147 +108: A517359A64226F2D08B65203593F3427DD42852476A7609C7F6423C304FBA6EA83981470B8CF171F71BF02F688BB2448 +109: 62162975F98C8ED1B74ADE5B2325EC3D185F7BF8D9DE6C08BB3AB052E54C28399AABE2BE4295CBE12003A03924D4EE3F +110: 8F1E4237FBB668D2705FA6964FF50014F54AB6346A7DECC8DBAA282B51803DE20F9090E7AF2E6B40FD8A138AFE25E1BC +111: F5F9FE110D809D34029DE262A01B208356CAEC6E054C7F926B2591F6C9780579D4B59F5578C6F531A84F158A33660CEF +112: 33BA080EC0CCB378E4E95FED3B26C23AA1A280476E007519EE47F60CD9C5C8A65D627259A9AA2FD33CA06D3C14EE5548 +113: F14FC73C4192759B70993DC35FBEE193A60A98DBD1F8B2421AFA253DEC63015A0D6B75FB50F9F9A5F7FB8E7241540699 +114: 72B9E34E0E655DCD7D9C288D11839A4FD96292F76F69BFB2E7D4F848E498B842CD4ED6486E77E30C603D218144AEEFB7 +115: D71CBD531B25BA65E319954E5AA670C8055406A595D006F0DCEE11AFAAF735CB1615EBAB4CC98061645FB70F31CDD9AA +116: 1F4398793AE7B2C4975AB102BC054DCEECB238DE4307B5DC54F6D7C20E066F638A782E33441533276DF9DB1AD0EAA75A +117: CCD908195016DC596A78C6C10C92EF6F272C6251F3C40B2E7DAD3A4538BF3FF585D4E44035B49EC397D1476E9DD28D02 +118: A8A26DDB23032BBD4432AC857383A5DE280202B21CE173D864E19C4A52984E159BDD006D95605A4682458137FE6B71BF +119: 0C8D3031D85CEFA23A09E13CE03623F0E648A030E43700C82AA1C8AA7E3EA9CECEF3029A23815AD940CC39ADB7747D2F +120: 0577AD6090B2A39FFA1C4A25436F9E958890C55A5B23CF8CEE8195A5984316D81D6CF0B5916C0AD8B1F512FB39826C6D +121: A5E7C31DCDEC53D8898DCB27D52A5C1774115D8DB163543A330AB502FE31D6017FA4BA4C65ADE0CD911972C5A1B7739D +122: 2785C149B798E41E6ED600DDA5257E2F31484BA4D14D35C8353BA4BB3BFB47F6E2CD9B64C940E3C1F83AA4587DC29CAA +123: 977756EEF1A7C1D4CA31A8E6936E7B8884968A22F2846F20B38F247345B1CCD47405040F727BBE2E0FFCD159206F5E87 +124: 9E4811F182E5D6734EA097FCBC77892EC48F09DBA138AD5A5ABFE67F2E88AB61B0A3ECB29028B5528180191754231765 +125: E964C5CC45E8356DCE9FFFE715D01AEB3935D644DC9C2603ACD175A04E8924DD84A4D88A1384D6BAA8AB3F7F7D52D122 +126: 764EB963850537E57D0969C9914355C5AA67AA9722644569B7F50E20DA8461CC9C6CA5958ABE10F5469E4DC1ED27619F +127: D5FCFE2FCF6B3EF375EDE37C8123D9B78065FECC1D55197E2F7721E6E9A93D0BA4D7FD15F9B96DEA2744DF24141BA2EF +128: CA2385773319124534111A36D0581FC3F00815E907034B90CFF9C3A861E126A741D5DFCFF65A417B6D7296863AC0EC17 +129: EF49AE5B9AD51433D00323528D81EA8D2E4D2B507DBD9F1CB84F952B66249A788B1C89FCDB77A0DB9F1FEB901D47FC73 +130: D9B681BA08EC0D0598DD3A2A37F909D01A231D22DA52216126534402A58A072DB35FDAE555B99159894BC823F9DACFE7 +131: 961E792C94027A091DF880A713ECBCA94E7699FA392CCA3E4B9988CB95DD46C894AB6CFA3DE91236188F7A372B1C60C0 +132: 779C845CED9623B6558577C06C6F22768E4A01CED2A9722CB8788FCCA89E0B5CC6A8925533FD097F635997A9C191D59F +133: F8A6FA1C730483AE488191E5863AB3DAB4BBDA1722710E519A2B2455273E78A382C60DB0D21E3B497EF9EEB2780AB384 +134: 1DAA34486981474A57029F0B1FF5150A144CEC7939A5D0C3D7DDDC4F471225D98E83E8A0DE880036F1A265E24CA1E674 +135: 769694D69D701764BCF81C053E2899B232344506C08A39DEDE3D838F85870818C3A8CD2DBC8695EDAF8FE34B4A5CC35D +136: 97E29E4AE7C7E461196C1D698B5D1186822BB66ACA3B3E062A3AE07DB9DD0FED83A345014D3E5AD89E9046606AD2CEE7 +137: 6B57593EE18186573F92273A9B722F9FD77A4A512164FE3756BC2D9F665768016EB2766C46D473A103D7D7090073271F +138: 35235261C522612958048B7FB8E48F96462D2B8B52AB2455C7C142E442E4CF643B367ED466A30BA97D91C1C8C0070E05 +139: 67004A5E74598981A79984B2662FFF8C8F49F8FD13C8A841F68DBA18DF68015E9C1EF38D6522D44F89DBFEA8AF48D2D0 +140: 8ACD05F9738BBB176E50C7419A05C8200E1BA84B5797032E025ED4B55D7A61CEC4CE3662432A4E0BA938D8C9143D5254 +141: 9963300C0CE5F2D39C2B899E47988BFA914D2EA2DBB972C15B3CBC414E41DF3A2FE793597243D46CFF937F41C0D83136 +142: FBEE0F5E072237D19170999D02BB95F6F8F48FD0596A982A4FA2D1273872226398DF57A63E1ACCCF6343415DF387D89E +143: 32A65099C47EAE3BCD0F68645845C0171417385B15DB5E5F7BB5AD965F66C98CDC39B7534198AF70AD5739C8A2F2B8DA +144: E936DBA2CED7F65DE3450BA7ADBE1030D7AEFAFCCE0CBA94E671422790B45B49918319A90FAA7692780CAB4301D9833A +145: 1E20D13B4D71ACBDBD5D2AA129E98929510C795119EA8A07EC63917114315E2756B45E7AE42E1A44C5E410ECBEFB3661 +146: 02A0571C5C3076CACE7F061BDB108D7CD9C7EA51D0FBF1D00F202A0B5C87F22CE687D1CB15F798ED164CAF1CECF92CF2 +147: EA07C4A1DF1E5CB26DC7A7BC76FE518890FB8C424AF3B1C76B37AB21445D9F7FBAB73C7DB35E85337A8F7A0D55121F34 +148: 7829712876378DF986A63E4616DCA38DBE8833B14760168897AA808B96D8FFA4460CA3C1A9B674A0FC13E0625537C45A +149: A7CBB3CD50AA663BD2C4520CCEEF123F7D314870806291DA26A59C003D041E46E6B563670F27BECC5F838A273D349AFC +150: C14E7F70D28E17D3546EB40EE96D239CA5EF7EBBBD0DE64B964C145A5F2980D408A6AC248D651E4583E25093042EA286 +151: 19F87BFFBFF4B1E195612F41E67E1D4CD0393E73FEDAC1C36550C2B1A7323D3E7D747EAAB9844F45F150F8DF0FB72E80 +152: 6BFA3BC29FFF3A92FEC377AF8508D4823F4E87072D6F2F16370B7DD30789A944EE5721EFDA7ABFD47A512EA2D4984BC0 +153: EE10FDDE70EB0A11462DC00860AC4756B21C83BFF0066C431B17BA57CCBB9ED018E8058CB9EA44CC11952C3C9BD15F09 +154: E6A72B9D2A0FFCA41C3122C767A6FD9CFA04CB5B1D1D94B79A0B2C592A584F731CA0523AEA8F2DBA35FDEF74CAF165EC +155: 59118A53C4479070DC728D94BA36D211F4ED5D35F1B69E4DFC0543F07326F982D2B81DDB020F2CACCAF1E5E9832624E3 +156: 63778B7830A3AB7421912A52B3CE9303A53C2A6655291042F428691A633FB9FF173937A8D8F59B21F72D490F39A9AC06 +157: A702F15D9483BB767FC6BE9C3BFC64732277CE936AEBADE4022B24B4822BD1B0FA1213AACF7B4506BF8F330FB7643955 +158: A3FBEA92041484F7F46B380462C5114B0243A79FEED89ECF8E6D8306D60DBEBDC5FF1578EE7E94B5527EFC5707D2B7D3 +159: 1EAEA2602E0B6B328D008A5325C5D4F9DFF7AB9BB5D36816D3EBFEE733BE664E35170506667BF5A24D00222EBC5DCDCD +160: 92E4D41594E15628BEF06CA61E644D2A686C113BF8E3F9A8CD2CD8261B11D01B081EF2941D5182E565B70C566D461B23 +161: 2F08DAAA98DE6DB4E85B81E32C651D88075DE18B7F9C3F633BE1F29C89F24968525B1B357DE80C6EA8D9570E003C75DE +162: 5DF64E7960C755D40BE78F0BB7C1A185DF8E505F0B421BE23563472843E3B5CFC7DA0F40908BF56C6F3A6244581C1DE6 +163: DABB5DCBC32FE7298C811CE22025E9B1C0B87DA5E7931CC3614E3EE39112206DD8422A5504F11599436B806C9108B01B +164: 31AE27382E330115E009474FB5AC750A278B79EFF63755E323E3478B0761E5E946DA6D2436DC44ADE9F4578A8FBA9896 +165: 6804CF0314E455F499E73BBDF4FAA22CA49020330E74C55B1CF4A2D2F4C57D7149B41916002B2852ECFA0713BA91A094 +166: 7FAD2AB0972D8059D4306F0B63F25D9ACBBD8FD95EC8199CFA89D4E227EEDE6052AF0C53C703C7E319047DC5734C9F4C +167: 4635E654950B173D3EC81A8212C1E65605C85835CFAD8607C829786855636A660D6C3045FF17663DE465BF2B152879E2 +168: B40764D8F066C897C3A8FE54BF21DA294C6B3F1B35255F68C8AB325AB3B94EE8AE2E5173936C17FDC95C9B7C3D3D3A58 +169: EE7E424C550F79BA82043245C3B7D0AC32A41B876988C322B9997D87F0A0A1FB8263726B953B43B4616285A239994936 +170: 627DCEEACB27F39552AB683330A67A316B2F53842BCE8056FCF3988702955E3BA72FDEEAC2CDB53F13627858C1BBC51F +171: DD13F3B3E9C79958B20D1986650A79CEE1343F9957FBEEDE18B2FB5E543E3B8839EDF7A57EFD818129C4F00F505D2112 +172: 0A7061C0FBF1EE8CCB0F4A1D0DCAF2F200291AC06830F0E38D05E1CA2429A2BF57DE5BF8DED5A7CECC3A4748FBCB880E +173: 3635AEA9152337FBFA4C2824C5499B9F3FD32061297C4121FB0A44CDF5D3C8D4C6EFD760A0BF076DBD1801C416949A9C +174: F9C58AF2259C719B0B852FC68299AC9F17A802B49B34CBF5FBEB85DB3C68767CC34DAE2CCB536FF90BAE49FDDEC0CFE4 +175: 3541EB8602A4C84545F4476749EAD54E4542C4358CC78CA5B7C8B6BCD9E9A3E649CCB243FE0B3D02930CF1CB7A507FFD +176: 4AA26C2565531A52811D30A1C59152BDE4C61AE2CEAFEF9642E7076EC44C7EBD50F1D1853761B4097D985DFE6878A701 +177: 32F1DD0B4AF205B4891E2F43D772EB5E4A5EA3658106FDC8B8CEEBD2D502F8048B583610A419E1A60020C8C2A5A02FC8 +178: DA7403FE3C3D3139893522C5DC8E4F615D36A0F7B7B8AAF150D1337C8DFE70311544E54880D1C575D664E9AF979984D9 +179: 39F8450D4A946ABC6FCA804AE11935CDE846D999BCFF3091F1E6944EAEAD504F77139A919F915D34DACC13757CCE0157 +180: 45CC03085CC3278B8337096BEDFE6F1D645994690660F23A358C4EC728EBAFD6966C487B9492DE217C17823B16589852 +181: A2150F3BA3349E3AA0ED97B1A02A58F31EB5731012393EC68846D95465F3B787C272852B6945B1CC0FC2B3BE999E0E46 +182: BF9392B085B3C5FFBDE70A3FB64AAB36E39BDE4816F1C9B2A608269336906303F7DFC15F4701D3FAFA5D7A8BFE316A1B +183: 21BDA179D5B80FA6B9444AB1D1F7E06F89F670DA4A038E7E83E8A63CEDD44AB6C1D069D12C6F538B45022EF3160D396D +184: B4216CDE6BC1C27A5C1EA9AC79E85776740F93440AE438D4D9CF51BE8A83AD44565586FBFB58DD743782724A440218E8 +185: 5C3D5C00381BCCF77FC2103C262F373592FE34C2B2895F54BCFD1F9B3C87026288130822B2B451D716FA9D4D7FCC93F5 +186: B927E3777D4BE05FA85D0CB707FB00F08C576777840634531795CD3D6818F192789977AD6425018025E10F5892FFE708 +187: 9C6976E1EDFAEDC32378C8D2758D1B0C5B287C500442EC5D19560BC87C75FD2A7379A3E64ADC1421B7410D1ADD6456BB +188: 9C20482AB71BBD8E985D7891499DB526BCAAE11D2A42DD72FFED664D7BF7F254C2F8DDA2E340690FB83E1F5C58378B72 +189: 7899D5AF410188A3D0D0B12D52437313D786CE7959FC4D194D6A3ACA85729B60ABBDC58AC40731B9E833505156BEFE24 +190: 4F958FD1841D2B790A199EE3358F4DCEEC64CB34D0886EA91AA5E38F8600FBE13DEE4D6A55AC1273B3730CC62A3611B7 +191: 66572F61FE6C34B440AC00C8D3992B9CDE3FC465FCBB193CB7716B53E8032C743718D4F8245D94A22A9AE125795589E0 +192: E7AD49861960D1460A77F4F363341ADC2207E205302957250612C7E903802AF5C9423414C52F4C1AD55CC1C8B2922EF8 +193: 62BE3AA3A9D08CB41F2CA3ABCCB96E2E91A248E569FF58F58C8BECDDA5B4B25FF46BB30EB37999E6131D944CF3253302 +194: 3E082F7DBDF5BBA5F52CC870F2C6E9C63DFCD5D547B183F3FFBE392BF0A1F8F4970CA21E5B9B4306792C138D6B2056C3 +195: 5CC36277225DA2EDCC6CB603EDE9C629E5DA823E6D233AB7833F70FEA2878B2F8D08F361BD5B4C7609577329784D87DD +196: 9555EEEE1EE60EE981CED3FB6BF74699E5383436ACC283BDA0F9F6FFE20561ECE75ECE2C5A82C0A158C071A3BA59CF58 +197: 0B975D2ABD0551BA987680C4890F80DF93AF2292FDD1E47322560B0AD3BDD38A67D3A78497D78B3C38DA597846C5159D +198: 016CE0B8AD1628C7FBA358EEBB7C3667FA93566086B99F20EA6F87FBACB320E7BCEEBABF0008550A59AC1E6C3B4478DD +199: 3D138114480946A2AA1E2B78948B6BFEA95F53BD8BED81ECCE166062A67FD111933A696E6FFFBFCBDDF71041955C98A0 +200: 7EA4BB2534C67036F49DE7BEB5FE8A2478DF04FF3FEF40A9CD4923999A590E9912DF1297217CE1A021AA2FB1013498B8 +201: 80C399C975ADDAB12FA20B3C3D04F25218DFEB678B5A87F9963A462F5474732C7C5FAFE0EBBBAA94662789CC10C9AACB +202: C27E28A5B6C7BFBC7ED372B5BD2555EF1370FD96043753015B3FB9AF31D41E7189D4FA8860B183703560A298D90B6E75 +203: B792B021B3FA904B5948AFB4E56BD4C40119AC79E57EB24C32A7BF0A1A889313D816997E35F2CA192B34D2FF9B05ED9A +204: 7828C6235E2B8AC46E4BCD7F7C7554EA81B5BFC046133EEFA0C4E64AAAAD7115B04EE09E33CB4EA1FF476960C64D9A36 +205: 06678F9A2F238953A8D6646F859FCC3BB0C29BABA669D7F891142C2C3A0BAC1220200B4EFF8C17F5D79E261128C58248 +206: 0FD4448A47B6620FE90551A9AA06DD991AB13DBD2AF18A4F17AE4A9A24D9A83E7653D5F5A2C54633C42ACCB0E5915A35 +207: AABBB8857DE60BDBB21742DE7ACF7EB8D9180D5D0AED23B7F708F09006C6FC56CE85DB87D9642CB909038E70C15C1574 +208: E1BF933A4F32AF56C929911284F9B05B79F0216EF3A150483D74B2D4DCD78885190EB1601A320150C860168221C6BA49 +209: 9074B187372B0535738D4606AA0478BECB5251EAEC961699C2795FC028D641D60230532C8F6A096FEF419A46B0DB87FC +210: A63532A684A1851050E2861F7AB94296D131F768A94AB0019A941734E13842EBE8AB1F42DB4D0A84E261CB4707C74290 +211: DDFD64103308F0537ABD8D4F2209D8920CB42FA9ECBC93318D438C1493FE11B6134DDFF95DBE3FC6B8AA31F833E305A6 +212: 044ED56EF3129D29243665545A59FDC12412E137E1F55A543AACE511F9F86CD3202E3D24807B0FC878BA76223EDC6F42 +213: 2E470AB58A76690755AE6643D615039E767B84AE9E68480DD937913C44AC2350A27FDB45D6FADC242BD5F84809D59E2A +214: EC0ABAC477B5AD5F6B11DB4B699283FD4668D84C2BA7F8DF90A5BF83C0E1E224623F0D2BB3F2DC6EAAC5E41436035D58 +215: 9FEBB6C1604914837F6D00F9AE23A3459DEDCFD81EF755B96A3CC1F63E4CD2E67F5AC2605E594DCD2610F4962EA6C277 +216: 3873BF1A102F1609A624F1A096E420CC459C02590600808F7DA5E3FD49F5B491269C1116A2AC74185A3105B5E9606126 +217: CD7E8C16B59BCEE5888DC7FFC28E65B72570B26F3A0C85885BBCE81E5A6B63D781F953E497399DCB506E8C4F5E237169 +218: 3D24BC91A4932BF6D631EB7698549B03E7F3930662B8527EC122FC2C7AA41E330862102557F480273864FF9B06628BB2 +219: F0B21BC919A3C6089BE3CB7CE10B55D76E31552E759F0465086A89D1FA435E2671928AC329ED7B3D7C1D7121C158BABE +220: B32F9A1FD8A97E6E8E701371BF1A017078B26C3F4C58E342ED455B2557BDA16EAFAC00AEAC1ED7328C65D7C1E227FB83 +221: 5468F1B9192244C738EC20FA979F746CF6929FC48F69C79F43E46859AA022CC42E65203CE7CF77A039402093A1552EC0 +222: A58151FE3211C27651693B55E67CDE0E886BB0D8F2B6D9066615124CF1DA403DFA014C6F19C1B10DE7D3BBDBD0AB9880 +223: FE73FD3276463D27AE6A9F54877CD9BD3410C4A40381D25F5A915194538CA8C4F4B6154ECB9CE8B1B7E23953DC64F664 +224: 0D4EA680BA7CCBB9D88C09F6DAA6BC655BDB0B2A1C8C3DE0BE895328027794E223A45969AE594C7A21FABD5C92BA6530 +225: E6DC0E64DC804FEF91563B550A83BE7ABD50F51D3BFFA785A428EF9436775DD7E3A589793CB2717DC6BAD8B531CFC922 +226: DE168B8F03C0CE8143FD14BD2D294476FBE8DA85B09BF26C5D846E2D19957F87D6FE150B278EA4B3BCD36AE52D251FE5 +227: F34472A4DF2D3B529CE56E9D2A721A839DB05DB7B66BE8AB7202B024DEFD46ACF493973DD1FE88D8EF6E70673914DAA9 +228: 1F5E8FFB4678B3889E7FEB2288358A5F1377A97F76674A8D3E5EF39D185D02F6A1FB60E43BCC79C31E6974B37E74E50F +229: 190AFF1D363C413BEE16C78C544AFD20678C7B1141D3917B6942E4D1486EDBCEE90EDE8A50E441219ED3B11BEFA09F18 +230: 66BB67FC2BDC1D5E8E4366958804F459AA689E04D5FCAFA8CA222656D568B23E976086E2BBAD979EA0973AAA1FADEB8A +231: 0E14C70C02205AA29303D24D6491CC84B648EEB80AE9CC2A0997B7BB646ED32C69D2AE41C0DC007AFCEC514D7B04BCD6 +232: E38C413F3FC12764415F39A9F3638AA1204D3E818A43CF2EDD9F2CE01936D36C6720CF5BE8ABA362F92AEC81386A4800 +233: C3ED0B3697A84B388AA83DFF8EAA65F5BB12EF00315AD462F1F6D85D410D021BC32E77ADC763A254F7D9F1FB6EEEF1F3 +234: 8DC2C3F8C13C43709AAEBD408A679CEC524DA8C8F4157DA4BE551EFD687A395B33577728EB73EB498ECD0AD2487058E8 +235: 8AE817F2056903661E4EBF37D7293200D8BEE7AE0CADEA671E4987624A43712FD2C392E37C17D8E81EAEEBEE8E96653F +236: 9A622BC18F3A09C8BC1C8603B55260BADF32AE7ABD8DCB6CDD980C5E7A5B8A38C6D287A63FE88567BB9B0481743C06D9 +237: B74C6303DDF9F0AD7CBEE923F7F7F1C7FA52C84EF609F2BBCC07B9911C12F3D1A9BD818A9F36EBB40D4B400AA4D0FDC1 +238: 5B1AD3420ED592FA3D593435CA6EBC700583AC5E3CA2876887E5F190EC2109A1E6DD06AFC6C9D7ED0E8B0272B7F9114E +239: 2556CF077A788C49BB6D600F4A3CEE635C4443832D169F761537AFEE2980742B9F34AFBC87F598DD0AEDC4A826ED6A73 +240: D64769AD58F5A338669B935F3431E5BEF31667D0A2437BFF78F1E5275075F434FFF675F9833EA04AC4E5C2E2C2C99B8C +241: 3264CAD70D24B53CEC95269B980DAB85A30D24CF8BDBD68F0FF8A45C6208F05723A4B3270CD095FB8B2D9A4167FB3D3B +242: 4D564117E87700C69AFE5A4D90FF50DEF8A54A9BF19382E4290290D2BEE101355EBB2DFB2A9D6D044A6D12D6DDF7BDBE +243: 6AAD71FA5D5D7B63FEA64D94E211155B01F8C9E4B3D86C3B9C014CA4BB6C668037C4739A082F37B2EC5FF6D85F0A58FF +244: B36D529E55B5CF0FD3273F204F798E21DF533BE466AD1AF35EF80082132640493FD89A6CF41CA68AED066E93181A9EEA +245: 78814E883A27D6ED3A5B122260059CC00D31B8A0E933F3C377BB99EF33F47B13B6AD825B740784BEBDD9917879C2DAEF +246: A7978D0C79070B208F070241867476AE622EA887D26B0F6703FA8A455F411649D8919E6E12C540C59DF60CA9C05684CC +247: BDC3E02D31DB1EB7F04CD9FB8876AA9C7CB1852BD3BD62F56E062E216BE648A34FD327B84E3B6339F44697470711F661 +248: 9135E6D4B1E2356C3DE16A85E4AF57243CF6861DFB6C53CA13D9481371AEE285B75DCCAFC1A64499F1B2CBE4A3CD82C8 +249: D1F9BAA4007BAD437509DB6F6DCA22086CB786026553244A6F480C3A6488F7E26C416C6AE85874477BB5563BA0AECF2E +250: 49E5B7521794B6C73004BADF3D039F4185BE9BF8499FB08B9C8FDA2186B6C4BCD280AE2D2051C6775C19ECF1C776ACF6 +251: A7534C1716B59AB1C7AF3DF0AE32F22CD02A1823F61B318F36DFB536B8EF4515116A099F8DED19B00EE7B2D243539960 +252: 0F01FB323FADD9380A5E4EE6371E8BDF6FFB1F70C4D4A1B5E8BC9B281582AE0531AB354EA9F58A96568826F6172FC75C +253: 145C9D3926904D8418B75C8D645D43AF651684AE7FAD885AB46141B9EAD2D9727731F44D5AAA0204395E020D1B52DA96 +254: F663682EF7FA3F300DFF0B4D9C0D2D126F2BBC164F3B88C8A2207C3799464ED2086CDD324C1E88DAA6EF2D53CF7C190B +255: 98D7AC796C4CFB5D98A1C323656A4BE8AFAAAD168E5EE72B6B7A3FA3260461A043E27243120D41584B58F1AE4463121A +256: FFDAEBFF65ED05CF400F0221C4CCFB4B2104FB6A51F87E40BE6C4309386BFDEC2892E9179B34632331A59592737DB5C5 + +Hash: sha512 + 0: CF83E1357EEFB8BDF1542850D66D8007D620E4050B5715DC83F4A921D36CE9CE47D0D13C5D85F2B0FF8318D2877EEC2F63B931BD47417A81A538327AF927DA3E + 1: B8244D028981D693AF7B456AF8EFA4CAD63D282E19FF14942C246E50D9351D22704A802A71C3580B6370DE4CEB293C324A8423342557D4E5C38438F0E36910EE + 2: 80536C6170DD8626DC081AF148D39EC2FD5D090CC578A76647E7903FD34BD02E4333ECE57B0E24FF116F43429B6FF541834BD40EF0C8D3563ACEF5ED0FD254B8 + 3: 8081DA5F9C1E3D0E1AA16F604D5E5064543CFF5D7BACE2BB312252461E151B3FE0F034EA8DC1DACFF3361A892D625FBE1B614CDA265F87A473C24B0FA1D91DFD + 4: 4EC54B09E2B209DDB9A678522BB451740C513F488CB27A0883630718571745141920036AEBDB78C0B4CD783A4A6EECC937A40C6104E427512D709A634B412F60 + 5: B7B70A0B14D7FA213C6CCD3CBFFC8BB8F8E11A85F1113B0EB26A00208F2B9B3A1DD4AAF39962861E16AB062274342A1CE1F9DBA3654F36FC338245589F296C28 + 6: 2F3831BCCC94CF061BCFA5F8C23C1429D26E3BC6B76EDAD93D9025CB91C903AF6CF9C935DC37193C04C2C66E7D9DE17C358284418218AFEA2160147AAA912F4C + 7: B7C0B47F42F7202BF7D28D6834BEE365FC01CE3F0C8C8DF24B4D940406C2E9C230BA88854E946EBCD786C18C748969FDF012362B7C96400604B6058950FEAAD4 + 8: 8A414C5860CF1BE7BC8531442F69A65EF2ECF0B7CAD9994BCB407097EB74CCB92E93AABD24BDE60331123B4D900684CA7BE6027099D4946BF537F4D6C6DF3D82 + 9: 8B5E5E7FB6530CCE1BFFFD1B1AA338D3282E8483319BF028BB674BB6AEB8200DA389647E3D8631503DC5C487BBFA7D074584493615B036849E0242610EA4758F + 10: 0F89EE1FCB7B0A4F7809D1267A029719004C5A5E5EC323A7C3523A20974F9A3F202F56FADBA4CD9E8D654AB9F2E96DC5C795EA176FA20EDE8D854C342F903533 + 11: 8FFAEE0CCCC162851FAF051AE38667EEFD423C0164C50055F8ADE00AFC3705E3CDEB9900004B0E426CA66AB63AA3B99B075273F44FD37C22A3555C6FD1F37CCB + 12: BA51B2A9DA2F26FE81FC3EE11524255937EC6BEC48835EB437C598C55674E15AA50F88922DE7584332A5E4D24787090CB14DFC3ABDB39C55AEDF6EE108F95354 + 13: B6E30A4016029486F9205C5D141344F885B3DE2468EDFB0B870545F1775CE82597C2A40462F385C957790C20822D9E920EF1AE230878D6B23F221B0182879CCC + 14: 79D76024A31CDBE54CA951D264C46E78F6F5AC5DCD018BAF89AA586333BE82B2D5CA2BC64B99CA2A99D95A984F2DC0D6C07E7C96059DD346BB3296ADE3AA33C0 + 15: 4236736D08F26244E75B51614091CC2C2907D5DD162F8497B14D58D0D954A777C8397549BEE468F30E480252D9B893175DF7D2BF415A128CCC79407D9D5FA536 + 16: DAA295BEED4E2EE94C24015B56AF626B4F21EF9F44F2B3D40FC41C90900A6BF1B4867C43C57CDA54D1B6FD4869B3F23CED5E0BA3C05D0B1680DF4EC7D0762403 + 17: 7B9AE840AAB8BEE45B038CE398D15A8679DB92D0BA46FA67D1B8177986E41EACDE915C6552FC2AF8678425B8BE81B57E0F7EEADCC93B56C58DFC38B4D33BF25D + 18: 0EF6A8C19E19A466DBA3139E2A401175BEB9EE01FB56A8FC11A3E53B345F2327959F6DAACF0CE6121987D2491251DCF550C95F6026F93A1D96A0F4164CB1C642 + 19: D6221AACC88CE14EB7DE0F15F2260EBF4294D9AC3D75B87465EF7AF9570C959077860EBBC5C8153000507CE1E39AED5D007F2286210EFFD26A118966ED15C143 + 20: C9AC4561A7503FAB9C6B71C843AF6911438550BCDF4881EEC18DDA06E4D8B820CCA9521DFA9EF47298CCF6308FE4C4F2F5E34DFEC2ACB78FBDC04D2EF0A5A09E + 21: 73C5D58B05E1E6FCE4299F8D9294681416BC3785F51E402DCEDC0E30C0671DD48321A0248CCC13389A012B52513F1B5BBF820E91EB4F616928183485B4F1EB22 + 22: AB1725C57427DDF93B34AAC62C26F3FF1E49CAD30DD41AE7B5FCE23894245E7E889E0FCA5EC076F247DC7E929D72FB965B45688E57D8CD54212714A17480BE0E + 23: 456F6757A82F0589040996BF88F28E61317C358135A9AB6E96E22F5CA68E2A6438D13D176B01157ACA1FEEDCE3C1A6D5C3A9B1D5A471691917392FB94D0834F7 + 24: 5330241E6F01A49B21AB0D01A9C76AD662E97A325BF8E24C4EB82C6F3B7D2538ADD98F62307F36F900F3934861B80FC9844B761BE15460A1B102C26CF0410E83 + 25: D8DDA603DC21C20A6DD3C6A4F380C297679F035D27BBA82554D02E1F95ECA2EB20496164F96DC4B84B9BB0942B96A3796AFF6125BB9E8711E2674B440176E91A + 26: 81E5A3AF460DD2881353D006AF37478C58AFFF16022441226FB04439783DA920D09FD03E19F45BC82F82735FBF4F2E5F588F11AFDB87B69DB91123CBF05F7F2F + 27: 25AECF7D241EE54E668DDD345582DB777F9F631B9D2432CE4D32119BEA3968D9FA3E184B135364DF62247AB74BA7B86AC3542F63D9F18653D86B9B47944AB96A + 28: 8A372F722A922E29CF5CB22BDABC6D284364F376DA355CA65BE36DAE2FA6F0335744CEFA9089DE55D331AE64E9B2F1037E73608B03B978758A20A012924AB235 + 29: D57C54ABB87AD2D518790B81230DA336F551A0D89A57D0A3CFE2F4ACC55B4B210261CD1482BC436F62D3FC96D1536B82A2E93E9A3DB5CD0F1822EEACF307460C + 30: 6092F1E76F04A5926F6FCD149B18DC9DBE8581BDE6D2A1468145280463472B636C711FF61F5CCA84FD2F044697BD1DD18340B3ED0A131F4BBA35F839A2DD9E0B + 31: 0674A3CDF5F7C18C1B7524C87C36037F3D0267512D11E052F453DBC097CFD52BC331950880CF904656C70758B2E25E21FE2C7E0462E861112A2DC9D0636BBAFC + 32: 3D94EEA49C580AEF816935762BE049559D6D1440DEDE12E6A125F1841FFF8E6FA9D71862A3E5746B571BE3D187B0041046F52EBD850C7CBD5FDE8EE38473B649 + 33: 301F1CD7B25B097AE4C79A97E92BCE359D1289F6754E76B71E7617A06E7783A3CC30F5290209BDA3E6AF239D0DC0F3D1CD4C5E866F4C5C3209EABBD7AAFB8058 + 34: A8C7114B292CC6F46D73824CB073CAEB23EB1ED5EBB37F064A0A76AD452D936D1DF41433FFA337C3F7CD53F5CC00658ED0633252B69DE192E61D9F002B0F133D + 35: D2F92068E07C9AD0572693CF546FE75070E574807C02F5483A31B8CB2105CA55CC6AADAAFE74977F581CE90F43E2AB48260BD7E273D4A83C442EC4871CD88AAC + 36: 1A4133CDFA6CC518387D392814029744D6FA71122EBDFB70059512B89469CDB9D9B5E45900E99E67DBA54B4708036298A94835751EF583149F06AB272B2BA355 + 37: D30DE790B4905717C956A95F60D9ED5948F9E509BA27607E1C5C8FFE35ACD83F719AE04D63364C0BCB72BA529AC79C321ADDFBF7AECF7CA3CAC840A372E6F6CB + 38: A25F5D4BFFBC5F0E3D5CACC3A91870866D8C2D22573556C9B9FA0D24E1D68C55EB42726B1895DF8E5E870DA33755DDBBAC130AF2D96D84DD0D57761D25FDB64F + 39: F44001A74D0B087AF2A143B778DCDEC1554BCE5992C9672E3D0F6704D022CA1E78F087543569CB99D249B820E683138A2DDC5DC178D585167FDD269D17396A89 + 40: 692F36EB114060FD04CD38555025251DF985DDF681A0636FBD290EFEA6FCAC5226859373F3E10E8CB07AB5343547EB0A543C18420D70527D2BBD90040F8DAA52 + 41: 4B1CEF875A025624398CD06DB876EF9AB34FDB1B6A75A07CCB591D9B20EA66E24BAF323911B5CE8B67904945A36C28630B36129939D23D26218610CB049D7AED + 42: DB3E80F11517AB797265829371F245A7A0A384E36A8D43E72852C8D47F8CE37A178475EEF44CE8BDEE5AB054F47EED502E76D49B9F4A5AA392077ED1E6F43EC1 + 43: BD08551AEA7759911B37E9D45748219B47C4EC17A2D2A306D9B8FDF982A9E3106BDC1ACF3F47D383B6D16E85910BBA08128E35EE578E7C55F2E9B9B59F611298 + 44: 3BD8A709DB9A4E0B874B113564B11EAF8270AD1DA3A9236DBB16F58F43285070344962394C2231B3917401924A3F688150B9A9ED3B410547DE3F56450739592C + 45: D0206C8577202C617592B47AE178DA867AC7DAAE4E65B912C771C5FB09585FBD10C36782064E83ACE749BE27045508D544532B628F67DF00A6B7DBA9775D3E06 + 46: 745083E5994158A0FEE4D849012F43A822D19F068AFB327B372A7A8BFE8347E579DD29424EC95319BF75A24B4DB4280D9C16CEBFF5D930D61D34909061A478AE + 47: 3527A5E1E5E5953EC57F309C6513C34405531603372BA0DFD5725E68B9510E5090CC6B317B2E7359D2ABD5ADD353AE1435B85535EB5B0B8F2E09D4DD1BAF3C8B + 48: 622BE417916F1B0E9CE8C952171B11B6D2E2932D6197CC17431B9FFDF03FD0ADB69B08DEDAEBDD0F94812BC2C670C894D65165B31D2F2879532F2C14453E6A0E + 49: C2EBDADE0368F1DEBE44F8E1B77E66BC1C25E7F0FCED7784D615811E2C01192DBC21253E10709D0BEEE746DE6EF93CF65AA39BA29551E11F602ADDD27B196019 + 50: 5ACE0640F0DCB25871E1925F96BAB48162D692BA134C9C7052A37FDFA4895B90AC56C7FB0E7FAF155D147A467839500D980E9D4ED1CC96661177ACF0BA8D4167 + 51: 5D43600C04E52BF6524CDCB9DAD89B1C7563912E7C7E2CA3D34B27B3C1D07D85D35EBB7A65AF0434155AFA3102A580AD557468CC23EEA1E151BFD4EA817FC5B2 + 52: 38D7538AC3E51DDFB6724F57B29A5E46D15A8C08FB29D15FB0681A4315B03FD6747B85D0EB2B9E5FCEC709F365DE08D61A1EB363094BF292B5154671D15D61DA + 53: 2DCE13E5882A31F7396D970AE72E89FB59270D78BF7B4579D0855C4E8BA231D23E5566B77E79CCDC1146762DAAA74F49D82F9EFC0D4FCA891E78F9FF86C61300 + 54: 6D7644DB575C5C238DA02CC4259996CF163A3A3B5ECCC4FC62442DDF01AA05EF0C4EDBE3E6D220DF189C984AA55726A4922EFE004832F2D8887F0B8A9267DB40 + 55: 6856647F269C2EE3D8128F0B25427659D880641EF343300DD3CD4679168F58D6527FDA70B4EBC854E2065E172B7D58C1536992C0810599259BA84A2B40C65414 + 56: 8B12B2F6FE400A51D29656E2B8C42A1BBFE6FCF3E425DA430DB05D1A2DDA14790DEE20FA8B22D8762AFFFE4988A5C98A4430D22A17E41E23D90FA61AB75671A9 + 57: 92CB9F2E4EEE07C7B32B06CF4917FBE54365F55247CC9B5BC4478D9FADA52B07D1C302B3959D0CA9A75A629653EA7C245A8FBBA2A265CDA4EA70AC5A860A6F3D + 58: 23417F93C499DF9EAAF1BFD6A62AADBC711BFE56682943DE5D94E0DAC32F732B763BE28C32AD5F01CB95E5B322AEFF8494B111D7CD8BAB50E7C602695EA6FE42 + 59: 4ADFA8837BB499605D38716F8305FD50255DEA2EC4BF3EEB07560B3C93B5E3725C5A598277A32502CD5C8AF6C88D55756DEB03B69CFC278FFE2BFB3CA202B0F6 + 60: 981A245B249111B4CDCD565AE60C9DEB69FDB552B10C932E8D0635685904203C37CC65D674292405DF24A589682B8AA69BD0E16F666652290BD79AC10E3A9B37 + 61: 15DDF1E434A88F27DEDB8435ED837FE4F1F3BFC5B6FD387A98E93D1C83493D326467C7C53EFEEF158F6B9CC2081267D9761A32A5094399754C0FD62F4C72371A + 62: E08026874830E0B911F5CC51B81599A4DC21204F5C9381CB5A0DA8F452EE99D9FF7590B798805C2743822572E6D2E47C2C1F2D428EF3C28D05297BEDC5CAC4EF + 63: 9DC9C5598E55DC42955695320839788E353F1D7F6BA74DF74C80A8A52F463C0697F57F68835D1418F4CE9B6530CD79BD0F4C6F7E13C93FEB1218C0B65C2C0561 + 64: EE4320EBAF3FDB4F2C832B137200C08E235E0FA7BBD0EB1740C7063BA8A0D151DA77E003398E1714A955D475B05E3E950B639503B452EC185DE4229BC4873949 + 65: 02856CEF735F9ACEC6B9E33F0FBC8F9804D2AA54187F382B8AE842E5D3696C07459AAD2A5AED25EA5E117EB1C7BA35DA6A7A8ADCE9E6AFE3AD79E9FA42D5BBA8 + 66: 371DDB96ED5BE6521379457AE8ADD707A866732B629EE00074904D73858F3FAE827D84E503F3779073490B274E29D644D76154FAB18945222289BCA798BA6438 + 67: 96A693A22256D39A0596802319CB7AF997DB4BFE311577E38F8423DE81C567A96775D063471438F0982EFAA6B75B4AB173D9D3B3D4762030B522FA70DCF3B27A + 68: 7D8AB6155AB31F29740042D82788A69E880FC642E600BEDFC89098B9D2F4F98BC11141FD420870958810295100DE66F50C96E1E4F6489DE98F9BF2D4A9AA2237 + 69: CE561F8F679B4EEB1DC97DB0F72632B9DA1C5B5C0292CBF0662CAD981374BF8C9A0BE1355657FB18196F980E6685D52FE601DD45C6B0FBDE7AA5C9D52E7E5973 + 70: 10164CFD162CABC44C56D76D369096D759954074B0547FA7310C3388F0FB6BB2AA295FAF1E22C44CF59959A37EFE317698BC29AA718D57EBC831A14144F4E48F + 71: 658B337A8FA873C73AE4D19992BBAAD10E1325AFB4DC8B5733F870761429B4243A7982AB375E529C1FBE6339A48F9FB9E8FD6A568F9CAFE640E102B9F398A330 + 72: 4EBDFA0E60E1A3E7FEFB8DB424A5C3A52365F325EC7F51389A4955EE3453BBFC94692DEAC3FF6A4E94105C27D632DF26250FF37314C882FDEB65D53534F8A961 + 73: DFE9D2A6B0AD5DA802D695B3B91745852C97B0283D9A033F04D79D2CAD4FDE50048AC7D82BCF8C402B109E785D39FC9FA0203F7CFC620EE43577688BCF3E69BF + 74: F21869E1EAC3774F3878570AF0DB9A94F464373C1A92E097D180A331C9028A18A68BF4624D8E620B2216B03709F03FB6CD10004F77433ED605B0F771161145C5 + 75: F1F928D322E6852301AD6FC901E91F2156A3CEEFA204044DDA3B4B76A63692DAAC479FFC6D83EEE3BE028A1F651D3520758DD395A1B251E6C261B7CCE86D0481 + 76: 37954BB11B0AAA67F803973DDD2709A73B947D0A5FF8DC46C2D3C6918C87069AD0DF907589F3026A94B071E0F00230F00CF74AFE8010C24E489CC8AF9B8BD646 + 77: 140DB04BF46A194E44F07F6ACEE8326573AA0591F8370A79DF320093C45764A2ABAE531E5A742F496544657FADFEDB7F04D4BD74C347AAE237B5EE59921BA87D + 78: 6D0D30BE796B6E1039739BF24CE26D8DB954D25813F8D7F7444617816F93FC7488B71C69D96D77C65007EF6A2BA313AE0739302395F3D9EAB0244E372AB96961 + 79: 2B92E0D915BC7D56215651BC9F769544C55E2A27080EE726AB14FAC0A43AC51CD378EEA356DFA70EEC3C9146E08E98358C61FFFA3D477CCAC35FD6724A44C23C + 80: 2CED9E743D84F8EC5664A99C6DE2238464E61129B3C856A7FD2CE08B185F4D447A829F287870AC5428114A7234E41A78801C19EA5C6246FEFF961DC6A9B55835 + 81: 4462303D052C70DE76296234B72BFF1AF173E7B63D1CC0E26C518D103BF3BA78D9AF4BA88013192CBADAD83801B8FC29D0838A144AA3CB721AC859EEABF019C0 + 82: 880FEF79B74C109F030F3FA6FCB82DCA034528CCA68A23ED1EE4133C10B3E443434A37C436F079F3F3A922A8547549A39854120723791519DBC166936C239AA3 + 83: 12DE996C9DCE152C83BE6C0E69C66633FC4244B412066A5FE7CEAE27BD4A109FEC95332C60E87DF08A1C714D9D2ECF28A8A81F1CDF8BB3CD2CEF71011BF5A5DC + 84: 748405D18FC05F0AF7F61E0CCDDEFD8055D86826038C77F2AB230F7D97C89D0EF09CE82C4352A7491729C9FD704B279449D0DD7D86CD2FA52EB3B5A582DC2057 + 85: 746653CDC44B4C86B29DE5B28254BE9198C0271249F0690615B05F23AC0456DD66CDDD13D2F22924DF530C78FDFD3699E38E29A550E2739A803FD1FFBEB29E59 + 86: CED0B3E4011A6DA0415C51E37996EBBC5041861FD1584E3D948E1D4DBD7F8673EF93910A10797490DD5C62245EE7EC03D7CE8B8C38FAE21EFAC1AE6056AED143 + 87: FD4BE7DCAC6984196FABA1D88D0FFA9F33CAA29FBAB3E38CD3DDA7FBD94866C944F91B405B3EC613044E4AF11BE7187B15D5AFB4067C54FA09215C3BAC4FF080 + 88: 46836D5A579D5158B9F49D6EBE9A43C9F4A55C768869C3D542BB615FDBAEC8DD34FFCC40288567F8C5E9363852EFF44FEF0EFC0904BE178D3F78EA1B61B9E98A + 89: C05B8745D68BB9647E411E5AA1F924C2C9B96E7DDE71D190A3B8709ACC2856ABFF3C2DBD7093B25F81C6B9883D377E721968632FA4D566F7F72E1109BDEF2D74 + 90: 647A0E15CC4BB5EB3333919CC828D68C5352F1FCACE6964F23FCEB46D0D2408AE896D3319B202EC687F3F9E55126C05705FDB909CD8CAC88304A61B69ABCF65C + 91: 2DD1C321E3CFB58C2E883F5DC3D87F01936ABAB3F1F27648B6AE563333E3852BCCBBCBF4822230E8F0A0DFE32AB6D8DE92A2B8B2271E17DEBEEBF00D83046B75 + 92: 38122D8324807E25DC8A74012CA9C0292222604303CE8B66D7329FEA394D85B7BFBE0F656895EBFD26BD60A3B553A6E3E4003276157B31B3A47779E1633D89D9 + 93: 27FFBA5DD09485E141B659E218D2924AB0392163CDE296D4109F3AEFCDB02241CF0952F0A38E2680D5CFA35363391A324E12519B58C04E8ADF0E9C7A8B6E1712 + 94: 69DA55F3BDBB1C7397CB382B7E8075F615794F6F8453313C0933D33656A3BAB07C42FF977850625B11CA302494497B0EF3A51F3D2EC2E4AECD24BBBC661C6513 + 95: EE1270F6FE6223C19AD4814F0549B54C11AE7B43A8F3418B0F7BAC42BB5B093024DD4F3AB0C9AF5FD2025D50D5B8DC3505D8F754F98AC3237344A7C14FA50815 + 96: AD8ED48E056378B1AFCDC0B3D5D3936AC825F96ABE0953E9BB85B00EC16084A4F0BF12A2B0B73F0A29ECB9841A1DC7F003456016203E891ABA1BEE13FFD19BF0 + 97: F6EB6972CB5FB156FA20A93D8695AE1D9DA8BBDECCADBA81123E7ECBE917596B51E4A6CF9E1458D882B76B33AEA8F3286CC7CA1085F09EB3DB9B9263095339A5 + 98: 40C54D468FE760A7094726B9EF12A98A1F0FE5E7112137ECFB3A88DB04B0758EC581603EFDE3610B1D76AA879EC31933CB6AAFA2DFC559C59BA31425B091FFB1 + 99: DD0324C4DCFF798F024A32A13063A05AF673CB5F8F03E08A0D931406C868A86B5071BA711F6DA80D7FD2F7D3CEE1B7DC12EA456A1EBE4CBCB25ABFB27492390E +100: AF216A7122D29D6A7DC7B89C8B41C111E7C9A00781D4A867A1D75110B48A5A9C92A15D1DC2AEABB53B83BCFFC50F44CFDCAE29DC9984C8C84FEBD0189322BE25 +101: 1FD96E1905B024D5FA883B3BF76C00A0235EE6386EABAE4D9602B5C5E5EA81FE3A1DD0D81BFB0F904ABD4DA7FC71EF7A2BBD0DC6A766902021CEB03D2578B204 +102: 31B75B047B1214B915EC56983E284D14C214D567F149EB467A1A324080AA0D80264ED771E2F91104B2642E9A8312C0C001652CF4E55308A870A77ACFA088D7C0 +103: 59B8D11078C8B65C5DF4F39D1C532BDB9C6E8F2EF121B97DC5BBC29CAF76774A7DDCDCE0F3BCCFFD4779E57D9B23102EF596B8B940480079355CDCF7EC52D47C +104: 3F1702458BA7F28460E84A032BA160430126221AB5320AE028387B60AC53DEBC42FD169A23714AAC3009D52BF9F9485C0878C06A98BB42D1568E7D038234AD23 +105: C8DA7ABB93D370CE8BA6F2B58F91ABBF1302F96799544CCABF52D5D1EAC3318AD4EC853EDC99CF86DF9341D6D794B57B68CD1FBC5E37C03AA10297F9828D5D0B +106: E1680FAF315911FB7588AA2F02D5F96A3FB02F60DC3C93117B97E4F00E2CE6862DB06117A6627B14B11B9E4C61BBEEF09134E1684599A370C61721A3B086942B +107: BAEE728FD37CBE1DAB3FD5A922E58111BFBA9BB47E107909FBDEECCB1812DE27D2D87003FC6F9F67977ED592EBFC734470CD1E907858F555F21EAFD6E64F060D +108: 891AFA38F3094E487BADAEBA012F11D3109EF19B858394EECA4C7F0C2E8FFBB3B88A7105C7D73E7252E67BBA518ABB6A312A7B8A11742D31BF53267CF3B09E5B +109: 6E6E3BE3956224A97F813DE55B3594EC5E2F4A43BAB873D902025699AE58FB43DB71DE1DC159E83F7A7EFFC19CA5A03C1EFFD27B026EE9AAAD92D1D58104D3DC +110: 51F2BA331C24541EFEC042CC66398D388348C4FEDC3F77A4DDFDA39752AE2880C68E0465C15B07ABFD93E16BA635AE7CA7D7E144018ADE57607DE8643992F50B +111: A1A111449B198D9B1F538BAD7F3FC1022B3A5B1A5E90A0BC860DE8512746CBC31599E6C834DE3A3235327AF0B51FF57BF7ACF1974A73014D9C3953812EDC7C8D +112: C5FBD731D19D2AE1180F001BE72C2C1AABA1D7B094B3748880E24593B8E117A750E11C1BD867CC2F96DACE8C8B74ABD2D5C4F236BE444E77D30D1916174070B9 +113: 61B2E77DB697DFE5571FFF3ED06BD60C41E1E7B7C08A80DE01CB16526D9A9A52D690DFBE792278A60F6E2B4C57A97C729773F26E258D2393890C985D645F6715 +114: C02CCA2EE8BED9B4AC74438D4E8B39619347922DDA5CAD2BC3EB9E4CFD4FAF7CC7EB9F6B21ECCA2C55CB60D11EC450390EBCFBA18312E49598D2BC52020DA9F4 +115: E528ABD6C315EADE09A981E4861F6148C9DD4F2FCE0EA54CD3E9796F17033A3751FE9A223AA23CDE0E051A10C2BC27C0298BE97CB87C7110667A115B6D30657C +116: 1B0BF23602D272A06BEC3E86FC675E16DFB067B2AB662181315C45733D191137454BA22713B51478B096DC51D3FC7E9730504324655AE8B7BDFC184118933D36 +117: 12D5EBC3016C77ADCD01F1DE3F792C4230DE67C0B50102E03FBF3B6B80BF913CB66C3E72530C644719003DB2FCB15196803812D89761E0B781E8AFED7268A35D +118: A3527C4E62349394274FB15B30BD95FAC27472E1E521514775D2E667A5480C5367DA6EE526AAC8D0D1226C33EDA1358091C93EC6B1B8464739D25AC4795EF175 +119: 43E497279C2CE805903A33B54B746EA92D607F7C4807986C849823B81097A9099B5896AC7CC66DF3A93EDC8A91B6F3971D6C7F5688DAF635737760BD080E27B3 +120: 9636708964C5FF6600510319E07BF3FCFCB1F4058FEC278EFB677964BA1E140C1632505452F802E99BCF09DA3D456DC3868D149A0788A730E49D239CE7415145 +121: D5D17F592D401CB111FA7C34CF5035BC08EF6B2E0D3E64DDAB08430DEEFC8B9C09C20EB4E8F98D8EBCAC6F09AA2C1DBB7C1B3B2EFE792377CA6600F703643700 +122: 0EA053BBE2E72264AE4F54512C621C733120F777D3CF8FCD8A7CC1ABCAECFB9BE93EE821A15D19467D249A27961E474ABFC433B8C7132321198789D5C2A50896 +123: C64291C217E37E754F6F57C1316FCD8A7C2AC2426E86786FFB69797C0645848CAC41DE345FF90B72FCDE918B7CFAEA4D661687E6F737A088E9296EEF4C3B4F31 +124: DEF8A3CD4921127815F4D1650FBF8B3EF16EF724A38045133749B7359FA68BDE3EEBC9CB5190FB6720EE3D24473286FC046DE0646C6C0042EA1968B48FB6BFBD +125: 6F3581DF30AF789E44C7459356E1C248749B4A5A389759DFF37826BD278D293BA2264BB808A71C453E22A2962DD33A9C03338AD060B3783713EBA8CC8B43E2C2 +126: 2681BF910DDFA680B7204037294D00D0FCAEE84A3747F6E302A16704B3B08EFBDA0E57DBB8E61E92348C8D5FC5A59EAB74C77949A74C7740C30412A9FC65BF34 +127: EAB89674FEAA34E27AEBEEFF3C0A4D70070BB872D5E9F186CF1DBBDEE517B6E35724D629FF025A5B07185E911ADA7E3C8ACF830AA0E4F71777BD2D44F504F7F0 +128: 1DFFD5E3ADB71D45D2245939665521AE001A317A03720A45732BA1900CA3B8351FC5C9B4CA513EBA6F80BC7B1D1FDAD4ABD13491CB824D61B08D8C0E1561B3F7 +129: 1D9DA57FBBDAB09AFB3506AB2D223D06109D65C1C8AD197F50138F714BC4C3F2FE5787922639C680ACAD1C651F955990425954CE2CBA0C5CC83F2667D878EB0F +130: 90272B89212C81B9700897F611F13AC1D291C33A437000C1423336B4D962DD39CE23413160F023963E12F4CCF90D2762B31BFC6818EF865E8A7CBF918A94C1DB +131: 325638D30C9F63D7CDBAA689B7AF8D23826BFE8593B361C7042D3293926146C65C2D6092F20DB5068262359860B3E3D502B6034B9EC8E7253A1FBE4B2007B77C +132: A3FEEC20C69CDAF1936795AEB9052DC525A26F5559045FE458D4B24697E260BDAA45BE8C940A06AE39FDC1F9365F32BAD7DE824FE7722A444E469C7BC198B7C1 +133: 3F80B7BFBFC9D45073FDC2ED93F7C19F01E4D49CB912BD2568F248561F9C9ED1B6762270033D9F421C977F8BB8B4A73F9A99D580C0245DD4F64AD35D68C9847E +134: C292EF04844CD7C3E477C2C2FDDEF46FCEF97E5DEA7955FD4F418C7B4114BA0CA2CA230D0F73A585EAAAEA9277D72B83DB74AC5E887439A225C105B0BFB5A38D +135: 9F0DDAB7986DA54E65EF6B536BB4F7BFF468E0F310803DE28D3908492343E4CAA855B8CAC7409E3A8928E63B9C5D1CAEA7A408ED061809DBAE1AB1A67BA1B926 +136: C58867D309CA48AF74B4D7E49ECED514C89FD433F9DD842F9B50FFAA6C7810BEF35348D00D26DCBE28122BA1CE33D4CD00D09BA76F982A598B8F65790368AE59 +137: C8B1D6B4778932BC21EDDBBE4E48F7711D7E97ED5354DCF11BE98E3110510FB007948C288FD2F7AA71B2E41C86330DBBCA2ED472D15B444828C6DF4282815879 +138: F1C0C057C974E4C27E497EEF52A02963D5957EA02C7E1CFE06423048799AAF74475732A7352220A914BF32EBA6A0B6FF28C77D25CC3CA1AFBDA89870F4EB55D7 +139: 092E121F2C7A2621AA36AA9B040EFE4435DD649E3F336BA82788D57B9B164184F5B5BA644DB4076B46FF9F3A6B9F58D775CE94FEB648A372D960471A663B74E1 +140: 406A5382E9A563E60FDE5CC47F52C6DB86CEE271BD3974AC6E274A1B8C5A7EB369A9B7CD312C301F891D4E3A601A80B9CA06303C53CABD5D3B7834DBC5108470 +141: B2D3EFC2390CF7A1093B93C52B76D0DD74BC277F3D67A85F41635F89E923AEBC960B2BDF8A13860CF3083AC3FBA13D4FE5E426F144FC988554E89ED7A0324748 +142: F1F7100636AEEEC8AE93A2CAF1F4852F192E1EC1AF13697765CACE58FB40B9D9AFC3BBE7E52EDCE649F53C1BAF653CA20E75D3E4AD549D05EB33A68DD11E1898 +143: DB604416DFD0A7DC509DBD2C83D5FEDE5E31D641EE6C14390CF599CDC7D841660AC700D3DE4BE35E07006B724B7DD1BAA21EFC3CA6D346B3B858384FF691F913 +144: 87AE00E496649511C3BF947A65805ADB5D237AE8486CBFF01EBE52D5D5062A99DB3434EC22A37DFDB4CBA1A59AF1FA5825EE3DB2A8524BDEAE07F3264989B85A +145: F442BB697D498F2026FA2A5FFFF9AC5ACA0052F6D200E10805104D91BDFC71A3764CE0277009229B9E7C945222BD7C9085163987E4CED02ACC7420A96B0F9587 +146: 1061588877909CAABFA37D4915EEBD6E517B8D3EFD5660F872019050B3C1465F11FC9B44E72610219F3F5F21772933F101D9D58B5C5F79FD7457F95749BF11D5 +147: FBB4C9BD6821A04CF154DCC7A7507A2C655739F3636B69E8183418E2C33D951DE6BFDF2C3CA603694C44DE44057665EA4835281A2773CB8A84965BE02DF1F3E2 +148: 08D54B05F901FE95EA5B56BA19DF9120C66AD004F98BF8FCBDA9DA0874E64978EFC34877B8224A024DE12D7B926B5D83068E8A704EEF0F738A5061E5F8462F54 +149: B79F53A5117503B5A0316F801B8D448079F38CB90CC39BAFD4DFE169E3C931D622AF7E26835C9AD4DB25C0D6A684E7DAC4B88B475663E05601A99EE9FC8922EC +150: 2209CF6BA43F61D7E579651EBBA0890686A9CDC1E045255494DB0BC732C9512ACBF72158D5738FF63B500AADCCBA000D25A521D41AB4EE6D92D38E8077B79C07 +151: 8236F7CFFA68B49BE5C38A7A1BB67B745430D1511A08EF347383C32AAE1EF4AB2E7F63A20C9D8E5CF2198B32B7BC79B470D36BDF12E7263D669FA4AB8605B75F +152: 228BEFE5788090066D493CF87F75C666BC3C75E0B7BC63E80D38340CF9176251C6E185992B244D4A5B1CECFA42128DAE6EC3ED535AFF039769E364048C442DCF +153: 59171D498BF80731E2E35D0A32DA356419E69B8BAA5B1195D690CD8A5B11542087A007D8DE3FD000BFB03A0408C08E92A0C7712924373FD67A65218E4A4E0F68 +154: 4F94A8F6A136E49069C88DFDEA9361B34D68FFC25724F836CCB021BDB74E0AEE9DDFE80B938A5C12B01F0F1CC49C500FE7709C2090F809D9E0256FC93D93122F +155: DE5E17A668F75866262BBB2089C9DD86775100C77974161DF46BE02A9578855E7C81C77263105C473FD1A2D55483063970C0F643CB25AA4B4AB45A40888F61FB +156: 3314001C825DFD2CD1CE08C746F0BE5C451027F0FAA401431AC84FAEA51553EFD9E0646FB7E9B94CBC672DC98FE9870467C176AA648EC72BF61334B13E479E4E +157: 3EE80B1422E3572B46F7CE5841998BD2B6DF3B591FB5E46851B4D54BF572A17DB5963A04EC6AB98BA07C943475AC088B4D201AFD684F30F45C8037400A7C9510 +158: 3743FE18BD6AEF36887EAB7BEBCE36D5D3B69DFC306B58B1E8C6241E81A9D38425BA991A29C3B07D4F4B9C5CC762B2563C9E5A05B199CEA5833D9FA0062D161A +159: 7F9F71B086CC6D6B63052767CCD6D0349C076289F63483241CE105076B7549B3187897D45D7B5FB2147E54F056530347A1F9265E6F37953B5941272A29E2FAC6 +160: E09CBBFD3DDBB24755CBE8E51C8BFF1BFF36E571EE72E6C99DDA6D507AFE3C562D437E8612B50859AD5CD608424DBE625E0162E6CB7B838F20E7B2F93F40ED91 +161: 2E2F91BD5FEB5C79E98ED97C513E17D2D97B02A844780A0190264773C3040A2CF07FCB0E6424B7A0E88C221BA3824C1906FC1647AB40DC13E2D0CC507CBB6BCE +162: 8D4E87F66B3418105CD5583A92A2D2EBE8824E1F9150CB872FD3DA9C93D382C08065C818E1AF9B25875B142E70676D9A525D901EA2142E42D813A221D21EAEF5 +163: 0518E420BB5680B74367F8CFCF7DD32F3AAE009A0067FEC22456CEAD0832BDC2A60D8AA7B0A2FDCB9072C0F1171772BB665C0B28CD184609F63AD53F89597F9C +164: 247197FBCBEE77B8EAF6358F71A49D784CB43FB44D99910B0599E69B29E31C4019E830F322D5A7117A996BDB4D91E5CF323DB354E902E4DAEE8057B3F78ED5B7 +165: 35A7D806AF0C8167D1505B25EDB565E931864C453BF60AD7B6695035D7584E7714E21F377B35A5F3A69878835617B951977C209F5F3C5967B7DD9BEAA75A7CAB +166: CA9B60EA8DA2D0BBF46742E31AE882F5355688B071883F690AE775C4D949DED8077170F26E89A18CFC251662EA8D1FF43F5A5F28E3FB41ADD741AD2E28341A79 +167: A861DC64C745B0F5D3EFB2773C51981A836024BC420B1FCC564E03006163B491126AD8633FADB6DFCB25C2EF92FD82823FE2C7F1161A78C7766B5E21F96BACB8 +168: 1EE6CA0866F227B27678326FEDA4CBF59934AB0EA2E874E9EA233AA5C67141A05C1B4C950044BB6C9B9D146520C2E3779AE44187BE0DC1CC41FA7F72500B249E +169: DA1032057A25DA7EF987A2D7CF28B927D3DBD956979679F5A6BF4EA20FE1080BD8AF2DC8B1C7E236E7601BD82CFD64DFCA7D03A03087475ADD57EADFFEC2CA85 +170: 22E41325474C7C7EE980314D7738947E9CE3A970B2D28BCD69D545D5E795ED50A5A1839021645D000CD4779E181A65974171C15B9B08B349205B87C150688839 +171: 5FC5AD1B8B7622C4D17CCE23679FC7E0CCEBA00C1FD7178245206F866A6BB198F26A05A3D429E2C508DAAC6D0F698FAE6C0DE7FF971EACEEE84813110672F3AB +172: 2264F674AFC9743A46180CE4E4AA6A2BB33D6BF2F62AA14648179400806D718DEE8FE57DA48D88DF5D57B42087BB2FA62F833BFF87B6678606C6336CBCF34B3F +173: 65E9D1187801C74FC23C4F19698F6B93405C681B93A80D23D427D9F2CBFE63F7E2959B2AAD6CD7EF6E987A5FFD585E1BE8E314A1D502FAE80215C5331F8FFC2B +174: E0436B17C2BB096B08698F4CB448287D69322C34814776E0B1B21486A2D5B6906889A5B198FDDF699AB285BDF58783DE7913075F86ADA977DD35FD09AF336E21 +175: 857BE6485722B4BE445B72C7A15A1D0BEE6C7FB2AD541C2B4F0035DFA1EEAA10D4F0BA5A124F985DEFA53D0A0554BB258B2832BC2CB5B7787D812E96A55A93DC +176: 7B2298654B95CD00307D8D983A0079CCCFD89E5788180CAF352B6C965B9BB5153C9DE25C4A0CBB5E578859660696C887280EA378A2E02B7C7F9E6CC635509EBD +177: C7ADECC928EF065C263A97A273CE8CB30485BFC035F2FC02C78AE2AC6B7F7ED20E93897C0994CAB8D584EEF9DD475AA1613159A0C862FF179C67120F6B4C72C7 +178: 041A03CCE6696653ED5F367749AE1AF3C2654E8A9C0E70E467261E60023876C7271CAE545D114C32D38DA75389525CF0CF1FC0FA9A481ECF43FA0B1F61B868F7 +179: E652E4A88EC1A9C4678F8CFDBFB1D758774600255165E2B4DC15F61C18B9ADE14C5ACE7E8AE72D3062B7F1787583C55B14B347F642344E71D6E00FD6F4C56808 +180: 903675FD8C70BEBE9FD0DADAB17A638A2DD8089AE63114E36D28F4C75D951D75B0BCAB5247803551862720713AB45A932DBE141E48E9BF3ED9E76201577DDD43 +181: 6E61016D474D2AC2984E4EAD44ED82B7129B0B7FF0B9AAF5F45CA68B0529A736B846626CEBCAB9E7CE374D744E7A09C51BBBC746D989806F1A00703A002542FA +182: 20085D4717A204E896F10C5F7E1FD429C9AF848FFF608A2C46D3738EE4FFB944381880A7A455FEC6A1A21754D9ECCF3F1390EA22EC17FCFECE2B86E361784045 +183: 37216CA069259BA3244DE3933A3AD5F35712F0AB7B9C81D64000F0B91DD4232B53748B704E7ED0DD682A77D84BAC1B943D2FF7A3DBF5FE33DF455DDB10D11632 +184: 1F2467A57006D96FDC75A8BDAF98907AE72AD330C0418B06513C33D86DDB800AB6A51738DBFDF1C44676038C094EB5F309B5B590EAAADA4DB09FE7590FF04888 +185: C45893F92AC3E3AA3BC86A9ED659797A7C7DB949A66552ABD046DA2AA7DA9E52FF8BA2673CB44B2CB0481D599EC70020B6D5079296F2C19DB162DC8CCD64BAFD +186: 9919574ADE9B8640BB0EF45F98D1DB6FB7242C433D86CF6D4BD67AD14FF15D74A13F796429E312BAC581552E6597BAD2792F31B2488ED300C6118891ADEE9FB1 +187: 034A92D00A172A5F0CE717FC38AB8D68019F500493899401B563845EB604ABE0907749AA830F91B53AA7C89DFFF86664F8B123AFF4721D790A58CC22F36A560C +188: 54714E69859C60B07C7FE34859C855A37A82204D723F1A695F78D7765CE906D109FA6144EBA9E7E7A7D8343A99495E72D160DD468BEFB794D97659B8E2D8F1CE +189: D6CA476F7E68095DFCEF4338BD6466FCA90DF78A17DE9E29111D4645B0DAA0C6E98F156C0EBF9134BC28EF9E0EA67E6D839027DD5CB084E9EBA899DD3413E222 +190: 86EB8C026D6BF090636F01F623CD98B960D08E521E44697F364BC1AE1655B9AD6FC3EA38C929AC9A244D18E697342594F3E7DFE605954579AE4042CA69E65AC3 +191: 1F63EE615E9B809E3661C77B5029C78A92DC4BE3CC4DFD8BBE78DC7B7D990BC717238004969A8B854CBA04B4D9B30AA1A1964264C47F23D9BCDF45C74FFFD918 +192: 0351F475C711D068BE7B0395D65343B5E249FEAA3C3F3B6B87100C50306EF0340F60EF36233F0E6287057EF7BE8634BFC4D46B49E4A8F2CC4839F42F486A16FB +193: 16645F9C0ABBDA602B7436DE3B1C55AAFD1E844057D51EF80A96CBC2FAFF6E3B2706B45069C90A52D779E101793EAF4C9AE85CAD0A5A394164F0BF34C189A2A0 +194: 821E46199F4FEBD9C118D49B1CE9FFE953113EB6E4E33DA9E39C676399A0B3F792C2990A9F75D729E58EF750857C07336526631CBAA5EE0643699C8E7B7EEA13 +195: 64CB83ABF2BB0A94451F2B9C3EDD76E4A15F9D1F9EE32C0607F5E0951084377E484A8259B3C64428293396F78E6674CC3C027CED1BE12F5671D328D131740770 +196: CCC1A68114DF54BF467EC49CB15CE381EBA7E6FF06A93EFC88F442F8A35827D5DC6494A4F39E8423167CC1C3269A3EE6AE68825FE3E2E40EAFB75C8D878FF88B +197: 94D38693F1B1A8F1013544419C5B3BA0CD79B72478A91CF3AD325E4C3CDCE092AB667572233A4F8DFF132401968BC74C553AEEE96D530CA4E5F6D427F9D2C422 +198: EB080E256FA9A5D51C3DF577509B877563958704C0F1DB645F75CE24005D3B12503BDC26FD3A66E8F6882D3491428A4932EED6F5F58532FEAF521BA5FE05B70C +199: 9A43D7D0C42D7B5409963339C9D9805BA59ED8A63DB144165A3C759EB9F5D756E6288308DD2FE460CC50DE26E1A1C1747AA165FE6C8A1FD5B0F7CB1373E28CAC +200: 986058E9895E2C2AB8F9E8CBDF801DB12A44842A56A91D5A4E87B1FC98B293722C4664142E42C3C551FF898646268CD92B84ED230B8C94BED7798D4F27CD7465 +201: 9FCCC4EEF7571A2BEEE06981856228CEDAF3BD412E777F4AE8524B81C373FDBC210795C1E788EE7081BA42EC3FAFACCF2F386A9096AC719E6565B4E384E390E2 +202: E4E8BF0BF40249236FB88C442E6668E3067ED6001189053A3A81EB755798911258E25CACF7282811DD5E5147811844C4B5BF52FC24A6862BCAF9407F2E38EF5D +203: 317ECED703044C1BCE944DDA7114DD1E36244DF6A533790FAADBD0B8DDF1AC0D198B593F0479A038198F4B94AA6ED294168FE0EE800C02E769EE78ED45249945 +204: F5FA1EDDE359173067E463107FCDF00EF227CBBA0EC5EA02EBBABE2C79B12E793B98FD3A90A72BC26240D994F53DED65FE22C6FE87EAFD01B8478D1E8569A882 +205: 6323E2A8E380CE86433D5B8FCC5E02FABA4ED7F9CE5BD194F7CBFA36F65844B61A7BDF8F131CB4B28C56ACFDB99CD84830557C571FD369650B4608376BBE4FDC +206: DC6BDB69D1C6111E280F993635BB59CD6E7B189166DE593B71E194C5F218D67B00EBE0D028E944976D6538DE410C4D86A2B6F272BB94FFA590208C644F99240F +207: 2428590D2043634FB10268435EA90ABD082D45317D2C54D065529F15E180438AB18FE4CCC9129584804EB04EA1CFF646FA881878520BC01AFF392B6D7D9C0369 +208: 1A29341BEF679E5351911809DA190BAB8E665A9375BC2D477742176A70A6BE8ACE4A35645BF8DB97AB9BBAF1F0313004AF8B4CF10ADB26AC0198AB1D45D05C46 +209: 0EF4FCF3B2010921C58056B2BA367B4C09F5325E6AE9AD732AB277281D4BA797A847B1C6A74D81523DEA163AB0E556FB5102C14E8CD94AFBAC0AB0A921BF1A25 +210: 73C65AF2A53E8860BEE63AF0BD8A457B0AC8D3C5D243FBB1BC3D67624727CC175F3CA133B26342C3401D75DCDDDAD9A692D9A2B1264E90CFFD4BB9E6E775DE15 +211: 18D3DE049396E2EA541E15C31C0EF0E0BD90CCC6CA35663856B94F6F18160D616667C55F3ADC1B33E749F60BE50514A4F3BE48ABE2E18FCA10F85ED0266972D5 +212: 34DED45ED26FE224E0C5A66A193C11A2CC0786E61D421034B3BB16175019C95453F20BDE865DEEAC5C2BB5C86544641482B51C4E61D9DDACC238D050CFC35776 +213: 025D211B55974BAF086B139D8FA1AEA75B627CE1AB894D52F8769874557BE5944D27FD4BA3606266BC7F50D1734436C53D4555A1D2DE0DD2AC51D7F2FA373867 +214: 08CD521B1F13440D57001F30BDA0029FD8AA17FF26AFECEFA2CB7EE1812FC79A694ACD0BDA98184154B72FB7CE305FF4897F466CBB3972B4863FC88B3DA52C28 +215: BA3BF464071BDF124034CD122451D3374AACFBBC916C858B93E191006235F4D741564BA1DE70372269C122D360121DD3D427853BA76C6B450BB46F4156EA7524 +216: CB0B3250639B4ED947BE0C83EEF67D370DE76AB901F607F68FBF1BF8ADA15984DDA7BECAA4D7FDD55FBFE479EEE3F5ECC9CDA7BAEDC9DB7D35DC227411DCF20E +217: 8AFA4024BD96BD50323AFDCF92A7F3E7BFB4C927108CF81C01FD378F61C55D850020DBEB88C6528B8FC141C37EA4852481C14902878AFDE51A7F1EA1612D0324 +218: 27057269EEB73333A1A8059D6C9D6FD5AC89EC26500F6F9838CACEC20E93F1713CF5569E820BD80969547D77E56AB0CBF57F03182EF45AC8BDDE114470C6DDEA +219: C79C3D4A4608C7CB4A3D0C14B28CBB96364F44DD8651F36D908AE502E547AD7AD5DFC10DA26CA26C6D9E51CD40F6D7F1BEA0A03358967D867A97333DA8ADF3AF +220: 9DC3B1EF11D85FF8A57330FDF91D5B5AB142FB89A72D880DAE476E020755C2F3B4CA58C9ED36239E8807C059BD66F826EC517B7A44187E7216E48B683B567076 +221: D11A97FB7B967E90C2D39EF42EBE49327CD58EA6977C84275B01698E322DD97024A40FC3EEDD96207310708F737E81B79659A6C7202E96BE7AA34D18D4026F63 +222: C9BD62C0FCE47736ADCD9275B46845E4ECA23B73678693FEB8E21909EB8405D4B057AF2AFFD7E667E047A07E6ACCADC2A58D7360C17689769DB009F0A7795560 +223: 7FAFE6ABE7CB8C109B18A14BC4FC2E4FFEADD55A43AE7DFC58D89B9CCEBB4467FE4CC163FF6EB16C8C71B8EFF12E7891D11D3DA2C6DFA8152DEC52B232267B6B +224: AEC37B2A1157708142BDACFE77E5204174F539D86A12730BBEF6386FCA098AFF2A5C31EA1AB21D3B4537531DDEB27CA9DAEA22F5CC8C9956B2F2595F53BB931C +225: 6B005CC923D9AFF56334CFC7A5E3ECD70E97C4247EB372A3180E7DC5BEBE676E72E2FDFACB74277B70E15D871819626F46661285DB04B3F825C49EEF42391B5E +226: 509B5C993CDF61F8F507A84BBD7D6D7AB090970927400043D39E5F47DC23AC289F5BBF9D3246EDB174D9C5D72BA7A066DC13171EC15FF9508911464F8730D395 +227: 00A05302C3A60E58C4C52847F47379212A918060931A72BC660D88E7BF5599DF6C38DE92452B4823B4725BA3EEE866235CCF4D5903E91714CAA230C6D6EEBE45 +228: C4FA5EFAA31CA205A732FCD5DEBED53C09A4F30C5BD9ADF27F8C1DCD4B2730925BB6AF176E2E680B2BE325F7DDEFBC9EE6C1CBC4F0426ADCB5CBF18D1437EE6C +229: D125006B8107FA63C375A79AAA0EBE82017372B7CC65C3157CE078DDBDAEE8C569BB84FD8490F2D66D15FE73C6881245761AB2B1D4F056637ECA70641745CDA4 +230: 01C7D098DCE4E40A69DE14682587FF2A40BAF9833BDCC6413AB54DB0E64262F290D584CD5B21C6558682C50E1E27BF53A18A16D72ABDE878C3522156C9F04DE3 +231: E863DA51CAE09500F589BE05CAAD5788587E2017907444D76F547D6F30632AC658EEB8585733BBB815D2E19EA046369ED3B81AA773FBFFAC316162389E015A71 +232: FD8232F7B79BDF9CC52FF0D5DE1C565E9D659BF19769096895D182A88028C1CDB7387DD240128A7ECFD2708EBA7E9E3C676D6E2A036E1B993940F5CCDF1A736A +233: 3BF8572CDC7B825CE7F3222A3DB87F1C52FBD1A8229B957ACFEF2047C560567483C479603A3C0B0F1B2DD265BEC257D1A32C651508D7A4DF501BC015657DCAC0 +234: 23FC530B031136A17B8B2FCB55046DE7271312EE3E77851FBDB05F78A294815CB2169079168E07647A2BD5D05C1BC2B1EF1B64B929DAA1F9CE723D448C936FEC +235: 83D10057C7FB494FAAD289B4FE5F093DB2A0C7D79A298173DA735CD5063232BF9E5327A7B4AA795C99F323045790B554476F37EB9D04FE3DF40C047E4113A720 +236: 0AA201EDF4124F421D4515554A1A642E3B9D18C70E09E83A886D6F0CAB0750D9BA1FFEB9C587F3ACAB0D8B9C1D83D789102F0E2A6CFF885C50F485929DF4602D +237: B85CC52981751513B917F58305AFFDDC7D901CB3BB1D1BF5DAB058DEC9B8CDCD2DAE543D73EC6AE0889C9D785F9178D207059D994E1C80706EB28AE65AAA100C +238: 068FED72E55444AE108EEFBDD59A96DA4AEA3D81A6642742C38BBD4EAAEDA6EE21FB8702C2F95152F1F997A5F40F06C54619481F2EC343AD33400913D6FDB4FB +239: CB4C7FD522756D5781AD3A4F590A1D862906B960E7720136CB3FB36B563CAA1EA5689134291FA79C80CCC2B4092B41DF32EBDCB36DBE79DB483440228C1622A8 +240: 6C48466C9F6C07E4AB762C696B7EEB35CFE236FCA73683E5FAB873AC3489B4D2EB3D7AFCCE7E8165DBBF37ADED3B5B0C889C0B7E0F1790A8330D8677429D91A5 +241: 4F663484EFCA758D670147758A5D4D9E5933FE22C0A1DC01F954738FF8310A6515B3EC42094449075ED678C55EE001A4FB91B1081DFAE6AB83860B7B4CC7B4AB +242: 81A70404857420638D72672A2DF5A49D52B9F9F38B385D8C5129D6A2B82A682CFEAFE6509266E4B00F6B6A07341C2F64E4D4F2152583ED143E3DCFB14C1C216F +243: 31F655A1334E1A45584F12A22E03B09E3C69ED0E1D0FD573AD0D56F9C86862299E333ABE78590E97EEAA5C2FB14DC9F34FEF6DDAF6E7A9BFBF68CA6631195CE5 +244: B62C5102F97E5C4D7554790A4CF53A58D3EF44C83142D6E009BD1F6FC8F3A19AA1B89DA8DD9BD1310827A5BF662BE7CAC750C48E6ED91313E940D7D9E5EB9C22 +245: 380023C0BAC4C9524FF6778BE80CDF195E36FCF460E8CF1BF04E5C2FE08E38C35F183FBCDC3726FF26423F351C507279F6258F2319EA1403B6C8A3DCB384AC7F +246: 473FC167C7C4BC40B17DA039EE09FF3DE884879557E40C52C1981AC419CE021A090BBAE014822D05714077008988D74FF151C927AA43E88CD63FF2CCD2012AF4 +247: 006086E61959B1D66C72E754427EAD5E1D6C02D8409F5C32B2F5AE448F54682B504A1ABC0346CCF39BF66A8C7B69081E886B47A7D0B02291462391C95351EE40 +248: 3828B2ED548CFD0B74BB34A1FEAE030E267222198D7E387E7FE3ED503905A25D4C3301A9A47E78372F685B05847062476C507708CDD75580ADB579E4CDC79AA0 +249: C26A7D5BB103EDFEAE2F1201BE58AAC127F69AE378DB04156074E991745D4AA5AAB3BA064407DFDA8D34E573B7EC1F9F37CEF01ADC17FAF393C262A09F2C4736 +250: DCF82307195035A668097514FF1A10E0BF0E802B4945A702D2E17AF6DE1D3D9BA49616DFD16D802054B5219CA37884385E87A713B4EF5C7FCB69661C7F56D5E3 +251: 46049EA0DFA5C49429E15626AF4AF2CE0A9DD2F308B99BA6E6E3F3088250A146870FD0B53228D5A1F1BF9859480E1B7A3D3DA180AEF4D5D41BD2951C4E19426C +252: C0A1FB6C0A65A0D1AF46A5FE86C8A88E8A86F83E36317F435542927C98E74833C887CA3AB5E792CE5E3E21CC6C6AF437349F5A66FAFC4DA79742491C643901F9 +253: DCDD20CD47B7C7D011E9DF7855B08336BD5007C4435208BD3B914D7E503B8399164A155697E68A1B88A0600BDCF847A114D98FB773C81FEC817B92057A6998A9 +254: E2DA07644DAA73B66C1B6FBCDAE7FF28E3B9024F0BC5408FE02C18E3744CF9BD6DD54EA7BFA1F6F3A81C8560FB938FDFF9A38A29853A3A819B58D10213A290EC +255: 15025C9D135861FF5A549DF0BFD6C398FD126613496D4E97627651E68B7B1F80407F187D7978464F0F78BFEEA787600FAAEBBE991EDDB60671CD0CE874F0A744 +256: 1E7B80BC8EDC552C8FEEB2780E111477E5BC70465FAC1A77B29B35980C3F0CE4A036A6C9462036824BD56801E62AF7E9FEBA5C22ED8A5AF877BF7DE117DCAC6D + +Hash: rmd128 + 0: CDF26213A150DC3ECB610F18F6B38B46 + 1: F069A435C14A8D4B02A7BBAEE02D0BC3 + 2: 48456EA1CD4C51DD8E1130F625DA4F8D + 3: 6E41F2AE95605779C74CB5ACDFB361CC + 4: 0C7A6C73E99A5C65B12D3EF47ECA9D2B + 5: 3B80361C079D1B67933455D00AB1428E + 6: 0F74C4BFBFC740A027B1D5BB9CAAAFA8 + 7: AA54ED5DA34CE9205B64D138538C0C1F + 8: 08445C3C3E71434DE375CC2071430EBE + 9: 1FE0AE641DEC6F8C172F0E27E9E73B9E + 10: 4E8152B7EA8F7A31D8649A51389260F9 + 11: 0F851C98C2B997C2459B34CCB209E481 + 12: 52D27461FD7E095EE3C6ED43BC24EF23 + 13: E9F3489135F3D90EBBADF9F916C34920 + 14: 36D527B693D6531A5E4E15BDE9E4A670 + 15: 57433A07CC200953B7FD440253D5E476 + 16: 4A91FFF90756026A90A83927066EC911 + 17: 5A247C26BB1BABDF1009B6B4951FD76E + 18: 002DA29AC9F51F065A1E371660BB67BE + 19: CFFED09ACF01DEC9D3891033C0973953 + 20: B78F28AD3460C99D428AF24E2787EFE7 + 21: 5E203157AB6BAC57660F3D25FF615C95 + 22: F128F5DEC3A24AF34AD3E7F3883C8051 + 23: 2E05AF10A6CE9AD1E0C0FBCBF69B1C9E + 24: 67FAFD9A5CEA5D41863D03AF2932C5CF + 25: 5ED7E86651AC4BD0EEA718C773812977 + 26: 6BC74F78256A98761981882C3CF7AAEB + 27: 44CC573B964002D877E79B75E4433E41 + 28: FC02FF53665B52B58DE38784E2C28E92 + 29: BC4D69312DFD24EEA219F29FF2AB2072 + 30: 0355E82F130341EFDD997EBDF4469221 + 31: 453D500D997FC85F6AE16365D83ACC05 + 32: 42DF4C5A3844F00F77ED84E125237113 + 33: E782D7162BB54E735F7B9FDD75A3F14E + 34: 78993013EEEA7B14999DDD3979191D74 + 35: 27BFCEF540F0782E9A28328E8DBEE59B + 36: DCF00356DCD264B7E359F02D7D2CDBB3 + 37: 9EE0BD7F55EBD844A8D114F83B3E8FC3 + 38: 01EF8F3154BA9B9B817AE717FEA00A68 + 39: 4DCBC2AA56D785CE7249761791442BBB + 40: 10282C07B870BCCE0C8DF9E68B4C5DAD + 41: 0757B359AB2D1D121BA01BB345A12A87 + 42: 450AEDEE570A2E9B1A19D5B4747B2AC9 + 43: 2C45713898BD259B10E2352BECFD6DE8 + 44: 3E92731175E510FCD07D28AD47DDA0CE + 45: 6A8E5690AD4AA2180966AC1503A81A18 + 46: 820BE195E2AE85C115BFE3C341567030 + 47: 9C97E1F0E7DA29A0527AC4F59D520100 + 48: E1257842EA15216543BFE84521B9FDC3 + 49: 42BA484CB70A58EB3EB5DA43F1D5D5D1 + 50: 2C674397A81CA35EDF1FE77B442BADD3 + 51: A3E07C012A7C67D2B6557F4A8B4DD031 + 52: F01789A2E0379CE16D87EEDE671171CB + 53: FFF1657EC846507BDECD2DD829DECDA2 + 54: 1673DCE23D430948AB818D47E83BB5CD + 55: 37CEC696967031AB2122155998A07F51 + 56: 320B7D4DE17A731B9BA5CBB48956D605 + 57: 1EB07088E5F563DBC5DD988ACB84B048 + 58: E4DFE704E4C25D06224D2560B4650467 + 59: 6C072AD491BEC80667A6D71D9C8F2FF8 + 60: 53DA8AE3F36FA8F85072A89962F39B76 + 61: 40210D1C7A728A27E1B5F92057DA4765 + 62: A4C4E5F271F3BDD74C560787718E8816 + 63: 4466033447F1E1C9BB107D152BF06051 + 64: 406C6EC2643CCEF38F964864D12C9191 + 65: 19F725CB43B171DFE18EDCB90A9DD900 + 66: EFAC3C9FBF1AB0C0F3601C18FE3F0212 + 67: 9B9BCD32F735EE353D33A657C2292475 + 68: 68F4A4294C640BBE4B1E90FF107E05AC + 69: 3630FD1C9542A56C851140A7D76C0D00 + 70: 21AFDFAACDD8FAB91027A61F8DAB6C91 + 71: 2C7AAC93B6CD1F8E23AAFD49F04C69DF + 72: AE4C5124059CFFB3B823E68FAC8CFB33 + 73: 79E95CB7E752863AA87A7693D0677D89 + 74: 1B491E33A96D9838398A4F624E773DAF + 75: 1F3986FC593D8A8E927C82DFE1F538F8 + 76: CE64F09024A907E76726E29E1364E606 + 77: AC98817981B59789E7C7E9CB9F70FDC3 + 78: 3827B4B077493B289C25EC3E91B36D26 + 79: 75295EED68F750E506C60A780B7F0285 + 80: 4FA47F32992EE6C96C3B96B6A69A6656 + 81: C52E142B7838D731FC036517003FA73E + 82: 3451812871ECD1C09E4A95CDC80369B2 + 83: CB5261A793A55DB33016ED27A35A20F5 + 84: 2D06368ED98E266E81A3C6491BC24890 + 85: 677F6509BDB3D44BCFB088A81BFD96D8 + 86: 6990256193FB0697862AB5A45FFF082E + 87: C88D698EAF83E446C025EA915998EA01 + 88: DB8F672EE8129BF4BCE25704DD57BFA6 + 89: 807F491456D7E28A36AD6E934B053EA8 + 90: BBFD55A483CBD0F9DFE18FEC5070A166 + 91: DF7735106411CC29535664D85ED81603 + 92: 24FE3535DFCC295C2F34F3F88CACDC88 + 93: B80CDE220C4199DE303BC97FEE125048 + 94: 8C252310E9A71C7BC40C3D2011E24EA6 + 95: BBDB705F5660C50C5B0C87CD812B76FD + 96: BD517928591240C7E63C8D9F957F6A4A + 97: 78A534AA0F4250EE83D752F3E6940148 + 98: 3346EDA882F00D6073D133CE609D3B83 + 99: 51EB1D3235CD35A2386E314F815588C1 +100: B4860192E79C1233A08FE595C084315F +101: 79EDBE3E80887B4F741199295347117E +102: A2793EA5F25492D32D315B3923E945D3 +103: E398223EBEFC56D3437AA5FBC5345CA5 +104: D3E6593D69B24069AF0374671E466930 +105: 12D63F5AC48F99BD59EC863B61952C1C +106: CC99A81A22B62A0FCAB4AE889112A8DC +107: CCC82CA5D35A421FFF313F90B9D1A675 +108: 5B4A2912071CC36CEA626F9AAD34F257 +109: D21FC82D78AC98C5DA436388AC9AC6BE +110: C2F22C7C16DD2E1BBFDD2BE7915B869D +111: 2B5AE5D14DC053558A1702959367760B +112: 7A6A3A6553B2C3387BEBE119E80CFB2B +113: 7E2206BCF666B89341CD7615D0291E3E +114: 93D87A658259C7E9FDD0BCDF93A24356 +115: BDBC0B062FA3D743C1B070F2AB43D180 +116: EE0A575AFFC966F58B91BB66CC1E6B6A +117: CC24CF8DF0798ED2CCED077B06AF1BAF +118: CBAE264BB4AE635A15D8FDCF7F9A6852 +119: B879B9BBF61B6F291A8E4645B70EE06D +120: A6F88AD4A16F789A58F178799279B40E +121: 3DCB6B1674608B11F496F45C9828F90C +122: FF34A1C7748C5B5F2F014ADF57241C43 +123: 1A77E2B20ADE5F286705251495AF04BC +124: FD47EE73738626733CC63327D4F5EB7E +125: B9438B50CC80CCE0303244713853A0DA +126: 040BC7876B31E22590F5898068B19859 +127: 16ED82C338495D067BBE1D4AE73345FB +128: FBE1AC0EECF0AA2671A6F25733E9711B + +Hash: rmd160 + 0: 9C1185A5C5E9FC54612808977EE8F548B2258D31 + 1: C81B94933420221A7AC004A90242D8B1D3E5070D + 2: C0C355CA556CFE356ABC0A5595BAB1364BD86444 + 3: 6D8D360567AC2CC8C4EC11DEEDE0ADCACDDA388A + 4: 04DE53FED2BBFA80FA79698B4C5627536FB620A7 + 5: 9538F24F7432E952F030BBA82C9F744365035197 + 6: 817ABE77EBB7EA159AF7BA7DE1EBBF034FE6CAFE + 7: 340835AD791316DE50DDB59838F3EB13F5521228 + 8: 64B7269FA971B162612265C73B9911F53EF43B63 + 9: AFDD1E7F8E39C63DEE7104014AD9EB32B855E0F0 + 10: CD2E472470BE8FD70A306DAEC5C59F485EA43929 + 11: 550844206034AA74E37D813FF29973D3000C1DBF + 12: DC24FD5F309A7BEB9A7CFA7A354F2DB2CBC15AFF + 13: A814B4CBFAD24B7B92AF0E16794A793DC16D10A2 + 14: 6C316617808A930BD29972B1142C0AEC89EF00AC + 15: 3286BABC7C4635FEC52F67CEFF1471E122D50258 + 16: 696C7528A3545E25BEC296E0D39B5F898BEC97F7 + 17: C87DA6F87A65CBCBC4B02BFD6D01E26F8047B5C4 + 18: F1AC2E0951EA5875B71723BA1A2158DB49EE073D + 19: 091A39765126ED406254E7F810F02E0A6124C6A3 + 20: 4002C0305550C5A726705DCF8D3880C54FED0453 + 21: 2B59904E1585334B1298AAE6EAB06526CAE5A232 + 22: 0EF94DF816593728611664F4ED6A0C4DA28C5AA9 + 23: FE7AB8A5B0CA3C86B6524E3333490D0430E9A4A0 + 24: E748023DDA7E4B77DE8A4424744331EBC62A6590 + 25: 96147FE511BC64D9493C795ADE8FC71A78FA8C23 + 26: D81D7D3B46D5BA875EC2604814616230D7A075A1 + 27: E8245E6537FEF146A2CF6AF9BC54472BEE6213F5 + 28: 231CAE27B96A78767A0915A529ADB6B72A8006B6 + 29: 4D6BE5BB6D29A15A259C8B7BD4827EA82F514425 + 30: 3B00599329120E535A5D1A46F35AD03CCA27F9D8 + 31: 2AF4160DADBB84707F7355177A4644E4CF577DFA + 32: E6BABB9619D7A81272711FC546A16B211DD93957 + 33: 1E374AB924A652FA36B395D654D226BF901B6A04 + 34: 67281E2EFADF2EA6211B549426D3A598B5E1F291 + 35: 993464E56DC035716064577245BCE99ED175356B + 36: 298D2CEC0A3887C93501307B51F75BFD5CF0AFEE + 37: 2A0A02BF4D63CC09978EAF3B3B85A4DE8470B025 + 38: 6236F6FE25D5157BA95BF49EEBA8987A6A301D2C + 39: B4DD7121567E8A428F16BBD5A8832FB2EE68BC0A + 40: 5FBE6037F8D8EFAA9A315C070CE3373080244496 + 41: 04D5E112C47EA03BB60CBCEB9FC8ED7D92A68C0A + 42: 658797C7756256C98E04E6718D9F8952F90DA672 + 43: 6A27ECD40BDA4CC81C599DE94D0D2904716FD457 + 44: EF5AC5B8E7A00560E79DB54AAD4B97E996D2745E + 45: E67EE5275910B48F7D248A8B844DBC041257D695 + 46: FFD256BCBBF0F3BB4DF615B4236C147FD09F4F1B + 47: E83A4B18C347F188301DD3AA78265AD3AB3C0311 + 48: 13968583BC017CF0C5043364A42EC0D97E923711 + 49: 39C33EA7C4F393C4DD4B882F73FDDAC2D7FE1EDA + 50: 50B0068D46AA025615053132BB53F88DC062DB2D + 51: 434198200766DB6CF48C993906FEAC2B47224A3F + 52: 004FBC3820002357434D6B8ADCF79BFA6F9E3DD7 + 53: 13F7A8CDDDE021BCA6227EFF1A71DE19AF399B66 + 54: ECAB85CA0C2AABF18F5359F94AAD7578A08AB5EF + 55: 3C86963B3FF646A65AE42996E9664C747CC7E5E6 + 56: EBDD79CFD4FD9949EF8089673D2620427F487CFB + 57: 635B0D05BE254D82503A9E1DB7647DD1B5D5D6BF + 58: BE314B818A657DDEF92DF123FCC17C1DAA851C04 + 59: DCFBF0575A2B3F64B24DC203BDCB46290B21791E + 60: ADA425E87A8DACF9C28B67E8BE4B204A31960004 + 61: 35691DD184E08A80230467ADC6E68599B7295A51 + 62: AD1CAEFC7ABDC90E7877D376957532B7D91D7434 + 63: 6D31D3D634B4A7AA15914C239576EB1956F2D9A4 + 64: 2581F5E9F957B44B0FA24D31996DE47409DD1E0F + 65: 109949B95341EEEA7365E8AC4D0D3883D98F709A + 66: AC745186C82DF8697458326051A6CE7E4E9C1C1A + 67: 5DE50BBB11C62ABE22E7EDC288B7D1B6A1CFCC60 + 68: 7DD54CC4E8C70A4AC55F4C0485A4DFE139253757 + 69: A5E0EFB95E6162F9637D58D3E4836F9661D6A34A + 70: 6C77DE7607A361D22852385E663171148C0499BD + 71: 3467662275B136AF096D84258B17CA5F23BD6397 + 72: 1C56A69A826F95B8971635AA709978A441E75836 + 73: 9094727596F086BA28956A6BB69CCBF3B2B29FA6 + 74: 8C0B6183C33E902C22F17D81D18144ACB7B66FB2 + 75: 24ECF7598894FFBBC7D30FB1EA47092F03C398CA + 76: 6A02FE0041D98AB7AA6916A5245BFBBCF6635C2D + 77: F3021EDB24459533488660512660DDFF7F451C3C + 78: FBB7561C0065C90D7B8182018EAE73A18288E968 + 79: 32784F0E354A20688359B6EE7FD3874714C48677 + 80: 8BFBA0972D36739EA808C37C07F2E320ACB4114D + 81: 74EADA88C8ED0B649FCCC36DE338CB538242FE10 + 82: ED812B77C12856DB371E6F7DDF15A59FEBDD6962 + 83: 27021F491E923CF0B191E13ABCADDAA72586B769 + 84: 47664874218C135C09ED40DFAC26E06733AD02CE + 85: B39E492616FDAF2480F13D6E46CEBECC1FF5CBA5 + 86: DE967F65BF6DF26150AF866FADCA58C45DDC337B + 87: 8F2E2D23CC6A2B52B904032119CE68649406033A + 88: 247FB8B2BD1BDC35D0C07EA10FD9686A19E4723B + 89: 9D1E80D5695569D0DE28587D37103BBB0701E462 + 90: FA5C338E7506AC5418C4FC2C04AA933588892D4A + 91: D6BC93880FEC0163E3F223C8A64BA0879BBB0AED + 92: 8F27EE9C8A923C9698584786B5227CF17F0F557E + 93: 4C10ACF2F404236E2DABED0BB48DDC6D00AC4B16 + 94: D5166CC6B779EB2D45AB3222181064D05FFB5E23 + 95: 13042EB8245A8C5DED69CFCC1F1DB264889CF5CF + 96: 07136FE8CC1A03673891BC614E29BE79EA02D627 + 97: 73C50B2751C502572492C801C28B02C7E9F61B76 + 98: 8BE4B71D50C2D2895B9CA359ECB69F90CDCB1DD5 + 99: 36A669D7C1DA8E23D07B29BD6769DC324EB6D6B3 +100: 8AE5D2E6B1F3A514257F2469B637454931844AEB +101: F16396E005FE5ACC34EB53E6086F477415794BF2 +102: 907CD2922CA5F62F79E17B28AF389A38066E2C9C +103: 62C9351A21A50F2150367F25D4C166C63E771C32 +104: 8809CB529232A0CB22D384B70462B64D93B0EC1A +105: A85E4B4260A836BF0DA50B83BE1080D98CEF8A17 +106: 21D2A0D78435B2590B2C6366439939B9B15246E7 +107: 204FFDFDFCA5D46CCEC5FA96A778BFCBEA70BCE9 +108: 01DC05D6006E12D2F63A8F061B00D18CCA135D41 +109: 30E67D3FC0A0A6D2F257AE24EA8C168A4B0E0F5B +110: 9B9454E2B42908E57403871A64EA5E930F35B70A +111: 9F72DB053BC5370C786E34013FB8DA5958000D5A +112: C1BFA4009BFEAA30ADA4D940FC40F97FFEA3FC39 +113: 26FC30BF64087DC3FA4CA394637D15F73B7687FD +114: 36106E0DF24B7DEF46E9AEAB7CE0D784FE619D9D +115: 0D82262E443C3C56565EE35776F95978E16F1757 +116: B19E6C73E94401020B14ABBF19A15A6F0C9061AF +117: 68ECB5552C7B7B26940A82B6A67B0F4C62EEB871 +118: A834797B79DBB564AE587003EC4B74914A1580C5 +119: AD430B4283203A7B7F338B9D252DFDBF807402BF +120: B89CDC109009F1982C8B34FCA446953584D3F6C4 +121: 8030CC5A4F55566958A5BFCA97CB6F40B9C19279 +122: D0CBD1EA711E2D405DA5ECC2905DD8A3A3E83C37 +123: ACCDC924549D314019C4FD1AAC6AE3CDFB81BC84 +124: 312933643FCAAEBA4DB9BDE6EF7D6EFA70E37399 +125: 47F11AE47E2E693EDC0B06351E935C9B5DA42A35 +126: E4C6AA211767C15E90935DF552E4EEB89F23AD50 +127: 2BE8E565E24A87171F0700ECAFA3C2942C97023E +128: 7C4D36070C1E1176B2960A1B0DD2319D547CF8EB + +Hash: whirlpool + 0: 19FA61D75522A4669B44E39C1D2E1726C530232130D407F89AFEE0964997F7A73E83BE698B288FEBCF88E3E03C4F0757EA8964E59B63D93708B138CC42A66EB3 + 1: 4D9444C212955963D425A410176FCCFB74161E6839692B4C11FDE2ED6EB559EFE0560C39A7B61D5A8BCABD6817A3135AF80F342A4942CCAAE745ABDDFB6AFED0 + 2: 2661D03372ED5C961EE23F42ED9498B451030EED2FD01F29178955529B2F8A758F0444087C82AED85540C8217E959EB8CB43EBBBB77A7E0D2980D6406AA2190B + 3: 7314E8035788304E57E68AC9EA89544ACE6D2379035697D91B98B64B105130DC814B67A4B46B4DF6C103016B8F7C7403E0B943F0291ED6909E2219B6E18E89D8 + 4: A6C01D8CB93A5CEC17A9BDD270B24C8EE78686CAFFC454F253D9B8DAD5398E52304CD57F30F2111BE78FD98338DD3A41FD8A45124C940C4A59F270100DD6CB6F + 5: DB22986F9FECA154CCF0E7DAD914AE8C0851E170D116E9B550C39B373F109FD073395C0711745E40233226F96B5FBF6C8EF1D7F8E2E4AF5375821C897EB18514 + 6: 793498B98970BB3CF187B0A28D353AB2EEC8F6CDA12E6D484CBCCDB96B2BFE6B5278CDB38C9BEDAEB59A8404645DBEDFBE1FE54227947E226EDFD36114067F34 + 7: 052A7C4EC5AD200B6B8131F30E97A9A5DA44899E1C6C31BBE078058630D5E208FD6F2F51A796F814F8AD048D759F8DCE442C405D96D6E1B1A197AD908B366E98 + 8: 219B01987262C597603DBC495792F2423E24A4BCD38825A74CEE8ED91D55935296D80E73DB43A78FDD6119233A31DA5940C6E335EB22600729478A20F61A56DD + 9: 4BBB8746D1D754CE91C27F3A6262ACBBFD4A38D100A65ADADD3174ED6EF8F6AD343F0ED2DF28309A6E979E02B12E732A3E70371EF1E0935E8A30B7C55146D9AC + 10: 81BE2AD26A90BF502C9514F46681276F927E916A630FAC442D823FE4D8EDE0FAE2E8384F3C267B56126F0C009BF8689D475C53425322BF8CD7F6C80CD2C725C6 + 11: FCDEAB03C0FAC7939E8478FD152EEC2408D4A6C0D829B55AFCC5184C50706C253676CF68DA3ABC1C1AEEB5822898C5194AC801881B8CBCC8DB15930EAAEE9373 + 12: F943E5CD2DF74699913B25EEF0B08FCA6BAE9E66BC073DF0BD950CA02FF17276F4A28393BCCCF6E567024CBC6C05C94EA912F1B07034AA375009F594B25D9542 + 13: 1260728E085D172EE82065B3F878FE21F550748598E72A40F4FAC3F54B72A99E6B3CFDA7141C7E5BE123757AE4332C8320786408523DFC8655D7E1F7010792B2 + 14: 67EB4E93961EF18A82152DE2882CC5AF4DD1254732A8FC1959147268441A80EAF0E0B68041F7CF013313ACAD044BD440F1E06D3E449D206433F3B52BE2C9E7B9 + 15: 9AB90A3384DA32A03B31DDA21732B398358DD40D7586E836CFA047961360CEA2F1E3DD0CF2D90CBB57F68C4334110694A6C1BA17B1E9E533E6CF3A3ACCEFF84E + 16: 112C2ED4CE732E21334D7248A30E683246BA602AD3681BAE365E857AA840F1F80FCEF1B9ADA33AC1F9BF6FB75045F9E61449B26F9201E482E7F2ADC8ED9A1D80 + 17: EF574EE7B498AA64F3ACBE1972E42B873C6FADE053A1459AB52D5E5B49C0AFA0C62FE901ADC3FF07A7D0ACC459C3DDB3F6D499C70B63F68B60B02E2784BB9AC4 + 18: C6185B5836DD3B160695E5E27058AB266EDE91A5417DC086988EA5181DF5BA0C51DEB11F6BA14AF2847540BE368B6C561CD976809E2D9982F4D49F96E0AF4F7C + 19: 8510D305A5E1AB3A0832B242ED402BEC2D70C24B41BD840B8D2DE436A6B4DBB7CB5F7F9F1432E694F0CB1239EAB0DDD92E6D0C7E96FDAD5F8E465E286D7588EC + 20: 926800FF566CAFAEABACA9990772EFEC8AC956C3C572A360194F95AAAAE477F98AB7750B2710E262D039D8584BE79D93E9E6405BA25DFF6DCF29C54D748DD655 + 21: 0F0B98CE94E2CC67D36086D153A2DF48F20283413407C3CD0570B619871DAC188AA37BA30BD706AFEF475BDA7AEFAB63055ADE8B792F025D088B51A08E941B01 + 22: E6538F3479D33979F046FBC88D4BA785B072EF58877BFC9D1214FA8374B78DA6895D5A4F4E50E6AC6A237E48A73EB18E4452E7C8AD50C82238FA9B323C96935C + 23: 378E83B88847F234A6A2FF7304ABA759A422E6823334ECF71E9C3C1F8B21B016D9A8A100B6B160772FFF12482A50613BD832EF534DBD1D4D055F3227C7513F11 + 24: ECFC0F6C168962197E181C27FC9AA1975FED01E655B3D4A7857872451D6AF810783184534C401709A63BF6BE6CDB1D1455C382CBAA6F68E8180CBA9E0CDDB9EE + 25: 8523B737250579A3787BD83E5DCC57F7038B393F003223A7BAB98EE4D040441190622290B164F32FB96682730DF62CC366FC33126DE2F7DDE3A38C818C48F680 + 26: C6BE341A28878B733C30F50D67F6933D3A15A0950CAAB96B9F3D7D78C95C61874A400CAB65A100302D9E2DCEADC4A0C043834EB0433D5D684C187AED93B5EC6A + 27: 4AE827A36DA140D2271F74DF1AF4303DF4B1C319428F8BA94EA28BD3765BE4535275053DA49B630E6B754097ADCD7F17DC7C16158F43E2C1851951EC3016CD8B + 28: 6D3F01856A8A28E28EADF60401E84253C3F7CD13F3A9FB8F94D8B07B74F7416817F274903C135BA0DA4509A78D004388CBCCA75B06132C7CFC0156C03803E85B + 29: 07CDC2BDD9CDC49853384FB647736B50D788AB80A0A54A0969B86603B683C22A1C5FD32D3AC92E73D378F379C4BA30A48E7D38FBB867E981271FB3962C745659 + 30: 9DC875BF987C55CE646A709E89CA89E226B0F15666D5174771368FAD768BF3318B8BC7D8CA80AFB5E6BB7FC0090B5559F11DA165DE51B940C9DFE911D4790477 + 31: 58BEE92BE003CCC34F9CE8C0B323C6BAF1297460BAAB4998CB3B52D2BBAA24D1B06CB597EB2E609A008572FF93710E3A7F42AC53E3FF09D4733757EACA41E20C + 32: 888AEB1BE2BECB28598556A128AFEA037D0689C8D13D9894F1416B2C48B2551CB2FDA321A26CC4D7E1C87332D7A3C18FFB455C92C0E7AAF829FA40B8A28BB656 + 33: 19099B4E8ABF225DC7BD1C1DC6D52F54E8FB7E4EAE0AB19293C686E6FD2828221A1153BBA4C143795D1A718585D9255B6DC911C0EDA5E0042A10565AA5D6D8E7 + 34: 22B3ED65F64C8E51257A922FF90DC09447224B9A8C7B5A6A94D68601F3D4C7C1557BB90B91DF318EF9F8BB367E838D36A3CA82FDCB85721AEA20A8A2268D90AF + 35: 0D2B24C6FD5D772704BC17D2FC8C011F1511F92491104F3C22470864882656AA40DD07C0C329C8BAFD90ADEA7F473349038CE475D352DA41E24FF64723070566 + 36: FEB43F7DCDE56A2EE963236C234E5800C011FC54D14396288DE5A7AC7DB2A72D1E8F63F04D1DDB3C55CF3BF19F4E0FBA4B79405A6B45ECB31254C9F1951C632B + 37: B8AE2C8427A750F34647C3529A05D44691B8DE0C79525D9145665BDA5C0C396C00E936BF2493F12945899B6FDAA9F61E6E7B22846023D140F873EE7D48D76BC8 + 38: E80C49D1E29F6FAF0BB5C7B47F5A85B3A0EDDED84418890748724792CC83B53AB044B051722F1ADAAB713E5069E883C1D172CE0EFF6EE6AEBE05B1FD77DB652B + 39: 1FED03FA70436EF45286648ABF39057C33815E6A80A19E22009B89C809DD6F0099C944B882FF9DF3DF08DD51295F3F02FBAB40F606C045BD4395969E27647D24 + 40: 2E3630EB519F6DD115B3E4818DB4429CDDF1C6CC2C8548F8CCA226A24F87A949A27DCBF141803B87B2A2C0F8AF830031DB1FE084E3996D8834F8E7D29EEA4AFB + 41: D54509526805DFC0871CBD6E41ACE395C64373E8F57146A657C28BB3ADBF7E57A152D27BE24B8F30F08329C2E040359B119690D9A1118BC14A3B1883D093466E + 42: 0AB062968EE4D71DCE807EFAF835EE11588854ACA0959B5341DDFD10E70BA9AD427D92168B31B8E6EF81F58615AF9215A8708CE1F144EE29901D1FC282C3F78F + 43: 45862B0D0F0AC5CC1C5769C29D786FD3AC788CFBCDD6CAECFB120D05D71F2575F4174CAD5E5A00D2D740D0714E92822427085F044A72D66631755BC55E5BCC8E + 44: D3A9EFFA759181346D8FE53130F05B2C65F96E1D5908A61DA8FA3A9BC551A7781ED7B1A6CFFCB2F742DDAE8D22B0EC99D82B14EB85719253693FF920FD5071D8 + 45: DB53395A78DDE62A406211955EC56C6F7BEB9EC2275501C35CA955268C3E2D71BA246B4286C76FAFDE012F9E2CAAC8601A74699B466023FE9F8B1BA26F65042B + 46: 9426FFB7B70DEDF1CFBCE6610583CDCD91AB421FE39DDC31F4215CF7604B9050C84A3BA29C4B236F1CC3B09F53D29229132FDDDD9B468CBB6338BBBA6193F84B + 47: 3D74F17DC6FE057703C72452BC7A078EC019424A89783F1FA40003657C323997DF30BBA38CB4B16BAD8FDC43260956090F765C26AB1FC88BF7F87EACA1821B52 + 48: C6EF119085EB17EC1B9F74791D95E366FE916F5397C20857A8966C52512F4EE16E63B53A28F7632A867EFC7FFD8080B173D5E2E33A2063FEC7D1181ACF8C7824 + 49: D878B30402FECA5EC93362105D5E183D658DD2FD38B8173FF609740CC84239C4F8F533AC3451D369001CCD4AC78814058DE0F7E1F93D167A46E85E3002F4F386 + 50: 948C4254AD2C5658A28D42DDC3CB4FE4CF731B4180B8A4A183C23C54CCEA045307422547600598CCFFD3C6229DAA6CDD006D3C782ED91AC61172059D016970DE + 51: B74FDFED0388D5164BEE25E37C6687FA8D5C069D4FB0D42A7F1A270A676F83F24FD1C9048EC0D49F7BE913D893E0015E0A3F724653B3F0AB0017683948712E46 + 52: 497EB803D053D5DF498369BADBF8AAD57ED1B072CF361D3DB2A528D3DB16DD962887916E9D21FFB439DC2C025CDD8C21ADCC98A23C8C5B0245F2D71CF728F10F + 53: 63F4098F650820EDCEA3E7C10B65D3B0F1949A28FEA323702F27C7D311C7E6BFC82D4C01F4FAD06FE0288E410EF325DE192F78B88E04075FA9581AE2B031A68B + 54: 337914B013B8056D7849E42ADB47FA761B5AB05696CB8FDA6B87FFF88B0477902991AD81664727164053E4E47ACDF880DCAD0E0E67F7141123DB494450CF0B61 + 55: A385FE66F8C852638F5BE44503B680298EBBF27DBD9F20B1A0447215C0E2C1078926002113A71C78148D5019FB22C8132DD05356C78A1A8D8E4EEC5A6442DBA9 + 56: 218336585A419E9877CB63387C5E759FC93F0FE1A7BA717B8BE9B2302393E0D14DEF2F749D138692D0A0296F1C792B567F40037DD2B8787F1F47FF363CF34F37 + 57: 7EB842771A61A9AF779C8794CA055518E7F38CD13F61638900EAAEA000B12816D52C593B62B9DAD79DB7397A463AB99A9D0035E7A1369B0556D593DB41EEEB6B + 58: E41D1492D3472FBD42F2460650F9DAF2ECCDEAEF5F4516B452D940DAD516F5168439154B4BA76610461B343BCF1E7DD7DD8C285EC0CC46C17CE3C7E14103042A + 59: 88057C0B8442BC5763283EA17FD1FE1AE011A988E1D7E0F914004CD3AD2E06FEEECDF59E309B9EBDABF19559954C37F71FA98C14BB19F7B91CE5F827C1DDE1B5 + 60: C5DE99AA273D1971272263C740E689739B39725A0B7C48B41577F05738A24F5EE2C0B673F93BD52A083798DDDC6E70A209213B58C95D49ABC5BCBABDD6AE7D22 + 61: 68296AC346BA3B14C038CDC629C5F5700CEB9F5DAFD94F948C6B991C0F91813BFD02660A2A05A02A61D8EB03BC93601F9F6A38196650047E1D7DD1071CC6974D + 62: 1CE0E6793B0ED59C4DB7D5F24FEF75A4ED2F28CE4AA7E5EB25919219C2C04935E4B15841821FA92FC7537DE2A538871E5A043A773CB1ED061333113223248C18 + 63: 37BF321F66ACE827B66ECAA651CCFCAD30AB627E717AA4FE441279C4FA48555CB7784B0AF25A73B86375BE71A1E3FDDEC661E0EB8115E0BB2B9A7FF81DC75DF9 + 64: 5C3C6F524C8AE1E7A4F76B84977B1560E78EB568E2FD8D72699AD79186481BD42B53AB39A0B741D9C098A4ECB01F3ECCF3844CF1B73A9355EE5D496A2A1FB5B3 + 65: 85A19923268414DE6A10A2CDEF7917D7AA01E68DF9D028CBAB5C5236FAEFCED836BDE9CF90D8A214013056202A1BAE5CB73606078C5572D8FE85C36002C92D70 + 66: C2FB9763A6F86225F6C66F55ACC8E7E17C1A2664416B2704D64AAC2CC5B04A626030B5243CA61D62076DDBDF3C6B3765C38D0CFA01D4D45C124EA28DA593F84F + 67: 5083280300FA5A1B172D7B5CCADA5CECE1EE5B7B5D382EB4A430179EB133970B0B89F6BB6DCBB1F38EC9F13F5B7D1559F114DE0EE26178EBC56CBE31BB26A91D + 68: B3571E8C1CBC0C58E23094B39352D554B43F9E7DD0FF981C12A01E0D8BBFF06A39875D90BEDA7F345550E6F67935A49E0183456B9967BB319D74AAD87CCA3695 + 69: D11537B780D458D37279D00621F646EBAD3244A22E4D45DF11AC5D084FDF70E7A32F897DF727E65EDD1019DABCC05DF0B5E015FC5CC1184129C5DDFB14F62154 + 70: C146458EF40E6F1944BFD863B2862A97145BA580D47C7ACA67E797EAC6790841C57D68A74930AEFCD49031819FBED806A0C033DD529A203B4E460F357BA1BBFB + 71: 660F3E1D5CD3B2AFD95DB0D8C258F6AD74DD40DB688A37AB4A24D720766541B1CB928001EF6D67CE5429039C9C1490613DDF90A27E6152BE7D42E1614C590056 + 72: DEC468EF73E98F44B60EB994935921F920DC0CEEB7498655F0FAB7607A77A7A3D9462DD8BAD46CB408EFA81FF08D7E9508BC565C1578C37C2B87D41A0A32A549 + 73: 070D4C36A0934C5C12E6B65FFF385404E49C3871DA8674D93D26E3166A7EF9693D946B419F0E10C9624964B37493DC8A46D26D8AB8942E60143036659CA4C91D + 74: BB8935CC84E08E6B4E7C6233E41D880D70CC018D1668EE64F19906A83730495D01AFCE1A4EA8129A98B7F9E074FD35C0BA6D5667625DB63A867BAA67BDEFC190 + 75: A0A7A0B619643115C582BB6953D2A3EAA942451F631FC56C0933B535313D668FA4CA7D6BEC4DC9FE2AD7528DD6F8DBE68478A040FBFDD2F3DC3AD7035DB67371 + 76: D6C57C3FB08D07A30A622B25985A52A6E552499345244725B1084E41691B11EB31D3B9776940A9A7E6115D2D1A93372D3A7388D87B01D13BCA726E8823E89729 + 77: 413CB26BE2B1BA8ABE930ED1B9978BA4874CF32B38C825CB6DFE9C21A87C0BD115D3357198FDA0A5B7CDEB4235A354E9C2F37D11B33AC6A257DEC67326830E23 + 78: 748E4648FBD009E4848E44A284D0CB2088300F50CD5215A285826E968B9DA59B6322E1987F78447150AF72CE37E516BE9E83B05A9817AB7A924ED8B09557CB5F + 79: 0A8111FEA824D43E0991C22FC3B1368A191D0C73308283494309D0762AB1EE5AF0CE2DB8F0562DECAC636128688540E845D72BEA3852A19CA2ED22D6C1E82CF1 + 80: DB1067879F014EF676471D950A81DA073D676DE52E85F67890C8471FE6144078DAF940CB6F9F097BEDB8FAC94C737C5B8A3B4217CFF4A56DC349B2AE845AB25B + 81: 6165F19F569BAAA3A3ABE6D6108D07E1ECB22092F66227DC27173DAC097118C2D927F2E5F7D20C8CEF0F99C6FE6C7AA46BF18FBC452F6FDD733728030CD0A4A6 + 82: 1D4AA14617A4BB9E48DCC1A7EE5DF65298AE45FB193F077FDB6D1C2B3252E1633AF86A527C29861661CE155A47E5BAC91D9B07715E0FF7E08B39A3128891EC42 + 83: C2C22B53D6BA460954C2D826FD3DEEE60E33AF2EFC87A61CBF2AA021166AFB90967ADE2C564D037518E4141BE9C0D0BC0B4F95498D5AD920BF28CAD4F5FE700C + 84: BB5E9CFE19C6A2D14EA4C1F6BDE51855DF61D650B23330BAC30A5072EAACF86CA02AD31FE4C146176DEC75C56A56C2B868177E0E365414508D2E7606AB9E8921 + 85: 6B40A13C5486396864608BE7285BD4D1205180BC41E10E537042A1CC6CD12FA7737B5E73D768BBC5D687FCCE41880A8D9773C26316ACEA2D78DA26FECCC11E90 + 86: DAD0DC8A7D78E29B12182D36F47B93CAB562C44FD6C5B1718651022CDEEC30133437431D13C43EC1C02DCE776F459A57C29355B3FA0D67C6BF84AD26194A8854 + 87: 8118AEE5DFBD7FD9F94403FFD3C6BEA08706D4C4DC78CDE72F751A6C4027ABEC7786A62732819ADC036B787E25E151AC51B60BD2381A64F05A326800D7514B15 + 88: C64737334A61872EC00C8A3F1B1EA931FEE8D80203CE6DB9F1ABEFEE2CD3E652971615AE4F9A23400B9E31D861BE6B7E0F6DED28ED74B45D6AE90E70AD49508B + 89: F927B571B03B892B46C0A16148F13A2E6B80630CE41BA7DBE311F9ADBB5E8F23923CF0CA527DDD20BB3FE42BBE805066BEAD569F6FED12A2722A8629427ED841 + 90: 2576A445CCD8977F24F50EE30EA7A51F0F3F49D41BAA663BD1C1734E02367A382E3D0E8C07EAED0C6A47CF662FE573BAE5593D9C4BA8FFDB4AF024F6064F7A89 + 91: E85C73AEB638F35565BDD2523AE2A86B573C339B4D5FF8498ADF71BA587CBF146AE63B8C920B2F0A166F802167A04CD0D7F7A842D7D058165894CF9188289032 + 92: E74E2ABDD6AFFF851EF78F8A866DDE9B9F86D906B298DD1E3630E1D4A30B6FCD7FF91943A57367A00E2658A84346F53ABC896EDAA395167E5EBD12C954E0B820 + 93: 6827226985276BA731A9AE2E4DBF2D0187C05D566F06D098E05E3F425DC058958B50F09B4CE0741F1375E9B522F94A61F1ED8A43A8D03A036D2ABFCEDD4F0C1F + 94: 19A71A12DCABA1BA185BA38BCC0D915584A801EA49F975393B25AFBC456571CBF1A6F9121CBAE89A9B438092C65532489A95A0864320102EAD9A2EBD30D41F6F + 95: C70F19BAEA7420A7482C9C54CBB689A9AB93E4F8538EDC2371A1EDB3A103DFB7176E04DF170FF71EF46DFDAC1E8F9CD6FF96115BE1EFC271A56BDCFB67D29E67 + 96: 8BBCCFC8815786ADD9F108F4381A2B084179002AE940ADD4C42AA2550C353CD0351C2F7F1BD544D8F268FA332B0E803838318A39079E9D93269A01EAF9CAC967 + 97: 5266FA966A04B8A2450ECF3826C9E1516FEDC33EE81D4911A601351564D27C8BD4A11BF00E0DE237E50D75421CBE475E38967F28E6A1C5D311A2C95B84898D1E + 98: DF87823E1E02AF34532C5F3A08CF03CB9B2017B835525B3E3C448B1ED15569935D9A1DA19A6B1E8D056FBC868447ABE6226B97F256F6B638B052B4BAB3BD4808 + 99: A1317CAC2364B10EABBD3540B6139D337C0EB3F7A740C050988FF9B3584213DF5833AAD81D36C30CE6CE76962A9E1D45F08667A314036A299454F25F73EB067F +100: B752B6EEB497A8BEBFC1BE1649CA41D57FD1973BFFC2261CA196B5474E0F353762F354C1D743581F61C51F4D86921360BC2E8AD35E830578B68B12E884A50894 +101: B0BB23AED2CFC9C58C8BAB019CD10DBE75717EE8F04AA45FD8D84748E3F05C523FD2F70DCC460F7A18DF7D28A224BCB86CFA4C8164D081D51F3487A7BD0C8109 +102: 0FA46C6A759DA9A3649679780A28FDD51EDFD3F99A4B801C5824247B270A137CF40006609E149C919CDA0A6C856A9A8E855A670A2BB2CD5211FAD42E84F6E365 +103: C4E350267BD335848D00151AF2C380E49A323E63AA264D534EA1BF7A860B764A78993F7FFF34ED93ACB1F5A5AB66758C462B4D2F2F4E14225D29FEC0C102E772 +104: AFA0F1DB8A321FC6C4EF7C65ED2ADC4B094E928E230D27295699DE68FB5C1657FE0E5C4E66C5852ACFC45DA94BEFDAC89CF0D4174B262E6FD51CDC3E7FFFA5CE +105: 9A86A440FF8A33DCD38C69D7564EF827F614629CB699B7F45E7FFF1CFF4AD5E27EFFDD32EF1D0845987A6A273EA34C19374E9FB606BB2E3B909157CC6666D29A +106: 1FAF8C564575D654133B0A452EC43959C9F9E20C044724B74EFC90D2CECE4C49A0512C9F4DA2E999552E3ACC04CE0F0E2FDA9826C2A1FBBACEC4330081D5CA43 +107: 8B35FFFCD91E617C8A49B13CD0FFA2199FA1F20E5633AE6E95881BBCA02B1E047392DC9A4C0F0A4C39D3984E78ECC4DCC1B5C94A26ACDC1F69C7ABABFFB45175 +108: 6C8AB69E946FE86DEF6F14B955B8F1977686EAFF8E384CA45F245CCC0EB1C80AF8E62B0E7387C0DA52BBA31B1A01EBB00CA26CBFDA9D8069A773C3B62F989A2C +109: C3A243B45B7C3C2002CB197BADBD84C4900D504FCD277D2DC6C06D34B1317B41EF098BB980800FA9D011C0363D074308835AEBCF3393B1C925045E97E14831C0 +110: 803E065AFEFC6C48EF9F701233AF512465729E81B0DBFF99A2E7FEFFB542831E1D3B30230BFA2F30343695C060AC8140C37CC8D1E25E95E6A1139C5522F4ED28 +111: 86618429B8720ADCBC8B9FEAED8BD44E0848572CB6137213273563EBFDA859240E17DFDAFF68B09953F1853C9E7EF217875E7BD6959E76DC3A1CE5F548B76CEB +112: 96439A93295B5C479F0310B28377FC10DF81B593AC233556B15897F1FA3886C940639AFF2ECEB29894DA884626B4811254FE2622EC7B4577087D9046C96AA556 +113: 9F7BAE13DB80C72A434BC4704998A73D7E546CC2590E0D0EE511CAFC63C622A8B2A296426E42754606D02B6EA060892E325EA1AC13EF0B523A3551F4D25BE241 +114: E999A862E5C479B7BB21EB52E4BD301571A8A39B712EBFEFAC720F28C515025E98CCC74B950D57CF3C3B34D788D62CDA0339AE0DA02C8A107BCDD797C4751FF1 +115: CD00EC5142CBBCA87BC15D69EBE96B5222F25BE1576B318208178679B13A9A8BA4BBABE9A488BB38C4EEF327C9A4DEA4225DD30C0F70B97C18C5C2FB19FC2134 +116: 1289951D2B62112BA590D8C0CF9EFA38AB77737F994060596738612E6BDC41EC8672F50A027A2C049299FD39E1776BC3EEBFE3E66CCF4009615D63F0A4C43ABE +117: 451A46FBDC954FB76E744AF3DA8429C881197F6BC12D22412438729288AA4540843B9FD4CD1BDBA5E864FEAEF0CD6CFF045A37510B3759FADFEF4697E9BF9240 +118: A267FCDF72D9160DA2A01E781E07701478F95A38C262ADEBFA194EA6D5A50A9CF3E04D32AA4B492580C6E8D8FAE1F813F3C17F82B7F47D8CE0C900F0F3052F98 +119: 3D910AB6579455653EFC939BE1B22D993537408086361008EBB166724FAFE3C8578EF4BE0378BC28ED883FC0FF3DE5A9310CEDE65FAF3AD9590A13B3CA4F81C5 +120: 47386DF4D41775737BC4E52D7CB2EFC11BA335A5D59597B5DEB3DD0A35032461F5DB4779D48BD6F3A10C5503AC563C790235E6F54EA79CEADB6A56AFCCE890DF +121: BA59044EF3A242974F074337CBB6840FA0506C2227A429498F546B2CEBE0644DFF1D442190C48CB54BEE72F960670F71AF1F8402AD5ABE8C1482DEFA881FA903 +122: 89B4F35E5C8C19AD61CF1600BA80C1A1BBCFDC86AD9F8066C967BA10F62827FCEFA1EBD07C90C82B48082A5B7D6A72E0AAFD230DE05955C7E8C081286B0CA96D +123: 0C7F94250F4EA7647F91E7EA8B8612AE8E7BFE4F5BCDD90CDCE564BC9842F6987AFB4C3661D8431440FEE18EB2EC70BCCD34A6B61D209CB72BE782A0808C08E2 +124: 2C8B8B17820085795BC6A2720B5D0BDF5407D9DEE1CAA4270FFAD010AE9555DFD2B74A742512BAFFAA1D5B4F14ECDB2BD4BF37838D5981A317C7287805974019 +125: B464C5A9D040F11DA45D98C4BCA9295D0F589DB11EE5603410C62BDACCC329B9AC14567C3A6F3BBA4B92CD3B95BE58AD4DA435199CE62D8BD61269F8BEA38FE4 +126: 2F64554FD54AA4A04ADE3793AFCC5C968B1C3603F4F71E1BB5342BA4E951D79A4580BF57736E7FC13A43604A057E9C360C099AC5B3403DA8AAFDBBF417FF6ADC +127: 3C9A7F387B7104DF19CF264B0B5821B2E46E44ADC79262546E98FFA113EB3D45799EAC78CCA4643C937FCC3C1D249A212FACB34C63D45EEC81069095D7CDCE7B +128: 803A3B37C89E84FBBEC75BEE3D00DD728FFC4246B5A5E989DC8DC2CD0F7937966AB78C79E1D4648EE6EB40F3D70491CB46B8AB42E155672E2AB8374FCF70DD79 + +Hash: chc_hash + 0: 4047929F1F572643B55F829EB3291D11 + 1: 8898FD04F810507740E7A8DBF44C18E8 + 2: 1445928BB912A6D3C5111923B6C5D48D + 3: D85B2E8854D16A440CF32DDDA741DA52 + 4: 5F3082124472598098B03649EA409CDC + 5: 604A19622A06D0486D559A07C95B297A + 6: A16F89E4DACA6C8174C9D66AA23B15AF + 7: FC6893F79A2D28315FBBEFCAF0280793 + 8: 6A80F04CB93B1CFB947DED28141E877A + 9: D036D0B4DEF1FA138C3181367143D1A9 + 10: F031A2DC2A196B268046F73728EE7831 + 11: 2E05C9B5A43CFB01AD026ABA8AE8201F + 12: 8B49EF0BC936792F905E61AE621E63C3 + 13: 485CF5E83BC66843D446D9922547E43B + 14: 704767A75D1FD6639CE72291AE1F6CD8 + 15: 19F6228C2531747CB20F644F9EC65691 + 16: B78FEC0628D7F47B042A3C15C57750FB + 17: 3EF9AFAAFAE9C80D09CD078E1CC0BD8A + 18: 5E4501C8DD0D49589F4FFA20F278D316 + 19: 00D2D0FDD0E0476C9D40DE5A04508849 + 20: CC7382E78D8DF07F0BAB66203F191745 + 21: 85B841BCCCB4AD2420BCABCFD06A0757 + 22: 7159E38F4D7E4CEBEBF86A65A984BA2A + 23: C8949A9D92601726F77E1AEF0E5F1E0F + 24: 8CE35EF6EC7DDA294134077420159F68 + 25: A0F4E4522832676B49E7CD393E6D9761 + 26: F55C27D180948585819833322D7BC4CA + 27: 0A3975A0113E1FE6A66F8C7D529715B5 + 28: F77135C5D04096181305C0906BAEE789 + 29: 31FF81B49B9003D73F878F810D49C851 + 30: BE1E12BF021D0DB2FC5CE7D5348A1DE7 + 31: CB4AF60D7340EC6849574DF1E5BAA24E + 32: 7C5ABDBA19396D7BE48C2A84F8CC747B diff --git a/t/digest_tiger192.t b/t/digest_tiger192.t new file mode 100644 index 0000000..8f0cf7f --- /dev/null +++ b/t/digest_tiger192.t @@ -0,0 +1,105 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::Tiger192 qw( tiger192 tiger192_hex tiger192_b64 tiger192_b64u tiger192_file tiger192_file_hex tiger192_file_b64 tiger192_file_b64u ); + +is( Crypt::Digest::hashsize('Tiger192'), 24, 'hashsize/1'); +is( Crypt::Digest->hashsize('Tiger192'), 24, 'hashsize/2'); +is( Crypt::Digest::Tiger192::hashsize, 24, 'hashsize/3'); +is( Crypt::Digest::Tiger192->hashsize, 24, 'hashsize/4'); +is( Crypt::Digest->new('Tiger192')->hashsize, 24, 'hashsize/5'); +is( Crypt::Digest::Tiger192->new->hashsize, 24, 'hashsize/6'); + + +is( tiger192(""), pack("H*","3293ac630c13f0245f92bbb1766e16167a4e58492dde73f3"), 'tiger192 (raw/1)'); +is( tiger192_hex(""), "3293ac630c13f0245f92bbb1766e16167a4e58492dde73f3", 'tiger192 (hex/1)'); +is( tiger192_b64(""), "MpOsYwwT8CRfkruxdm4WFnpOWEkt3nPz", 'tiger192 (base64/1)'); +is( digest_data('Tiger192', ""), pack("H*","3293ac630c13f0245f92bbb1766e16167a4e58492dde73f3"), 'tiger192 (digest_data_raw/1)'); +is( digest_data_hex('Tiger192', ""), "3293ac630c13f0245f92bbb1766e16167a4e58492dde73f3", 'tiger192 (digest_data_hex/1)'); +is( digest_data_b64('Tiger192', ""), "MpOsYwwT8CRfkruxdm4WFnpOWEkt3nPz", 'tiger192 (digest_data_b64/1)'); +is( digest_data_b64u('Tiger192', ""), "MpOsYwwT8CRfkruxdm4WFnpOWEkt3nPz", 'tiger192 (digest_data_b64u/1)'); +is( Crypt::Digest::Tiger192->new->add("")->hexdigest, "3293ac630c13f0245f92bbb1766e16167a4e58492dde73f3", 'tiger192 (OO/1)'); + +is( tiger192("123"), pack("H*","a86807bb96a714fe9b22425893e698334cd71e36b0eef2be"), 'tiger192 (raw/2)'); +is( tiger192_hex("123"), "a86807bb96a714fe9b22425893e698334cd71e36b0eef2be", 'tiger192 (hex/2)'); +is( tiger192_b64("123"), "qGgHu5anFP6bIkJYk+aYM0zXHjaw7vK+", 'tiger192 (base64/2)'); +is( digest_data('Tiger192', "123"), pack("H*","a86807bb96a714fe9b22425893e698334cd71e36b0eef2be"), 'tiger192 (digest_data_raw/2)'); +is( digest_data_hex('Tiger192', "123"), "a86807bb96a714fe9b22425893e698334cd71e36b0eef2be", 'tiger192 (digest_data_hex/2)'); +is( digest_data_b64('Tiger192', "123"), "qGgHu5anFP6bIkJYk+aYM0zXHjaw7vK+", 'tiger192 (digest_data_b64/2)'); +is( digest_data_b64u('Tiger192', "123"), "qGgHu5anFP6bIkJYk-aYM0zXHjaw7vK-", 'tiger192 (digest_data_b64u/2)'); +is( Crypt::Digest::Tiger192->new->add("123")->hexdigest, "a86807bb96a714fe9b22425893e698334cd71e36b0eef2be", 'tiger192 (OO/2)'); + +is( tiger192("test\0test\0test\n"), pack("H*","4d8ed1a51a0f2bcb0f74ae5dee0c7b0a804d98ba9e9a74a1"), 'tiger192 (raw/3)'); +is( tiger192_hex("test\0test\0test\n"), "4d8ed1a51a0f2bcb0f74ae5dee0c7b0a804d98ba9e9a74a1", 'tiger192 (hex/3)'); +is( tiger192_b64("test\0test\0test\n"), "TY7RpRoPK8sPdK5d7gx7CoBNmLqemnSh", 'tiger192 (base64/3)'); +is( digest_data('Tiger192', "test\0test\0test\n"), pack("H*","4d8ed1a51a0f2bcb0f74ae5dee0c7b0a804d98ba9e9a74a1"), 'tiger192 (digest_data_raw/3)'); +is( digest_data_hex('Tiger192', "test\0test\0test\n"), "4d8ed1a51a0f2bcb0f74ae5dee0c7b0a804d98ba9e9a74a1", 'tiger192 (digest_data_hex/3)'); +is( digest_data_b64('Tiger192', "test\0test\0test\n"), "TY7RpRoPK8sPdK5d7gx7CoBNmLqemnSh", 'tiger192 (digest_data_b64/3)'); +is( digest_data_b64u('Tiger192', "test\0test\0test\n"), "TY7RpRoPK8sPdK5d7gx7CoBNmLqemnSh", 'tiger192 (digest_data_b64u/3)'); +is( Crypt::Digest::Tiger192->new->add("test\0test\0test\n")->hexdigest, "4d8ed1a51a0f2bcb0f74ae5dee0c7b0a804d98ba9e9a74a1", 'tiger192 (OO/3)'); + + +is( tiger192_file('t/data/binary-test.file'), pack("H*","87fff912ca5497def55a1a7b5c705ad037a53660432e1d63"), 'tiger192 (raw/file/1)'); +is( tiger192_file_hex('t/data/binary-test.file'), "87fff912ca5497def55a1a7b5c705ad037a53660432e1d63", 'tiger192 (hex/file/1)'); +is( tiger192_file_b64('t/data/binary-test.file'), "h//5EspUl971Whp7XHBa0DelNmBDLh1j", 'tiger192 (base64/file/1)'); +is( digest_file('Tiger192', 't/data/binary-test.file'), pack("H*","87fff912ca5497def55a1a7b5c705ad037a53660432e1d63"), 'tiger192 (digest_file_raw/file/1)'); +is( digest_file_hex('Tiger192', 't/data/binary-test.file'), "87fff912ca5497def55a1a7b5c705ad037a53660432e1d63", 'tiger192 (digest_file_hex/file/1)'); +is( digest_file_b64('Tiger192', 't/data/binary-test.file'), "h//5EspUl971Whp7XHBa0DelNmBDLh1j", 'tiger192 (digest_file_b64/file/1)'); +is( digest_file_b64u('Tiger192', 't/data/binary-test.file'), "h__5EspUl971Whp7XHBa0DelNmBDLh1j", 'tiger192 (digest_file_b64u/file/1)'); +is( Crypt::Digest::Tiger192->new->addfile('t/data/binary-test.file')->hexdigest, "87fff912ca5497def55a1a7b5c705ad037a53660432e1d63", 'tiger192 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::Tiger192->new->addfile($fh)->hexdigest, "87fff912ca5497def55a1a7b5c705ad037a53660432e1d63", 'tiger192 (OO/filehandle/1)'); + close($fh); +} + +is( tiger192_file('t/data/text-CR.file'), pack("H*","3ae7a1ed6473e8049fa12df17256e8f24578d68e9dce447a"), 'tiger192 (raw/file/2)'); +is( tiger192_file_hex('t/data/text-CR.file'), "3ae7a1ed6473e8049fa12df17256e8f24578d68e9dce447a", 'tiger192 (hex/file/2)'); +is( tiger192_file_b64('t/data/text-CR.file'), "Oueh7WRz6ASfoS3xclbo8kV41o6dzkR6", 'tiger192 (base64/file/2)'); +is( digest_file('Tiger192', 't/data/text-CR.file'), pack("H*","3ae7a1ed6473e8049fa12df17256e8f24578d68e9dce447a"), 'tiger192 (digest_file_raw/file/2)'); +is( digest_file_hex('Tiger192', 't/data/text-CR.file'), "3ae7a1ed6473e8049fa12df17256e8f24578d68e9dce447a", 'tiger192 (digest_file_hex/file/2)'); +is( digest_file_b64('Tiger192', 't/data/text-CR.file'), "Oueh7WRz6ASfoS3xclbo8kV41o6dzkR6", 'tiger192 (digest_file_b64/file/2)'); +is( digest_file_b64u('Tiger192', 't/data/text-CR.file'), "Oueh7WRz6ASfoS3xclbo8kV41o6dzkR6", 'tiger192 (digest_file_b64u/file/2)'); +is( Crypt::Digest::Tiger192->new->addfile('t/data/text-CR.file')->hexdigest, "3ae7a1ed6473e8049fa12df17256e8f24578d68e9dce447a", 'tiger192 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::Tiger192->new->addfile($fh)->hexdigest, "3ae7a1ed6473e8049fa12df17256e8f24578d68e9dce447a", 'tiger192 (OO/filehandle/2)'); + close($fh); +} + +is( tiger192_file('t/data/text-CRLF.file'), pack("H*","1d33d392f100dce854ec1e6b71bf58b5724271a9ebfc7b83"), 'tiger192 (raw/file/3)'); +is( tiger192_file_hex('t/data/text-CRLF.file'), "1d33d392f100dce854ec1e6b71bf58b5724271a9ebfc7b83", 'tiger192 (hex/file/3)'); +is( tiger192_file_b64('t/data/text-CRLF.file'), "HTPTkvEA3OhU7B5rcb9YtXJCcanr/HuD", 'tiger192 (base64/file/3)'); +is( digest_file('Tiger192', 't/data/text-CRLF.file'), pack("H*","1d33d392f100dce854ec1e6b71bf58b5724271a9ebfc7b83"), 'tiger192 (digest_file_raw/file/3)'); +is( digest_file_hex('Tiger192', 't/data/text-CRLF.file'), "1d33d392f100dce854ec1e6b71bf58b5724271a9ebfc7b83", 'tiger192 (digest_file_hex/file/3)'); +is( digest_file_b64('Tiger192', 't/data/text-CRLF.file'), "HTPTkvEA3OhU7B5rcb9YtXJCcanr/HuD", 'tiger192 (digest_file_b64/file/3)'); +is( digest_file_b64u('Tiger192', 't/data/text-CRLF.file'), "HTPTkvEA3OhU7B5rcb9YtXJCcanr_HuD", 'tiger192 (digest_file_b64u/file/3)'); +is( Crypt::Digest::Tiger192->new->addfile('t/data/text-CRLF.file')->hexdigest, "1d33d392f100dce854ec1e6b71bf58b5724271a9ebfc7b83", 'tiger192 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::Tiger192->new->addfile($fh)->hexdigest, "1d33d392f100dce854ec1e6b71bf58b5724271a9ebfc7b83", 'tiger192 (OO/filehandle/3)'); + close($fh); +} + +is( tiger192_file('t/data/text-LF.file'), pack("H*","4f4b4a8577833926bec95b6f59d9be248411160593375ba0"), 'tiger192 (raw/file/4)'); +is( tiger192_file_hex('t/data/text-LF.file'), "4f4b4a8577833926bec95b6f59d9be248411160593375ba0", 'tiger192 (hex/file/4)'); +is( tiger192_file_b64('t/data/text-LF.file'), "T0tKhXeDOSa+yVtvWdm+JIQRFgWTN1ug", 'tiger192 (base64/file/4)'); +is( digest_file('Tiger192', 't/data/text-LF.file'), pack("H*","4f4b4a8577833926bec95b6f59d9be248411160593375ba0"), 'tiger192 (digest_file_raw/file/4)'); +is( digest_file_hex('Tiger192', 't/data/text-LF.file'), "4f4b4a8577833926bec95b6f59d9be248411160593375ba0", 'tiger192 (digest_file_hex/file/4)'); +is( digest_file_b64('Tiger192', 't/data/text-LF.file'), "T0tKhXeDOSa+yVtvWdm+JIQRFgWTN1ug", 'tiger192 (digest_file_b64/file/4)'); +is( digest_file_b64u('Tiger192', 't/data/text-LF.file'), "T0tKhXeDOSa-yVtvWdm-JIQRFgWTN1ug", 'tiger192 (digest_file_b64u/file/4)'); +is( Crypt::Digest::Tiger192->new->addfile('t/data/text-LF.file')->hexdigest, "4f4b4a8577833926bec95b6f59d9be248411160593375ba0", 'tiger192 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::Tiger192->new->addfile($fh)->hexdigest, "4f4b4a8577833926bec95b6f59d9be248411160593375ba0", 'tiger192 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_whirlpool.t b/t/digest_whirlpool.t new file mode 100644 index 0000000..4eb7b6f --- /dev/null +++ b/t/digest_whirlpool.t @@ -0,0 +1,105 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::Whirlpool qw( whirlpool whirlpool_hex whirlpool_b64 whirlpool_b64u whirlpool_file whirlpool_file_hex whirlpool_file_b64 whirlpool_file_b64u ); + +is( Crypt::Digest::hashsize('Whirlpool'), 64, 'hashsize/1'); +is( Crypt::Digest->hashsize('Whirlpool'), 64, 'hashsize/2'); +is( Crypt::Digest::Whirlpool::hashsize, 64, 'hashsize/3'); +is( Crypt::Digest::Whirlpool->hashsize, 64, 'hashsize/4'); +is( Crypt::Digest->new('Whirlpool')->hashsize, 64, 'hashsize/5'); +is( Crypt::Digest::Whirlpool->new->hashsize, 64, 'hashsize/6'); + + +is( whirlpool(""), pack("H*","19fa61d75522a4669b44e39c1d2e1726c530232130d407f89afee0964997f7a73e83be698b288febcf88e3e03c4f0757ea8964e59b63d93708b138cc42a66eb3"), 'whirlpool (raw/1)'); +is( whirlpool_hex(""), "19fa61d75522a4669b44e39c1d2e1726c530232130d407f89afee0964997f7a73e83be698b288febcf88e3e03c4f0757ea8964e59b63d93708b138cc42a66eb3", 'whirlpool (hex/1)'); +is( whirlpool_b64(""), "Gfph11UipGabROOcHS4XJsUwIyEw1Af4mv7glkmX96c+g75piyiP68+I4+A8TwdX6olk5Ztj2TcIsTjMQqZusw==", 'whirlpool (base64/1)'); +is( digest_data('Whirlpool', ""), pack("H*","19fa61d75522a4669b44e39c1d2e1726c530232130d407f89afee0964997f7a73e83be698b288febcf88e3e03c4f0757ea8964e59b63d93708b138cc42a66eb3"), 'whirlpool (digest_data_raw/1)'); +is( digest_data_hex('Whirlpool', ""), "19fa61d75522a4669b44e39c1d2e1726c530232130d407f89afee0964997f7a73e83be698b288febcf88e3e03c4f0757ea8964e59b63d93708b138cc42a66eb3", 'whirlpool (digest_data_hex/1)'); +is( digest_data_b64('Whirlpool', ""), "Gfph11UipGabROOcHS4XJsUwIyEw1Af4mv7glkmX96c+g75piyiP68+I4+A8TwdX6olk5Ztj2TcIsTjMQqZusw==", 'whirlpool (digest_data_b64/1)'); +is( digest_data_b64u('Whirlpool', ""), "Gfph11UipGabROOcHS4XJsUwIyEw1Af4mv7glkmX96c-g75piyiP68-I4-A8TwdX6olk5Ztj2TcIsTjMQqZusw", 'whirlpool (digest_data_b64u/1)'); +is( Crypt::Digest::Whirlpool->new->add("")->hexdigest, "19fa61d75522a4669b44e39c1d2e1726c530232130d407f89afee0964997f7a73e83be698b288febcf88e3e03c4f0757ea8964e59b63d93708b138cc42a66eb3", 'whirlpool (OO/1)'); + +is( whirlpool("123"), pack("H*","344907e89b981caf221d05f597eb57a6af408f15f4dd7895bbd1b96a2938ec24a7dcf23acb94ece0b6d7b0640358bc56bdb448194b9305311aff038a834a079f"), 'whirlpool (raw/2)'); +is( whirlpool_hex("123"), "344907e89b981caf221d05f597eb57a6af408f15f4dd7895bbd1b96a2938ec24a7dcf23acb94ece0b6d7b0640358bc56bdb448194b9305311aff038a834a079f", 'whirlpool (hex/2)'); +is( whirlpool_b64("123"), "NEkH6JuYHK8iHQX1l+tXpq9AjxX03XiVu9G5aik47CSn3PI6y5Ts4LbXsGQDWLxWvbRIGUuTBTEa/wOKg0oHnw==", 'whirlpool (base64/2)'); +is( digest_data('Whirlpool', "123"), pack("H*","344907e89b981caf221d05f597eb57a6af408f15f4dd7895bbd1b96a2938ec24a7dcf23acb94ece0b6d7b0640358bc56bdb448194b9305311aff038a834a079f"), 'whirlpool (digest_data_raw/2)'); +is( digest_data_hex('Whirlpool', "123"), "344907e89b981caf221d05f597eb57a6af408f15f4dd7895bbd1b96a2938ec24a7dcf23acb94ece0b6d7b0640358bc56bdb448194b9305311aff038a834a079f", 'whirlpool (digest_data_hex/2)'); +is( digest_data_b64('Whirlpool', "123"), "NEkH6JuYHK8iHQX1l+tXpq9AjxX03XiVu9G5aik47CSn3PI6y5Ts4LbXsGQDWLxWvbRIGUuTBTEa/wOKg0oHnw==", 'whirlpool (digest_data_b64/2)'); +is( digest_data_b64u('Whirlpool', "123"), "NEkH6JuYHK8iHQX1l-tXpq9AjxX03XiVu9G5aik47CSn3PI6y5Ts4LbXsGQDWLxWvbRIGUuTBTEa_wOKg0oHnw", 'whirlpool (digest_data_b64u/2)'); +is( Crypt::Digest::Whirlpool->new->add("123")->hexdigest, "344907e89b981caf221d05f597eb57a6af408f15f4dd7895bbd1b96a2938ec24a7dcf23acb94ece0b6d7b0640358bc56bdb448194b9305311aff038a834a079f", 'whirlpool (OO/2)'); + +is( whirlpool("test\0test\0test\n"), pack("H*","3dbd3f37a844611382f9fc757b3ba299d1c250fa1f2fdd69f06b113f28e1c3756f5cc551996932dd8802f335db6789002f06e3ff11eb19c8715113e588bc39c7"), 'whirlpool (raw/3)'); +is( whirlpool_hex("test\0test\0test\n"), "3dbd3f37a844611382f9fc757b3ba299d1c250fa1f2fdd69f06b113f28e1c3756f5cc551996932dd8802f335db6789002f06e3ff11eb19c8715113e588bc39c7", 'whirlpool (hex/3)'); +is( whirlpool_b64("test\0test\0test\n"), "Pb0/N6hEYROC+fx1ezuimdHCUPofL91p8GsRPyjhw3VvXMVRmWky3YgC8zXbZ4kALwbj/xHrGchxURPliLw5xw==", 'whirlpool (base64/3)'); +is( digest_data('Whirlpool', "test\0test\0test\n"), pack("H*","3dbd3f37a844611382f9fc757b3ba299d1c250fa1f2fdd69f06b113f28e1c3756f5cc551996932dd8802f335db6789002f06e3ff11eb19c8715113e588bc39c7"), 'whirlpool (digest_data_raw/3)'); +is( digest_data_hex('Whirlpool', "test\0test\0test\n"), "3dbd3f37a844611382f9fc757b3ba299d1c250fa1f2fdd69f06b113f28e1c3756f5cc551996932dd8802f335db6789002f06e3ff11eb19c8715113e588bc39c7", 'whirlpool (digest_data_hex/3)'); +is( digest_data_b64('Whirlpool', "test\0test\0test\n"), "Pb0/N6hEYROC+fx1ezuimdHCUPofL91p8GsRPyjhw3VvXMVRmWky3YgC8zXbZ4kALwbj/xHrGchxURPliLw5xw==", 'whirlpool (digest_data_b64/3)'); +is( digest_data_b64u('Whirlpool', "test\0test\0test\n"), "Pb0_N6hEYROC-fx1ezuimdHCUPofL91p8GsRPyjhw3VvXMVRmWky3YgC8zXbZ4kALwbj_xHrGchxURPliLw5xw", 'whirlpool (digest_data_b64u/3)'); +is( Crypt::Digest::Whirlpool->new->add("test\0test\0test\n")->hexdigest, "3dbd3f37a844611382f9fc757b3ba299d1c250fa1f2fdd69f06b113f28e1c3756f5cc551996932dd8802f335db6789002f06e3ff11eb19c8715113e588bc39c7", 'whirlpool (OO/3)'); + + +is( whirlpool_file('t/data/binary-test.file'), pack("H*","a84b35e702371d7a96c5332747d5210a425512d2d6c5ec5eb8851718d3939faf0b84d3c1c6b1071e6c6e54efc96ea7b3a46f9019554fabb0d4a2924ffa5dff8d"), 'whirlpool (raw/file/1)'); +is( whirlpool_file_hex('t/data/binary-test.file'), "a84b35e702371d7a96c5332747d5210a425512d2d6c5ec5eb8851718d3939faf0b84d3c1c6b1071e6c6e54efc96ea7b3a46f9019554fabb0d4a2924ffa5dff8d", 'whirlpool (hex/file/1)'); +is( whirlpool_file_b64('t/data/binary-test.file'), "qEs15wI3HXqWxTMnR9UhCkJVEtLWxexeuIUXGNOTn68LhNPBxrEHHmxuVO/JbqezpG+QGVVPq7DUopJP+l3/jQ==", 'whirlpool (base64/file/1)'); +is( digest_file('Whirlpool', 't/data/binary-test.file'), pack("H*","a84b35e702371d7a96c5332747d5210a425512d2d6c5ec5eb8851718d3939faf0b84d3c1c6b1071e6c6e54efc96ea7b3a46f9019554fabb0d4a2924ffa5dff8d"), 'whirlpool (digest_file_raw/file/1)'); +is( digest_file_hex('Whirlpool', 't/data/binary-test.file'), "a84b35e702371d7a96c5332747d5210a425512d2d6c5ec5eb8851718d3939faf0b84d3c1c6b1071e6c6e54efc96ea7b3a46f9019554fabb0d4a2924ffa5dff8d", 'whirlpool (digest_file_hex/file/1)'); +is( digest_file_b64('Whirlpool', 't/data/binary-test.file'), "qEs15wI3HXqWxTMnR9UhCkJVEtLWxexeuIUXGNOTn68LhNPBxrEHHmxuVO/JbqezpG+QGVVPq7DUopJP+l3/jQ==", 'whirlpool (digest_file_b64/file/1)'); +is( digest_file_b64u('Whirlpool', 't/data/binary-test.file'), "qEs15wI3HXqWxTMnR9UhCkJVEtLWxexeuIUXGNOTn68LhNPBxrEHHmxuVO_JbqezpG-QGVVPq7DUopJP-l3_jQ", 'whirlpool (digest_file_b64u/file/1)'); +is( Crypt::Digest::Whirlpool->new->addfile('t/data/binary-test.file')->hexdigest, "a84b35e702371d7a96c5332747d5210a425512d2d6c5ec5eb8851718d3939faf0b84d3c1c6b1071e6c6e54efc96ea7b3a46f9019554fabb0d4a2924ffa5dff8d", 'whirlpool (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::Whirlpool->new->addfile($fh)->hexdigest, "a84b35e702371d7a96c5332747d5210a425512d2d6c5ec5eb8851718d3939faf0b84d3c1c6b1071e6c6e54efc96ea7b3a46f9019554fabb0d4a2924ffa5dff8d", 'whirlpool (OO/filehandle/1)'); + close($fh); +} + +is( whirlpool_file('t/data/text-CR.file'), pack("H*","2846f7f8c731fc77c085037b71bec091bdf772f4759c06760bea914ef6f1e0cfb24548828650bb7487d6a1e96ade543268bd01e90daec95dbe9ef817dc668bd0"), 'whirlpool (raw/file/2)'); +is( whirlpool_file_hex('t/data/text-CR.file'), "2846f7f8c731fc77c085037b71bec091bdf772f4759c06760bea914ef6f1e0cfb24548828650bb7487d6a1e96ade543268bd01e90daec95dbe9ef817dc668bd0", 'whirlpool (hex/file/2)'); +is( whirlpool_file_b64('t/data/text-CR.file'), "KEb3+Mcx/HfAhQN7cb7Akb33cvR1nAZ2C+qRTvbx4M+yRUiChlC7dIfWoelq3lQyaL0B6Q2uyV2+nvgX3GaL0A==", 'whirlpool (base64/file/2)'); +is( digest_file('Whirlpool', 't/data/text-CR.file'), pack("H*","2846f7f8c731fc77c085037b71bec091bdf772f4759c06760bea914ef6f1e0cfb24548828650bb7487d6a1e96ade543268bd01e90daec95dbe9ef817dc668bd0"), 'whirlpool (digest_file_raw/file/2)'); +is( digest_file_hex('Whirlpool', 't/data/text-CR.file'), "2846f7f8c731fc77c085037b71bec091bdf772f4759c06760bea914ef6f1e0cfb24548828650bb7487d6a1e96ade543268bd01e90daec95dbe9ef817dc668bd0", 'whirlpool (digest_file_hex/file/2)'); +is( digest_file_b64('Whirlpool', 't/data/text-CR.file'), "KEb3+Mcx/HfAhQN7cb7Akb33cvR1nAZ2C+qRTvbx4M+yRUiChlC7dIfWoelq3lQyaL0B6Q2uyV2+nvgX3GaL0A==", 'whirlpool (digest_file_b64/file/2)'); +is( digest_file_b64u('Whirlpool', 't/data/text-CR.file'), "KEb3-Mcx_HfAhQN7cb7Akb33cvR1nAZ2C-qRTvbx4M-yRUiChlC7dIfWoelq3lQyaL0B6Q2uyV2-nvgX3GaL0A", 'whirlpool (digest_file_b64u/file/2)'); +is( Crypt::Digest::Whirlpool->new->addfile('t/data/text-CR.file')->hexdigest, "2846f7f8c731fc77c085037b71bec091bdf772f4759c06760bea914ef6f1e0cfb24548828650bb7487d6a1e96ade543268bd01e90daec95dbe9ef817dc668bd0", 'whirlpool (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::Whirlpool->new->addfile($fh)->hexdigest, "2846f7f8c731fc77c085037b71bec091bdf772f4759c06760bea914ef6f1e0cfb24548828650bb7487d6a1e96ade543268bd01e90daec95dbe9ef817dc668bd0", 'whirlpool (OO/filehandle/2)'); + close($fh); +} + +is( whirlpool_file('t/data/text-CRLF.file'), pack("H*","5d09c8cbfe7f68f5e374aac357ee0ee6b3accbe794b1b826b8a72a4f6771f86cdb65604325e09c547f6eeb71a25e94d336186ec045255c152d52fb57d394d9cf"), 'whirlpool (raw/file/3)'); +is( whirlpool_file_hex('t/data/text-CRLF.file'), "5d09c8cbfe7f68f5e374aac357ee0ee6b3accbe794b1b826b8a72a4f6771f86cdb65604325e09c547f6eeb71a25e94d336186ec045255c152d52fb57d394d9cf", 'whirlpool (hex/file/3)'); +is( whirlpool_file_b64('t/data/text-CRLF.file'), "XQnIy/5/aPXjdKrDV+4O5rOsy+eUsbgmuKcqT2dx+GzbZWBDJeCcVH9u63GiXpTTNhhuwEUlXBUtUvtX05TZzw==", 'whirlpool (base64/file/3)'); +is( digest_file('Whirlpool', 't/data/text-CRLF.file'), pack("H*","5d09c8cbfe7f68f5e374aac357ee0ee6b3accbe794b1b826b8a72a4f6771f86cdb65604325e09c547f6eeb71a25e94d336186ec045255c152d52fb57d394d9cf"), 'whirlpool (digest_file_raw/file/3)'); +is( digest_file_hex('Whirlpool', 't/data/text-CRLF.file'), "5d09c8cbfe7f68f5e374aac357ee0ee6b3accbe794b1b826b8a72a4f6771f86cdb65604325e09c547f6eeb71a25e94d336186ec045255c152d52fb57d394d9cf", 'whirlpool (digest_file_hex/file/3)'); +is( digest_file_b64('Whirlpool', 't/data/text-CRLF.file'), "XQnIy/5/aPXjdKrDV+4O5rOsy+eUsbgmuKcqT2dx+GzbZWBDJeCcVH9u63GiXpTTNhhuwEUlXBUtUvtX05TZzw==", 'whirlpool (digest_file_b64/file/3)'); +is( digest_file_b64u('Whirlpool', 't/data/text-CRLF.file'), "XQnIy_5_aPXjdKrDV-4O5rOsy-eUsbgmuKcqT2dx-GzbZWBDJeCcVH9u63GiXpTTNhhuwEUlXBUtUvtX05TZzw", 'whirlpool (digest_file_b64u/file/3)'); +is( Crypt::Digest::Whirlpool->new->addfile('t/data/text-CRLF.file')->hexdigest, "5d09c8cbfe7f68f5e374aac357ee0ee6b3accbe794b1b826b8a72a4f6771f86cdb65604325e09c547f6eeb71a25e94d336186ec045255c152d52fb57d394d9cf", 'whirlpool (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::Whirlpool->new->addfile($fh)->hexdigest, "5d09c8cbfe7f68f5e374aac357ee0ee6b3accbe794b1b826b8a72a4f6771f86cdb65604325e09c547f6eeb71a25e94d336186ec045255c152d52fb57d394d9cf", 'whirlpool (OO/filehandle/3)'); + close($fh); +} + +is( whirlpool_file('t/data/text-LF.file'), pack("H*","05b2f5e28833a734dc8dc763e12030fb78dbac5fd9709bc30315ea81507d3b338697c1c58474abeb41f110444381000bffda176a0fa0b12b1b65ccfd9f6d19b0"), 'whirlpool (raw/file/4)'); +is( whirlpool_file_hex('t/data/text-LF.file'), "05b2f5e28833a734dc8dc763e12030fb78dbac5fd9709bc30315ea81507d3b338697c1c58474abeb41f110444381000bffda176a0fa0b12b1b65ccfd9f6d19b0", 'whirlpool (hex/file/4)'); +is( whirlpool_file_b64('t/data/text-LF.file'), "BbL14ogzpzTcjcdj4SAw+3jbrF/ZcJvDAxXqgVB9OzOGl8HFhHSr60HxEERDgQAL/9oXag+gsSsbZcz9n20ZsA==", 'whirlpool (base64/file/4)'); +is( digest_file('Whirlpool', 't/data/text-LF.file'), pack("H*","05b2f5e28833a734dc8dc763e12030fb78dbac5fd9709bc30315ea81507d3b338697c1c58474abeb41f110444381000bffda176a0fa0b12b1b65ccfd9f6d19b0"), 'whirlpool (digest_file_raw/file/4)'); +is( digest_file_hex('Whirlpool', 't/data/text-LF.file'), "05b2f5e28833a734dc8dc763e12030fb78dbac5fd9709bc30315ea81507d3b338697c1c58474abeb41f110444381000bffda176a0fa0b12b1b65ccfd9f6d19b0", 'whirlpool (digest_file_hex/file/4)'); +is( digest_file_b64('Whirlpool', 't/data/text-LF.file'), "BbL14ogzpzTcjcdj4SAw+3jbrF/ZcJvDAxXqgVB9OzOGl8HFhHSr60HxEERDgQAL/9oXag+gsSsbZcz9n20ZsA==", 'whirlpool (digest_file_b64/file/4)'); +is( digest_file_b64u('Whirlpool', 't/data/text-LF.file'), "BbL14ogzpzTcjcdj4SAw-3jbrF_ZcJvDAxXqgVB9OzOGl8HFhHSr60HxEERDgQAL_9oXag-gsSsbZcz9n20ZsA", 'whirlpool (digest_file_b64u/file/4)'); +is( Crypt::Digest::Whirlpool->new->addfile('t/data/text-LF.file')->hexdigest, "05b2f5e28833a734dc8dc763e12030fb78dbac5fd9709bc30315ea81507d3b338697c1c58474abeb41f110444381000bffda176a0fa0b12b1b65ccfd9f6d19b0", 'whirlpool (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::Whirlpool->new->addfile($fh)->hexdigest, "05b2f5e28833a734dc8dc763e12030fb78dbac5fd9709bc30315ea81507d3b338697c1c58474abeb41f110444381000bffda176a0fa0b12b1b65ccfd9f6d19b0", 'whirlpool (OO/filehandle/4)'); + close($fh); +} diff --git a/t/jwk.t b/t/jwk.t new file mode 100644 index 0000000..11e4c36 --- /dev/null +++ b/t/jwk.t @@ -0,0 +1,249 @@ +use strict; +use warnings; +use Test::More; + +plan skip_all => "No JSON::* module installed" unless eval { require JSON::PP } || eval { require JSON::XS } || eval { require Cpanel::JSON::XS }; +plan tests => 97; + +use Crypt::PK::RSA; +use Crypt::PK::ECC; + +my $rsa = Crypt::PK::RSA->new; +my $ec = Crypt::PK::ECC->new; +ok($rsa, "RSA new"); +ok($ec, "ECC new"); + +### RSA + +# test whether exported JWK JSON is canonical +$rsa->import_key("t/data/jwk_rsa-priv.json"); +is($rsa->export_key_jwk('public'), '{"e":"AQAB","kty":"RSA","n":"t6Q8PWSi1dkJj9hTP8hNYFlvadM7DflW9mWepOJhJ66w7nyoK1gPNqFMSQRyO125Gp-TEkodhWr0iujjHVx7BcV0llS4w5ACGgPrcAd6ZcSR0-Iqom-QFcNP8Sjg086MwoqQU_LYywlAGZ21WSdS_PERyGFiNnj3QQlO8Yns5jCtLCRwLHL0Pb1fEv45AuRIuUfVcPySBWYnDyGxvjYGDSM-AqWS9zIQ2ZilgT-GqUmipg0XOC0Cc20rgLe2ymLHjpHciCKVAbY5-L32-lSeZO-Os6U15_aXrk9Gw8cPUaX1_I8sLGuSiVdt3C_Fn2PZ3Z8i744FPFGGcG1qs2Wz-Q"}'); +is($rsa->export_key_jwk('private'),'{"d":"GRtbIQmhOZtyszfgKdg4u_N-R_mZGU_9k7JQ_jn1DnfTuMdSNprTeaSTyWfSNkuaAwnOEbIQVy1IQbWVV25NY3ybc_IhUJtfri7bAXYEReWaCl3hdlPKXy9UvqPYGR0kIXTQRqns-dVJ7jahlI7LyckrpTmrM8dWBo4_PMaenNnPiQgO0xnuToxutRZJfJvG4Ox4ka3GORQd9CsCZ2vsUDmsXOfUENOyMqADC6p1M3h33tsurY15k9qMSpG9OX_IJAXmxzAh_tWiZOwk2K4yxH9tS3Lq1yX8C1EWmeRDkK2ahecG85-oLKQt5VEpWHKmjOi_gJSdSgqcN96X52esAQ","dp":"KkMTWqBUefVwZ2_Dbj1pPQqyHSHjj90L5x_MOzqYAJMcLMZtbUtwKqvVDq3tbEo3ZIcohbDtt6SbfmWzggabpQxNxuBpoOOf_a_HgMXK_lhqigI4y_kqS1wY52IwjUn5rgRrJ-yYo1h41KR-vz2pYhEAeYrhttWtxVqLCRViD6c","dq":"AvfS0-gRxvn0bwJoMSnFxYcK1WnuEjQFluMGfwGitQBWtfZ1Er7t1xDkbN9GQTB9yqpDoYaN06H7CFtrkxhJIBQaj6nkF5KKS3TQtQ5qCzkOkmxIe3KRbBymXxkb5qwUpX5ELD5xFc6FeiafWYY63TmmEAu_lRFCOJ3xDea-ots","e":"AQAB","kty":"RSA","n":"t6Q8PWSi1dkJj9hTP8hNYFlvadM7DflW9mWepOJhJ66w7nyoK1gPNqFMSQRyO125Gp-TEkodhWr0iujjHVx7BcV0llS4w5ACGgPrcAd6ZcSR0-Iqom-QFcNP8Sjg086MwoqQU_LYywlAGZ21WSdS_PERyGFiNnj3QQlO8Yns5jCtLCRwLHL0Pb1fEv45AuRIuUfVcPySBWYnDyGxvjYGDSM-AqWS9zIQ2ZilgT-GqUmipg0XOC0Cc20rgLe2ymLHjpHciCKVAbY5-L32-lSeZO-Os6U15_aXrk9Gw8cPUaX1_I8sLGuSiVdt3C_Fn2PZ3Z8i744FPFGGcG1qs2Wz-Q","p":"2rnSOV4hKSN8sS4CgcQHFbs08XboFDqKum3sc4h3GRxrTmQdl1ZK9uw-PIHfQP0FkxXVrx-WE-ZEbrqivH_2iCLUS7wAl6XvARt1KkIaUxPPSYB9yk31s0Q8UK96E3_OrADAYtAJs-M3JxCLfNgqh56HDnETTQhH3rCT5T3yJws","q":"1u_RiFDP7LBYh3N4GXLT9OpSKYP0uQZyiaZwBtOCBNJgQxaj10RWjsZu0c6Iedis4S7B_coSKB0Kj9PaPaBzg-IySRvvcQuPamQu66riMhjVtG6TlV8CLCYKrYl52ziqK0E_ym2QnkwsUX7eYTB7LbAHRK9GqocDE5B0f808I4s","qi":"lSQi-w9CpyUReMErP1RsBLk7wNtOvs5EQpPqmuMvqW57NBUczScEoPwmUqqabu9V0-Py4dQ57_bapoKRu1R90bvuFnU63SHWEFglZQvJDMeAvmj4sm-Fp0oYu_neotgQ0hzbI5gry7ajdYy9-2lNx_76aBZoOUu9HCJ-UsfSOI8"}'); + +for my $f (qw/jwk_rsa-priv.json jwk_rsa-priv1.json jwk_rsa-pub1.json /) { + $rsa->import_key("t/data/$f"); + my $kh = $rsa->key2hash; + ok($kh->{N}, "RSA N test $f"); + ok($kh->{e}, "RSA e test $f"); +} + +my $RSA1 = { + d => "5F8713B5E258FE09F81583EC5C1F2B7578B1E6FC2C83514B37913711A1BA449A151FE1CB2CA0FD33B771E68A3B1944649DC867AD1C1E5240BB853E5F24B33459B14028D2D6636BEFEC1E8DA974B352FC53D3F6127EA8A3C29DD14F3941682C56A78768164E4DDA8F06CBF9C734AAE8003224278EA9454A21B17CB06D178075868CC05B3DB6FF1DFDC3D56378B4EDADEDF0C37A4CDC26D1D49AC26F6FE3B5220A5DD29396621BBC688CF2EEE2C6E0D54DA3C782014CD0739DB252CC51CAEBA8D3F1B824BAAB24D068EC903264D7D678AB08F06EC9E7E23D960628B744BF94B3694656463C7E417399ED73D076C891FCF463A9AA9CE62DA9CD17E237DC2A8002F1", + dP => "1B8B0F5E473A61AF72F28256F7F20B8F8C6EA69BB49738BF1FB553912F318F949D5F7728134A22998C31222D9E99302E7B450E6B97698051B2049E1CF2D436545E34D9746E80A0D33FC6A4621168E6D000EFB41EFCD9ADB9865CDC2DE6DC8DB81B61AF479B120F153200DDB3ABC2DF9FD1149ACEAB63739BF187A22A44E2063D", + dQ => "1B8B0F5E473A61AF72F28256F7F20B8F8C6EA69BB49738BF1FB553912F318F949D5F7728134A22998C31222D9E99302E7B450E6B97698051B2049E1CF2D436545E34D9746E80A0D33FC6A4621168E6D000EFB41EFCD9ADB9865CDC2DE6DC8DB81B61AF479B120F153200DDB3ABC2DF9FD1149ACEAB63739BF187A22A44E2063D", + e => "010001", + N => "D2FC7B6A0A1E6C67104AEB8F88B257669B4DF679DDAD099B5C4A6CD9A88015B5A133BF0B856C7871B6DF000B554FCEB3C2ED512BB68F145C6E8434752FAB52A1CFC124408F79B58A4578C16428855789F7A249E384CB2D9FAE2D67FD96FB926C198E077399FDC815C0AF097DDE5AADEFF44DE70E827F4878432439BFEEB96068D0474FC50D6D90BF3A98DFAF1040C89C02D692AB3B3C2896609D86FD73B774CE0740647CEEEAA310BD12F985A8EB9F59FDD426CEA5B2120F4F2A34BCAB764B7E6C54D6840238BCC40587A59E66ED1F33894577635C470AF75CF92C20D1DA43E1BFC419E222A6F0D0BB358C5E38F9CB050AEAFE904814F1AC1AA49CCA9EA0CA83", + p => "F378BEEC8BCC197A0C5C2B24BFBDD32ABF3ADFB1623BB676EF3BFCA23EA96D6510C8B3D0050C6D3D59F00F6D11FBAD1E4C3983DAE8E732DE4FA2A32B9BC45F98D855583B638CC9823233A949789C1478FB5CEB95218432A955A558487A74DDFA19565893DDCDF0173DBD8E35C72F01F51CF3386550CD7BCD12F9FB3B49D56DFB", + q => "DDD7CE47D72E62AFB44BE9A414BCE022D80C11F173076AB78567A132E1B4A02BAA9DBDEFA1B2F2BA6AA355940ED5D22B7708139C276963305C39F5B9AF7EF40055E38967EDFCD1848A8BE89E2CE12A9A3D5554BBF13CC583190876B79C45ECEC67ED6461DFECD6A0DBC6D9031207C0213006F4B527003BA7E2F21C6FAC9E9719", + qP => "1B233FA7A26B5F24A2CF5B6816029B595F89748DE3438CA9BBDADB316C77AD02417E6B7416863381421911514470EAB07A644DF35CE80C069AF819342963460E3247643743985856DC037B948FA9BB193F987646275D6BC7247C3B9E572D27B748F9917CAC1923AC94DB8671BD0285608B5D95D50A1B33BA21AEB34CA8405515", + size => 256, + type => 1, +}; + +my $RSA1_jwk_thumbprint_sha256 = 'NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs'; + +my $RSA2 = { + d => "", + dP => "", + dQ => "", + e => "010001", + N => "D2FC7B6A0A1E6C67104AEB8F88B257669B4DF679DDAD099B5C4A6CD9A88015B5A133BF0B856C7871B6DF000B554FCEB3C2ED512BB68F145C6E8434752FAB52A1CFC124408F79B58A4578C16428855789F7A249E384CB2D9FAE2D67FD96FB926C198E077399FDC815C0AF097DDE5AADEFF44DE70E827F4878432439BFEEB96068D0474FC50D6D90BF3A98DFAF1040C89C02D692AB3B3C2896609D86FD73B774CE0740647CEEEAA310BD12F985A8EB9F59FDD426CEA5B2120F4F2A34BCAB764B7E6C54D6840238BCC40587A59E66ED1F33894577635C470AF75CF92C20D1DA43E1BFC419E222A6F0D0BB358C5E38F9CB050AEAFE904814F1AC1AA49CCA9EA0CA83", + p => "", + q => "", + qP => "", + size => 256, + type => 0, +}; + +{ + $rsa->import_key($RSA1); + my $kh = $rsa->key2hash; + is($kh->{N}, $RSA1->{N}, "RSA N test HASH1"); + is($kh->{e}, $RSA1->{e}, "RSA e test HASH1"); + is($kh->{p}, $RSA1->{p}, "RSA private p test HASH1"); + is($kh->{q}, $RSA1->{q}, "RSA private q test HASH1"); + is($kh->{d}, $RSA1->{d}, "RSA private d test HASH1"); + is($kh->{dP}, $RSA1->{dP}, "RSA private dP test HASH1"); + is($kh->{dQ}, $RSA1->{dQ}, "RSA private dQ test HASH1"); + is($kh->{qP}, $RSA1->{qP}, "RSA private qP test HASH1"); + ok($rsa->is_private, "RSA private test HASH1"); + my $jwk = $rsa->export_key_jwk('private'); + my $jwkp = $rsa->export_key_jwk('public'); + my $jwkh = $rsa->export_key_jwk('private', 1); + my $jwkhp = $rsa->export_key_jwk('public', 1); + is($jwkh->{kty}, "RSA", "RSA kty test export_key_jwk as hash"); + is($jwkhp->{kty}, "RSA", "RSA(pub) kty test export_key_jwk as hash"); + ok(exists $jwkhp->{n}, "RSA(pub) n test export_key_jwk as hash"); + ok(exists $jwkhp->{e}, "RSA(pub) e test export_key_jwk as hash"); + ok(!exists $jwkhp->{p}, "RSA(pub) p test export_key_jwk as hash"); + ok(exists $jwkh->{n}, "RSA n test export_key_jwk as hash"); + ok(exists $jwkh->{e}, "RSA e test export_key_jwk as hash"); + ok(exists $jwkh->{p}, "RSA p test export_key_jwk as hash"); + my $jwk_tp = $rsa->export_key_jwk_thumbprint('SHA256'); + is($jwk_tp, $RSA1_jwk_thumbprint_sha256, 'export_key_jwk_thumbprint(SHA256)'); + ### jwk re-import private key + $rsa->import_key(\$jwk); + $kh = $rsa->key2hash; + ok($rsa->is_private, "RSA private test JWK1"); + is($kh->{N}, $RSA1->{N}, "RSA N test JWK1"); + is($kh->{e}, $RSA1->{e}, "RSA e test JWK1"); + is($kh->{p}, $RSA1->{p}, "RSA private p test JWK1"); + is($kh->{q}, $RSA1->{q}, "RSA private q test JWK1"); + is($kh->{d}, $RSA1->{d}, "RSA private d test JWK1"); + is($kh->{dP}, $RSA1->{dP}, "RSA private dP test JWK1"); + is($kh->{dQ}, $RSA1->{dQ}, "RSA private dQ test JWK1"); + is($kh->{qP}, $RSA1->{qP}, "RSA private qP test JWK1"); + $jwk_tp = $rsa->export_key_jwk_thumbprint('SHA256'); + is($jwk_tp, $RSA1_jwk_thumbprint_sha256, 'export_key_jwk_thumbprint(SHA256)'); + ### jwk re-import public key + $rsa->import_key(\$jwkp); + $kh = $rsa->key2hash; + ok(!$rsa->is_private, "RSA !private test JWK2"); + is($kh->{N}, $RSA1->{N}, "RSA N test JWK2"); + is($kh->{e}, $RSA1->{e}, "RSA e test JWK2"); + is($kh->{p}, "", "RSA private p test JWK2"); + is($kh->{q}, "", "RSA private q test JWK2"); + is($kh->{d}, "", "RSA private d test JWK2"); + is($kh->{dP}, "", "RSA private dP test JWK2"); + is($kh->{dQ}, "", "RSA private dQ test JWK2"); + is($kh->{qP}, "", "RSA private qP test JWK2"); + $jwk_tp = $rsa->export_key_jwk_thumbprint('SHA256'); + is($jwk_tp, $RSA1_jwk_thumbprint_sha256, 'export_key_jwk_thumbprint(SHA256)'); +} + +{ + $rsa->import_key($RSA2); + my $kh = $rsa->key2hash; + is($kh->{N}, $RSA1->{N}, "RSA N test HASH2"); + is($kh->{e}, $RSA1->{e}, "RSA e test HASH2"); + is($kh->{p}, "", "RSA private p test HASH2"); + is($kh->{q}, "", "RSA private q test HASH2"); + is($kh->{d}, "", "RSA private d test HASH2"); + is($kh->{dP}, "", "RSA private dP test HASH2"); + is($kh->{dQ}, "", "RSA private dQ test HASH2"); + is($kh->{qP}, "", "RSA private qP test HASH2"); + ok(!$rsa->is_private, "RSA private test HASH2"); +} + +### ECC + +# test whether exported JWK JSON is canonical +$ec->import_key("t/data/jwk_ec-priv1.json"); +is($ec->export_key_jwk('public'), '{"crv":"P-256","kty":"EC","x":"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4","y":"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM"}'); +is($ec->export_key_jwk('private'),'{"crv":"P-256","d":"870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE","kty":"EC","x":"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4","y":"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM"}'); + +for my $f (qw/jwk_ec-priv1.json jwk_ec-pub.json jwk_ec-pub1.json/) { + $ec->import_key("t/data/$f"); + my $kh = $ec->key2hash; + ok($kh->{pub_x}, "EC x test $f"); + ok($kh->{pub_y}, "EC y test $f"); +} + +my $EC1 = { + curve_A => "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", + curve_B => "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", + curve_bits => 256, + curve_bytes => 32, + curve_cofactor => 1, + curve_Gx => "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", + curve_Gy => "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", + curve_name => "secp256r1", + curve_order => "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", + curve_prime => "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", + k => "F3BD0C07A81FB932781ED52752F60CC89A6BE5E51934FE01938DDB55D8F77801", + pub_x => "30A0424CD21C2944838A2D75C92B37E76EA20D9F00893A3B4EEE8A3C0AAFEC3E", + pub_y => "E04B65E92456D9888B52B379BDFBD51EE869EF1F0FC65B6659695B6CCE081723", + size => 32, + type => 1, +}; + +my $ec1_jwk_thumbprint_sha256 = 'cn-I_WNMClehiVp51i_0VpOENW1upEerA8sEam5hn-s'; + +my $EC2 = { + curve_A => "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", + curve_B => "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", + curve_bits => 256, + curve_bytes => 32, + curve_cofactor => 1, + curve_Gx => "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", + curve_Gy => "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", + curve_name => "secp256r1", + curve_order => "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", + curve_prime => "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", + k => "", + pub_x => "30A0424CD21C2944838A2D75C92B37E76EA20D9F00893A3B4EEE8A3C0AAFEC3E", + pub_y => "E04B65E92456D9888B52B379BDFBD51EE869EF1F0FC65B6659695B6CCE081723", + size => 32, + type => 0, +}; + +{ + $ec->import_key($EC1); + my $kh = $ec->key2hash; + is($kh->{pub_x}, $EC1->{pub_x}, "EC x test HASH1"); + is($kh->{pub_y}, $EC1->{pub_y}, "EC y test HASH1"); + is($kh->{k}, $EC1->{k}, "EC k test HASH1"); + is($kh->{curve_name}, "secp256r1", "EC curve test HASH1"); + ok($ec->is_private, "EC private test HASH1"); + my $jwk = $ec->export_key_jwk('private'); + my $jwkp = $ec->export_key_jwk('public'); + my $jwkh = $ec->export_key_jwk('private', 1); + my $jwkhp = $ec->export_key_jwk('public', 1); + is($jwkh->{kty}, "EC", "ECC kty test export_key_jwk as hash"); + is($jwkhp->{kty}, "EC", "ECC(pub) kty test export_key_jwk as hash"); + ok(exists $jwkhp->{x}, "ECC(pub) x test export_key_jwk as hash"); + ok(exists $jwkhp->{y}, "ECC(pub) y test export_key_jwk as hash"); + ok(!exists $jwkhp->{d}, "ECC(pub) d test export_key_jwk as hash"); + ok(exists $jwkh->{x}, "ECC x test export_key_jwk as hash"); + ok(exists $jwkh->{y}, "ECC y test export_key_jwk as hash"); + ok(exists $jwkh->{d}, "ECC d test export_key_jwk as hash"); + my $jwk_tp = $ec->export_key_jwk_thumbprint('SHA256'); + is($jwk_tp, $ec1_jwk_thumbprint_sha256, 'export_key_jwk_thumbprint(SHA256)'); + ### jwk re-import private key + $ec->import_key(\$jwk); + $kh = $ec->key2hash; + is($kh->{pub_x}, $EC1->{pub_x}, "EC x test JWK1"); + is($kh->{pub_y}, $EC1->{pub_y}, "EC y test JWK1"); + is($kh->{k}, $EC1->{k}, "EC k test JWK1"); + is($kh->{curve_name}, "secp256r1", "EC curve test JWK1"); + ok($ec->is_private, "EC private test JWK1"); + $jwk_tp = $ec->export_key_jwk_thumbprint('SHA256'); + is($jwk_tp, $ec1_jwk_thumbprint_sha256, 'export_key_jwk_thumbprint(SHA256)'); + ### jwk re-import public key + $ec->import_key(\$jwkp); + $kh = $ec->key2hash; + is($kh->{pub_x}, $EC1->{pub_x}, "EC x test JWK2"); + is($kh->{pub_y}, $EC1->{pub_y}, "EC y test JWK2"); + is($kh->{k}, "", "EC k test JWK2"); + is($kh->{curve_name}, "secp256r1", "EC curve test JWK2"); + ok(!$ec->is_private, "EC !private test JWK2"); + $jwk_tp = $ec->export_key_jwk_thumbprint('SHA256'); + is($jwk_tp, $ec1_jwk_thumbprint_sha256, 'export_key_jwk_thumbprint(SHA256)'); +} + +{ + $ec->import_key($EC2); + my $kh = $ec->key2hash; + is($kh->{pub_x}, $EC1->{pub_x}, "EC x test HASH2"); + is($kh->{pub_y}, $EC1->{pub_y}, "EC y test HASH2"); + is($kh->{k}, "", "EC k test HASH2"); + is($kh->{curve_name}, "secp256r1", "EC curve test HASH2"); + ok(!$ec->is_private, "EC private test HASH2"); +} + +{ + my $jwk = { + e => 'AQAB', + kty => 'RSA', + n => 'ln_cp6g_c65R6uYmwFx6AF1PyyZF7N1EaLhvUjDStK6Scmp_XCD-ynz5Q1iS0Q2t8gnh_s5dQtThiuvOGxCK1j69TA6Jpo0uUBL-gzf3J25PhqdNmTbGGRNkD0aT8qfeY9_bXTA1vmawh-46A6xrVFiT62NK7IdsyQNzrtR9QwzcSR79m9UqTVe5MdDB9tZZIotmqWQlZ5MVb26PPmgkuh6AthS-an2KeDdYRwAyQtfR1B6f-swzIPwq-AUy1pfmGVe-d6K5dCOU9RUMPPRiQ7atmodAxfcWywmnrCtSCfPk0fkTLN4RsuCWV85NXcGnpr41m4uacALT0Xs0IqBKbw', + }; + my $before_json = {%$jwk}; + + Crypt::PK::RSA->new($jwk); + + is_deeply( + $jwk, + $before_json, + 'new($jwk) doesn’t change $jwk', + ); +} diff --git a/t/key_derivation.t b/t/key_derivation.t new file mode 100644 index 0000000..48a2564 --- /dev/null +++ b/t/key_derivation.t @@ -0,0 +1,138 @@ +use strict; +use warnings; +use Test::More tests => 27; + +use Crypt::KeyDerivation qw(pbkdf1 pbkdf2 hkdf hkdf_expand hkdf_extract); + +{ ### rfc5869 test case 1 + my $keying_material = pack("H*", "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"); + my $salt = pack("H*", "000102030405060708090a0b0c"); + my $info = pack("H*", "f0f1f2f3f4f5f6f7f8f9"); + my $len = 42; + my $hash_name = 'SHA256'; + my $expected_prk = "077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5"; + my $expected_okm = "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865"; + + my $prk = hkdf_extract($keying_material, $salt, $hash_name); + my $okm1 = hkdf_expand($prk, $hash_name, $len, $info); + my $okm2 = hkdf($keying_material, $salt, $hash_name, $len, $info); + is(unpack("H*", $prk), $expected_prk, "PRK hkdf_extract/1"); + is(unpack("H*", $okm1), $expected_okm, "OKM1 hkdf_expand/1"); + is(unpack("H*", $okm2), $expected_okm, "OKM2 hkdf/1"); +} + +{ ### rfc5869 test case 2 + my $keying_material = pack("H*", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f"); + my $salt = pack("H*", "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf"); + my $info = pack("H*", "b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"); + my $len = 82; + my $hash_name = 'SHA256'; + my $expected_prk = "06a6b88c5853361a06104c9ceb35b45cef760014904671014a193f40c15fc244"; + my $expected_okm = "b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87"; + + my $prk = hkdf_extract($keying_material, $salt, $hash_name); + my $okm1 = hkdf_expand($prk, $hash_name, $len, $info); + my $okm2 = hkdf($keying_material, $salt, $hash_name, $len, $info); + is(unpack("H*", $prk), $expected_prk, "PRK hkdf_extract/2"); + is(unpack("H*", $okm1), $expected_okm, "OKM1 hkdf_expand/2"); + is(unpack("H*", $okm2), $expected_okm, "OKM2 hkdf/2"); +} + +{ ### rfc5869 test case 3 + my $keying_material = pack("H*", "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"); + my $salt = ''; + my $info = ''; + my $len = 42; + my $hash_name = 'SHA256'; + my $expected_prk = "19ef24a32c717b167f33a91d6f648bdf96596776afdb6377ac434c1c293ccb04"; + my $expected_okm = "8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8"; + + my $prk = hkdf_extract($keying_material, $salt, $hash_name); + my $okm1 = hkdf_expand($prk, $hash_name, $len, $info); + my $okm2 = hkdf($keying_material, $salt, $hash_name, $len, $info); + is(unpack("H*", $prk), $expected_prk, "PRK hkdf_extract/3"); + is(unpack("H*", $okm1), $expected_okm, "OKM1 hkdf_expand/3"); + is(unpack("H*", $okm2), $expected_okm, "OKM2 hkdf/3"); +} + +{ ### rfc5869 test case 4 + my $keying_material = pack("H*", "0b0b0b0b0b0b0b0b0b0b0b"); + my $salt = pack("H*", "000102030405060708090a0b0c"); + my $info = pack("H*", "f0f1f2f3f4f5f6f7f8f9"); + my $len = 42; + my $hash_name = 'SHA1'; + my $expected_prk = "9b6c18c432a7bf8f0e71c8eb88f4b30baa2ba243"; + my $expected_okm = "085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422478d305f3f896"; + + my $prk = hkdf_extract($keying_material, $salt, $hash_name); + my $okm1 = hkdf_expand($prk, $hash_name, $len, $info); + my $okm2 = hkdf($keying_material, $salt, $hash_name, $len, $info); + is(unpack("H*", $prk), $expected_prk, "PRK hkdf_extract/4"); + is(unpack("H*", $okm1), $expected_okm, "OKM1 hkdf_expand/4"); + is(unpack("H*", $okm2), $expected_okm, "OKM2 hkdf/4"); +} + +{ ### rfc5869 test case 5 + my $keying_material = pack("H*", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f"); + my $salt = pack("H*", "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf"); + my $info = pack("H*", "b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"); + my $len = 82; + my $hash_name = 'SHA1'; + my $expected_prk = "8adae09a2a307059478d309b26c4115a224cfaf6"; + my $expected_okm = "0bd770a74d1160f7c9f12cd5912a06ebff6adcae899d92191fe4305673ba2ffe8fa3f1a4e5ad79f3f334b3b202b2173c486ea37ce3d397ed034c7f9dfeb15c5e927336d0441f4c4300e2cff0d0900b52d3b4"; + + my $prk = hkdf_extract($keying_material, $salt, $hash_name); + my $okm1 = hkdf_expand($prk, $hash_name, $len, $info); + my $okm2 = hkdf($keying_material, $salt, $hash_name, $len, $info); + is(unpack("H*", $prk), $expected_prk, "PRK hkdf_extract/5"); + is(unpack("H*", $okm1), $expected_okm, "OKM1 hkdf_expand/5"); + is(unpack("H*", $okm2), $expected_okm, "OKM2 hkdf/5"); +} + +{ ### rfc5869 test case 6 + my $keying_material = pack("H*", "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"); + my $salt = ''; + my $info = ''; + my $len = 42; + my $hash_name = 'SHA1'; + my $expected_prk = "da8c8a73c7fa77288ec6f5e7c297786aa0d32d01"; + my $expected_okm = "0ac1af7002b3d761d1e55298da9d0506b9ae52057220a306e07b6b87e8df21d0ea00033de03984d34918"; + + my $prk = hkdf_extract($keying_material, $salt, $hash_name); + my $okm1 = hkdf_expand($prk, $hash_name, $len, $info); + my $okm2 = hkdf($keying_material, $salt, $hash_name, $len, $info); + is(unpack("H*", $prk), $expected_prk, "PRK hkdf_extract/6"); + is(unpack("H*", $okm1), $expected_okm, "OKM1 hkdf_expand/6"); + is(unpack("H*", $okm2), $expected_okm, "OKM2 hkdf/6"); +} + +{ ### rfc5869 test case 7 + my $keying_material = pack("H*", "0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c"); + my $salt = undef; + my $info = ''; + my $len = 42; + my $hash_name = 'SHA1'; + my $expected_prk = "2adccada18779e7c2077ad2eb19d3f3e731385dd"; + my $expected_okm = "2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48"; + + my $prk = hkdf_extract($keying_material, $salt, $hash_name); + my $okm1 = hkdf_expand($prk, $hash_name, $len, $info); + my $okm2 = hkdf($keying_material, $salt, $hash_name, $len, $info); + is(unpack("H*", $prk), $expected_prk, "PRK hkdf_extract/7"); + is(unpack("H*", $okm1), $expected_okm, "OKM1 hkdf_expand/7"); + is(unpack("H*", $okm2), $expected_okm, "OKM2 hkdf/7"); +} + +{ #PBKDF1 + is(unpack('H*', pbkdf1(unpack("H*", "012345678910111231415161717"), unpack("H*", "F7560045C70A96DB"), 12, 'SHA1', 20)), '59a9c8a32646428e6724cc9f43c72aa69a6edc1f', 'test pbkdf1 A'); +} + +{ #PBKDF2 http://tools.ietf.org/html/rfc6070 + is(unpack('H*', pbkdf2("password", "salt", 1, 'SHA1', 20)), '0c60c80f961f0e71f3a9b524af6012062fe037a6', 'test pbkdf2 A'); + is(unpack('H*', pbkdf2("password", "salt", 2, 'SHA1', 20)), 'ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957', 'test pbkdf2 B'); + is(unpack('H*', pbkdf2("password", "salt", 4096, 'SHA1', 20)), '4b007901b765489abead49d926f721d065a429c1', 'test pbkdf2 C'); + ###LONG RUNNING### + #is(unpack('H*', pbkdf2("password", "salt", 16777216, 'SHA1', 20)), 'eefe3d61cd4da4e4e9945b3d6ba2158c2634e984', 'test pbkdf2 D'); + is(unpack('H*', pbkdf2("passwordPASSWORDpassword", "saltSALTsaltSALTsaltSALTsaltSALTsalt", 4096, 'SHA1', 25)), '3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038', 'test pbkdf2 E'); + is(unpack('H*', pbkdf2("pass\0word", "sa\0lt", 4096, 'SHA1', 16)), '56fa6aa75548099dcc37d7f03425e0c3', 'test pbkdf2 F'); +} diff --git a/t/mac_blake2b.t b/t/mac_blake2b.t new file mode 100644 index 0000000..0e275a9 --- /dev/null +++ b/t/mac_blake2b.t @@ -0,0 +1,45 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 36; + +use Crypt::Mac::BLAKE2b qw( blake2b blake2b_hex blake2b_b64 blake2b_b64u ); + +is( unpack('H*', Crypt::Mac::BLAKE2b->new(32,'12345678901234561234567890123456')->add("")->mac), '171e61c46e5eb96bfe44b8167f72112fa3dacff54ff9b938c92a988b7b65a550', 'BLAKE2b/oo+raw/1'); +is( Crypt::Mac::BLAKE2b->new(32,'12345678901234561234567890123456')->add("")->hexmac, '171e61c46e5eb96bfe44b8167f72112fa3dacff54ff9b938c92a988b7b65a550', 'BLAKE2b/oo+hex/1'); +is( unpack('H*', blake2b(32,'12345678901234561234567890123456',"")), '171e61c46e5eb96bfe44b8167f72112fa3dacff54ff9b938c92a988b7b65a550', 'BLAKE2b/func+raw/1'); +is( blake2b_hex(32,'12345678901234561234567890123456',""), '171e61c46e5eb96bfe44b8167f72112fa3dacff54ff9b938c92a988b7b65a550', 'BLAKE2b/func+hex/1'); +is( blake2b_b64(32,'12345678901234561234567890123456',""), 'Fx5hxG5euWv+RLgWf3IRL6Paz/VP+bk4ySqYi3tlpVA=', 'BLAKE2b/func+b64/1'); +is( blake2b_b64u(32,'12345678901234561234567890123456',""), 'Fx5hxG5euWv-RLgWf3IRL6Paz_VP-bk4ySqYi3tlpVA', 'BLAKE2b/func+b64u/1'); +is( unpack('H*', Crypt::Mac::BLAKE2b->new(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add("")->mac), 'a9c114765666cf3e313253110efcc3b844739fe14bf1b32bf69316c6716978f0', 'BLAKE2b/oo+raw/2'); +is( Crypt::Mac::BLAKE2b->new(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add("")->hexmac, 'a9c114765666cf3e313253110efcc3b844739fe14bf1b32bf69316c6716978f0', 'BLAKE2b/oo+hex/2'); +is( unpack('H*', blake2b(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"")), 'a9c114765666cf3e313253110efcc3b844739fe14bf1b32bf69316c6716978f0', 'BLAKE2b/func+raw/2'); +is( blake2b_hex(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',""), 'a9c114765666cf3e313253110efcc3b844739fe14bf1b32bf69316c6716978f0', 'BLAKE2b/func+hex/2'); +is( blake2b_b64(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',""), 'qcEUdlZmzz4xMlMRDvzDuERzn+FL8bMr9pMWxnFpePA=', 'BLAKE2b/func+b64/2'); +is( blake2b_b64u(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',""), 'qcEUdlZmzz4xMlMRDvzDuERzn-FL8bMr9pMWxnFpePA', 'BLAKE2b/func+b64u/2'); +is( unpack('H*', Crypt::Mac::BLAKE2b->new(32,'12345678901234561234567890123456')->add(123)->mac), '17391b8e492e7994b958bcbf7ab2c4fe807749e8c5401d84b8dff226e0d56369', 'BLAKE2b/oo+raw/3'); +is( Crypt::Mac::BLAKE2b->new(32,'12345678901234561234567890123456')->add(123)->hexmac, '17391b8e492e7994b958bcbf7ab2c4fe807749e8c5401d84b8dff226e0d56369', 'BLAKE2b/oo+hex/3'); +is( unpack('H*', blake2b(32,'12345678901234561234567890123456',123)), '17391b8e492e7994b958bcbf7ab2c4fe807749e8c5401d84b8dff226e0d56369', 'BLAKE2b/func+raw/3'); +is( blake2b_hex(32,'12345678901234561234567890123456',123), '17391b8e492e7994b958bcbf7ab2c4fe807749e8c5401d84b8dff226e0d56369', 'BLAKE2b/func+hex/3'); +is( blake2b_b64(32,'12345678901234561234567890123456',123), 'FzkbjkkueZS5WLy/erLE/oB3SejFQB2EuN/yJuDVY2k=', 'BLAKE2b/func+b64/3'); +is( blake2b_b64u(32,'12345678901234561234567890123456',123), 'FzkbjkkueZS5WLy_erLE_oB3SejFQB2EuN_yJuDVY2k', 'BLAKE2b/func+b64u/3'); +is( unpack('H*', Crypt::Mac::BLAKE2b->new(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add(123)->mac), '3a246b8de4f0957420dea4fbeb84f3e8f60bc79f04c08f98610008a1e814e963', 'BLAKE2b/oo+raw/4'); +is( Crypt::Mac::BLAKE2b->new(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add(123)->hexmac, '3a246b8de4f0957420dea4fbeb84f3e8f60bc79f04c08f98610008a1e814e963', 'BLAKE2b/oo+hex/4'); +is( unpack('H*', blake2b(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',123)), '3a246b8de4f0957420dea4fbeb84f3e8f60bc79f04c08f98610008a1e814e963', 'BLAKE2b/func+raw/4'); +is( blake2b_hex(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',123), '3a246b8de4f0957420dea4fbeb84f3e8f60bc79f04c08f98610008a1e814e963', 'BLAKE2b/func+hex/4'); +is( blake2b_b64(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',123), 'OiRrjeTwlXQg3qT764Tz6PYLx58EwI+YYQAIoegU6WM=', 'BLAKE2b/func+b64/4'); +is( blake2b_b64u(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',123), 'OiRrjeTwlXQg3qT764Tz6PYLx58EwI-YYQAIoegU6WM', 'BLAKE2b/func+b64u/4'); +is( unpack('H*', Crypt::Mac::BLAKE2b->new(32,'12345678901234561234567890123456')->add("test\0test\0test\n")->mac), 'd24786aeea8e412a8a8ad4609c5b2244f01af0d40da2f4ae27f21171cf9bf77d', 'BLAKE2b/oo+raw/5'); +is( Crypt::Mac::BLAKE2b->new(32,'12345678901234561234567890123456')->add("test\0test\0test\n")->hexmac, 'd24786aeea8e412a8a8ad4609c5b2244f01af0d40da2f4ae27f21171cf9bf77d', 'BLAKE2b/oo+hex/5'); +is( unpack('H*', blake2b(32,'12345678901234561234567890123456',"test\0test\0test\n")), 'd24786aeea8e412a8a8ad4609c5b2244f01af0d40da2f4ae27f21171cf9bf77d', 'BLAKE2b/func+raw/5'); +is( blake2b_hex(32,'12345678901234561234567890123456',"test\0test\0test\n"), 'd24786aeea8e412a8a8ad4609c5b2244f01af0d40da2f4ae27f21171cf9bf77d', 'BLAKE2b/func+hex/5'); +is( blake2b_b64(32,'12345678901234561234567890123456',"test\0test\0test\n"), '0keGruqOQSqKitRgnFsiRPAa8NQNovSuJ/IRcc+b930=', 'BLAKE2b/func+b64/5'); +is( blake2b_b64u(32,'12345678901234561234567890123456',"test\0test\0test\n"), '0keGruqOQSqKitRgnFsiRPAa8NQNovSuJ_IRcc-b930', 'BLAKE2b/func+b64u/5'); +is( unpack('H*', Crypt::Mac::BLAKE2b->new(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add("test\0test\0test\n")->mac), 'dc29010f123a4cd59c91da5fc494375962502ca2179021ebca2f6dd41befa8d2', 'BLAKE2b/oo+raw/6'); +is( Crypt::Mac::BLAKE2b->new(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add("test\0test\0test\n")->hexmac, 'dc29010f123a4cd59c91da5fc494375962502ca2179021ebca2f6dd41befa8d2', 'BLAKE2b/oo+hex/6'); +is( unpack('H*', blake2b(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n")), 'dc29010f123a4cd59c91da5fc494375962502ca2179021ebca2f6dd41befa8d2', 'BLAKE2b/func+raw/6'); +is( blake2b_hex(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n"), 'dc29010f123a4cd59c91da5fc494375962502ca2179021ebca2f6dd41befa8d2', 'BLAKE2b/func+hex/6'); +is( blake2b_b64(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n"), '3CkBDxI6TNWckdpfxJQ3WWJQLKIXkCHryi9t1BvvqNI=', 'BLAKE2b/func+b64/6'); +is( blake2b_b64u(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n"), '3CkBDxI6TNWckdpfxJQ3WWJQLKIXkCHryi9t1BvvqNI', 'BLAKE2b/func+b64u/6'); diff --git a/t/mac_blake2s.t b/t/mac_blake2s.t new file mode 100644 index 0000000..5698556 --- /dev/null +++ b/t/mac_blake2s.t @@ -0,0 +1,45 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 36; + +use Crypt::Mac::BLAKE2s qw( blake2s blake2s_hex blake2s_b64 blake2s_b64u ); + +is( unpack('H*', Crypt::Mac::BLAKE2s->new(32,'12345678901234561234567890123456')->add("")->mac), '6a0915e97a27e1119f10c6991e8c6218fbaaab516a099399fda92803ea24aed8', 'BLAKE2s/oo+raw/1'); +is( Crypt::Mac::BLAKE2s->new(32,'12345678901234561234567890123456')->add("")->hexmac, '6a0915e97a27e1119f10c6991e8c6218fbaaab516a099399fda92803ea24aed8', 'BLAKE2s/oo+hex/1'); +is( unpack('H*', blake2s(32,'12345678901234561234567890123456',"")), '6a0915e97a27e1119f10c6991e8c6218fbaaab516a099399fda92803ea24aed8', 'BLAKE2s/func+raw/1'); +is( blake2s_hex(32,'12345678901234561234567890123456',""), '6a0915e97a27e1119f10c6991e8c6218fbaaab516a099399fda92803ea24aed8', 'BLAKE2s/func+hex/1'); +is( blake2s_b64(32,'12345678901234561234567890123456',""), 'agkV6Xon4RGfEMaZHoxiGPuqq1FqCZOZ/akoA+okrtg=', 'BLAKE2s/func+b64/1'); +is( blake2s_b64u(32,'12345678901234561234567890123456',""), 'agkV6Xon4RGfEMaZHoxiGPuqq1FqCZOZ_akoA-okrtg', 'BLAKE2s/func+b64u/1'); +is( unpack('H*', Crypt::Mac::BLAKE2s->new(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add("")->mac), '18e3ce19987ba50b30dd144c16f22655eba31409d66210bc38bbc14b5dab0519', 'BLAKE2s/oo+raw/2'); +is( Crypt::Mac::BLAKE2s->new(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add("")->hexmac, '18e3ce19987ba50b30dd144c16f22655eba31409d66210bc38bbc14b5dab0519', 'BLAKE2s/oo+hex/2'); +is( unpack('H*', blake2s(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"")), '18e3ce19987ba50b30dd144c16f22655eba31409d66210bc38bbc14b5dab0519', 'BLAKE2s/func+raw/2'); +is( blake2s_hex(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',""), '18e3ce19987ba50b30dd144c16f22655eba31409d66210bc38bbc14b5dab0519', 'BLAKE2s/func+hex/2'); +is( blake2s_b64(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',""), 'GOPOGZh7pQsw3RRMFvImVeujFAnWYhC8OLvBS12rBRk=', 'BLAKE2s/func+b64/2'); +is( blake2s_b64u(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',""), 'GOPOGZh7pQsw3RRMFvImVeujFAnWYhC8OLvBS12rBRk', 'BLAKE2s/func+b64u/2'); +is( unpack('H*', Crypt::Mac::BLAKE2s->new(32,'12345678901234561234567890123456')->add(123)->mac), '5612150160e1943e36f569d635a452eca1d745f959ca9c8dae004e8c69c66ff4', 'BLAKE2s/oo+raw/3'); +is( Crypt::Mac::BLAKE2s->new(32,'12345678901234561234567890123456')->add(123)->hexmac, '5612150160e1943e36f569d635a452eca1d745f959ca9c8dae004e8c69c66ff4', 'BLAKE2s/oo+hex/3'); +is( unpack('H*', blake2s(32,'12345678901234561234567890123456',123)), '5612150160e1943e36f569d635a452eca1d745f959ca9c8dae004e8c69c66ff4', 'BLAKE2s/func+raw/3'); +is( blake2s_hex(32,'12345678901234561234567890123456',123), '5612150160e1943e36f569d635a452eca1d745f959ca9c8dae004e8c69c66ff4', 'BLAKE2s/func+hex/3'); +is( blake2s_b64(32,'12345678901234561234567890123456',123), 'VhIVAWDhlD429WnWNaRS7KHXRflZypyNrgBOjGnGb/Q=', 'BLAKE2s/func+b64/3'); +is( blake2s_b64u(32,'12345678901234561234567890123456',123), 'VhIVAWDhlD429WnWNaRS7KHXRflZypyNrgBOjGnGb_Q', 'BLAKE2s/func+b64u/3'); +is( unpack('H*', Crypt::Mac::BLAKE2s->new(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add(123)->mac), 'a76d7d9b3388d0e4f878634d7912ee9646f9f90089c44ee7fa70c6dc55321881', 'BLAKE2s/oo+raw/4'); +is( Crypt::Mac::BLAKE2s->new(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add(123)->hexmac, 'a76d7d9b3388d0e4f878634d7912ee9646f9f90089c44ee7fa70c6dc55321881', 'BLAKE2s/oo+hex/4'); +is( unpack('H*', blake2s(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',123)), 'a76d7d9b3388d0e4f878634d7912ee9646f9f90089c44ee7fa70c6dc55321881', 'BLAKE2s/func+raw/4'); +is( blake2s_hex(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',123), 'a76d7d9b3388d0e4f878634d7912ee9646f9f90089c44ee7fa70c6dc55321881', 'BLAKE2s/func+hex/4'); +is( blake2s_b64(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',123), 'p219mzOI0OT4eGNNeRLulkb5+QCJxE7n+nDG3FUyGIE=', 'BLAKE2s/func+b64/4'); +is( blake2s_b64u(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',123), 'p219mzOI0OT4eGNNeRLulkb5-QCJxE7n-nDG3FUyGIE', 'BLAKE2s/func+b64u/4'); +is( unpack('H*', Crypt::Mac::BLAKE2s->new(32,'12345678901234561234567890123456')->add("test\0test\0test\n")->mac), 'ad7aab35edfaab1bdd4cf1f4fea1a7a5002b7f19892b8431961aea301c57ed8b', 'BLAKE2s/oo+raw/5'); +is( Crypt::Mac::BLAKE2s->new(32,'12345678901234561234567890123456')->add("test\0test\0test\n")->hexmac, 'ad7aab35edfaab1bdd4cf1f4fea1a7a5002b7f19892b8431961aea301c57ed8b', 'BLAKE2s/oo+hex/5'); +is( unpack('H*', blake2s(32,'12345678901234561234567890123456',"test\0test\0test\n")), 'ad7aab35edfaab1bdd4cf1f4fea1a7a5002b7f19892b8431961aea301c57ed8b', 'BLAKE2s/func+raw/5'); +is( blake2s_hex(32,'12345678901234561234567890123456',"test\0test\0test\n"), 'ad7aab35edfaab1bdd4cf1f4fea1a7a5002b7f19892b8431961aea301c57ed8b', 'BLAKE2s/func+hex/5'); +is( blake2s_b64(32,'12345678901234561234567890123456',"test\0test\0test\n"), 'rXqrNe36qxvdTPH0/qGnpQArfxmJK4QxlhrqMBxX7Ys=', 'BLAKE2s/func+b64/5'); +is( blake2s_b64u(32,'12345678901234561234567890123456',"test\0test\0test\n"), 'rXqrNe36qxvdTPH0_qGnpQArfxmJK4QxlhrqMBxX7Ys', 'BLAKE2s/func+b64u/5'); +is( unpack('H*', Crypt::Mac::BLAKE2s->new(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add("test\0test\0test\n")->mac), 'a31f0e2ba5e73a3aab7e14503690515662758279075d7b68512709824923e65c', 'BLAKE2s/oo+raw/6'); +is( Crypt::Mac::BLAKE2s->new(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add("test\0test\0test\n")->hexmac, 'a31f0e2ba5e73a3aab7e14503690515662758279075d7b68512709824923e65c', 'BLAKE2s/oo+hex/6'); +is( unpack('H*', blake2s(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n")), 'a31f0e2ba5e73a3aab7e14503690515662758279075d7b68512709824923e65c', 'BLAKE2s/func+raw/6'); +is( blake2s_hex(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n"), 'a31f0e2ba5e73a3aab7e14503690515662758279075d7b68512709824923e65c', 'BLAKE2s/func+hex/6'); +is( blake2s_b64(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n"), 'ox8OK6XnOjqrfhRQNpBRVmJ1gnkHXXtoUScJgkkj5lw=', 'BLAKE2s/func+b64/6'); +is( blake2s_b64u(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n"), 'ox8OK6XnOjqrfhRQNpBRVmJ1gnkHXXtoUScJgkkj5lw', 'BLAKE2s/func+b64u/6'); diff --git a/t/mac_f9.t b/t/mac_f9.t new file mode 100644 index 0000000..374468c --- /dev/null +++ b/t/mac_f9.t @@ -0,0 +1,81 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 72; + +use Crypt::Mac::F9 qw( f9 f9_hex f9_b64 f9_b64u ); + +is( unpack('H*', Crypt::Mac::F9->new('AES','1234567890123456')->add("")->mac), 'd7d52d77795c5057977939f22fcce305', 'F9/oo+raw/1'); +is( Crypt::Mac::F9->new('AES','1234567890123456')->add("")->hexmac, 'd7d52d77795c5057977939f22fcce305', 'F9/oo+hex/1'); +is( unpack('H*', f9('AES','1234567890123456',"")), 'd7d52d77795c5057977939f22fcce305', 'F9/func+raw/1'); +is( f9_hex('AES','1234567890123456',""), 'd7d52d77795c5057977939f22fcce305', 'F9/func+hex/1'); +is( f9_b64('AES','1234567890123456',""), '19Utd3lcUFeXeTnyL8zjBQ==', 'F9/func+b64/1'); +is( f9_b64u('AES','1234567890123456',""), '19Utd3lcUFeXeTnyL8zjBQ', 'F9/func+b64u/1'); +is( unpack('H*', Crypt::Mac::F9->new('AES','12345678901234561234567890123456')->add("")->mac), 'd8186a166fafc2aa245f15155bcb889f', 'F9/oo+raw/2'); +is( Crypt::Mac::F9->new('AES','12345678901234561234567890123456')->add("")->hexmac, 'd8186a166fafc2aa245f15155bcb889f', 'F9/oo+hex/2'); +is( unpack('H*', f9('AES','12345678901234561234567890123456',"")), 'd8186a166fafc2aa245f15155bcb889f', 'F9/func+raw/2'); +is( f9_hex('AES','12345678901234561234567890123456',""), 'd8186a166fafc2aa245f15155bcb889f', 'F9/func+hex/2'); +is( f9_b64('AES','12345678901234561234567890123456',""), '2BhqFm+vwqokXxUVW8uInw==', 'F9/func+b64/2'); +is( f9_b64u('AES','12345678901234561234567890123456',""), '2BhqFm-vwqokXxUVW8uInw', 'F9/func+b64u/2'); +is( unpack('H*', Crypt::Mac::F9->new('Blowfish','1234567890123456')->add("")->mac), '063daede33be0e37', 'F9/oo+raw/3'); +is( Crypt::Mac::F9->new('Blowfish','1234567890123456')->add("")->hexmac, '063daede33be0e37', 'F9/oo+hex/3'); +is( unpack('H*', f9('Blowfish','1234567890123456',"")), '063daede33be0e37', 'F9/func+raw/3'); +is( f9_hex('Blowfish','1234567890123456',""), '063daede33be0e37', 'F9/func+hex/3'); +is( f9_b64('Blowfish','1234567890123456',""), 'Bj2u3jO+Djc=', 'F9/func+b64/3'); +is( f9_b64u('Blowfish','1234567890123456',""), 'Bj2u3jO-Djc', 'F9/func+b64u/3'); +is( unpack('H*', Crypt::Mac::F9->new('Blowfish','12345678901234561234567890123456')->add("")->mac), '063daede33be0e37', 'F9/oo+raw/4'); +is( Crypt::Mac::F9->new('Blowfish','12345678901234561234567890123456')->add("")->hexmac, '063daede33be0e37', 'F9/oo+hex/4'); +is( unpack('H*', f9('Blowfish','12345678901234561234567890123456',"")), '063daede33be0e37', 'F9/func+raw/4'); +is( f9_hex('Blowfish','12345678901234561234567890123456',""), '063daede33be0e37', 'F9/func+hex/4'); +is( f9_b64('Blowfish','12345678901234561234567890123456',""), 'Bj2u3jO+Djc=', 'F9/func+b64/4'); +is( f9_b64u('Blowfish','12345678901234561234567890123456',""), 'Bj2u3jO-Djc', 'F9/func+b64u/4'); +is( unpack('H*', Crypt::Mac::F9->new('AES','1234567890123456')->add(123)->mac), 'b3ec60e084566cd17423b3636d395f30', 'F9/oo+raw/5'); +is( Crypt::Mac::F9->new('AES','1234567890123456')->add(123)->hexmac, 'b3ec60e084566cd17423b3636d395f30', 'F9/oo+hex/5'); +is( unpack('H*', f9('AES','1234567890123456',123)), 'b3ec60e084566cd17423b3636d395f30', 'F9/func+raw/5'); +is( f9_hex('AES','1234567890123456',123), 'b3ec60e084566cd17423b3636d395f30', 'F9/func+hex/5'); +is( f9_b64('AES','1234567890123456',123), 's+xg4IRWbNF0I7NjbTlfMA==', 'F9/func+b64/5'); +is( f9_b64u('AES','1234567890123456',123), 's-xg4IRWbNF0I7NjbTlfMA', 'F9/func+b64u/5'); +is( unpack('H*', Crypt::Mac::F9->new('AES','12345678901234561234567890123456')->add(123)->mac), 'ea9a400b9a8dceaec669c1dea926d567', 'F9/oo+raw/6'); +is( Crypt::Mac::F9->new('AES','12345678901234561234567890123456')->add(123)->hexmac, 'ea9a400b9a8dceaec669c1dea926d567', 'F9/oo+hex/6'); +is( unpack('H*', f9('AES','12345678901234561234567890123456',123)), 'ea9a400b9a8dceaec669c1dea926d567', 'F9/func+raw/6'); +is( f9_hex('AES','12345678901234561234567890123456',123), 'ea9a400b9a8dceaec669c1dea926d567', 'F9/func+hex/6'); +is( f9_b64('AES','12345678901234561234567890123456',123), '6ppAC5qNzq7GacHeqSbVZw==', 'F9/func+b64/6'); +is( f9_b64u('AES','12345678901234561234567890123456',123), '6ppAC5qNzq7GacHeqSbVZw', 'F9/func+b64u/6'); +is( unpack('H*', Crypt::Mac::F9->new('Blowfish','1234567890123456')->add(123)->mac), '1fdb454cb94a332b', 'F9/oo+raw/7'); +is( Crypt::Mac::F9->new('Blowfish','1234567890123456')->add(123)->hexmac, '1fdb454cb94a332b', 'F9/oo+hex/7'); +is( unpack('H*', f9('Blowfish','1234567890123456',123)), '1fdb454cb94a332b', 'F9/func+raw/7'); +is( f9_hex('Blowfish','1234567890123456',123), '1fdb454cb94a332b', 'F9/func+hex/7'); +is( f9_b64('Blowfish','1234567890123456',123), 'H9tFTLlKMys=', 'F9/func+b64/7'); +is( f9_b64u('Blowfish','1234567890123456',123), 'H9tFTLlKMys', 'F9/func+b64u/7'); +is( unpack('H*', Crypt::Mac::F9->new('Blowfish','12345678901234561234567890123456')->add(123)->mac), '1fdb454cb94a332b', 'F9/oo+raw/8'); +is( Crypt::Mac::F9->new('Blowfish','12345678901234561234567890123456')->add(123)->hexmac, '1fdb454cb94a332b', 'F9/oo+hex/8'); +is( unpack('H*', f9('Blowfish','12345678901234561234567890123456',123)), '1fdb454cb94a332b', 'F9/func+raw/8'); +is( f9_hex('Blowfish','12345678901234561234567890123456',123), '1fdb454cb94a332b', 'F9/func+hex/8'); +is( f9_b64('Blowfish','12345678901234561234567890123456',123), 'H9tFTLlKMys=', 'F9/func+b64/8'); +is( f9_b64u('Blowfish','12345678901234561234567890123456',123), 'H9tFTLlKMys', 'F9/func+b64u/8'); +is( unpack('H*', Crypt::Mac::F9->new('AES','1234567890123456')->add("test\0test\0test\n")->mac), '9fa4876ee09966ff8c1ae43b05e0b155', 'F9/oo+raw/9'); +is( Crypt::Mac::F9->new('AES','1234567890123456')->add("test\0test\0test\n")->hexmac, '9fa4876ee09966ff8c1ae43b05e0b155', 'F9/oo+hex/9'); +is( unpack('H*', f9('AES','1234567890123456',"test\0test\0test\n")), '9fa4876ee09966ff8c1ae43b05e0b155', 'F9/func+raw/9'); +is( f9_hex('AES','1234567890123456',"test\0test\0test\n"), '9fa4876ee09966ff8c1ae43b05e0b155', 'F9/func+hex/9'); +is( f9_b64('AES','1234567890123456',"test\0test\0test\n"), 'n6SHbuCZZv+MGuQ7BeCxVQ==', 'F9/func+b64/9'); +is( f9_b64u('AES','1234567890123456',"test\0test\0test\n"), 'n6SHbuCZZv-MGuQ7BeCxVQ', 'F9/func+b64u/9'); +is( unpack('H*', Crypt::Mac::F9->new('AES','12345678901234561234567890123456')->add("test\0test\0test\n")->mac), '6934865f133c0092e4941b45cca38c5f', 'F9/oo+raw/10'); +is( Crypt::Mac::F9->new('AES','12345678901234561234567890123456')->add("test\0test\0test\n")->hexmac, '6934865f133c0092e4941b45cca38c5f', 'F9/oo+hex/10'); +is( unpack('H*', f9('AES','12345678901234561234567890123456',"test\0test\0test\n")), '6934865f133c0092e4941b45cca38c5f', 'F9/func+raw/10'); +is( f9_hex('AES','12345678901234561234567890123456',"test\0test\0test\n"), '6934865f133c0092e4941b45cca38c5f', 'F9/func+hex/10'); +is( f9_b64('AES','12345678901234561234567890123456',"test\0test\0test\n"), 'aTSGXxM8AJLklBtFzKOMXw==', 'F9/func+b64/10'); +is( f9_b64u('AES','12345678901234561234567890123456',"test\0test\0test\n"), 'aTSGXxM8AJLklBtFzKOMXw', 'F9/func+b64u/10'); +is( unpack('H*', Crypt::Mac::F9->new('Blowfish','1234567890123456')->add("test\0test\0test\n")->mac), 'fa83d84023c43a81', 'F9/oo+raw/11'); +is( Crypt::Mac::F9->new('Blowfish','1234567890123456')->add("test\0test\0test\n")->hexmac, 'fa83d84023c43a81', 'F9/oo+hex/11'); +is( unpack('H*', f9('Blowfish','1234567890123456',"test\0test\0test\n")), 'fa83d84023c43a81', 'F9/func+raw/11'); +is( f9_hex('Blowfish','1234567890123456',"test\0test\0test\n"), 'fa83d84023c43a81', 'F9/func+hex/11'); +is( f9_b64('Blowfish','1234567890123456',"test\0test\0test\n"), '+oPYQCPEOoE=', 'F9/func+b64/11'); +is( f9_b64u('Blowfish','1234567890123456',"test\0test\0test\n"), '-oPYQCPEOoE', 'F9/func+b64u/11'); +is( unpack('H*', Crypt::Mac::F9->new('Blowfish','12345678901234561234567890123456')->add("test\0test\0test\n")->mac), 'fa83d84023c43a81', 'F9/oo+raw/12'); +is( Crypt::Mac::F9->new('Blowfish','12345678901234561234567890123456')->add("test\0test\0test\n")->hexmac, 'fa83d84023c43a81', 'F9/oo+hex/12'); +is( unpack('H*', f9('Blowfish','12345678901234561234567890123456',"test\0test\0test\n")), 'fa83d84023c43a81', 'F9/func+raw/12'); +is( f9_hex('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), 'fa83d84023c43a81', 'F9/func+hex/12'); +is( f9_b64('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), '+oPYQCPEOoE=', 'F9/func+b64/12'); +is( f9_b64u('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), '-oPYQCPEOoE', 'F9/func+b64u/12'); diff --git a/t/mac_hmac.t b/t/mac_hmac.t new file mode 100644 index 0000000..f7b4def --- /dev/null +++ b/t/mac_hmac.t @@ -0,0 +1,81 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 72; + +use Crypt::Mac::HMAC qw( hmac hmac_hex hmac_b64 hmac_b64u ); + +is( unpack('H*', Crypt::Mac::HMAC->new('SHA1','secretkey')->add("")->mac), '3353ae0208558692a0cce27396e07165ea76f969', 'HMAC/oo+raw/1'); +is( Crypt::Mac::HMAC->new('SHA1','secretkey')->add("")->hexmac, '3353ae0208558692a0cce27396e07165ea76f969', 'HMAC/oo+hex/1'); +is( unpack('H*', hmac('SHA1','secretkey',"")), '3353ae0208558692a0cce27396e07165ea76f969', 'HMAC/func+raw/1'); +is( hmac_hex('SHA1','secretkey',""), '3353ae0208558692a0cce27396e07165ea76f969', 'HMAC/func+hex/1'); +is( hmac_b64('SHA1','secretkey',""), 'M1OuAghVhpKgzOJzluBxZep2+Wk=', 'HMAC/func+b64/1'); +is( hmac_b64u('SHA1','secretkey',""), 'M1OuAghVhpKgzOJzluBxZep2-Wk', 'HMAC/func+b64u/1'); +is( unpack('H*', Crypt::Mac::HMAC->new('SHA512','secretkey')->add("")->mac), '683f73ef2765ef315191ac32b1b4438bf5c2c6d0de8999574eeb522f902f02e1ef7f413cd615f07738a9d8be8250e0abfb78368dd487c03639f56ece28ca8c6c', 'HMAC/oo+raw/2'); +is( Crypt::Mac::HMAC->new('SHA512','secretkey')->add("")->hexmac, '683f73ef2765ef315191ac32b1b4438bf5c2c6d0de8999574eeb522f902f02e1ef7f413cd615f07738a9d8be8250e0abfb78368dd487c03639f56ece28ca8c6c', 'HMAC/oo+hex/2'); +is( unpack('H*', hmac('SHA512','secretkey',"")), '683f73ef2765ef315191ac32b1b4438bf5c2c6d0de8999574eeb522f902f02e1ef7f413cd615f07738a9d8be8250e0abfb78368dd487c03639f56ece28ca8c6c', 'HMAC/func+raw/2'); +is( hmac_hex('SHA512','secretkey',""), '683f73ef2765ef315191ac32b1b4438bf5c2c6d0de8999574eeb522f902f02e1ef7f413cd615f07738a9d8be8250e0abfb78368dd487c03639f56ece28ca8c6c', 'HMAC/func+hex/2'); +is( hmac_b64('SHA512','secretkey',""), 'aD9z7ydl7zFRkawysbRDi/XCxtDeiZlXTutSL5AvAuHvf0E81hXwdzip2L6CUOCr+3g2jdSHwDY59W7OKMqMbA==', 'HMAC/func+b64/2'); +is( hmac_b64u('SHA512','secretkey',""), 'aD9z7ydl7zFRkawysbRDi_XCxtDeiZlXTutSL5AvAuHvf0E81hXwdzip2L6CUOCr-3g2jdSHwDY59W7OKMqMbA', 'HMAC/func+b64u/2'); +is( unpack('H*', Crypt::Mac::HMAC->new('Tiger192','secretkey')->add("")->mac), 'f8a326890e07530aaf7eb1b60c4e10bfa4c875550ba8683e', 'HMAC/oo+raw/3'); +is( Crypt::Mac::HMAC->new('Tiger192','secretkey')->add("")->hexmac, 'f8a326890e07530aaf7eb1b60c4e10bfa4c875550ba8683e', 'HMAC/oo+hex/3'); +is( unpack('H*', hmac('Tiger192','secretkey',"")), 'f8a326890e07530aaf7eb1b60c4e10bfa4c875550ba8683e', 'HMAC/func+raw/3'); +is( hmac_hex('Tiger192','secretkey',""), 'f8a326890e07530aaf7eb1b60c4e10bfa4c875550ba8683e', 'HMAC/func+hex/3'); +is( hmac_b64('Tiger192','secretkey',""), '+KMmiQ4HUwqvfrG2DE4Qv6TIdVULqGg+', 'HMAC/func+b64/3'); +is( hmac_b64u('Tiger192','secretkey',""), '-KMmiQ4HUwqvfrG2DE4Qv6TIdVULqGg-', 'HMAC/func+b64u/3'); +is( unpack('H*', Crypt::Mac::HMAC->new('Whirlpool','secretkey')->add("")->mac), '742456ee0548c7fe7e81fb86a05b291d0fa37bc95f1ce562a8a4f4e7bd37a5862a16647963ec3b934355cff410f0d0d8b98fa531f56547a85c1eb1ab25b22a5e', 'HMAC/oo+raw/4'); +is( Crypt::Mac::HMAC->new('Whirlpool','secretkey')->add("")->hexmac, '742456ee0548c7fe7e81fb86a05b291d0fa37bc95f1ce562a8a4f4e7bd37a5862a16647963ec3b934355cff410f0d0d8b98fa531f56547a85c1eb1ab25b22a5e', 'HMAC/oo+hex/4'); +is( unpack('H*', hmac('Whirlpool','secretkey',"")), '742456ee0548c7fe7e81fb86a05b291d0fa37bc95f1ce562a8a4f4e7bd37a5862a16647963ec3b934355cff410f0d0d8b98fa531f56547a85c1eb1ab25b22a5e', 'HMAC/func+raw/4'); +is( hmac_hex('Whirlpool','secretkey',""), '742456ee0548c7fe7e81fb86a05b291d0fa37bc95f1ce562a8a4f4e7bd37a5862a16647963ec3b934355cff410f0d0d8b98fa531f56547a85c1eb1ab25b22a5e', 'HMAC/func+hex/4'); +is( hmac_b64('Whirlpool','secretkey',""), 'dCRW7gVIx/5+gfuGoFspHQ+je8lfHOViqKT05703pYYqFmR5Y+w7k0NVz/QQ8NDYuY+lMfVlR6hcHrGrJbIqXg==', 'HMAC/func+b64/4'); +is( hmac_b64u('Whirlpool','secretkey',""), 'dCRW7gVIx_5-gfuGoFspHQ-je8lfHOViqKT05703pYYqFmR5Y-w7k0NVz_QQ8NDYuY-lMfVlR6hcHrGrJbIqXg', 'HMAC/func+b64u/4'); +is( unpack('H*', Crypt::Mac::HMAC->new('SHA1','secretkey')->add(123)->mac), 'd1e8eaf9de1843fda2fa8e63bb6cc8a61a706fd6', 'HMAC/oo+raw/5'); +is( Crypt::Mac::HMAC->new('SHA1','secretkey')->add(123)->hexmac, 'd1e8eaf9de1843fda2fa8e63bb6cc8a61a706fd6', 'HMAC/oo+hex/5'); +is( unpack('H*', hmac('SHA1','secretkey',123)), 'd1e8eaf9de1843fda2fa8e63bb6cc8a61a706fd6', 'HMAC/func+raw/5'); +is( hmac_hex('SHA1','secretkey',123), 'd1e8eaf9de1843fda2fa8e63bb6cc8a61a706fd6', 'HMAC/func+hex/5'); +is( hmac_b64('SHA1','secretkey',123), '0ejq+d4YQ/2i+o5ju2zIphpwb9Y=', 'HMAC/func+b64/5'); +is( hmac_b64u('SHA1','secretkey',123), '0ejq-d4YQ_2i-o5ju2zIphpwb9Y', 'HMAC/func+b64u/5'); +is( unpack('H*', Crypt::Mac::HMAC->new('SHA512','secretkey')->add(123)->mac), 'b0dc661fb66a42a2a3af93087da36317b088684b026030215986793f17b1ae748ec9d3234ac63d41976d6c7f7c2d8465a4ffd0fe7baa56460b4664882b8175e4', 'HMAC/oo+raw/6'); +is( Crypt::Mac::HMAC->new('SHA512','secretkey')->add(123)->hexmac, 'b0dc661fb66a42a2a3af93087da36317b088684b026030215986793f17b1ae748ec9d3234ac63d41976d6c7f7c2d8465a4ffd0fe7baa56460b4664882b8175e4', 'HMAC/oo+hex/6'); +is( unpack('H*', hmac('SHA512','secretkey',123)), 'b0dc661fb66a42a2a3af93087da36317b088684b026030215986793f17b1ae748ec9d3234ac63d41976d6c7f7c2d8465a4ffd0fe7baa56460b4664882b8175e4', 'HMAC/func+raw/6'); +is( hmac_hex('SHA512','secretkey',123), 'b0dc661fb66a42a2a3af93087da36317b088684b026030215986793f17b1ae748ec9d3234ac63d41976d6c7f7c2d8465a4ffd0fe7baa56460b4664882b8175e4', 'HMAC/func+hex/6'); +is( hmac_b64('SHA512','secretkey',123), 'sNxmH7ZqQqKjr5MIfaNjF7CIaEsCYDAhWYZ5PxexrnSOydMjSsY9QZdtbH98LYRlpP/Q/nuqVkYLRmSIK4F15A==', 'HMAC/func+b64/6'); +is( hmac_b64u('SHA512','secretkey',123), 'sNxmH7ZqQqKjr5MIfaNjF7CIaEsCYDAhWYZ5PxexrnSOydMjSsY9QZdtbH98LYRlpP_Q_nuqVkYLRmSIK4F15A', 'HMAC/func+b64u/6'); +is( unpack('H*', Crypt::Mac::HMAC->new('Tiger192','secretkey')->add(123)->mac), '2625b3d7df40fbdcb87987e8cb50b4e815fcf91eac104c81', 'HMAC/oo+raw/7'); +is( Crypt::Mac::HMAC->new('Tiger192','secretkey')->add(123)->hexmac, '2625b3d7df40fbdcb87987e8cb50b4e815fcf91eac104c81', 'HMAC/oo+hex/7'); +is( unpack('H*', hmac('Tiger192','secretkey',123)), '2625b3d7df40fbdcb87987e8cb50b4e815fcf91eac104c81', 'HMAC/func+raw/7'); +is( hmac_hex('Tiger192','secretkey',123), '2625b3d7df40fbdcb87987e8cb50b4e815fcf91eac104c81', 'HMAC/func+hex/7'); +is( hmac_b64('Tiger192','secretkey',123), 'JiWz199A+9y4eYfoy1C06BX8+R6sEEyB', 'HMAC/func+b64/7'); +is( hmac_b64u('Tiger192','secretkey',123), 'JiWz199A-9y4eYfoy1C06BX8-R6sEEyB', 'HMAC/func+b64u/7'); +is( unpack('H*', Crypt::Mac::HMAC->new('Whirlpool','secretkey')->add(123)->mac), '26ffebc6d041002a375f5808095ee49aa0517070a750c40f4fd5e0c3adc8cdf8a8723cb8e1e37704ccc566bbb7613a46e23915428d97133fb31ef8cd264c4d60', 'HMAC/oo+raw/8'); +is( Crypt::Mac::HMAC->new('Whirlpool','secretkey')->add(123)->hexmac, '26ffebc6d041002a375f5808095ee49aa0517070a750c40f4fd5e0c3adc8cdf8a8723cb8e1e37704ccc566bbb7613a46e23915428d97133fb31ef8cd264c4d60', 'HMAC/oo+hex/8'); +is( unpack('H*', hmac('Whirlpool','secretkey',123)), '26ffebc6d041002a375f5808095ee49aa0517070a750c40f4fd5e0c3adc8cdf8a8723cb8e1e37704ccc566bbb7613a46e23915428d97133fb31ef8cd264c4d60', 'HMAC/func+raw/8'); +is( hmac_hex('Whirlpool','secretkey',123), '26ffebc6d041002a375f5808095ee49aa0517070a750c40f4fd5e0c3adc8cdf8a8723cb8e1e37704ccc566bbb7613a46e23915428d97133fb31ef8cd264c4d60', 'HMAC/func+hex/8'); +is( hmac_b64('Whirlpool','secretkey',123), 'Jv/rxtBBACo3X1gICV7kmqBRcHCnUMQPT9Xgw63Izfiocjy44eN3BMzFZru3YTpG4jkVQo2XEz+zHvjNJkxNYA==', 'HMAC/func+b64/8'); +is( hmac_b64u('Whirlpool','secretkey',123), 'Jv_rxtBBACo3X1gICV7kmqBRcHCnUMQPT9Xgw63Izfiocjy44eN3BMzFZru3YTpG4jkVQo2XEz-zHvjNJkxNYA', 'HMAC/func+b64u/8'); +is( unpack('H*', Crypt::Mac::HMAC->new('SHA1','secretkey')->add("test\0test\0test\n")->mac), '909a8e4f5688eac58c095db91cd1ad0d7e95bb08', 'HMAC/oo+raw/9'); +is( Crypt::Mac::HMAC->new('SHA1','secretkey')->add("test\0test\0test\n")->hexmac, '909a8e4f5688eac58c095db91cd1ad0d7e95bb08', 'HMAC/oo+hex/9'); +is( unpack('H*', hmac('SHA1','secretkey',"test\0test\0test\n")), '909a8e4f5688eac58c095db91cd1ad0d7e95bb08', 'HMAC/func+raw/9'); +is( hmac_hex('SHA1','secretkey',"test\0test\0test\n"), '909a8e4f5688eac58c095db91cd1ad0d7e95bb08', 'HMAC/func+hex/9'); +is( hmac_b64('SHA1','secretkey',"test\0test\0test\n"), 'kJqOT1aI6sWMCV25HNGtDX6Vuwg=', 'HMAC/func+b64/9'); +is( hmac_b64u('SHA1','secretkey',"test\0test\0test\n"), 'kJqOT1aI6sWMCV25HNGtDX6Vuwg', 'HMAC/func+b64u/9'); +is( unpack('H*', Crypt::Mac::HMAC->new('SHA512','secretkey')->add("test\0test\0test\n")->mac), '97b775cb90e756d586e535ea6f90f9baea45514b9399eed71a1e9da262a753df0f54bce89d97e07b14b524d191c45aec469a66699636bf5f2a5edfc127aed342', 'HMAC/oo+raw/10'); +is( Crypt::Mac::HMAC->new('SHA512','secretkey')->add("test\0test\0test\n")->hexmac, '97b775cb90e756d586e535ea6f90f9baea45514b9399eed71a1e9da262a753df0f54bce89d97e07b14b524d191c45aec469a66699636bf5f2a5edfc127aed342', 'HMAC/oo+hex/10'); +is( unpack('H*', hmac('SHA512','secretkey',"test\0test\0test\n")), '97b775cb90e756d586e535ea6f90f9baea45514b9399eed71a1e9da262a753df0f54bce89d97e07b14b524d191c45aec469a66699636bf5f2a5edfc127aed342', 'HMAC/func+raw/10'); +is( hmac_hex('SHA512','secretkey',"test\0test\0test\n"), '97b775cb90e756d586e535ea6f90f9baea45514b9399eed71a1e9da262a753df0f54bce89d97e07b14b524d191c45aec469a66699636bf5f2a5edfc127aed342', 'HMAC/func+hex/10'); +is( hmac_b64('SHA512','secretkey',"test\0test\0test\n"), 'l7d1y5DnVtWG5TXqb5D5uupFUUuTme7XGh6domKnU98PVLzonZfgexS1JNGRxFrsRppmaZY2v18qXt/BJ67TQg==', 'HMAC/func+b64/10'); +is( hmac_b64u('SHA512','secretkey',"test\0test\0test\n"), 'l7d1y5DnVtWG5TXqb5D5uupFUUuTme7XGh6domKnU98PVLzonZfgexS1JNGRxFrsRppmaZY2v18qXt_BJ67TQg', 'HMAC/func+b64u/10'); +is( unpack('H*', Crypt::Mac::HMAC->new('Tiger192','secretkey')->add("test\0test\0test\n")->mac), 'c22b1eba9138c1dba72d43426a3d3e4db14c90b6232d4781', 'HMAC/oo+raw/11'); +is( Crypt::Mac::HMAC->new('Tiger192','secretkey')->add("test\0test\0test\n")->hexmac, 'c22b1eba9138c1dba72d43426a3d3e4db14c90b6232d4781', 'HMAC/oo+hex/11'); +is( unpack('H*', hmac('Tiger192','secretkey',"test\0test\0test\n")), 'c22b1eba9138c1dba72d43426a3d3e4db14c90b6232d4781', 'HMAC/func+raw/11'); +is( hmac_hex('Tiger192','secretkey',"test\0test\0test\n"), 'c22b1eba9138c1dba72d43426a3d3e4db14c90b6232d4781', 'HMAC/func+hex/11'); +is( hmac_b64('Tiger192','secretkey',"test\0test\0test\n"), 'wiseupE4wdunLUNCaj0+TbFMkLYjLUeB', 'HMAC/func+b64/11'); +is( hmac_b64u('Tiger192','secretkey',"test\0test\0test\n"), 'wiseupE4wdunLUNCaj0-TbFMkLYjLUeB', 'HMAC/func+b64u/11'); +is( unpack('H*', Crypt::Mac::HMAC->new('Whirlpool','secretkey')->add("test\0test\0test\n")->mac), 'dab6a22e05b46ce641e022e6ea2b42646a25b994ed15fed09145e3906d159efba37b899c344f589b3ad5868cd631a8eb304d21dedf47e364c791ccfa665681f7', 'HMAC/oo+raw/12'); +is( Crypt::Mac::HMAC->new('Whirlpool','secretkey')->add("test\0test\0test\n")->hexmac, 'dab6a22e05b46ce641e022e6ea2b42646a25b994ed15fed09145e3906d159efba37b899c344f589b3ad5868cd631a8eb304d21dedf47e364c791ccfa665681f7', 'HMAC/oo+hex/12'); +is( unpack('H*', hmac('Whirlpool','secretkey',"test\0test\0test\n")), 'dab6a22e05b46ce641e022e6ea2b42646a25b994ed15fed09145e3906d159efba37b899c344f589b3ad5868cd631a8eb304d21dedf47e364c791ccfa665681f7', 'HMAC/func+raw/12'); +is( hmac_hex('Whirlpool','secretkey',"test\0test\0test\n"), 'dab6a22e05b46ce641e022e6ea2b42646a25b994ed15fed09145e3906d159efba37b899c344f589b3ad5868cd631a8eb304d21dedf47e364c791ccfa665681f7', 'HMAC/func+hex/12'); +is( hmac_b64('Whirlpool','secretkey',"test\0test\0test\n"), '2raiLgW0bOZB4CLm6itCZGoluZTtFf7QkUXjkG0Vnvuje4mcNE9YmzrVhozWMajrME0h3t9H42THkcz6ZlaB9w==', 'HMAC/func+b64/12'); +is( hmac_b64u('Whirlpool','secretkey',"test\0test\0test\n"), '2raiLgW0bOZB4CLm6itCZGoluZTtFf7QkUXjkG0Vnvuje4mcNE9YmzrVhozWMajrME0h3t9H42THkcz6ZlaB9w', 'HMAC/func+b64u/12'); diff --git a/t/mac_hmac_test_vectors_ltc.t b/t/mac_hmac_test_vectors_ltc.t new file mode 100644 index 0000000..6a351fb --- /dev/null +++ b/t/mac_hmac_test_vectors_ltc.t @@ -0,0 +1,1826 @@ +use strict; +use warnings; + +use Test::More tests => 1739; +use Crypt::Mac::HMAC; +use Crypt::Digest; + +my $trans = { + "chc_hash" => "CHAES", + "md2" => "MD2", + "md4" => "MD4", + "md5" => "MD5", + "rmd128" => "RIPEMD128", + "rmd160" => "RIPEMD160", + "sha1" => "SHA1", + "sha224" => "SHA224", + "sha256" => "SHA256", + "sha384" => "SHA384", + "sha512" => "SHA512", + "tiger" => "Tiger192", + "whirlpool" => "Whirlpool", +}; +my $tv; +my $name; + +while (my $l = ) { + $l =~ s/[\r\n]*$//; + $l =~ s/^[\s]*([^\s\r\n]+).*?/$1/; + $l =~ s/\s+//; + if ($l=~/^HMAC-([^\n\r]+)/) { + $name = $1; + next; + } + my ($k, $v) = split /:/, $l; + next unless defined $k && defined $v; + $tv->{$name}->{$k} = $v if $name && $k =~ /\d+/; +} + +my $seq; +$seq .= pack('C',$_) for(0..255); +my $zeros = '\0' x 255; + +for my $n (sort keys %$tv) { + my $N = $trans->{$n} || die "FATAL: unknown name '$n'"; + my $key = substr($seq, 0, Crypt::Digest->hashsize($N)); + for my $i (0..255) { + my $bytes = substr($seq, 0, $i); + next unless $tv->{$n}->{$i}; + my $result = Crypt::Mac::HMAC->new($N, $key)->add($bytes)->mac; + is(unpack('H*', $result), lc($tv->{$n}->{$i}), "$N/$i"); + $bytes = $result; + $key = substr($result x 100, 0, Crypt::Digest->hashsize($N)); + } +} + +__DATA__ +HMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are HMACed. The initial key is +of the same format (the same length as the HASH output size). The HMAC key in step N+1 is the HMAC output of +step N. + +HMAC-tiger + 0: 2EF793765716EE48A671BDB5F002103C43734304C8717C85 + 1: AE61B56C82BE9FF96DCFBC20DD02B4BEA4FC6B6D5F4EC412 + 2: B54ADBFB404457E6C5AFCCEC27199D1F259EE1994FFFE99F + 3: 08AEEC38E88403BB854935EB6F1464CE95B044F4B4202524 + 4: 4C9DAEDC1929E22128F2A7ED5F3556D8A6D3A8315A7B556A + 5: 764794ED9EE1F94891835CC3A361FE75C600C7951A07F450 + 6: 1A4C447A0FB8826A0881ED2E7BD89499EACA4B6C49F96060 + 7: 1396A21D8B465C6B898511DF94846588EE8E35C0095AD90A + 8: 7552EB03CE26A8F079AC96B42F556FEAEB756014B8FDE622 + 9: 835B7CCA9D9F13BA2A36CBD746E5C92D5B2D123CA2EC848E + 10: 7CF4EA88FF8B9A5A57E5ABB6B35278EE9D8653F624D662FE + 11: D588D953C6F438D077A1E302F84E25EF31AD99B9C5FC9DB4 + 12: 86EC62CF1A08CEA9171AC742E8E615B3F0C7B6FBC95DC3C8 + 13: 6EE7C51E26187F86370A26811C75136E28B0C39A113D80F8 + 14: E1326D54123BC26CF41B30F9F2BA2E732203836AF8A74273 + 15: F211E4C46862E3AC8B8E69976A705582CF6D1B34A6D342B7 + 16: 0C6160FEFE70C81C71B7465F42F070F30808CDAE448D1974 + 17: 492FC6BC091489F926F0F54CBF3E3F6C8CEC6ED14DF2DF8C + 18: FD166027ABD1BD9DBA13E3908D16C403E1691FF173328CA4 + 19: 28D99C64CDFFAC1E6F7B33C8E675E49749CE835A177A1C63 + 20: FD7BD55BC2A684F4875C811143A2997356AA87A300345843 + 21: DB8968E787BF65C00992ED9DDE974EA71BA947395111FFB3 + 22: 4C31B2FA4E6F7F40DECA589F85BB69BFAD1815A73CF9EB23 + 23: B4D8D7FCB314942F171F85EA0953F7816DA9F07D72AF48B5 + 24: 9A6A70BAD76203A7A1F64D1EE34375EC8BCB21810ECE0B68 + 25: D21D7E5EF6F1579C84428AB5D574468933BA037C9B0C34B6 + 26: 3C5292C87B24626241693F0EBE20A96800905691C5945E65 + 27: 350BEEC075258BA7FE0314E6803152B021570F067AE0D4D4 + 28: 6881F892886F9D66E68B937BB3A71FF5CB064611C722996E + 29: 07831F1B2D00108386339F192729687B2F57B9DAB2B1210B + 30: 38DE8DE8398EEC32939A239BC0198B0CFB18D12E4F2A3023 + 31: 5B683578F81867054089AE2E1B20E02B3BD92334CBB01FA9 + 32: E30A80BE07651BA17E2DF0D43A583A9DB268DFF3AB7393ED + 33: 42341B1EC4F61E90571188F5599FBA9ACF884B1E15694921 + 34: 7D98297D65F5FEA85CB967F22AE0707E03F305BF1D2249DD + 35: BC8EE5CE0FA8F9E6694406009EC9358BC420B7E5DE07B6F8 + 36: B8095DE6770CB4CC2127FA672F93F39CA4AF0CCBB9805DDB + 37: 20C0E981DF1B763B6BB47D43F66765AD434127C1FC55F829 + 38: 59795328D40D2CE6CFDED8DD5089F2D5B796C9438E7646CA + 39: 0789CAB229AD54416C82CA5A2E667EC7CE66019FCACF766D + 40: F7C81B1AE705019FF9A9905972AFD72484A70E11FB81B278 + 41: E72F52644BF5EE59BE87DF692EF0070D095115B7664BB53A + 42: B9A5DD984358D0B0F3C2781BA60E9BD3473C1C89C7982F23 + 43: F7BA22269249759F1A87AEA0A125D4DF9B58E93714449008 + 44: 5D2257317F8978576CD7D2CCD346E861A59FE949F74A3D82 + 45: 199D8D5B0B5C5B61E046F50E0E389DA6F19CB3A7A37C8588 + 46: F489CC6CB2D3E9F741D6C9008265CCA97E7E54D62F5EB85F + 47: A5E7CB0787EB7E62A9CFD8486390A6628C9876654B9E85E4 + 48: 22FA78EA17F0D29E16276C70A564D234BC4ECA7302301528 + 49: 4422534FB9EEC601CE7662345D6B6FF932E54BB0483C2F62 + 50: 5D2E2B90B460D393F36BF32B2F491E224EF388FA72A48501 + 51: EA5287BCBB856BF04FC785541079087CE24783E9310F3090 + 52: DEDA3920899FA69F913AE50A4F0D7119C9D3CE8F4E6D5BB2 + 53: B2F55D8EA64C9842BFEA4FADFE616664CD44C57D53998C58 + 54: 3D2C72F26188E1EF5C0F0FC8B541224066C4DF455FEE78FF + 55: 50BB36BD8A8D97E4D6CA78DDCDAD0690FBBC93DC9A66BF18 + 56: 48140E192FF8AB74FC22676AAAA186C1A7E2FA0166E986AC + 57: 40AFD540C40EE7E598D26AE3FE5A47939299B5DD46B0B4FE + 58: CEBBBD763B077342BA16D4B20412C9EDE0F0508ABCE3501B + 59: 0FE4DFE539160F5924C324B8B43DACB4F220195D286C6FA1 + 60: A06D135075F943CEE74AAB1B8DE08B772055551B1E73ED48 + 61: D4E1B5EBBDA5CDA5040DD697BB96DD702C6730CFCC012992 + 62: BD5E77B67B42C507C4912130C8880A9DBD66431DCA0C0038 + 63: D81F583A9B4DD1F48028CA602CC0F131D60561FA34F7B3B4 + 64: A41F0481EE52842CDF676177F8E43BC1F1B00A5682C63E15 + 65: CDB29E274ABEB20EECC8378D5BD806997502E4271AB56708 + 66: B8366ABD45565BB3D26CE46B6F419F74B34851863FF4C336 + 67: 5AD2C193D6D51C9C7E56C5BFF55C1D61E045366B51E7F619 + 68: 9948E3AB7D121B15A6CA8DFDF4EE5377C957F0DE891C3575 + 69: 095676D61096853635128A80570BD1CE803AC7249C0A0F57 + 70: 354F4CCC1E5112770B2AB035AE07200A6CDC0280AD088AFB + 71: A8723395E80BED25DFE8F9ACEDA942A77D225D00440302D2 + 72: 0D2BCE0F8CF396FD8277C8BD9B19D54965308D3ED04D2F27 + 73: 54B1939E9944F499798B3DCE3479AC315F2C42A1EF231984 + 74: 5CFF726EE4B2596240E6CBBC66D7C737A4D12A702B40E81E + 75: 82996D7F3F27B473BDA647BBBA7230DF217288F2D1A38B99 + 76: CB95F63E0E7A2EC4F26E94B81A3C8C757E04EEEAB35A8C2A + 77: 057DEDF45207EA885A0BAC5B64240DD21CB9D99CD8F38FEA + 78: 27DCDD1ABA459506EF98E5C8D567692264C4153F91FDB269 + 79: 911C83660F7EE8CFB5F54890AE98CCA36C4C12B8CC771DF8 + 80: 67CD07209988C517FAEE01E64AC4B5CF261B6035069508FA + 81: D9A40C407E2BA852684770A5EB08D8502DFD264F2DE5A5FC + 82: 9AAC50A2BCFD74BE3DF85237478AAA833484FA3DF912A3AC + 83: 38078488F6183B5A94B655F24212FC9769450D93986C9208 + 84: 2EFFCBFA4CCCAFCA66BF8B368FB1FEFAC280C20416BB90EC + 85: D626FD6D285C49F20E99B88B9F82640D93D9E765CA55B5B0 + 86: B1DD178943B26AA241D34031D3128344C6955F6A942CC5D3 + 87: DA0C850E2067F9FDAE433C1230E0F629700FC8896ADDBDE9 + 88: 58E393E353BD7DF75A591904AA99526E94FA45C98D095E21 + 89: 323D0E04D239BD70192B2ACCB9ACF06E2F8C3B07565893AE + 90: F9C4147C6921640C097534BB08020540B420AD569D03665B + 91: 5171DB964AC815B3A6D058419FD47833DDAED71039966E6D + 92: E7DC7C574AFC2C9A59E46CB8ADBD03330A5321B237DF7899 + 93: 97074CDA9FF8D40B0501E9F632ED7335D6A7926101A34C0C + 94: BDDCD4D007DE39680B80F9AF9803A9F21C836EA971250CD4 + 95: 0DBFF45E3155098D4B4C13815FB461D3C4BE41E9E1A68757 + 96: FC16CB95478E4D23A7AD15CCAE3C24BBB3D0FBDC8A00A144 + 97: 93A7CB506481D6A72EAB14A2BA544F8631542B55903CCAAE + 98: 9CC1FFA19736AB6EB36EB4A2C1624FCB6913B255D2346795 + 99: CE3526A088FFEDEA4345AB221707848823B16DADD19AB487 +100: 1E1D790323586DB8A306EDCCAC8C64A6F29A36F772B8D61D +101: 8C403515F2B9014E9519EC04769ACCF23E522D3E22DE7F41 +102: 6B6A634607634804988301240CA5AB029A9E86E51281D64E +103: C7C3483CC8E6B58520B554259EB08866AA7980B53FFB6B86 +104: 96E429611C9E411321947469E2095CD9B0EF29578030E40F +105: 5C5A7F2B7F1F9BCE730BE2779304A443188FD3B31DD2BF19 +106: 70933F999325353277E0AA1F543B5CBED3F28DAF4FC70A57 +107: 5CD6D136FDDF4AE9CE42F008301FB6647096D5007E79973F +108: 1162BA742AD199AC17FC707285301A82BA9CB12C09BA229D +109: C36615F6D5E29E6CABB7EBC44A6D3F7B024DAFBD338FEFFA +110: C29FEF051D1606CEFCE3417BD571CB9188BBF0FA8AB98679 +111: F925144EDDD27244E19E4B6E433F312C6CDE43EF4F9B84B5 +112: C4230A59E54A34D0709F3F1DB02C18EC8AA270078DE424D5 +113: EB1699CAEC36681CCF8A9144DFB5050566042977D15FD1F9 +114: 9FBF0D9B2DD9A6E87240E538590E9799B76E22604D22AB75 +115: 2657EA06D69A78A5895A9169F849B3DE111B31E5673A8E17 +116: D1F9E1BA4F4E52CDAAFC388FA4C366EF4BD5F440608D86B0 +117: 049196BFFD9F77175FA936066C3119293EAB79D1E0028C8F +118: 9CC1BD2CADDEC1D82FFAFA7031F2E5C9B6765CF1727A0ACB +119: ED00438670D68A70CE2E0729997CC9648947EEA35809B8C7 +120: A520A0089BC16C84CB8E05425B330C6D261108EE3049FACF +121: A55B470483E547D2752EDC3C4FDCF3B4C48A1990AD857941 +122: 46A78E772C533EC8EDA60EB4A127FCEBD35E7D0E7F183241 +123: 5EB9A774124D571FCCC83D1F36C603D9C387390DFB3928B2 +124: E904066FC77F73CA41166297A8FC631FF59634B659F0AED0 +125: B85B66AEF7D9904356F1CAA5583757D1D69EEBB8AB1D1420 +126: 6639F85214BC798D71B757FCD480CB78D325881781A3A073 +127: C5B72BBE80917B55036A9AD6908D59293C49373F0BDD104B +128: C0BD695F6B9B42DAB543C31BA73C9497A6AA6419A007A9F6 + +HMAC-md2 + 0: D39AD9DDE006587A8BE949B11B9288F8 + 1: FCB21B5348C95E8A8DCBEE50A80302CA + 2: 2F26B6ACCD0E03FE9B21A1B0E75FF665 + 3: 17CF85D985D0D85F545897CD42C6EFE5 + 4: 1537A6943B4F5AC1272E4161225D987B + 5: 83E17165D62CA6E4B9ED67DF1E599954 + 6: 7A3195C863DFF86A98968F254E128E61 + 7: BD05057AEBFCB92FA4B07456085EC6C2 + 8: 23AC0D307BFC2E87760F8BDB21851DF8 + 9: 2CD26A2F2994106A375BEB0433575BDE + 10: 1F63BFC44FDBE9A966CD90DF82265EFD + 11: 72735FAADC3819CC24CFCE1D589BA311 + 12: 28B589C3C8078B8FFEF1C8297E33C1E6 + 13: 70A6DC014CAD2752931A47C0879D2371 + 14: 81694317A37FFBA816504974F38B4829 + 15: 72F26208B3051F1B938EA7E03DD8C107 + 16: F945F57FE0696A4C81EC59AE69384FAB + 17: 54D8DFCEE33969486956698495B4BFD0 + 18: 508B82F88A234E753A9E305E15A14D82 + 19: 527D77D2AB25131693B02F653ACBD90E + 20: 4868AC540FCC3A896D5A89F7A0444D36 + 21: 6189807C5FDDDD68D20356ADF3B90DC2 + 22: 0356362F2BC4206F2B930C4282213758 + 23: 2F59956F19B3CAD687C66C4EC3CC916D + 24: E30CEFBDA3FA1A8EDDE3B72614ADDEDF + 25: 33E0E6BFCBC9581BBCDF13F4D3F26724 + 26: B11C6476F9775219A9F18B5E88857790 + 27: 49C7A9D7F56344BD405E53BE927E3A58 + 28: 99A06874B0F0CA45C9F29E05D213195F + 29: D21A60A18F061FC453AD5AC2A519071A + 30: 2F735E82090144C036E3D12DEF2E0030 + 31: F9539EAC81BBCD0069A31E2A3C43769D + 32: EDCAA9C85A614AB6A620B25AF955D66A + +HMAC-md4 + 0: 752E874F35085E497D5032112CC65131 + 1: 6B2CAAEE210F970AB481D6D8EE753114 + 2: 2162A41522C2DB0B8AF1F0C712C19A22 + 3: 7C2106C3CB687F35FE2658BEEFB497A5 + 4: 3715333CA3EB74A15B4B1802A1A78921 + 5: 403D9A691A130AFFFB81A655AAE1D956 + 6: E697C3CB42716CA1973DE0D15486068E + 7: 99676F34E42C61E396F0E76BCB77BEAB + 8: A2B2CE8CF8AC151C5556A36D58894C61 + 9: B8614BFF1DAAEA90BF319F333024976C + 10: B8759E8B97DFCBB2DB94D8CBE2C96B20 + 11: CFFE6119EB0C649831459339C1B0C82A + 12: B2FC0DBA9C4830CA66423728599D3660 + 13: 454749F1DE579F1918FF046FC1CAE7F6 + 14: CC625178FEFD46481B7D02618AF6194E + 15: C26D523EFCC42C4AF7EEC2EA4B45B719 + 16: C352DA2D077FA3F493A5CE0E9A79CB87 + 17: 570DDE9FD220F59867F17484605D2061 + 18: FF5954A163CBA61CD3C8424CC71682C8 + 19: 1240D12E3D6C07F6FE1CD595C847C038 + 20: E87A4D7958C43CA71791B13E16301036 + 21: B2CEDE4A15F8D64C53D243F8C5763C05 + 22: 54A9E9EAE155E7AFA6FC8A7E05D7FA9B + 23: DF0E79F27CE25E56ABCFF5E74D1212CA + 24: D9BE454A95E5D9127990577F7EB7183E + 25: 26F9221A8B854767861BF0281303B89E + 26: 92BD4CC81A673B254A4AB493864BB014 + 27: EBC3851E0AD28BE9876BEFD6B0A88B44 + 28: 1134BC8A40E1D2FB038B67548AC2040B + 29: 954700135C4E7F232337C84130B43360 + 30: 8C3EF2D8F896C8D252851A1543F72493 + 31: 52817E79D2B0B3A37DC08D18D3519F92 + 32: DA661A428B9659DD59545E3B09162F8F + 33: 3FF5BB67B48F87B4B642DACCD2E4001E + 34: C674F95BB622D7B8281FFF34E9EF3E7B + 35: 3A4D25E3BCABAD8CD4918CE650EF00E9 + 36: 2D91248C51837A8B80898E2CE42CBCB4 + 37: C0B3BD2B36493F0EAF9AAFEFDC37064F + 38: 9B4723B091102B480B2B59069317F292 + 39: 0F8EABB489254491FE19AD0E328A483C + 40: 25469BD482E1405E51AA021752394C4C + 41: DF1DF50EF9D95892D08DFEFB79D6552B + 42: 707A546964CB22710482C478E58C2E0F + 43: D1E243DB14E2F946D650C811030ADE9A + 44: 11A1AEA678E98A65420747DD6CF9293F + 45: 66E735F658BD689A9F1BA0B526827CF9 + 46: 98170734E67F576CCC3D01D83965A6C9 + 47: 399D99CB7979E80F6D3B5D5BBA5871CA + 48: C26651C32EABC76289CD0843D3BCDD92 + 49: AE0F50954C90E8897BCF504592D0626C + 50: EA3AB701136862428EC326D2551F8AC8 + 51: 4AE98E5A1E6B1BA8CEAE844E34934039 + 52: 7C9826187053186DDC2760AE6FB56DC7 + 53: FE0F555B851CAD830BAC9FBB40705671 + 54: 221BB509584BCC7E10F3B4FAB2AEB1F3 + 55: DD93EAFE25EE27C6FDC2CCDE7D273267 + 56: 535472E1ECD49FAA75CC6621BE7E6210 + 57: DA4554FF7D5B289A03D195F94154AF47 + 58: F15A3F547B5A3844BFF713CBCEF701A1 + 59: 279DE06FD5644C520BADD3B97D96274D + 60: B933E929073492EC1E2AEB78071C7B83 + 61: D1DA2335654AB4CEBAE5C2E78CF27553 + 62: 06FC50285F4BA5C8B5A478E9C02D6434 + 63: DB66A5D55224DDB50337B7FEF9A808A7 + 64: ECFCD0385FB49553EC89DD94AB084D23 + 65: 4187B0B79E6CB916F747B857AB2F75D3 + 66: E03E14F5E00B2DFC0614308608B929B9 + 67: 5F61FC3005167EB3256DB549DA8BA562 + 68: 21A4D14DF8E934A858569D8BA7F151E8 + 69: 5955DDA4CEF16ABADE2B551841C69B8B + 70: 8E77066A973B60DF64C27DBB93EF204A + 71: 2101EE9DC8221FF17D9D887FC39F41BA + 72: 6574A9DE32B7A673B5BA20FF18EF8C93 + 73: F571B14C9F5C5C1858D48AA944A13050 + 74: 0BA4BE0A5E853D07F79B2D29BCF046B5 + 75: F240C8C38D71131F510369D79FA32208 + 76: 920C294DE37C28803FF3C49A4135CD65 + 77: 38796D25822AD8F2AB4D64E4A65626A0 + 78: 65A203170FDF794397FD1090E318C5DA + 79: 965A767FE4A75BEECE26BAA79D816AD7 + 80: 0F4B30947B790C47924657648FA1D88C + 81: 74B05F7B7D006F7DDAB31DAE251C3BB3 + 82: 61B0366B57A8F46C2F6C16F935DA768F + 83: D4CB13CA922B542980F854C9780A1951 + 84: 039B2F23A1CE410FF4696D9C35C40C08 + 85: 2D734E28F995C2AA2A7AE2412EB99A10 + 86: 1A55FE47703ECDBE446033F492412812 + 87: 6AF4CED86D0181D6E99EE6AE57F295EC + 88: 69C239A875E0352D20BCFBCF8D5CA19F + 89: 62723FBBF0AC6F397438589AF06625A1 + 90: 424EC9353901795251AEF7D7BCFEB8BE + 91: 9BBE4ED6C8BD14F85BA86E553B1B8152 + 92: D7840AA82F788B7D58712E29003D1239 + 93: 4AA55512DCAF770FE4D9428FB318B0B0 + 94: D040BA08BEDFFB20D2C499FEB35EE12A + 95: 0F295EDEFC85546547860B7F7CDFB1AE + 96: 720FCD871B7D8824EE6A7DE9FF1A62BE + 97: 2FE3AD14E24C441C36186673A0D60767 + 98: 943FD502136B66D0313951198680F746 + 99: 4EE6829F3EFFD0A87115512ED28C85BA +100: 6EE1AC28A320246CA5C37F981E22D294 +101: 36BC623D6573C3ADB164F8A6F02315AB +102: 08B3AAED34FB0A0F99C4B22714B9CEAD +103: BDCD10B66096AB992DEC5539773EAF23 +104: 6DA36A53A79FA2C68E5060C0D2D43E13 +105: A3E886199532C025074D4646113F9C23 +106: 00D67A1D2ADCA77A20441CBF593FDEE5 +107: 2E4399F5FB44FF5573B73D01C5B248E2 +108: ED22A18A8824A30B68EE0EF9907B2B91 +109: 36166824634304417BECCC9519899CDD +110: 0757DB01193BEEE90617AA8CAD0360A8 +111: F7691CBEF4ED2E9FE4EB992CB3939970 +112: 09DC2FA975CBE8CE828919957D110EC2 +113: 7DDB74DEC57AE8C318AA5CCFB53872F6 +114: A26B7DD0AA30EAAF1F4F8314AB7DF16A +115: 088855527BEBCDB67A40FEA4FDDCC061 +116: D0F8ECC0C32B7060CB6128279F57FD80 +117: DF5B79D3671CA5E5B44CD395F6FFA551 +118: DA8999EA059C463D5F05D04020EE867D +119: C0EE404DD8447AA70D3725D5634E2B53 +120: D19D1A725F5E9F0DF21871B31900CA73 +121: EC202984BE149C93CC1D440CF6D29E1F +122: 422DB7C21B1348983B75498E270FE6C1 +123: EF136334BC30C92DB9082A9654B391E4 +124: 0B3526430AE734054873B14DD696CB3E +125: 3BEB77C0F85F8C6F21790ADF30EBB812 +126: 4376F8C8EAF5A94871822DBDFBB5F88D +127: F7DEAF52378FF735B2D171B17EF573D8 +128: B4FA8DFD3AD4C88EABC8505D4901B057 + +HMAC-md5 + 0: C91E40247251F39BDFE6A7B72A5857F9 + 1: 00FF2644D0E3699F677F58ECDF57082F + 2: 1B6C2DB6819A4F023FFE21B91E284E93 + 3: 04B0ED3E73FBB9A94444FDFFAA530695 + 4: 1557A22261110DFB31ACE25936BDE45D + 5: 54C5A67A9CB4544CA66BBDA1A2B8479E + 6: F803D9E43C934545AF078FFBB34BC30B + 7: 32F56EA655DF36D845E430D637C85D17 + 8: 14BD2095F4A478C10EEBFF379DE76DD3 + 9: AAF6867B3FA01DD26312B0DFD6371A2A + 10: 0FA2A6FEFEBE7CE3C31A38400F8AB260 + 11: 54C37BE13B7333287D0E74AA9D9227F6 + 12: 385D75A58B0C95E5CDC059DB168BD1D2 + 13: E73003103ED65C08E62D46AE1E1B771A + 14: 278ED4A4EBEA1FFA5EEC874F198C0CC0 + 15: F65CE9EEA7FDB90B9CC603329D3FB9A9 + 16: 8640836944EE0009B2CC6FDC3F5C39E1 + 17: 7819A99F82BABDF060AA51AE109629DB + 18: EF26336668486C76921D1DAB67ED5673 + 19: 13ED7BC140F1496E09AD29C644586957 + 20: 5FDD337CE9C4AC8D910833FCC2BD837E + 21: E9470246ABF7CF4D37FD378738D8F763 + 22: 384A75C33EFFA12EB69187BB80DF843B + 23: 63866A5406B9EA0341032FCFD0244A4B + 24: 8042F8572C8A9B88E135ACB83EF1FD39 + 25: BD1BE6AF2D022F966F612569E191F0E9 + 26: 9F70C839533EE4C7B3CF20C6FB65C94C + 27: 800A5CE92CA4FEE6F1D353F496113873 + 28: C35E93E1E54C84C4389D2DE71E1B9846 + 29: A130EF5F91465F5A56999F450E63F4F9 + 30: 5F16564E05285A099F628245DF9A3C2A + 31: A34F7E3DF06DD84CC67E8A922240D60B + 32: 945E50753B6E6C920183822D5F280F10 + 33: 2DDD269DBCDF5C21A1C3FD540FF4ABA9 + 34: 212FE3E2CEF7DF74FC01CC2CC83119B8 + 35: D98B2930011649F16C08BC8C0178D838 + 36: E39E21026111C1EFB0C491C0FDFA841D + 37: AE46DE06C3B0D2CEC35352C95A1003F0 + 38: 5550EE50BF88C9DE5ADA34567FE044C7 + 39: 6BC486627760373EACFF508F7032BF31 + 40: AE6E0B8DBCFDCCA4B3449B57647D5AE5 + 41: 6BE5A0F140DFC4B75439630E6F9A36EE + 42: E3E4E735BFE79397D4653A6243DF1925 + 43: 68C1D9E8973A3F6B92B588469D68A2A5 + 44: 956132D512118D5F446C8CB912B924D9 + 45: DF5C2AD650B3CA7A89EBF92EE618C845 + 46: 14D375CF7E4294ED99135E4237414F01 + 47: DB966D40B447692E2D13CC0C09C1B495 + 48: 53DADCF1C6B99BD403052A1CE1ED0D14 + 49: DEC4A3C1DB8F6AA4515C512C9299C4DC + 50: 3B3A51DD83AB1DC56A7F0CBE1C71923F + 51: 03C73353B3203EF9CDB95F9DB8750AF1 + 52: ED9E15FD86D66DA2D546D2BFC55041AD + 53: 81B649338F9DB1C6E592427D38221C7C + 54: 92E170E13BF40FF65E3B4C665F222DD5 + 55: 00D5E23F5F829B21D454C4445851AB53 + 56: 39057029AF0B3F4391A7BDC6DDCE4D07 + 57: 2DEACEFA698F9CCAD5198C4E17E69A93 + 58: AD35FD52EA199E26948009DF3546D3A2 + 59: 4C42CF2CFD4D8FD9A06E3F73D02FE818 + 60: 4D7C893E4313FFF72103854463414277 + 61: 3F04E8B32AB56EAF216503E46BD7AEBE + 62: F015DDC3EEF41ECC93E944FA3577DB52 + 63: 31F77A50A2ED96ED8E4A3CE04B9DAA23 + 64: FBF481373481756E0C88978F7E0809A2 + 65: 7D8D793B287C04E7D2896D76EAA5CA15 + 66: DAC74AEBECC2385DD9D0C3147CCA1F78 + 67: F6DDE50D37B460FF5E8B4C03A0854BD5 + 68: 5710D6A54A2124E06A6DADBE9BF76119 + 69: 19DB5D13A53E57184759F33976537AA5 + 70: 848DD8D32130626FBD11B0133C2A29E3 + 71: 4F75BE04BF2F6DD85D048DB82F19C38C + 72: 4AE9436540ED24BCB5EC62977AC90789 + 73: 859D1A9FC2B795AD60F24A37EB9EF890 + 74: CD45865317FD17B652DE9F9EBBBA16B6 + 75: 52313319D395F453BA2C0A0159CF180B + 76: A7B190C0EECACCA4DFC5B45DFB324718 + 77: 23E85CAE85B50F45F7F48EE0F22FDE85 + 78: 6A80DBFF139A5345235EF76586CFCBC7 + 79: 850E638FCE5A2F3B1D1FE9C28F05EF49 + 80: 797CDC3F7E271FC9A3D0566A905D1CFE + 81: 030CE97A9A0B1D5403E253D883FCAF12 + 82: 648FFFF44E416D9DE606BA0DDB751194 + 83: FE15098E0DAC65FA8EE45CAC67121CC9 + 84: 17C90ECD390A8B41046B4C7FA0354E4F + 85: 7D149DFF5F6379B7DBF5C401DB6D2976 + 86: 8D055A4701DD51CB9D1AF8E2AE59BD21 + 87: F3481CB07B034EB4A023D00D4FDA9A86 + 88: FEB22562FFAAA9CCE5CDDA34C29E55C3 + 89: A620AA447216709D8CE5C5F23474ECF8 + 90: F25FCBB2BF7440C5E3C5B53092B8C828 + 91: DBBAE1CF60BBCA0B05EDEA0B362F0A33 + 92: E18E85BCB4633A797FAF7975CEF44B84 + 93: 1BE27EEC72C2EDE151978705C7C7DED2 + 94: A15D36C5C5BED77699838832FC225DD8 + 95: 08F31E68BFBBB420742F80B20B69BE8C + 96: 5E9B4B5B3228F533BA8EFC3C0B9AAD3D + 97: 1239BA6D941D1D8AD2ED561BF517D4B4 + 98: 5233F50218E0D097EFCC68F1536F30AE + 99: 340B47C78B003272EAA4B9D22C3B0542 +100: E7F11759FE8A897364C21767570885BB +101: 054BD6ACBFD5421C0290B0839C0A0ACC +102: CC0748F7B2CC921CF5FA019F955066C9 +103: A4DF167697949B1AEDBBA3226A334BAA +104: 29893B9776BA5E750A9FCEA37B0116AE +105: 2DC25C935F006F7965FAB3256D77004D +106: 24089811FFF2189FB9AF38651F43977D +107: 0E048569D634BF652CD8EBF859C9B69A +108: 00386B569DAB73844A708BA5B48BBAA8 +109: 8033E1AFFBE1218F81C8331343FBE5B5 +110: 9B82008A34F3847C1204ACA89F3D57D1 +111: BE1A529F88AA05A42AFC40F663E97849 +112: 5237637AA645E83B0E56A1361AB80643 +113: 15BC4405E891ADAF48FA56D4356705D5 +114: 0820087438832B63AADC479CFC88BDBF +115: B1E3BA7E96605D5FF614B1BEC1F57AC1 +116: 838A096D64E6C0DDB069DC89E4C3F839 +117: 934BCE159F3959A933C87AB497CA8D42 +118: CA501F1DE619A570DC38FDCB8B3F7722 +119: 033B27D5994A6F5D5F6800539B69E876 +120: B447FC68FEF4E3CF9290B06EB6AECAA3 +121: DD3D3F72F0F1FBCD030D839DCFEE457A +122: EE73C4C996E0150D93B3144F20FB2C1B +123: 5AF9679D2441542391C6A903FD8C1626 +124: 2BD84B87230511DAE7256B62A46AA45E +125: EB159E5694C191F7708951EBC0AAF135 +126: 60F02EFE1DAFAACF65F6664A2321B153 +127: 14E5A0E90D4420E765C4324B68174F46 +128: 09F1503BCD00E3A1B965B66B9609E998 + +HMAC-sha1 + 0: 06E8AD50FC1035823661D979E2968968CECD03D9 + 1: 0CE34DEAAD5CF1131D9528FAB8E46E12F8FE3052 + 2: 23924849643D03BBEAC71755A878A83BD83F5280 + 3: 6119DD9A7024A23F293A3B67EFA2BF1D82EC0220 + 4: 379DC76AC2D322FD8E5117CCA765391BC0E10942 + 5: 7897CC86CFF17A3F95C7AF02CCA03546F5CC2368 + 6: 1FA1EF3980E86B8DF2C8E744309381727ED10E8E + 7: 03B2B726D71DAC6A2BEE63EAA09631DA78F5958B + 8: B8CAC4C104997A547374803B5898057B3F8110A9 + 9: E165E07F8D542FB288C7D367198D0618DE3C9917 + 10: 18125F046C675F434B3C53A28C301FB2D91B5D34 + 11: FAAB993F2FEAE442D28FDBB613D2C768ED13342D + 12: B657E7EE3A65C6484D007E21484813D9AED1264C + 13: EEEC2BB7BAC158742711ED13090FA20462A5E5C0 + 14: 12367F3A4E1501D32D1731B39CD2DB2C5DF5D011 + 15: 57DD9DA36E7A4E567A2C5AE9F6230CF661855D90 + 16: E37110DDD295D93990C4531D95564E74C0EBE264 + 17: B2115C4E923EC640E5B4B507F7BC97FE700E12DD + 18: ED20C67345867AB07E9171B06C9B3B2928F43188 + 19: 6CA7DFC9F8F432DED42E4EFE9F2D70D82507802D + 20: B39EB4D2C190E0CE8FA2C994E92D18CFBCD8F736 + 21: 91BE5ABF1B35F6227772E36337F258420CF51314 + 22: EB957199EF666C6D0EACC64FC4261D11C715BB23 + 23: 2A18D8D4AB1F8C528C9D368BF5A7CFFC2168D067 + 24: D4DC370D482D82932701DF8CEAC9337682C2551B + 25: DB9665A6A26DBDE20238F04E9F1A368D26564E4F + 26: D5AE212C9E543F2656699B59DEED54CAACA9A071 + 27: BE8890F9DEC6A02AE2848D8505B6408E884E6D1A + 28: E8D9DD9FAA3080560B0EDE798B745FEE2A1E5479 + 29: E219219D2CB8C363C2687F578446ADE1C0404287 + 30: E8E7767B35ED8D0965F68272ACE61924CB044262 + 31: 1B26689C1EF55448A61DFAEF98B6E7206A9675EA + 32: FE850390864E98A17FC43C3C871383169741B46D + 33: 3F63068D536A282C53E5C003BCEEC96646CF7455 + 34: 2962C292CE247F11ACB7E1F981447C51E9BBE63C + 35: B28909A2B7B2E0E13FDCB1124B0BDC31D7D2FEDE + 36: 8DA0FC30C8322DABD67D61E82FC92351894789AC + 37: 543DAC6D449FE2DDC3201927D08695F68F832905 + 38: 371540F3092F77867F0CA9DA69318C7673F68388 + 39: 7EAF32204EA5993C87E9A12C67ADA4C85D253281 + 40: FC4994BAA05F592901085ED7DA188EC3A9BF36E3 + 41: EBFE77592EF34E81BDA05305876411484DC0744F + 42: 25F64E8F076305D6F5741EA58232F68B725B8F6E + 43: 5DBA03F7E4B4226666F0D8D5BF49FEE77951D121 + 44: 98E1D56D723DCACF227D2AC67BF2D6E7FD013497 + 45: 53550BC55A367D87416FFA25261362E7D4618DA2 + 46: B18434BCCCC5F08B35397C1A6684D60F4F3A452F + 47: FF2BF38DFC6909B46A01E055D173F67A7E456341 + 48: DAFA445432ED37FEC99059DB8A0BC528E788E95D + 49: 7FF823C570F8B4C0E483165C076AEA7B5E727632 + 50: BC4FC948AB621FE1419CF6006DC04E7D7B32FA23 + 51: 1678AFCC3FBD1063E7C82CACAD5B6A933A93091A + 52: 97DC2F9F56738FDAFFD555BF09274153FC2FD009 + 53: 74F5CB4F0900441B7AFFC278C01A3038DF3D60C8 + 54: 021F66143270C9D58F26AB193DBA81A811917CBC + 55: F486D1C8127813FEEEA8A693C4B8ECB5BB53C3A2 + 56: 8397CAB8EED5B2164FEC6BE688971DFA2138934E + 57: E4477CE9BF8CC5A4CCDE039B4E3000F1A0F4153A + 58: D6D2D1E3EE4D643AC4B38836AE54E846F99B376D + 59: 9545B2C6279371D4D928AEE24328121D43DE1E5E + 60: 947ED38EC087C4E53F417E8216408863A8EBFCB2 + 61: 32518A2326ACDE1E962B3D0D2BF950F318894E83 + 62: 5D21D368FB9D879ADC27B341D608BCF860AB14F4 + 63: E2BEDD94D565A51915B1EC6FA9DE18C62D12533A + 64: 15ABF657DB6473C9E2F017C7A2F4DBA3CE7F33DD + 65: 0C9DAF8D959DAE3B66FF8A21A94BAFC523ABC462 + 66: A36BE72B501D435CB627C4555A426C4ADAF3D666 + 67: 1C171979D67A014A0422D6C3561C817A354CF67D + 68: B75485B08ED052A1F4C3BACCE3C563DF4BA82418 + 69: 17297624219C5955B3AF81E5ED61C6A5D05BD54D + 70: 38A9AC8544F0EF24A623433C05E7F068430DA13E + 71: 1E9EEEAD73E736D7B4F5ABB87BA0FABA623FB2E5 + 72: 4B9D59879EAC80E4DAB3537E9CA9A877F7FAE669 + 73: 7F76F2F875B2674B826C18B118942FBF1E75BE55 + 74: 1716A7804A9A5ABC9E737BDF5189F2784CE4F54B + 75: 168027EDF2A2641F364AF5DF1CB277A6E944EA32 + 76: FBC67DED8C1A1BEBBBC974E4787D2BA3205F2B1B + 77: 33DD26C53F3914FECF26D287E70E85D6971C3C41 + 78: 97906268286CD38E9C7A2FAF68A973143D389B2F + 79: 45C55948D3E062F8612EC98FEE91143AB17BCFC8 + 80: AE1337C129DF65513480E57E2A82B595096BF50F + 81: CEC4B5351F038EBCFDA4787B5DE44ED8DA30CD36 + 82: 6156A6742D90A212A02E3A7D4D7496B11ABCFC3C + 83: 3040F072DF33EBF813DA5760C6EB433270F33E8E + 84: EE1B015C16F91442BAD83E1F5138BD5AF1EB68E7 + 85: A929C6B8FD5599D1E20D6A0865C12793FD4E19E0 + 86: C0BFB5D2D75FB9FE0231EA1FCE7BD1FDAF337EE0 + 87: AB5F421A2210B263154D4DABB8DB51F61F8047DB + 88: 1B8F5346E3F0573E9C0C9294DD55E37B999D9630 + 89: 09DAA959E5A00EDC10121F2453892117DD3963AF + 90: ACB6DA427617B5CD69C5B74599D0503B46FC9E44 + 91: 9E1BB68B50BD441FB4340DA570055BBF056F77A2 + 92: D3E0C8E0C30BCB9017E76F96EEC709BF5F269760 + 93: BE61BB1BC00A6BE1CF7EFE59C1B9467D414CF643 + 94: 19D693B52266A2833ECA2BB929FBF4FCE691A5C9 + 95: B99816886D9FE43313358D6815231E50C3B62B05 + 96: 7A73EE3F1CF18B5E2006A20BB9E098E98B6513CA + 97: DEC620F008EF65A790A7D1139ACE6E8B8EFCCA5E + 98: B6BA0EBD215CF1B35742A41EB81A269ACB67C9A4 + 99: 3A0FAAD14D3B64BE4EDB9D5109DC05DFFA7680E2 +100: 12E62CE53283B5422D3EA5D8D00BC7F0AE8A127C +101: AA36F0CC6B50AB30286BA52BCB9BB5C1BD672D62 +102: 55120C68B419FE5E12DB526D4ABFC84871E5DEC9 +103: 372BF92A9A2507509C3D3932B32444B7BE1C9BAC +104: 7AB4B04EEC091F4ADA0807DDD743609BCD898404 +105: 20CB412425E88482E7D184EFEF79577BE97BAFDA +106: DEB91399A7BFB8323BC8E6A5F4045125277C1335 +107: 6769F41624E553B3092F5E6390E4D983B851C98C +108: 716760E4F99B59E90A4F914E1FB72A6D2C4B607A +109: DA0AA5548B5C0AF0CC494F34CAB662A30372DD11 +110: 17A0E2CA5EF666EB34E2ED9C10EBC5DDCD0D9BBB +111: 1B3614AF749EE359F64F3BE3650210CC3C3498ED +112: 346E604622CF8D6B7D03B9FE74E7A684AECCA999 +113: 629E46882D214F9BD78418C2A97900B2049F1C83 +114: 765F86114E942214E099E684E76E94F95E279568 +115: 002ED578F79094B3D7E28CC3B06CD230163F1586 +116: 52CC9748778AF5C8E8B41F9B948ABCECF446BE91 +117: 9326190BF3A15A060B106B1602C7A159E287FD4C +118: 18A5DFBAE6E7C9418973D18905A8915DCEF7B95B +119: 6D25BF1E8F1244ACB6998AA7B1CB09F36662F733 +120: 5F9806C0C1A82CEA6646503F634A698100A6685D +121: C3362CE612139290492225D96AB33B2ADFF7AF1E +122: 3D42A5C1EAFC725FF0907B600443EEF70E9B827E +123: 7FF97FFC5D4F40650D7A7E857E03C5D76EDD6767 +124: 3A92F2A18E8F593E6A8287921E15E2914DF651EF +125: CDE6F2F58166285390B71640A19BD83CA605C942 +126: 21A227A8DA7A9F5D15C41354196D79FE524DE6F0 +127: EBE93AB44146621BAAB492823A74210D3E9FD35C +128: 6560BD2CDE7403083527E597C60988BB1EB21FF1 + +HMAC-sha224 + 0: 6E99E862E532E8936D78B5F02909B130AB09806B2AF02F7CB9D39D12 + 1: 1D1D08669FC34CDC5FE5621A524E7181CD5B5BAFCA3DA56D2E15FCD9 + 2: 014A21F82D0CAAD15EB74DD892187D7AD93F2BEB549A596DFF2C9AA9 + 3: 5F600F19EDED821AEED09781792F9435458A32A60FFC1B678FE2C905 + 4: 8D933E18052E7FD1F98E5E7D02384DA60F3E743801032256282AE2CA + 5: 21362A65B49C33568251CD1366EB13A4E683359855C00F3AD6710896 + 6: 1E1814B72BFB185265AF94FA622E4A1A70826C06F2BE2EFD96E4E168 + 7: 118F2E1C2F1AB8AF2BD17842FCBFAC966F5B21A81996E3CBADF76442 + 8: 2C6C72703E33A20EA0333629503EBCC41B64DB829064A5C7897C465B + 9: 794046ABC3BD8165D12C2453FFA3FC518D1A6498A48C91053BEA2966 + 10: E6C3B6E2DC215702960633C976B86B8378D7780FF884910454032C7E + 11: DE7CFF6E85D9411FBD58B28FACF72DFDAFA115614BEF3119F6527104 + 12: 11CF7495ADC07EC29EAA7B3464F772D49999A5E1832F71FCE18CF7F1 + 13: A7541E63945FCAD62D2570B015079DF0422E96075986B45772860F38 + 14: AFD3EB7EBFBA79CC68E4F6F6A2D758969B5C5C014FFB53CFF21C2841 + 15: 28D942E37CB92EDE2E6F994E9EEE2BA01077D099F3562FEF97A8CAC6 + 16: 34C7562962548AC9661759B4FC347D6A82CD47991EA06E855571CDE1 + 17: DA76FA12D69D1FDBA5E544495BBE45F620BE147B73D6AA64D3B3C298 + 18: FBF1911FA019CB7ACA20E3F93ECC0D5E8D60DCA0A1A7420C63BA1864 + 19: 565FEDE0EE20842B82D59644929C2A1A426E397B38FAA772781FE018 + 20: 7B9C2BA77B2989904F194021D308089E23F00954275AE9AD87306A31 + 21: 66CBF93ED8071FFA36B61F3AABFDBFE714C3C055B2FBDCD3CF369025 + 22: D96F10ECBFAD7FDDDF60BF1511E94869ED1D992051539E50D5F32831 + 23: 5473F93F0D979D77C3C6B9CEEB2F3DC1058D81401669EF4AEAFA17E7 + 24: 5B5A75A7D99C1B40961533C345B95FBF0AFA916D6E133967FCAA15F2 + 25: 2A1E50E18C37AB7BD928AE14C206FAC9B3E869173CA337FB9374565D + 26: BF2B241659C96007ADC25D9567947BAA740555D066636731EEAE3C97 + 27: 6E1E7B64A70B190BEEBDB9DA82C8E4B160CC73B8FFA224A6B92180B3 + 28: BE36A5F8DAE9294B3995D278CBE9273E66F04D46890B44EC55028C3B + 29: 9983C289CE2F806F41182752A753E0A890217DAF3778B3AD2ED6685E + 30: 8B0F08EDF2CBE25E8F9EE4D2948BA6BF81672BF4F509530328A8BAA2 + 31: B65FB77E6CB86E5F409EAC2F1B5A05E1910213563F816121AFA8CF14 + 32: 5D15E17C8C159EA5DF5F126B12ACE777EAB36A0082C57DF71E4D9609 + 33: DCCB3D17C8756F2546B3E5B24B1678438959D83A56524415666DAE05 + 34: D28DAB7CA715AC86BF4469D743A0005AEE0101F339350661D46A1684 + 35: E7A1CCC4B2B300457DCC64534152119390B69610C7FF9DD3A683439A + 36: 29380148DA403AD5911C7BD52C783EA97EC306F2B32BC426C4D7FD35 + 37: 56DF59CD635F025925A968591E60DF2CBAB22F98B67C78122F3CE868 + 38: C20EF10AE9CD99CBB54C94C971780E0487899D7A810FA51A6553DCF5 + 39: 5B78837F366097CAB6D31624C06B099BDC71286E3AD8873509ABF4CE + 40: 8DA09589C44E710B9F84014FE553074E72E0A86C9418EFBBE420D2C8 + 41: EEE18FA2BB5A5CD16017B4621ACC4211EF7CD60613A8C879B0AFC0D0 + 42: AD9670FCD043E6F91CE986E6F55905337248B72E7B8551AE72ED32BF + 43: 97FA4FBA4815DA49F6127C96C969574AA9543B338F93BF9171D2547E + 44: 838D5AC81EA6BACB827327E8EFE96CC2B14D92C55B40CE58F4DA181E + 45: CA99480DC8480FA07784EF02074453664DBC92257366514060F07C93 + 46: 93B0E493D272470F9F274DFE4B9DDF183B26011090E15861FA21CAF2 + 47: 770CAE487AE5890DC0B931EC17623293EFA5B22EE1ED496A37EB9FCE + 48: 6F1D5CA0446E7B82DA02847ED1761CF02D646E56FB0CAB9B120E5282 + 49: 2A8A1254F6CCC3D656397A5F2D64C266412FC5207866B073B77DBDEF + 50: E8CB788AAA965ED87FF2C7B5F3107684326DCBB0E667217E0EA62C51 + 51: 85BDB6D1486F27827D5870812BEEE2C3976E0DED4BD2F994BBEC12AA + 52: A14E0343FAD6BD78E0A8E3BCD6D0B6C83B1220FE6C89F57F44BC805C + 53: 2C60D71F2D4BEC90CF10804DCEDB9311637B34D62E9CB68B8503162A + 54: 36397D66B434BA744174DA541F080CF6582F10322C7FB1869A100141 + 55: F612E4EA307F56447112CAB5D2EBEA7D12C7C4427D9155D4085687FD + 56: 9798B420980748993BC78E3601B8AEEE2D2CF6E59799C7B07B88435E + 57: 50BED37F1EE78FAE16D178FECEC2EBE4776C8E5FC738F9506E8AF676 + 58: 2755438A9AC457B81999D9E1E479C36DD9AE1F920F5BE6D109ED7431 + 59: F3DC2238B13BA706A048253F86B79045B72EF767CF25DC62F96DAEA0 + 60: 11900A3154C4DFC49B941258A134C9201DFD280728BDB3F8BC7903F8 + 61: FC584202454DD7C9258F72A6258E42F3C2669FD138FD7AEE6200C4CB + 62: 185355C13E146EA89387C332225DF31CF114AEC0BA3A5A5B53667709 + 63: 8194DABD2F7A02DDDD7B752AB5669821519640EE3B0059FD333F3401 + 64: 2CD6946C6DB676ED1EC272AE34735A0546AFB8D996323272C39A814C + 65: B7A344BC5EFFEA97AC49894A85B96F9B570E680DFBB28C76F7F9A180 + 66: 9011B80655A9CC7964CBC4BEE1CC03074003CCCFF5DA553B289ECF6A + 67: 6BDE25371B7EA9ABE31A524E49CAAE40DB220E405463D93FC7F66904 + 68: 35694194E10D0EBCA6758099D09C99C3CAB37AFA52FC4F4361C510F3 + 69: 4E7A79F362D7AE5B1680F30E6770CA46FE6264C9FCA566718C01EF67 + 70: 9DD18D21E413AE12112AFBE16684BFD4FAED7467A2FD5904EF0B493C + 71: 7532D374B66B1E5B17EB49810DC3C04264553E4C36F4550D1E860B70 + 72: 35EB09C82A624B1E3ECD965ED8522E9572EBF26791EFA667B4DB952C + 73: B9C17DF6F2A6506FB1DFCF1A9089974C45760A438330AE7547DFE685 + 74: A7DD0267C15B36D8BD1879F879E894FB9F33F254556B87BFFEDD71A0 + 75: 68A354D120CD63A5D34EEE84B7E5E5BC1E5DF6E021F712BD4270B781 + 76: 441DC4884130D48BA134E2FBA86AF643C8EB79CD1AA4688F82E0D3DC + 77: 17A3F16DEAFDBC1DA00BD14D9C24497BE765F41E2EC79578421ED8B9 + 78: 8756A267D0CAD54BFC848FCC4D6B6C94D39CAF07831EE35324DCD35F + 79: 004EBADA70F19BAB48E6072E2090941DEDB5CC0A7B624E4BBB671382 + 80: B7F8D35CB865977423710FA1E0F939808E68ABB54BD7EB0427DA03DE + 81: F3D0AAA2F912FF95251D3CF51EBF79B940DB56839DEA8BA5872D1FDE + 82: 0835B2DC376BEAE873F1FA337D75C72FD1BF0F72A81669AA891F2722 + 83: 7CF9A7D57CADEC3F013D4BD87C00B420CBFF73670A9CBB072D18EBEB + 84: 68AC0A34930329F5AA40137987208481E34D8B9C08EF7A85AE3AB38B + 85: 00492F706D84B903D5355FDC0B68C2C33B484A95A173FDC4AC945028 + 86: 6F6C509CDCC84CE1C36AB76C9BF30E4422C90C869C164C64696AB5B7 + 87: 4C0A35D512BD0DB15915DE08FEA8E6027063A1780C104F6273CAD5C7 + 88: 27087F6425878D64A56BD5ACCC0E303F803B7208F20AEFEF75501F03 + 89: 4EF78140430EF60F3CA12AAF8132674B0DDB154F495029B4051C2A36 + 90: BCCA3153EF93AAF21CA02D235A23D3013976295E704223CB37E860BA + 91: 20CC8D4C64E09B00ABF23864BD7EDE542F5BE480AFC4B9551B301EBA + 92: ECA3F86DA00098D91F866C58558BB7B00C9E4239CF83C5A3E76291B3 + 93: 7AD9AB198858820D20373C45173D76AF8D68F829D9A250ECADEE0DA1 + 94: 3E1C202F2D589BDAB015306AD063784E5BEA48AE8D1DAF45D571D2FD + 95: 990C44330D56EBC9EDD951F8CB92D5847F4BD3C6442906F57A828FA9 + 96: C92F9FCC6220EDEF52B6F842635A83914B236862F6CCBED16F4899DE + 97: 0E41C85D5C6D625E1884EF7438DD9EBAC818AB50CC265A73165928D0 + 98: AE087D57F9CDBCDF4DD68A3E8D5BDFEC709A532A4A646CB31785506C + 99: 4CB03AEFD24C833B5350996EB261E803F6DB698FB81F37F8A5C3D891 +100: E680BD218AE972999BECDC905F4D39251ECF49B29CF0A13AF5FB09A1 +101: 64326D6B692B0A17045434BFF13282ACB91E7B690339F7FCEBCC9AE6 +102: 20CD91504AB04E2D3CD849808F2362943BECB310F4A0BF6E3BD47751 +103: 80F607E2D79E1EFB0458E47C8E5726CDB8387BC05F42D6EAE3239A20 +104: F83C023D6F539967AB24309DD28321599782ACFCFC76B77186307300 +105: 70164A250799DBE6C5BD3EDCDEDB16D2516A9FC1BBA294C49F753824 +106: 1883397C9C4C9D33FB9E1E03325EDCEA1606D7ABF86C4387DABC449E +107: 1355DFA06822CC1F216C131F2BAA92A10BBF109BA3E648419A35C0F3 +108: 9E35B9B307990B7D664B9EB7F06EFDD23037F859ACB6B96A5287A846 +109: CCCA26C8F8405FF62421558255F2DA06F73F17D1AE1763A0BF8430DB +110: B4FAE909368405206333491674559B9094DA4C48913D9EACA28AD75D +111: 3A5E7D9273F91E10545FE6861D4FC223A5EB0F7B4FBFBC9931634C25 +112: 96553CF0C5C6F6A17FEED04024FCE1D292C392E60B3595FF53007AD9 +113: CA9B79F403412F71FBC10E094B35088576EB3F7F8B5D08757D89F45B +114: CF60CC5B1822E4A12EEB3E1E5F4AA79E345D8C8FCC546D57DCC7C784 +115: 807D65C33E74DA0E2D5E3788084C61AE3E8771FDFE643D1269A7901A +116: A5418DBCA94A1F9692FFDB3F7AEED75806CD9FD47171A6B67921C0A8 +117: C2B880C9E9D78B0C397D72C8B6684276E8C22A7F4D6821DB7C998775 +118: EA447EA731673E5DEAB57012CC9E0D3A7B2443165B665822963FD6B5 +119: 0F6D50C04357DF9240802977779D7F2214FBDBAE95B6D8F59B414964 +120: A3B24B29B29BBF32A01F21FFF13F44FCAA5FED50718803AC3BAAC548 +121: E31E36C38A7F2525ECADECA047533830A9C46D609E297142AB3DACAA +122: 592FF0C399A6CC1606FA3F404DA4BF8618A4DF159CBB7E05DCD30BEB +123: EEDD6A5902091ADB8EF491F820613740DA73A160D825121912613DDB +124: 3A2FCBFCB007F45CB0EEDBDD5A765EA0CB7A142CE3C024114D6D61DC +125: 5D29E1732898854AF468BBFA5B87065BB811AF8F55C91E82E888E842 +126: FD1F646D021EF31F634EF5FB0506620686B9F7D9B5C672734CA10FDF +127: 5E43945BA9DE62C364E34CC1361FFFEE9BE8974D7CF5D2E06428916B +128: 0FF4DA564729A0E9984E15BC69B00FA2E54711573BEE3AD608F511B5 + +HMAC-sha256 + 0: D38B42096D80F45F826B44A9D5607DE72496A415D3F4A1A8C88E3BB9DA8DC1CB + 1: 12B06C3218C858558CAD1DA6FE409898C31014D66CBE4ECD47C910EC975E104D + 2: EDBEF6AA747C951F25AB6AAA0D874648CF18FFECC4C9159F8FC71E971FAC6D21 + 3: 03436338A166E9051599AB268CD74867C6159378069A9FF46FC07CAE375EDA68 + 4: 634758DF0774A587F3AC6AD7988D0965524DE24EBE4DFF07EF622BCB8DA71ACD + 5: 0C08E52C7CFF8B5F70781197069DC8F209552D241687BA0D24661CCCC28D3937 + 6: 749F473E0D934694AB9917569A61591CA50BEF18CABDED51666DF243DE879D53 + 7: B1E12CFE0273F5D27192D1A4B70EEC4DDC714B66C8BB1921C63381F78CEC5219 + 8: 1C60F13A1C539788E989BAC2EBD4F8E126EE6ED82C2E25817C63B2B633FABD33 + 9: 5643F445B2C0656A49BB3DB5088C9E2E4B2082C2B611BBA0DAE5791F2FAA5D43 + 10: C467F47251DAD4694C9C7A6758E54CEBD68FC933C7C57458020774A2A2B4288B + 11: 85C90CF2719BEBF40EF8D501FDA20C342BC406E728551BC0275ADA1747BD981F + 12: 06B72DAC895B008DA249B7B1D8A5133F09D86BF82DE2C4251BFA6C3D8C4CF03F + 13: 49EDB6714A556DF324E41A3CE5B57006E38FD7CA8B90FEEA2ACAB429204747BE + 14: 7411921D759DA0B491D6D4CC372DB79CC163F146C345B4A73D93EEB4C262A1DF + 15: 5C37FFBD1F0512AF443265B2F3E8B6D01AD9B45FF6F373D2CD0A7C6E48D03E26 + 16: 773165FD16D51E51CD8A958E548902B47BBD0A6E156C31B6FEA036F6D8C4A90C + 17: 5B4BE909754EBC8ECBBB8B5DA6298B8341B35D92E17CE7281909EBA1EF568347 + 18: C6EEF2D12F54815561EEED3426D7AA7E671E26D42384B9478D91FC6B14CC76F8 + 19: 4C9FA0575CD96BB1DEF6EA79F5EC7A1F0478E86352812F690C2C2BDB70028BCC + 20: 7F87BA45FC41EC30E76F61E4EADEC013CE2B4C49CA6FE6D2FA525F6BBD45E103 + 21: 9B8CA1D70339A0894E16CE4E76F6655ADDD3EEB598F3DD80FECC5EEEF3F638C3 + 22: E4608AEA430A638799991B748BB858C91AF58F56B226E1901D28336B30498279 + 23: AF4F9C52079B28546FBB44EEBA20C7AF0BF493D34EF6967B07CA32FC4DE25ADB + 24: FE51F3A9313EEDAAA991350AB4D1D7045D42AACF3AC7155DA3AD9A2F1DE3A73E + 25: C1F5AED9D77F85404A4B308A139D33F351B20C91A738E698BD8182F124D96C82 + 26: 3CAC12A252B93B7D724AF9119FD3C18E85E88401F93BFF42AA05711B9833B1F6 + 27: E61D4E94C212324A64B1A0C04B2237A9A1C5CC003D83EA80BCEB45452DCB42F2 + 28: D01BA47DABCE4704B6820EC0ECDBEF137B9C4ACB80DC99B7C9220CFD9F9CE363 + 29: AED502C53A8B2C76F671376CDDBD0596376B3664B917CD9C9ADBC489543D4721 + 30: 3405AFD96584C5E5963362948D112A70155877BE3B5EFD479F226B73351ABAF0 + 31: 5FA0290DC68B72B1FA27DBAF157923C706B3F52CDE9C4EE38CDA31D376B0BC0D + 32: C1391C694C985CCBA707A8C78AD05E2180AF6B4DA5BB877AAC5E2AB33B4890E2 + 33: B018E7B15F92DBEC58F767633BCA3BD0D84B6D5B9443784DC1757166D7AA1C16 + 34: 8D9E2C84967004E3957DF59D502BC11CF8C8959368117EC5DB56AC958A3E791B + 35: B0EAF9C0E869D7A304DDB30061A73C580B0A6F9D49E15442ECFBB3B5A851855B + 36: 0B48B0D8C3ACF7B4F9ECF8E46563C921B1B6720B6C650D72DD1126B6763CD595 + 37: 8879D239EDB09F6606957D96A1F4BF37EAC0F3419881EEA79E8BF1364FB3FF6D + 38: CC663E436DE42E32EA110F9D90EB990D9151C9F06D51243D2076B0CC45361736 + 39: 732DC3B1F809E55C498C53FC75A23966CAEA16BE984F795CB1BC94D026FAB30E + 40: F1F0EEC77D97A0234D0F19B2FB12A96B6E2FF8626F79A74D4AF26CDE1344D838 + 41: 75C9D8C7344668C478D8AE6D9E2C41E336E7A2504CDD43B73CCBF78B4C05EEB1 + 42: 4B149BCA6429408B242E76C52C4D3A0A5F5437EC0AB6D24D71EB1AC5496D75BA + 43: EDB65EBEBC0411B4FDAF186033E306AD500711CCB80E770E99523BB2672A237A + 44: D1BBFF5A48346A0DFD5CFFAA7A2AF08C27F3FC2908D7A5D2F575E07CA9E72474 + 45: E8EFB6373DD3457610E57750738358A50026D2C6704A98148CDD69BFF7B70551 + 46: 8E3733B729CEB97444BCCA405044B98F45FC59BBA86444A3FC0F4DF4854B5C4D + 47: 868F3EE8F4D4DFEDC3FFAEEE1FA069F5FBB2CB818E63C28151C1566634189234 + 48: 3F5396115DC7F17AAB19A3A9779CFFCCA57DE7A7C1A42F748FEC49B7D8C2B82D + 49: DC2A5E3E176A693AD8CAE551A505729B78FBDE778B526E28953BC1A56B54840E + 50: DC91FD745E9A7A9D0B41C79B3B3939B84BDF78BEB007F9AAF8FF82084759223A + 51: E73DCF5413F17D4ECCEC813DC060EF907C2E952AF92DD247A0AE2BE798E6A40B + 52: 696B5EE4C1E1D8B60B0015EEA2389C9A35088022FFF10034D0D09FA722A2A3E6 + 53: F86C07265389512B2CE240A89EA29D61C6C79C2738FACA157B0DE43294485682 + 54: DB31CBBFD28D6F8564219911EFB748A5663E482DBA26E38634E8E27E3CF65707 + 55: 2F9675313AAB7A940AE77CA906D0342A448FDBA3F7589D14B1344D586EA157DE + 56: 7D829FD994258EF2AFDEF22C8CD5CC1D29A9A55B62847B3B6F5DB630421CF999 + 57: A6CDB9BC9AF75EA4680E895E8EDDCE76F536F7CCA571D62781A06DDB3424FA50 + 58: 1B4186A34EB07F5B3127F2BE0F3943610679DB0F6BABC7DA03B416FA577D36E2 + 59: 7B5DFF3459DC10B9B7AA2B2829094F97706DB5B2F133B8BF9F48D90253D68359 + 60: 2ABB68160300028BBF3B5A414970D11DF4FD6F4B4A35029DEF8492ADFB19A480 + 61: B1B13ABF9D20C42E755D63EC63C016126259C8A6C3F9AB3F0F6AC5D0BD44ECA2 + 62: 9ADDD17E5CF407CDBB12E5E52A50CE134F1B48A2A2AF90D7308344FB5A70485F + 63: 6A4C06DF40BA515C56476471D4A94F87A2B91EAFF6C66510892F2F20A342B736 + 64: 555D424206C003BAD0B08BEEA76DFC81B307C79BBB6E4F15325B2ECD37E04423 + 65: 8A58733E0B990D0D82F93F77DF36E30DCFD03B3181B73C544BB097A3A73B6AC9 + 66: 6FCCCCA4172E30A281A702E36E7BCA07370D4B57272385077A44D5F7933DD2FC + 67: 3B1A91E49AF88B1832F8E91109C7CC5DBEE2847D9ACD2A57404DBB565480AC75 + 68: 69584075C278763CB0B09D4C9E15E9300A191BF99907049F14EC8DE24D86C121 + 69: 2EE24340D13E68B10B95C3F77D55027F98BDE6BA5328D0C02CF89965687C062B + 70: C04B37F5932F427D40E21EEAB7C9594B16BFCF4F5FE2BF175CD63C62F2CEEAA2 + 71: 058E1AC8971ADD2617A4BF7D02B46A8B74A4D52B25643DF9729A1E7DF6CCC86F + 72: 18001F246ABC760197482E25F3AC64B14A795E55B41B505D6027261BFDE7C52C + 73: 4AEAAED524B173E08E54A83E2D9A8B8824E6E2F1B89203D698E9BCE7C3242F8F + 74: 7D82CFB1D7427302889CADBA23A99154CBAC0C9ADEC94EAF29EB07DC86B0B7E2 + 75: 18D42E92BA532A409CEDA8E3A07E751B430800827F5A9F14D93E3ED231BA08AF + 76: 8CFBA378D8595372DCE5D9A6E726C23512F84C0C1EC3C66ADF6B6C55DF63936A + 77: DE1A6E280A9054C91B826785928F37A16E1D2A9A3CEC831185B26D2B8EDE158C + 78: 920C40B4204C7F3D4775176BD245BA0276604C568B3C29943C9AEF1A1C93428A + 79: 935BB39E5FBCE5C4A15AC2A854475578CF80308E531CA86818DABE69BED8824A + 80: D608E561471CC09EC0865C826242CA26AA1C90BDF1625E1A38B96E3EE0CC5F04 + 81: EFE2A8D806A1A71596A05A2F5F48D18CFD4A742247B04E8089FAB27291A8DD50 + 82: 80235BE35DDEA5D49F124D8BE3D143F87CCBA7D0608C7E2CABBAAB01BB95E477 + 83: E9410E0DC14F3BE36A49A5CA673C12E18CBE4F0817E0C1CBD2069349F8A09BBB + 84: B2042A81A36F27B4CB96DBB52A61F701A815869FF5AA0CDCAD0327E1ED1C2F22 + 85: E9E5A9501B24952DCFBB9D59CF95A9A9E6A27FB7315EB472D1E2B7F523D06D42 + 86: 99193B4FAFEFFC932B261EF169250B96901ABF877424FF667CC0DA0154C50498 + 87: 1D9C7F7E681D20E1E0324EFE71C8B6913FE8CA87EE52E443335115AB2C458E7F + 88: 7308DB7E2591D2342109C5084B1174F07D289FBE91472FB2D8C06DF39F826B84 + 89: 90F06ADC29070DC50A23D3F093007E273E783491A70A2F0AD6BA40E34F02518D + 90: E676DEEDC972019F10FEC24B4AEAC0A97870E924F7B1D6D3ECF91EF38A2AC544 + 91: B5DA3B40FBF373795E67A6338F9AC3AD742741F34048930D9336D429D02EE78F + 92: 6FDE20988863CE157042EE52065EEDA233BB2E6EC0464B9DCF2AAC1F3A18971F + 93: 428D4CFF477F0F0379F634D1E7C15E4CE6DA067ADC45221A860C9C3AC4235753 + 94: 9EC80B57E921DA3F81D13B65AA851F5971E4074C96E0D8B64E50A7F5089C1FC8 + 95: 9088151BEF766D0896A48EB6DCC8A09D151C3396FBF3A9FE193C5E7BF9030B01 + 96: 86D853024A762536666316F363BB867EFE25FBD03BDD28EA7522973A1A1BD95C + 97: 007104BD935B532BA4702A78C505D67B41358A61DB8069585B91B1445DC346B5 + 98: 5C5709F6202948E805FAC25C454ECFADFAC693955864494E511F0CD1FC9CFDCF + 99: 0B010F71C5323CC96D3B8DF71170968096E44969EA55B4C3DAC632D30D81D529 +100: 54621EC4F31CC7F6273601D81674612B44726B5CC4A76EAD2BBC3D32DBF62A9D +101: 28EFE1AB745BE64E5DD7286C97360FF2D287F862ADBE44380F85E1388008079F +102: 831BFA684C25542676AD52819249A10D9EF9C2505D69CC1397D0D39D08B39E5D +103: EF7922C40CD96A47C5E7AE4D958B495F1D6954EDC20596E303CFBA43190A9EFA +104: 3A0262EBC746A7C044C1DB043951F7EAC645C40F554898D3D7B2B7AAC4EBD396 +105: 1F2CFBA7275639A12DA7CD1986F920C47850DE3FE13C931618C0FAC765820ED5 +106: 7AC8913C0975101E187FDADDAC5B5EC467A25869C4E630EADBB42DD2DFE4958A +107: D386591F326C91D274FE625A667B6F9F6F7D99CF56ACB365A218F1CF8E167A70 +108: 66286CB1B61156B005CBFC94C2CAB1A6694D7F123411B8A123F2ACD821C291F2 +109: 844D1038E710690050DA737D56FD6B17C261C7BE512713E62033384B53C40902 +110: 7EF970C40080F554851277F4E950C6F378B0A3DA3CD1BE250D976162F8A4EE79 +111: 9BC20A2B67566688BCAC77FCF30259F11D9B2FD2277D033E6AAE19E36058A353 +112: 796C72D95BBA1A4341C6B0397E165DD21CFBEF55555B35C717CE33B6C6ADE490 +113: 1E6A9C1F78AFF266EF8FB25C32C1FDFB4A0F64AFFD046D257470BF6DAEF61D6D +114: 0E1AD927AD658C5E0321333AF8AE4ED69903B4F22C5DFF90AC93268507A7C86B +115: 07B7A778E2931704E7FECA284FF3B14071E255A2B824AD0A2272D21448579CEE +116: A8D810DF06368A0E825D6DB4394916E43E217BEE9303AD4096A8E1CAD37B8703 +117: 6A9C7D302CCA1EE170366F355D8F40AE3A20D28BFCB2BA163DCB68E08DACB748 +118: 40C3A8B08FF9F767491E4243D1808572FDAF1D8CD21AB47115849531513D0750 +119: F26EA6760AA80360398371855783815BCD34431E0CCEC58A34A67997ACE43CEF +120: EEA78D68A509988ED6D7E3F27FC22F3EBCD570EF0FE242A0251457EAC4C3C1F4 +121: AF977819B87F2E63C0E131DFA2A31C555AD831ADCA6DE0FC1BE48D21A1E7E666 +122: 846A75DF3691B2BF224FB0E66E360A2E8BB1DA32422190F2B319B73E6900AD42 +123: FFA997FCFABC9FCAD4B58B0EF848890FB23B974CD57FA07223037450C371B116 +124: 0028C776965A0AE5E9E70D9B833BF328BDBCD06C5A12A2F1C510911E60AA304A +125: 7FA234C59957C214A7BE8D1B909C540B48E54414EE5FD1081B4C339FD2204515 +126: A840BEEBF2C2E80AF2E4830BB26F71AEE48A9C65DE4A9425DA9F98FA3A37DD84 +127: A95332415EA29A8CA6FDB0F771E3F2262C6907DC45B0AC8BC229F6009323C3A9 +128: 8B185702392BC1E061414539546904553A62510BC2E9E045892D64DAA6B32A76 + +HMAC-sha384 + 0: 44BE81C415D283AB7A62A45188E5DAFBCB97DA606BD5B16C92C1FC36F198C0B3A714921848D5E03DF1C4849BB8310C66 + 1: C1E1E68D864F758941B87E30C262348B373F167CE4629E4117FBA208773CCC2E6C7797AE5D6BBE2ABE6BAD4DE2E1052E + 2: BB27A0F06A1BAED5AC4FC2267C36EAB663E11EC5F0FCC0BDC09B9B0E803B0ACAA2F39D2AC73DE489FC7C9AD6DE3FC9C5 + 3: 70A273A2E9E5092EF8D4C58E99734A911B7CADD48954FD518305313B0B682CFCE192018D4847375D7E311470D05D97D9 + 4: B4FAF12B325B486B67E38A855D18B45D1BF6CC60E4D00AAA6E58268F524CC1121AD3EDB64D6E0FA524F11C0F139D0BBD + 5: B509A325F561CDDC539A3A4680380759747709D428B77E69C4CFE926F65B147D92D2C83692F526EBB5CF606AD162559E + 6: 9A1E678A743BA285CE154ADBB555CFD097F5839EEB2DE4147986464C1BF032BA0D80473293467ED0A0AC59BEAE736598 + 7: 1DF214529464666002C1AF094BB36F0FB14A4923031B108C21825E8C55BF6A0BB34C9AD7D5030B2FC7C83A2CD4C79C1A + 8: 86D8BEE44CAC35CD3946321796599F20F3A41BE28F161FDA062E4440CCC16E88BC7FFC714D525A6420CDBEBDF6AE9E12 + 9: 92417595F9974B44BB11EB9200B7560FEA3382CDCB8BA4C2CC5CFDD019C2B5956D3E78D5B186633ACB765E822B3D4E90 + 10: 2E87CF886036B7A66AE6581BA0DBB9AC2A39E1C7C7594319184FF3B612A165DC02B3A7133E3AB3D29634B1CD5305A46C + 11: A5CEDD2B54657832F946BFBA14ED5106E8EB5937EAC6C5405BE5CBE7C58053514E784E3F6668C20466A242D25A44462D + 12: 74475D913659C2C304BA49DD2B39B0C7AD7D537BB2240D8611876CF5955B347694525396C43CA73951E711DA38C6976A + 13: B0AEE82D70411F1A79DD7012421BAC1202D7C3BAFFA15B4D8B868A3E6F92B513F6B026E2E8FEE45DB2AE70C15E11D19F + 14: 7D06EA64FF5B9139662FCF9318589E8FF1F783754A9116E090B0B7A981A9EF1D4C1BF582C8EF5E71A49DEA2834447287 + 15: 8F52BB9B0A2B1066AB67603C552C17E983D15114C3B9776C548D747F7E24AC782253812802EC456914444DD67C0CDD46 + 16: 9DE6587211FE4A232F01D6D20554102D24D98EC140A05303C1893F232BAA2C07C81A10C25A95A50B38E87898900BBE1F + 17: E0175EB9DB2649801EC2EEA9DE2C1E950C129CA249C14326614E0BB8C32AEE67DF1DFC6320439DAE4FCDB4B037A53868 + 18: 0606A848086DDA50D031A585103478EED0259A9167959657050F8D7DD21B4D6B62B93AEB0009B1E878EDADEFAE9B2ADB + 19: D4A45DD1A6B613E3D2D72B35E6030E1531D75AF7C3F100934CF27EE9D0E0F0C236581EC8EE74FF759D7A19C5AA6DA9E9 + 20: 3E0FD11AE4933665EF30E10035B0E686DCA837F6D6FE2D5A10B4EC30F183EDDF3558309905F028DB93323D09A3A2F3E9 + 21: DA2A204C7908FD27A29415CAE3BD16A0488FA1D42CCFA2E2F5A1EFD6F99583EC6B3B36762060F547C629B9A332585355 + 22: FFE8FFED47933CC941A8E9233C037080B9465B4F9C25DBAC790825C013545D2344930E953187C77466437BE226962F80 + 23: 69FE734D5C69F34366E5CA6B095DE91CD4DEA29AD70BEF06AFE9BB232162E6BBB1349263087212AE3AE5D74A3B060F50 + 24: EFCF1B825AF87FA5199FB3C76783CCD1769E7DC77BCF145DB76FDC622BFA2425CFFAA40E6376086B2DBF6F5D9D97A534 + 25: 98C3DC50FC08D2A87ABE3FC16871ECB820D530B453C41F83FD304D51660FD29BEC6A7D1C63E3E12B6E80E8C58CB129CC + 26: 945047CD723EF4F25AAAC4A19FDEED463EB04CCB78EA318989143298DFA70D793391BB7FCEA6BE0D79187543426AADFC + 27: 2718D89F835037C94CD6378A3806614B85365A888B48FFD08C09F0B93360C04E43B7E7A19C79BCDC5DB9F5944579AB79 + 28: F714F16238075796DD43960E17AE0EDF9990132D690F44957C3DE9EEC2773683172FDCC44ED2104320726BAA7DBDA1A7 + 29: A87A96ED8FF0E7FD1F235F070CB5F14B41B2C4438A6D7A0A39D038C74008FE9C52497CC506498414835AEA1192439379 + 30: 31B029DFA85DF545B752506E80675E617549A6725A658CA8123D8C837FB71D8C9961BBC2460D7CCE0CABBDEDACB56C37 + 31: 0B1A9DD308E5E6E65E4C60861D42B628FBDB2C2280370EFFAB736A77A8004C5ACD5269D090B652B1D8F146C1D518D288 + 32: 2A160E0B2EC7BC927FFF813A2B56AE61301AA14933C659B3398C7A0B3CA506DD00FA6F1DE9C6D47AB0FB2BF2E7B4B83F + 33: 6893C0205F3F4ACE906F2FACC97E2B1624D40997370419E5981E6041D5CF34C77EF5ABDB1AA0D3C8C3740100C2711555 + 34: 95BC8C72DC8C70ADB7CD38311292ADEB9D7BDEC6A9580EF4E11A18317CB65667D344D8D6603C044454E67F97F4DDFF40 + 35: 3DD892A4E724376814DD5A4CBE96E4317AA8AF72478D53379247E77C35461BB92CF493851FF1FCF57A6704923099DFEE + 36: 3A5DEAF967BFA3EECA3F259307991F7DBFCEC1F354DF385CF0EE8D93291721553EA954E9D6593506E9F3E330E0A02574 + 37: E00A883DCB5460AAD611603614C7214EC4A566E0580FCAB1CA4ECF1386A42DCDA746D3AE1B0D54E0B9AC1FA336FE787B + 38: F437CDEA425E7A70CB4D197C0CA01562532A7C51FFB8462B4796A4FD0A7EC880CB0E5EDDD5F703ADC179374416592256 + 39: CE69E40F5B5F2F25E0B53281BE76ECB0E5B4558292A1C1A5EC56F2CF11B01BEEB1F0BA01E6A9B3D03BEB69AE0511F320 + 40: 41AA84D15342CD0675C8C0312C024352E99914C3E01C98F969AD04CB5705E9184F3821CFC6A22D43A77C928F6DB79D8D + 41: 74001D972353BB45FF3F7F405FC727CB5D0B00431BC76A57EAF17862BD52949AF884403ED6B2A002D618EA33523DE200 + 42: 968BC28223799F1EB92F1432B6AAF5CF6953491C3F959977B065BDB800AA438CC8AA7EE1304C18999CB5ED709431CFFE + 43: D067EC03F14D2D639C4423A311EC86B3DDC3693A2CF43C259BD0358F8D0D68F41950CB705249A59072A2CE7DF155F5C0 + 44: F41EB77179934884DDB56DCF83DC90C606D0226DDF94135FF8E1E0AA56C9A90881C4C380CC0AD3BD0DA45A6352BACC05 + 45: 27BF9A98F9E2732972FE2F35ABC80AE2E5A2BC1D238B9B1D9CE605A89144EE9766987384EBDCD63533E64BEE094E4503 + 46: 166892E106BBD9D16819D9BDD3601D24C0C11860DB13799F0797F204D07DBE914A7BD286B380EFAC34DFE3C940CDD3BE + 47: 2D85DBCFC431A94F8F50132DC8C10B25001EA10AA9DF7C53AEE9E8383EAADFCECC21202EFBCA556BB4E33CC68156B190 + 48: 086007E2874E779A5EDF0E176AC1A11D241F4AD8D02AA99DF2BC1AE3E5CC4775AAA92ADFE772CEEE89D4FDF1B601D05A + 49: 2ECA3144F4F9EA0F37C2CA5943F458590A1D4D19C0ECEA6A55CDCA648C99CD457DC57EAA995042D7FBFAB598B8AFEEDF + 50: 9C1F31F5D3A589631D8B7EF89A507011736BFC328071513D64E5432D24B1BCF47EB10139B6410A3103145AF67B5B6C46 + 51: E0645EDA004D9005399A2C072ED9959E4F8905D15C57992553202A3B53BCFEA0098E6B28BE047A4B29EED7B57602C0E3 + 52: 6CE5CA92F0B1E84D7578DDB86C96A10924601A3680BAFEE5A0B27D8390B59752205EA483832ED3E9343DE7175601C03A + 53: 47F50844C897FD910C5C228DEA1EAF456882C1115AB71DB15E6832D96607CB79C8B7AD1CDDE01966FCDDAA0B0BA9F264 + 54: C0A7EFA24590833E4788BB117D3AB3CE00C84CB4820AD9FD7F03CF1CE1A8983F9906BDD138E1943D75ECD9B98D5AD8D3 + 55: D056E9F831B6DBE97FC751453B1C52C8C6C4D18A00050F5AF2427C1123706375A918656D6755A4C950F4E5B5C318CEBC + 56: 462650CE3981EDD13D0FD2E5FDEA93A9A18CF8FA74CD6142DF4707E604D1F72745D7EE08AB13AFF3A9F8D166EA90CE3E + 57: 2BA5249841412584B161063087AF9F5BAEEFD97989BF8A0455E65C94B0663410F0E1BB22EA6402E59CBC5A23F24ABBFD + 58: C3B1E4B05A7593CC315AE15F63CE8D91C4B30E0D846A97B7D8F01FAA1B6BD7C9234EB153372F6CC7799A035E22A77EF6 + 59: 1E652653B9A3CE862DBBAF2C919E86891C5C03F54ED5970E8028F8D5EFB533B9C111DFD88ACBBDE516F0D4D636F5E821 + 60: DA773D5AAC336B6266D27A03AFDF3A151FAB302E894CC1D09B6E4ECD07C4AF4BE06A2D28D01669C7557FAE8E513D01D5 + 61: 8C8FE648A29D4BA78B3E0B944597E392A31E28F98B15280E1EC0A721C9ED5E3639A6A457744CC5AABFB3600501F5054D + 62: B443DECF40A5693F67B5BF5580A665DF6EB98FA9F14A661CD50D6635E0F78FB2943731AF363839FE6DFC0B4C49F9E849 + 63: B22EC4AFEE3EA69364701E5621E453A0C3988C1E2FDA54FDB99353F285327A534F7162BC54D701652744413B9A5D4CBB + 64: 40A22B7881AE8139941540540FB37C9AF27BCB164B6D1A3BEC709730BBBB413D1F2FD6BA4A7B7EA747FF45F3ED3336C3 + 65: 246E426C57E414575DF312223272819B0F49FF94953DCB94665FFF74FEAB049AF15160706AC5F702AF66478CF2BBA5BD + 66: 184E6E6D5FB55454EEB6DBE323BF28DB8CE60C271DD0ECC8BD4D3F1C2339B7828C1515F030058FF37BD53568FEA81378 + 67: 10B23FE1616AD5609F6F6C1D9266F702C1B5E6F7FA0B3A81406B5A766E2179D082854687701318A7B46E21FA67D2404F + 68: DFCC1280C5206F99A555E291AA1DE6F0A3AE4B49916FEED4337582B91D7EF094159556B01AC87BF7A8E84F9F53595938 + 69: 91BA9A641616449084A57221647369E2E69525A30B274EE5403FE95A43D0A7C2B301B61929D89222A3A03303550521B4 + 70: 94F59A7F5E68B942A5D66D3C642A78685F3BB400F4FF971BA576DECE94A353455277632B70D06EAE38329CC2298ED792 + 71: 21A9F5C4B1290D95A1F3F051A0158F7DD8A879E7861B61CC757FB5C729FE9A8BD46BC6DCE595D20649092B31AD27433D + 72: E4246F7DE67C3A08F18852F6159F5DC9FA4C0129A9F894EB610C10F1FB8B61B1C9947D742A418F03A00A7E11ADF436F3 + 73: 8D2CE8209B8362311D99D68DC2AAE6BE4CC8E52C03A97D99D0C5C15D8E24F1D3B51738BD27BEB6E773472CD22A1225C6 + 74: 7EAAB124A3C900F33DE06B84E7831FE327FD638C4E68DC8648EB619E3C7E5736A26BCDCFD3AA6AF34EB137C6A210746A + 75: 8B60F61A1AC2C6528C8DB07B6874F19B8D474859F98AF03503B115EEB8082E19D53F63D397647BC2D4278B8C2B741D19 + 76: A48D92BA646DAFF7D0F8CBCB1D574E9C19D396A30573A7404F6196FBD7E226731C8AB05138F7B1936986DE6C1F1F7B52 + 77: 2C3ECCA6E7AF0F9587E5A03D462C98F18B8C13C039D02D2D29E06B5309EDC82052EF72C94E0A5EB7FD35827665CA2F92 + 78: C9B659AFAAEAA8778E9E4E3B725F758768963C55151A54BD9DC191E1302ABA1F1F085D5443C46441793682A8047211E1 + 79: 9A76E83A301C14AC6AB8CFB29D2CE39E0E86B335F2B20C3C889651B4E0B94C5218E910B1DAD28474251D06D12D47072A + 80: A526CFAA2EE981A9A4D0EF12A6FA363F562057BB75A218F4645BC5E9BE7CFE7EADFD87386AAE1C607D812772498ABBF6 + 81: B747819B54CDFEAA751FB9F5C22FB269151028BFBC6650BC518692944C5F4195D26AEC45C9B4C987ECF4076B3871C5CF + 82: D45968D452B5349CA43A0FDEFE4A5379381625825A27259AD9BF5A80C46CB07BF1C919FB3ACC250D73238B11C3A07D90 + 83: C0B8AB0F8C497ED9562C65091DF1D80C32C57A018B00957BF53C41DF81A2F6371FCFE82624B2E84859114152B36B6AAD + 84: 30D2BF3DA80C0F37807F042FE7B878851E0BC4093D987438FC2B993F4CC4AF6F704669938B9E30E59BF8999883639F64 + 85: BB782ACEE42930922A98F65F319089E9B4F5D2DD2374DD76035E3178DB4468A3C04F5EF878ECF9ED757DF14DD89BDD49 + 86: 157424F30A10748940BBFAFB6D99B1B06A897E7DAA4F03387E5ED03F02D39AF59F96A20E4E9F3A4C5C07C20A8FADC8D0 + 87: B9ADED711B1E1537A35AF882F1F868D964B5898E85B07F5677DBF183232F36C14AF4D9959C2108D9313F8BFB14830B02 + 88: 7C4563BAC3C05444C3682039EAF9F9EC79B96F0CD36245F584647BC444B81734D7ED4380CC1F0A2BA876020E55660BE0 + 89: 9811A4A45CB28A780C063047EC6CF94328102DEED9971DB99E11C6FBCFC046EE38C1A00F290FF64356B9A304DC0F340F + 90: 09A69D3255EB08E9B3CF7CFA73D86944CCC91DEEEFC04214F8982836726CAF006A3FD83F8FB75600CBD060ECD639C388 + 91: 52D6D0943728CD2EED671736B6B3BE801B811410992E4A3BB50AB4269EB21AB945F6A9F7036DA654A7F2785869335395 + 92: 8C0E1052EF2B06C0C20F67D92E51DFBADF3655FC6475935426AE1C88F3096628EAB9858E5470FB98A546EB11C7B752DD + 93: B21351AF8400B9756F104599BA4BB78C2904959E2B24AC3E15FD0398627E6C8D57A7F9FEED63D8638A206BC1683794A3 + 94: B9F7CFE97C79568D62B07F1EF887C4391B48CAA669AA8495B71A326B120FA49652F02EC0D53441DABA1E104AF091E0E4 + 95: 69D2D1773208CE3BF02B38A7F14910187F3476817ADCC7A1D9830C9F25F112E604AEBB95D0237AC8795DCB23ECF52927 + 96: 57A9FA7CA61FA2FDBF0BC3E3E6463901B3B26E5D9AD79DFC0CC77F79EF3AA1AE3949E7D71CF794E067D2E38E7038EDEC + 97: FEE9196A0A1199DA8697D00AC8084D6CA1F867D105EE928FFEE14E5E36BEBEDE5C79509CA5BA05E36C3F0BAFDC9A755B + 98: 0E8DAF8BA4ED614B38808B4E468CDF88EC9B148017C6BE3FE593410D37D9B50ADF0913B7844FFDCC2F1917A27A58B352 + 99: C7FD40463E26D6A21373EAE14BCB7403B127A1E23E4583B2AC727106B07B849F74C0907804AA799C05D9FF324D04B182 +100: 16E899F4850512FF3DB0FCC58FEA960831364E5FB077CD8DA3F5B3F0F50AC626601917E8355E4847A00E0A5166E786D8 +101: AF2DADB17605DB3CC471C00D63C42F75F815594C1B49D9396BCFE7ED4D4FBB1CF15B542675DE8C9FF50EF81B72FF72CE +102: 1699A1EA2CAC707205A6BFAD8DFDAF09C8D6FCDDF2BC14A9678453463AC80054627F2C39B713861734B0974F442D707D +103: 186DA71D7E913DA49D8D97101882B1282841D41CA12F514C1B2DD61543E330B751E9F97490E18A4A37FF1853EFDD757E +104: D82050038E6DF6EAE9D2D4019827025A25BC8CB15812E0ACF4B676C799A3D80ACAE5706C0FB1FF72B2C4851DC9232B7C +105: 1657C99506EC8B28AFC1684C4A9EE4970F8F426E4BB0C3FC2795CFBA82913B453C87D84AE9B32897A4CE26FF4320CF23 +106: 9834E936482592BAC2373AA64806FE0D5C8FA92143070C61E594004F0D3B8516C2A5B0244F273124E83B20FE9A2CF5D3 +107: 5C4856A82C8E6E49BB81E89C26E355AFB75EF921E579EC4B97868BE2CFB4B1D93195ABA0500D774C5365C2269FF333A7 +108: 67B88FAD5085C8BAB8E194DF73153A5B1D334431227DFC619D5CA5D5605EDC7BC95DE33512B2F5B714F46F54E1E61B0A +109: 90C6A8F36D42C5F21A89417AA04D822A53110DF1D062E0C1A6FD9AE59C6588CC1C78469B94578B6D7C05EFFAF7FEC26A +110: 817C0E7ACD548BD3733792F4F8D845D7E4B3CAA0F0EA943B51235EB82DA7C8B77A733D756E86D57EA303F34BD97BA1CE +111: 7FF397FB43DD909AB80BC381EAA4BD50B7278DBF10F39FE718B421D6C07324F398BA5B1DBAAC64137267DE2C62F19F7F +112: FAC12B732122E18DFBCF8DC7382AB1B55353134F07E07723608825C907DB05B4FDE40FE550878D971F8B0B0953C88C54 +113: 4DB0FA3C105D64A9CAE84C0B5D7AF0955F6F58717F68366935FF9F478E94D3969B1264B1F37F8F5538BF116DE29438AE +114: BA6E693A6C3C5B048FB7F232CC5E12CA71662332EBF689AD75F6F2C54715A689CB1F75525313FB8B2713909EC13EE0D3 +115: 00BA656BEA25DBA36861B92B356C3DEE0DB1C86D4503C7FEB0A88A3541A7018EA456C95224EFC46AA31CB625421BC811 +116: 812622078CA3B4F59141569A0E125B36F7CC471F76B7B65FEAA1F1F656BAB6A3CD61A4D2456E2F5109274B2090C1F4CB +117: DBDAD8926A811DD0295C31D55AE0D41672C7F22B5CAEABFDA2C1505B084AD01440E9B8FFDA4DFCFBE281222AFD547E29 +118: A32EBC13D689B31617D24E6AC03CE6FD7B1AAA2BA78CAE2E24C36A8CA7BC74ED9BD4CF6C74E3C96DEFF048FE3964F0A0 +119: 095D2C8DCF88F69DA4CC49C64B03B2A1D2C6922CE0C6EDA12642480AE0DF35152B4E4A9AB08D6642DDC313C0FA01444C +120: 578A4BFC0CA83F1B38A0D2EABE2C7D3D67436B559624B92E4FBD9241B2CA8C1AB679B503A754D5029314AAC3AF225F38 +121: 25E321E63E4AC8994FA464B3E2B687150007D83ED8D6E1B217E86B0CA0D163B0B9686E4FA2F26C1839F2D778EDCED86D +122: C761BA17FAC3CCCAF2CACE92283DC5E5B8A6571958FC59D0070FB21CABC88A80A40DCD56318988F3AEDF38AEFBB84EB2 +123: 5EDF5D71D2CF85E7ADF9C7E964FD628ACF304C4DE3483F672666A583E3D9B1D86E9E096541ADA237D69A140571F5B3B9 +124: 401702CD847ECA2BC9208F52F27D84D07B37A86CCA5C3A877F24366CDB9719DE63670E850F02CD02C6227B7214D5DDA7 +125: 362C899156DF70FA189A66DAB6DBB3CBF80B629D1E90D9ABEB007C3C5010277EA589C4D73009C81F94AFF3FFACBFCB1F +126: CA43387C71B8245B822D3085CF029004E18CEBDFC9F78C276F3559D962635601957B6D2287089AD43F3179D077F37686 +127: 4CE8504297E21812C901E77C6680529103A017553F095913CFF06AF20E3D6DE7EFE911B636DCB5791B292C60147F6473 +128: 2AC71958C77E39D4DE4DACE92FBB6A093EABD191320A5ADA7114BD201DD026567D2B799EAC78C1F084BA9FAEC2FC8BD4 +129: 87487060C273FE18A2CF1DFF222658E1B50C3BC5A3F1F4575B3A4A6EA2F42238DEB68B3A2EC6A325E3FCA504B2E20E26 +130: 4A79A1C3C798D9F26D54715108279948EAB246086EBFDF0EAC9152216C0BA3A77AADF82A230AA84A7C884063960419AA +131: DB0BA43960FA6B763202B8BDF3FE4ADA0BAD78EBB3E6E8E57C2D5640D1ED4CFB4AC18ADB1B9770DB49A4252CDD25A369 +132: EECE296E258EA3583FBCAD1CDF2B91F4D2AD1FCC1AA339D8F591F89C7ECB5EA2FA644954006F0A58F2F3BEEA1AEAF7F8 +133: 7AFD95C86517BB6050D04BF3BB1448A0608411B612A7C2A939BB44B984E361C40569E5E57AD7DACB018689C2B8E2B3A7 +134: 7FCE7894C8E8D1FB187CC35CF5758269E286427A63A522F4BC45F814B316C1DAEF981917642C50EC693F3EF4DB8E66E3 +135: F67F56C98221892F64E2AE4325CCB80C2846A43E1629D40BB50845184E9C3B66480B3E9F792389983F2FC48FD2508F09 +136: 1CD915561856936AFCC75530DFF151F49A34D0DD0030766FBC1BE47D611F10502BE86C97B91D0E8767D4F38913EEDC1A +137: 80D9CC8B1B2B883C4735B3C0C19AEDAB78A0771753EBB4688A7E584BE7366B3C181C8532FB3A8BFC484C9CB0BBC1B4F1 +138: 8ADE2B8527C994EAB0807A89CABD5B075CACFEF42381DA3CC3D702316842E25151C65A22E80885E5CD5FB5870FCE501C +139: 2B403F2188D086327C92169871FD5A7B432D2EB999FFB0F2369B2B766E799AFDC1463CF4D9941F828FE42591D6B966EE +140: 4A0C18CECC0641C28C4136D42FABD0BC27FEC27C2587FE8A57CE0D279ADAD70F80C1E812E01B26F2BF3ECDC7673C349B +141: 8906762B63651DD5948C98DBB1B39BD6095C1438B2E4CA4B5A581D451AD3EF76C8A0FADEC9C0B0036A833D8F5C13F1C3 +142: A363BF2A479F67F949AFC151C36B052062CC2CE840974BE2F5E79C0BFD7BA29008A6BFDB55B46527D17F61531C953081 +143: 4E2AC5D6EE56567902CC1E02F119E33974762C03885EB7DFF7C58ADE22E56BC384FE74BD491EFDB2E6CF4021E3016E81 +144: BDF0AFDF17F7B014A61ECE257F8C7E0B52384EB7DEF60ADE785F273851D645E5D3B4D9534C0E6097A12C3CFF5C11D42A +145: 0CDC61FF0B3D8510C319020B82C1C5AA12C7B6F257D7D4F118A5EC3CCE03C63FFD38710F8A3C621DD8D66D8BF3790B63 +146: 19E35E1E785C7A41C523F88CDCD919EDC45F63783330D9033768546CF59D10AEBC77F013057C0E41D6FD0FE77DBF914D +147: 8AFA5DF52F6581794FF014A2E1ABCB05781C7F44AE6F37112B363AB13FF01FE1E8074F14466A365374C29FEB048C5B9E +148: BC9ECD12706BE5ADBA04DCE84AD53AE1B324F99C1F5937774DFE19C5EB4D6A20982E97B8F8E4E02EED13B25B8B13E64B +149: 8D02A1E318DA1EBFD1CDDBB7280F3603AF3AFA21B3D4E0727C7CFC576F55640B7A978B179EECDB8FBE896AD38E82F12B +150: 196929CF0849022CCE9CBE4EB2DAF6E5D8014C5A25E119EFF799A82053035BFDB8B05F6C125B1DBDD4E7B393C684FB5D +151: 58808D04067FAD72BBEEE4F6A355E80A2FF76EDBB5366CA43FF358A842FBFA2F9E1AF5FF266BD2E2DAB1D286AF5BBF92 +152: 4A548031093ABA730D8D99A2C1C6EC2A986A94167CF8C1EBE83D52B34BC2068A4C95665988FA93F5246D0FBACDF85FE2 +153: ED949965036F16A0B5856EA4CF69CEDA35C653BB56FD0F0B397E73FF4884B3E679ECCB19B07D6A93504E82A1613CB87C +154: DBA644B20B01E4AC5CD0A325CB063EEF53AD77E5A9E7095C1BE0EB0E6B7CFE60BF25F38CD57F2AC055D327EB6AECC7D6 +155: CEFD6165F70D9019866374AD7AF9C73F3041B932D61A41734E39AE8AA9C7A4FBF1DCBAE9B2A4E979C64352E3CD4E1B95 +156: 732C3B457F78DED89390BC461380760FBEF3CFCB9BF42A6C86ECF120C821CAC79D4D51C71A955309E33724742FE2FA0D +157: 54803568BAE2DB4F143C78FF53B85E6A9D42EC3894FCFB39BED8EE611B36BBCBED834D366A1F797B626DFF3D83CE963C +158: 35A1858E567FC8A11B92737E369069B12502ED3F44DB50434506F2E540FE643655CBF806C06F15CF2428FB408A65C04B +159: D1F9E930418D10043D0E83096CF717B79C1C9234C741C59436F42737AC73BD39B3F4B6D6439375E0D44260131B25FDE9 +160: D5B56A1A70C47A3F88C519668097B54C989E119EE9DD5B8B34F0DBC092FE7108C9D396CFC62C9322563EE72A0E324010 +161: 1578BB76F87DB309A5D3A2229A2B346DE39ADB623836EF0561348ACA7E315C16C6E31328BC70DD0B0D7D9B7ECE076CE6 +162: F8DF4C71F3623ED00EDF8EFC4E0EC154644E21E78B06C9C5ACB980480732E17E92ACFA059BDF299BB6C8351C6CC6AFF2 +163: 090DCE25595D7770753B78C410F10E830140B23D779E0F52FC451582CDE7511A390450F8B65D7BDA77A18CD95EE3DD38 +164: 5D3A56D23BEF1324B1EAE33B8255F904F7DDF131517200A505031D41A2EC3F2AB03912DEFF6BCECBFEDCB8B948CDACA2 +165: EF712AC1E6859F70D0D2CACE7AEE120A666DF9F210512F5C94AA7FB388F1DDD913A12FF92CCD2537675EAEC870203411 +166: A0E6443505B193D89595A51BCBD47A46E1B5AEB239D68B8B18A119E5C9EA1EB8863B373F91B9F22FA944C29365406A79 +167: D97DACBF80BCC76335C187DA29FF33F6D35EA8A8925709322EF3C0F6FE35D128D9D423F911EE31F1C38E1DF36046E507 +168: 67FFCF0A9F88F84B3EE85000B2DE0B7DC12A06160FCBBB57BA291DC04E14B6DBB3CDB81A40C2EE1859956DAD097C1EE1 +169: 7AE82196B46DE3E6948D7FBC7383A6F080903D6BE6E357700A87F82A964581D375006DE35169446B447537B4F11C5702 +170: 502E0A4CF125EC0640DC7E7264D9E47300814B00D4322F2F62BC1D5F1D0D77173B0E7C2874CD59FD8E056B8F38F78D99 +171: 74FDBC4532534DBF24230ED5677A920B12E328E3D073364498D80F0CEAFBEC774EB53F28F0934F787C56AB794B60BE31 +172: 3C9BF5EEC652F40AA0ECB82A834C836E495E841D337E1299AAFC067A2049C540AABE92CAEAE02F099BC4D3A383D541B5 +173: 105AC61F2D4E586E376524C488C33521C4D49D1F95B752D27F49ACD7181E8FBBCA2E0F0B543EFC0CBD32A5EED2CC08A2 +174: 5CA49D8B554D70B3FC467604661DF8FA51D9987F2A77B13DE44D7809FE2956D21485B36F1D17B59F2261B1B40553FBE3 +175: 1DD075C696DB9B07510A0D276F8BAD12225E00515D19E3B85583BF97CF82B5FE3F685502F64D91F4FEEE1848BCD0502B +176: 11A018C4B213BC67C09370C8A3D0B720428BE71C01C6EE9EF6C9C9DA8B2E1FBAEEE42FA44EE54D0F526DCDCD3C2BB2FD +177: E188EC519C6E0B8A89DE68A7648DAC6D9F84FDAA678B431794EB4BFE077901C95FAE25CA3D39D48EA0292F3F6C35FF73 +178: FABEE0B0A02BA622931A5EB82CD63656B47A20D3C0E703D5A69AFDB92C0A7EC5CF6944D9D7A141C1255D60FF9532B089 +179: 3C8E0BB55E099CA9F6E436BB3CA39D511AB9CE5674469DF8BEA4A20193084AF8561D5130FDFFBE62193A712D7C2D4B48 +180: 914BE8F0A58082B877AF0DC077ED146CCD8245339A170B4099B146476B0A580749D01F83FB52834A033A3822D12041B9 +181: A1B31ECBF451571437DE10330A6E9AB4484576AADC4DEE0B31D9C3AFE59FC6DE028275126D7882A2C225EDFE491305E4 +182: E4DD2E805A5BDE3DCD329ED9D35CAEC2D5A97082966186118DC46BCA7AEB1EF52E0C6007CA28131790838DD8C00E96FB +183: 785B81A972DFC6A4982E0BB76F90F26DBB7BCD2D06E872304CCF6AB2D639CAD85FB29124ACE411EA4742468A6663EB2A +184: EEC3CBB5AA129C7206A32A176482C9BA24FE60E71B46F7C3C11FEF8EB57682A3732680E6541D5878CD6A715A48D75F12 +185: 254E279B7C4F17B911712BF7138E2C6933815BAB18661CB47388FEEBDCCDFFFB6AE8B4B88072B90074704EB7EC567843 +186: 9A8CC3FF0D9637220CF2B4AFC9A8A6CBA4D0ABEA6A0BAEBF151380848E92DFED8C0F0E57B6D05095EEAB0A58DFBAED13 +187: 349966E1D59BC9B32E1BEDB050354177868FC07257A3A1800F0E711AD00AE388746DB1E4591E3ABBAD8F418E1AE627DD +188: 84ED950BE54768557475E6B1A256C30F444E12340C29485832439BBB9CBD219050D184624D6282728D4AFBB98CE4BCD6 +189: 2A7CA4EF1A9356E853329D336B6E7E033F2CA13677BEA67CA669EB7C78DBDDE67F9E7D9099C68F34E07B96DE4155AFF2 +190: 7C7020B0528F1B3F76BA258836A89BD27429110F0AB730FD741FE9EA2714AF827E71B731AFD53A293328788292ACFE23 +191: 91400ABC089F8888DCB22880B87A380FEFDAF81F237D424F057E5C4C8E3C8EE4E423930C1D3D9E16199ED82996BE4232 +192: 412979E13B3D143270BB41FEBC12196B981E99BFD6687B780812F409C78A5E2DB7AE828994B60D26CA4A1F7A3A44C64B +193: 02BDD417852D9B03A37338549DFB6D765EC4CFE4C2385002848BA4D46F88053FAD2A39DFF615ECFAE0D41F02E5877251 +194: 77845BA2210971E362DC117B1BB13D7DFBA62F81EEEC7068D3CB9CD093DF535448CC357ADBF0C2394351EFB07C3E7DE7 +195: 0F43AA1739359C14BC5702322F193AF89335887F9175289933B2BB3F00A777D1D1DA74F5D45FC43AA90C9FFBB0CD580E +196: D1D9A7B995B9BFF09252566D2079121AB12B0A5ED06014994464FA1AA18CB1BD8E7D5E07E1C71E2EED9CF081A537F28B +197: 67DFFE8A168B7408B7DDBD10BDF14F4F2244FC904DEC5850F5D8302FE35AD1752BAD2DE50449F9C12182A2AAB8FBC9F6 +198: 030B5E833F6D8703BD0C5E36354387AF833F466AC812D4E1FAB6CDCD3146FFE3B0E56722D671FB85EAB22CA5CB0309BB +199: CB992B3785E51EF3A32DE88073586DB045F356F18A09329E82943E29A12B2D1490B386D8CEBF7D90FB492966989A73BE +200: A1D337D363A0BD8A0F2342351519C62318A120FAF88F9B90330845DA682261C64627B67D2F533FC48D2BE394DF8F4F61 +201: 319DF6326160C7277A3D3C65995BFB729A69B71B40C149DB1241C0B2376B4205837B5770805C86104677917EE5E5912C +202: EBABE3BCAD828A9A3D5EE05C5EBA9605A67E1ACE73AE69F20BF435C3A14AC63E43B61021CDF3FC2245A14FC14A7AB32B +203: 1723D844C0558D58EB3EEE3286C48C133C5F6C1D8CA512F2BAF1FAD7884D4FD5C3000A6756DD1E34E83DD066AD2BEBE2 +204: B048BED188BFFB8FF1B14CAA0BACE82605AEB1C666283FB7A6FDF216742F9F64A89C50B9852B8119B5FAEFE64615C241 +205: 7FC6E8633CB9B16F553ECA3C75C0C0F7B610010853EFC94AC330D36977EA8722B970DC264D5FC4D69F39105E7AA0EE3C +206: BBC6F0E0158B6DD549C5BADE0FDFE415747F1FA2D2A85CC9DB758F34998FBC8C8D99D573CD948EC768540B363D67C4F0 +207: 5073FA9E162BE773AF5BA1CE5E6FC21F2F0F902C80F09BBC3AECAA6CB1867DAE4DC011D1DB987642949E8095909CB984 +208: A641BB0E1D20D5DB0C5CB33D35B73ED83216F2F5DDD5234A0BAA3B209A39E015B7245C40F9F372E618EC73450487B54C +209: 948806B7335EDCC7C4BBE751844DF5717457B223C7A3B81B57AB3A949D0A726BAACFBA228BF6C2CF94E942F9B2F1A7AA +210: 0451CD5EEA206D50A7897F495D648425CA333158C126C4DBA44ADC06447A51D3C7BF2D4D81779535CAE29792C7FE5650 +211: B4227FEE0A32009D60C9C30033C12B7143D4C7A1C25F39F3E4A076BC4943992AD299DEB2C15E27DF867BF948DA27C009 +212: DAAEA18FA433CF3E117F2D43303139D3F1D8C3BB8AE8EFB30B44B9D5D4BD4E553B9B6EB9019CC4E1AE5D0DBB6C23A102 +213: 4434C818BCCFD92189A3A466D2757AE2655BF0D6CD954706C85220A33B95B184EB560FF3CDDCC4DF557E427E60F9FBFC +214: 6AA3B44FA507B6D704A66B4D7F26CBAAB2B400C6BE0A8B61B50EE617A16C2C09CB36E72FC309C6E4DB24961B1785CE3B +215: 63AE9C02B96B4BC456FE5CB9BA35366DD69E78DC9CEEC376C6780703883D609333D45CA577A982A177515674B975B658 +216: 3B5DD4CCBE8CDF32009CE29FEE4F6EC7CCB1471A3F8E9BC9A35E8CC37F6C56957B757DA4C3204F9014977B93F9E30DCB +217: 04A6528CDE6BB9F425132CCD4AEA1EC6CEA482249E5F3782B000FB071A4EB2434597A7FCE2A364A9BC9E0643A8403DDD +218: 69275CA1F9F102925165A568C1F152D25DF8820A6F34595C4359159070052FED260C55FFFAEA2116AEE7A63DDBAA0160 +219: 584697C23C63904709BEA89F055AC592DF48034F908C9F06C706A51C3F6BE5F0F2A5B953AC2119FBC0855B785326C06D +220: 04221F0A6C4799F9CEA3C1D9E65B9F77F77C613FD114135DB019D8C497B8899513AA4B499E720CC11AECADD1AC071DBC +221: C7B878613C2F2ED10C8EA413970B124838F11F0414AEC89A3825DDC588629A8049E82B461A23F25C4F93E5BD11C184AC +222: 1891E7A51768E05BB1D03A1EC1B844C7C8EF77C433F700175998B2D8E2EEEEC4618F00003793C5873655E093048B674E +223: ADD2B81466BC727AC85DBE258B566C4DB56F6F7D81D7A4E43F86C125F2AB2E08C648E628B9CFE440F8BC06FD5D861D3C +224: B3684BEBA86D275745CEAF0922473CA581CEB7371C5747EB87B407468006BA50D69F9BD8BB7F214185CD0D0C548C5432 +225: 0C783882FC826917619C07FD03FFC46DE6CD87BDFA87F1FB872989489C32FE74E8C5660748E1E8E9AE19C68B075B0EBA +226: DF52553B4F7BD148574BB47F61BF8F7B2FDBE5B6963E29CD559F236BAAFC3DFD6A7EB5EC9968E0C2B3A453F982F16AAC +227: 45102671440B04027B1F9966C1013AA351CAA3F3CF42C4D98F5B2D030FF37836E9F5865421D7DC8B037644FE53C6B280 +228: 247396BF60C0FBA27B245CFCA061D1F6EC50CB87CEE54E8C4A7186A07745D255E4EF9457C0A329AC9E3FC913DF86A4CA +229: ACC5998C464A26C1719E9B17E1B8F5E3657FF0364C46FE87154DCD1C95A84734214D2B81CEA8DDBA501975281EF4EA9D +230: 163F5AE385500C1A6EA212D6925E48CE2189DB1DD47F7F2D2D889272D17449A1C33EB3970A5982EF2FE5F1255367C33E +231: E8BBFF2C5CDA88CB60BEADB8D04B88795B0CCD89057CEFF1FF588A169363AD453564FE7528D1FB7148845363C3E17824 +232: 5F8671B7C62A5EE9717FF80EC2AA0A03E557A2840C0FD0B59027AFC834C051CC9B7BEFFDEE3478165DB9CA303E2D874C +233: E0E4DE22993E4A6B4884163C678A23AD6349DCD4C16B9041D01F8B3FAB1E8D8B07DA78BFEB57F8C235C173B2D238C4B7 +234: AD6F58BFA15FD0DF1191171F86F2B4C8729FE407128ADB4FAC3404E15C04752F2A4B5F4BDD488378C56FF8D85A38E583 +235: 90C5A75642A1811D8FC1ECB84AF4904C6D9E613353C1B9ED0FCA37D20974CC2425052E2300738824BECFDB981AFF06FD +236: EF73A9E6D23CE43508400163CE6F3E8F7076CEFB94E549EB6116C2557F740D66A1727AD51CA645A7F9022912058FD262 +237: 99FA424E413A57DB2B1B851098FAB1B6D3337AC7FA85709121F0BBDAFB3EE291F44092EA7EB28E9BF0EA0691AA531BFC +238: A1E0A088A279E750CEC429D0AE320B638ECBF9EE387C65C66D2231C884D844DCD438D4D4E052B8D76998A444E0666629 +239: 0657FBA0E7A73F7525505235120C44AAC6D37CE974FF23F52872D6ADA50DA022D417D8DAE40E80336846E8CE211D5AC5 +240: A72ED7917F0F9D0DD888DAB10AF9091A380F518D5DAFC005D1EBF0013F57A7452AEBA98913F509509A02665F332EE255 +241: 74CC959DC6CFB31CFBBE9CE8ABF32D1629E0F578F9199B9A2E90889A2F032919923142AB32E1DEE0A53ADAFAEFE0EBF2 +242: 9E4D463D2E3DC2B98CBA40EF84B022A76D01926D8DE6AC05F995C07C5F07D01742C5410B240240459280D7D278E8BFEC +243: 0D74C427EE654E4790C7118272998C131337D0D0555B68F488AC7CB8DE3CFB461B0248E78340D74B828C80CA28ADF478 +244: 952F274ECBC66B68EA74CC8534A5D7EDB219B755C91266E5A779EC22F52DD2EFA9C447DD311E71C90E1419B4B2F3DAE0 +245: B845B0A56AFEC2FB399559FA77C4835D2BC4C3F8D62BEB1C45462BAC661D2E553B43D0A86073F0BA5AB85B129ED20B1C +246: E65B931E25101224A6933FAAE7DFCF22FE84759937F5F3BDAA90D9C8E8ECD0BFA1777B99A77E3232E38917F9432CCBFC +247: 4F69FE2CB97E9233BC873D153ED9D61B88C20FA333BD4137A532F4F703A323FAC6F8675D8B44EF5FAD2314894F7D60B6 +248: B36F43A6DD2917A1AA0C6B566599C274701BDF03A5B7DC65E5E9F0ACF882786F07989B106A50D0D89629136EA0E26EB1 +249: 8DB7B80635C53DAEF891B777850487E72B67F57576EB05F708786F7665F1FDC2A78F441636569D1E84058A43F0243A1A +250: 14A43F1882AE0214F56819F4AE9276499D39DB4A4A939275DDDCDDD80CB6B70999E6178C4EF295E69A807EE5FDBF9AFD +251: E5AA44CEA67F0821D4ECBC981F258837A243FD901653D484BE5C24EB7F08E0BF33525EE3DDF9A89E1263A853485B5A02 +252: 0191F0505CE5512FA08500BDC090570F0C430161595894528FE7AE5DAD8726E110B0676181A228A7A90E21B7B055361A +253: 76FA1230972E771661485546D6CE556FCDA23B6DC0FFE94DD3BF7FF13FE9B46DCBC8D8FFC617F35687903B972FA7EA43 +254: FE280E1191D21CAE12EA3B53D77E03EA4D96108D35555CBFA9B156253A011ED91B857B82D644BB94BAC8E4FC4E0142B5 +255: BEDDC3C0E168A4B14B023DFC1AE07BE9A418678494C2399695EA9B17843D373077A708F8C82F37657BDC101950FED664 +256: AA5D7EA1126BF16DA2897AE036E94D1F96875AD306B19910EFE3F17B7A98F9A4163E4032EFD17DDBF78FE3321047509C + +HMAC-sha512 + 0: D29B9E3F87809686F34109FBC718D6ABBB09C278CF05A206ADF21463E1170362122E58272A31679720B254CBD63A7C6D696BF9283F9C6897E7D792483BB0388C + 1: 5EC18FCA20788348244720D58E9532B4B699E78D48CF7D7BDD1A4E5C61CD09C075EA7F112DE379FBE953332C6A7D6273B3F6360BC07203A5175FAE618E4A2F55 + 2: 293D275FDD5021716117D2B85E6D38F8D60D4984BC73E2D8D7EF5942CF1287B65C0675E566794786FEA18AED1192A024FC4B3E0505D91E1F91833B210590BFDF + 3: 8D9E222D6B16C58B3862D6BFA556BDFC2A4A152BB2574C2294D5381F6E38FB681500A6A19D55525B337A467A2FC30DD1684832FFF92AD071EEF05BC4F4399FE9 + 4: 71E7028F8C4CE9C1EAEFE459771528D26993E180E616D68355B9C618153AFF2C0E9620B151C8F733E71180EB87BD773A512B945AA353029A8F807FB2A8FF2264 + 5: 589F462D37095693ED0C1F3E0DCB892BD19086FE033718911931509EF6195AD17C79939A87665889EFA6DC19A69BEC6E7058531552832CCBBC06F1BEC70D1736 + 6: D94FC6BDAB3613271522BA05C998A6D1C57CAF0E6EE929651762F257E7EEBC07F5CC7CD3D4064A2755E408B347939B3927434556B4ED49CA406C21D1024E6D80 + 7: 4D8A886A89E9C60EDA3BF0BC512A295196C3F62018936DDB24BE9F6AEC7AA9511B33CBEC8A22309B6389417F4E7FB0489981CACF03DFECF7D9FE5B91D62BB719 + 8: D0E00955F0FFF98ABE885970EE44F1B5D4C23C205C64B681381FA13C543106B2AB4E762FD71F47008B4C429C39ED3D66B3EAEA946674F08684AC99F957F50416 + 9: 4F623E52B5FA2D556D25754FD00BB8429356FD75FE2EC57EB4BA4E25CE03C5332D3A632179C9FCFFF140E6B443A4285F4A7CE881E6D3EEC4FB0DB26C0E2DCDC1 + 10: 5196EE8D442E5308F9D8911C87050DD3C4842D0CDCF55AC554412CF096EDA94BE1A251743AD5BC5F8AC902A38B66D7D57C90C29200984572D57C04F64166B803 + 11: EF77019B0F93B1598E38D3B1B703B52660192547353E7FCD5A7C8525DBB516970D3A6F2A94729D90A5A34CEA255F310C1F46546C2A08975AF477DA2F3689F17E + 12: 0A77531D7081095AC0D0ADF2B379D3F820DD20CD89610917E287FF57BCA5DEABA750E1E075DAACA9CC4DDC74732E6F7BCCCD3671B6DD27503CA855EACC63FFB1 + 13: F1E04B1F7B09DA270A44B62DBAD2FC0160BA1D144D7721010D77ED250A00986932CB6652D95B4A977494F11AF7E7FC82A70DFDACFA11232D653B1A052820185A + 14: 7BE1855550A49FF66D6D395DA7DEBDEAF674F1AB192DF82D74F6BAE8088F83EF1471F413CE00A404486213E41B42CF6C4F7FF1BFA17A1E28928B7179F0A966EE + 15: DFF2CDE8856D811494F559E9F4159065A50B1E82961628E95F04D595F670249A2B71C2625CC1CC2B1F85829255DA007F0374363EB749E935BB72BDA24B8A3F70 + 16: D2F7FE57D9583EC1AA733403527DFBB118DFE07B2A60C43039FB238A7205A053E0496AD0F3C1896090AEAB3088283C8FAF272D1D53B5F9F88281E0A53FE7F8DB + 17: 963F629ED8F0E7D6D4CA4DC8A8B57C825F726380D0BA9A9857459491BA82F64A929EC4ABFCF79374CA68BA812E3A83A643D05454E146E9F4103D17E20B8350F5 + 18: 1FDAE69CA4A9FAACDDF30A56B23F14768EB7D5616F6666B6F01FE5E216825CD4201A69CE3D2D1D2C3D03246BA7D32ADCAAA4A7D03B9AE6AF4CFBB474E1717BCA + 19: 2532E98B6D91D8D658BC1A1FE41AC719D648D47BACB423C031A8E2E9C25CC6650D3E5DF8046BC3532875F0C8DADB38AA911F216E6741E9FAD700D31269EE5D46 + 20: C81E6E9F4B75A4EB2B903C4DE28CC437CD87BF789F6BE60EF521491CC7E44AF26E9EFAC55961135F79B3591F5F7B92ECDC9917641BDC34943C6759AAD9437498 + 21: C0C2B9478F956800B64FA408BB0E077FEF48DE4B146926B3C577C00688829FFA6540AD7C211A807286C546F7D146F95989E77B62F5E14D62FE0C77C85FCB6CC3 + 22: 980D06C1B27EB2EB15069566BD1BD838FD3DA453751BEC564C05941C9BFB9EE8443EECF84CBF8AA7DECAA294C7D1A3FA4A39C20A4659DF332CAFFCB2863A769B + 23: 70FB10E482AD19447CFAF10EB9FCFEE67F9DF7164B2647F19CB220E7D83BF892AB7B5C5ABB73B779522012BFD464D9D1B18C37C3F6CB70EC4106FA94F8CEFECC + 24: 7AB19BF67380012D3A53B93AC15E353D477FDD1E2E8851CD5AB5F36EA0C8B128D3193934F837D23D232F44009AC60DDD358AFC8D3A201BED3EAEEF74C03617A0 + 25: AAFC1227AC42CC27BBF78FE26B3FACBB7B15360891C8EAA8C737AD42C00971D02B3A07CA751774D02F402F7E76BE08E2C1241EB66242DB5E11B342C22AAB9FEB + 26: D8CC3BE5B48C7BEE8522BD8872419932907B78392B7F2546788477C858D0C7BD772985C0B0D202AB7E69AB5F4E1A0BC848A512FDD79EC29F19BC4BA6D28DEB07 + 27: 6133D836D68C82658F6263F794073CAD9029F20CC11D0A6CF589335B023CFD66D708F09136546C6C08769139363AE5CB4CC2CC86EC6911237ACBFD8B0423E377 + 28: 833DAC9CFFBD62FF0749391A42324E2848670913890754E24ECC29D4738AF00A78134660A20078FE59C66113787F4A3E6C0E783740B2F2B2BC8D36FE4EDE39ED + 29: A2F3BC0DF058506805DCF5CC3006CC4FC4085FD846C7A7A7DD3A06CD6DF635359F4FBE90A676DABD7F9AAF42577C8E3B07B63B9CEC8A9AD05B38D16F56214E8F + 30: A49C3BB487C561E5AADA4FBA2D9F5B42681486AE2DF56087DD65B3D5E03C625F709299C84C64A68D87C92A4CC90246D608E692D1FFCE2C099348CD0A19407C2B + 31: C8D7B7A7FFAEDE88963B09A09ECCCB4CAE77DF9D8D242BA19F6485BC7775308E5D11C78FE9C46E609F3AF070F3DA8ED929C103DA1F25BE7867FD4D3E4F2757C9 + 32: AD4627AFB02DECFF956E612537F011E82CB0C202A5A11AB7AFF55A201016C02CD21EFB4EB197BC2D13D272C6A830FD77F534E800B0AF1E79FCFB626ED6A0D6B8 + 33: 8D4E232D9614EA1194E60748496CFD32A4AC249BB8F08E55A7C9DFDA708DE90D067FC433EB9DA2A6833D43BBA8E8DBF31137A3C9B26903060EF9217471E9F945 + 34: 4CE5E4055F10F1D2182A7892F98206D9A120FBDA3251036B7EFEC835C95B4D1FE0BE3892E2363087D01948AA426AA403ABE1CD79F0AA851E2D1195511C7A85AC + 35: ABD65F8E9A2B39BFEF6EFC9A9EDEF6572489AE82034EF3BF2AE5F380026FF4CC40AF093F0408445735C0E6EBEF5D7E7ECC13C98B59807AE01FFE1BAB040FD14D + 36: E8C687D7AF785B1E547307875682ACD82FB58A8259551D81F309C923C2B1FBAF5935EE059B89070B8420F71EEE3BE7B1E3B55B196872F06DD1FB890F6FED11CA + 37: A344BE73E6585E0CC31525BD6D4EC3345D7780CF180D0D5C2D5FBDEDCBEA050A958FEB13C21924E311F57FD6A498756146AAC58412B98E4D2A3B29D9B77A9F53 + 38: F0A088CC818F76A1FD6B5D707B114BDE24245CD55E48611ACC6AA497A0CEF93768501B5F280AC518CEE48C15373118BE7B72F8ABB2E9FD3526DD1C18D9CB2545 + 39: 4D56D5C9222BB78E04DC9346FA9C4ADC27AE08DA3E34F490A13F674264896E58F9E9839715F633C7195B40DF722441275C84AEF162B513E673809F7874E7A124 + 40: C4B3C9E8140F0D5589E326916462354827E491F3444E0C361512E6E761F5E24AE1873B238B73F32F6BF8F1D1D8FF9437A01DACCB749282E776FF66151A4F7E19 + 41: 7B4E07BAF338DF6479E169EB6CC64CFF88167958D44C5CB6606964B7F9ECF5F3F1B1F695C63F2BD66354722F81EE4BC90B9FCF5345642E264C66F6950CC8C481 + 42: 8571A8F76A1D5DAA0900A03E236FE965D085BE6035B7C0601EAD338106BE7DAFAEC82F7C3D8AD346FF749B6DAFC69901A6072CA089B7A5724C75CB0818640F7D + 43: DF516D84392E571C3FE39F4A0BA5D16D866553644B4C4627D3513F0A1C60D22FC5AA4276A71CB37BD6D6AD05A12BF812A2D5388A606583B78372B84DC567431E + 44: 535AF3C73B479B61B8B70E590E335DC4C1E22DCA656454213E1FDD46D026B6D36133BDD372FBFBB27B6DCA8E487F4A54BDA8C5F67B37C871653C656DDE9524EA + 45: DBFA27964DC6A80FF76112FC6CC02C87811DF1ECA3A8620A5030C600561032FC374A6B060FEBE0ED67421D9217D2719F5A55621736FFFC6F4F26DD4C6049FC09 + 46: 6F69BFD2C60AB1554023A6A2094D30CA78D364501F7813A2CB73DEA94AD4B94A0EDF3A3698D6A30C8A5E764B81F51CD0CAEF0F996B8C685A345AA630CD10570A + 47: 2769DDB3AF3DD650BC381D7B10CBC4353699A2A352E57FA5D5CC4FB610E498767F49104ED0F4E06E2BD563F7F8045212F5B9C49CBE050A1662F2262BAC4053CE + 48: E50169B15772017CD9FF93D1B46AF273B375A39D174E3B8621EAC8EF968BD967E1448DC3B2C72A667EFAEBF2B90D4E6640698CB866075E95817719E0EE61DF30 + 49: 4212648E8F9ACBDC16D48CD7B355884E0817A95DB03BD9B8AC5B28BE6371D8AF83546DC82550B8B23DC77F6D06211E3AF3B25528BE686CCA1672C91117DF9762 + 50: 33C71EECDBE503A6AF72EBA8D2B9AA7AB8FA8DE536C87643ABF1BC3EDA535BBA64A8A7F4BAC90ADB7D8C926DCAB1D7DCE15D356C5074BB3EBC7B17516671EC8F + 51: C8EE9E57EFA859DC5553D03402AE80B84B1E0032CE3F2CAC43F8422A80E3EF59126AE7AB4893735F9C948CD9FA8793571E4582908DA19FC723A93C7C36F79F9C + 52: 7CABE0F83E90CF9A497DCE45F14F9926DC714DEEF05A1A0603F6436E134FC7C8346A19CB92DCDE69D794B38FB22233577BA3905C94A7020841224DA888B9BE1F + 53: FDC20554A15B71BA62F896DDC4F8B354E5D2434B0AF719CCA7DC56FBC9BD280B0F80136C4336D605C7C26208649F38C1DD0004C6E0E787A91FAA6075051FFDCF + 54: 87387F89646B4068038E011D7E02C353BD5649F6DA1C4C46CD9F7D69EB3A2F6EE84DD42D25B67BB81666CE8F92A5B1A0F3EA58D4F0B5B6E59EDEC86B43BA0CA6 + 55: 6D0210417671B66D59B8F28CA0EAFDB493C30A7D7329DF29194C53887F05EDC2C3F35853898ED77394CCC650E8D350F69598E3AEF3DDF540DACCED5BBCBAF6AA + 56: F14085036C69398BC7E0CD8A9D4451A10B080E7CEDA5582ED396E5D54441125EB3EF6EDE4534E788DFE6DD3DAAA204814097987981EC8BD8E39E8E8B35AD8FAA + 57: BA67FB4D7D137531D3F4CD3D91975255FCF8EABBEB97EF0FC7C21C4E25FD034658C63881B0AEBEECD2B7D15357C14542D26EBA3ACCA944EB4C4D7E44E9899D42 + 58: 4546585669E343AD40792308AB456DF623A6A23CCBE64B26B953D6C461460BBA7A3FB444481BDB3F7FC8D5E825F2527D2DFF193356CB3171CFBB56C679AD1BB9 + 59: 210F8AD68FCD10BDB8773194FE57EFF566C7E65BCD82BE6196DECB40BF39774691AC6BA718E4B5FF0DDCF2C0510182B9A114C6F0117A0BB0E1AD585C69D38D0B + 60: 29003A048ECAC0613CFAE8EC8757F5E5CF80E9B0BBF538D7460765FE2D6B56D6251ABCFD42B56D64B56D8F219868DEB42B968E88D3F3BE3A161DCB43EA98349A + 61: A308F9E2B60D0093A7278B0645A471408F58B45B3683531179F34931D06A15F4A502F2F7E1DF8B47830F65387BB9F102646058AB456045267F2DC403A1D9A6DD + 62: AD484DDC270FE74E68620AEC882E86320D0D0753E713D9D5C9C7FEEB894DD3FD5FDF4995DDEF87B1126B36E92618331126F5852AA8C0D44404BF9F77B780595D + 63: B4BA7B2F08BC0FC901188B50493FD165F659D3226227E2E9892BD70B02312C12D195A73AED3A4009618E6E74799DB158D9AC27FCCA9BC682B09ECF53BD368C46 + 64: 0AF65ED93646AE826C79BB6E8CD193D5246BD00B0BABF8425ACE03C845B9AEE428045D5F8267F3EA86C433F1A9DBF4AD1883AF164EAFE02C07CE43079668A248 + 65: 65F899BE2C5E9879F6A3BF7B60E62591B5DC5398283229E4FADB1EE78FFBF962295C427BA0D50BBCB9E2F1DD9694BD36CA598BAE7C2EF1F4D0700DC95BB66C37 + 66: FA9ACC46F0841962D6DDCBF5D47BBEC43A0E1E9B2A8F8B7970E2E73C06612FD95044B8BEB58C71B19AF4169B7E6500500445490F80EA4E305B6BB00C7181810D + 67: E9AEA6E12F881A7AEC3AAF428BBF0DA3138EBF69C6B8E52621609AD340D6537E4A03E2B099B735FA82A3D300F782606EF58598683D4ACB0870D5130B4B3142FB + 68: 3558ADBFD411DB8436A1A8B40420EE9C274FA153AEF891290F79DE5714130A50C70EB87E8A901D540ADCFC37E40EF44592822F6ADBBE8E5CB4EC89909633DD7C + 69: AF3852A0B4E846B59A4EAEB7A7A451311B1E8F554042CEB2D253F10FCB3067F9CA927C7DA3E57BC9C99E4E7997856B35DAB0645C194AE9F1FA0A92BC218CC9BC + 70: 6BD90F0F8FFA39C2A483E8349D2A29A96AA7F3CB4B4C1325FE5162988C9DEE849B8E56BF1423B6905ED3FC6A82A067F850372414E2A4A7E5CA379AB80F1C4F23 + 71: 6433885A8A39F2E4CBB36191A038EC3E3227BDDDAEAE24FD396481332A9AD7BECCC4E9BDEA0C8A7F33180ECB1EC1DB49218D17C4325B661967ADCBA25B341649 + 72: C3235054A1FDFF2C0D218C3B54EE6A58FA5AE99040A64A90B9C8DE601B80A7C130168FE7484CE1FD9FBE22E6E794161826730B63DE794EC4ED1D653E40B27F7A + 73: 89F4DF5AC626665D9791A1E1C30D1F206D89C4B0C59916DA295931539B0A607A1261B4EF022CCDA6ECE02E99449E252EAFC8929F5074866C3FF59CC58268E2B8 + 74: 3F1AC15A90C38AA964518F176016FDC73A85B096EFD1FCDCCF38F3EC692635BD4E610F1B3314E068164D02168F73A307AD549E1E7EF07DD374F9697DB6A17447 + 75: 4FE16A3BF0534DD2E4DACC43E221179C9B61D7D50DAEDA4DA9C45CCFDC76D6FA96EB3CC1C184DD5DDF7DAAA413D05B2FE518117E2C9A880726148C7AE6052160 + 76: 1EA870E13B7E59B97045F662682F29DAEC4413566DA341468CC9F5CAB733D1897BBAD8E9520B85C43DE33B9B70880AB774EA636248CD0A1626C9CDFEC3F1835F + 77: 37AE3A9828B08A055B2E47A613D25A8D43D5A456BF741E7964C0DF4AEC6D8E5F3EF874F2B20606A38AFCBD307C104DFA5BF40BFBB3078771436276E777F645DF + 78: 48CB9B779D37299162D2674CE2C2595B2422071917C28AB48781DED5060E76EDABA56E7C538C3182F9D960DC21928E6B3069D510046608C976D7A113DE54DCEB + 79: A565459CED6C996C04A21FF0DA10A7F24B1DE22EEAD7FA7FD2CEEAF522A42E29395F771140573D684C94F61F19C771DF68FF8EA0FF727C55294C70E701C8E426 + 80: 3A0ADB5479E65BE1F00462E60C8F7F74FF5C996680A2A4CF787B5DF65BB2E82264004E396AD7EAFCF8A201E03AA950D42B9A26EF2D24FD2AD7CF57CBD08AFFAC + 81: 6FFC799781B2E9F3F573651EB2DCB0771073DA1875CCC3D2B4C6C06F43161195610617007CA9A943B1F2B001E62518EBABD4542E73CA131E20A167FA6E8CAE44 + 82: 79C9E349F1216FCB295FFFE5771EF54A024306CED9CA111DA3DC629722DF7FA5F0927152E4401E0358BDC16D9ABFA02C709B1C21F6D86905B0CF0D6EC9FD1952 + 83: 6876CC513300CC83BAFCAAE5DFE4C4A0CB962079523ED475B19568243A63B208301335BDDE10CEC90CA816960013E08271F02111BD18FD03C1B941543FF4A579 + 84: FB5392BCB60C1329D3FBEDB4DE1131E7B89326A34F34BB099A7EBEE42B985682F52412D3F0628AA72A8C2C46BA3FEA08D5765264E48DDDBB96CB598C9C0BA93C + 85: FAE655D7CC2FDB54349870B199FA54CF47BEF2AD98021FA27B968AD4C3AE477C6B2DFA9A10C75FE275D5A32C5E9FA06B03D4C908184F49FCF15ABC409106E951 + 86: 9B15DD192392017E2F4DDFCD30B7AE58546AB71EC44DB94EE66CA3419D580AA05B5F10E5D36D9E60465FB8F56665366824B5B6E9A63A13F6E83A026F5A8E0911 + 87: 1A0EC6F024130D24D9740E8037C78A176D9C5933C4073DE3C6B0536E9F7CD20E0E89705953DAC9CD44C85EA059ADC496A7A0EFC40F187DF676D2BC83F80BE983 + 88: 5E9683BD68FA16BE904FF617510AE99249ED3477276A0B410B269EB2E03A3505EDF653C725811AD9DCD7FCCF6F2411980784F4BE7407D68C02CF6ACD21FA1B52 + 89: 47CE3079037E396A5B5A1A3FFFC3C60A138AA2C6BF4FFF26D846C7E1E84E31A26270AAC5C688DA7A29DED589018BC349E3247B073B765FDBA4C8BB271CC6E233 + 90: 280FE2B5B0B72FEFA48A9B6A1B0A3529CAC9D6338E2083816930B14FEA5B21088B1009DE147D81FC7F29B00BADAB32B57E15322A6180D713411F559658FAC715 + 91: 527C2E33018CE9895C3F84BA5C072055730AAF767DC82AE236F1F7C5511FBF2CFCBE32AAEEFEADE38EED4C0895290D0EAAB38E3A5CF7B2462675D1E6B26CE814 + 92: 8C0E22F5BE099CEE31C816A0F5DCF9A548B0EAB55AE7CC127D172AA5243A5C73B5BD3AFD77C89370D51460CB7E84F1DD15774D1B8442C07AD21A3B128688E1E0 + 93: 6CF00F05A9DD7EBA5F1A755987F5678F80AAAF9B5FC44D6199100C062DB50D2DA89096389DB94A6D68BD8337640BAB60AFC8793E1A909624A4E149AECBE415C5 + 94: 8452FD4AAEB1AF4ACA8192DD59926E7B0D7B295B8FE18DF4DD21E7C7ABE8F4ADE7391753E533EDA2EFA13CBCD96948ACF26B658F1E72390BBCD7C1BDCE8FD650 + 95: C4DBE8DC875D00FFAE2AAEB3E0BF1F01529A364454D56D329FD493D327287F3E34DBDF2AD54C5BAC5E6059F5897D18157C7DC846F15F2CDA1B2F0A6EEAAE58D5 + 96: 6C88BBBAD961E9DD1418E9F8EC69FEB443176108F56FA2B0B686E93B0E5F505E56302994FB190787EBA7CED5EAB69DD24CEC39BD566D18ABE337A31414991735 + 97: 439ACC720E8CD0C4A119B9C318FBC543CB7B35FF12DA190D82A951970248BB47D0DA2171A7BF850A881E8767FBCD542039E483974F18532FDB57DF23CD18B1D3 + 98: D71EF6284984442D05E8B6B1AB636E0BA013A8D70029F9F1B9BA7927A582D5AC6899B9C8EB990CA93B49E460AE140564D40467A1368FB4A9EFFED4A467E174CD + 99: 8B5AD2DDB4F8C044AFE2B0216B7E7D830EBDD285E4D992CA022CA2F59644806D8B7599CEC51DC73786D98B7B6F7C10C3BB7D4CEE3740FA42DB21BB51A1269611 +100: 28CA7AF155E9E7E1F5EB64F211F254D624C6C42935E27A91745F2AF2EECFDCF1DBD5896F60520A527499432DD3D0F3981F0E5BA72EF113231A0319467BF5271A +101: 45B69480A77AEE3D83D39A38717EC1CAE1634D2D50D05FD78F70309DDA566DFC160FDA967EA6ADEA8BF45B74557DBCAE4D6187DE1BB82A053CF84B4217F9CCA6 +102: BF46E03CEAE3211FEAED2147B3F2909D406A767005F9C8A5CE6139133D41C2812D3225123B3BF0792288E4BB5C8B5ECE9BDFE0F8FF097DD64FB2CCB964FC9862 +103: 3CA25AE24E0D847D9552FD74E1D6FAAF91736603DEE98E51922A2923630D7CF35917916A1DB23A758E7F067F26A5DE9135871B3DE508CE4ECFEBCBBA1A958C78 +104: 2C4380BB9F29041388A0F8292D97482E1E96429B79162A19F01918DBC2DF0B36244ED9E7D015A20290877ACC4D2FFB14D236CE7FC92ED16C7C57012B0CF6DF70 +105: A0020193ADA7F57DA648C1474731F145E6A8E9E7F9550ECE1A841E2D735B18769738AEA78E7AABB8ABB51EF08A34C187478B4C5AB5BFF4932E97F4E246C60C6A +106: 60E81090C365DA5E69E2FC12256131F134F561C7A411F51F72B7649727C9D7E99795D18D1AA54D09F6B2DD7FC556512F49D582BA6006D951D474039095F3ED07 +107: B213DA3FB3ABD16B1CF5CA81574D78649382A6CFEBA5A88C0B8DD40B1C6E18520F145968C342DB13A2B4B2659F4F865E8CF50BCF2138A7B09A1FC190676E1895 +108: 6862BF8F73054DEF42EF38C4A362ECC8F13BE7E705573D8E9AC6B347EFE6A218950A5AB5ACAC3607C0C94301E0A085BFAE7DAD5E1863D469C113B790C234A947 +109: 2D7D3040A495F8C089C67FEE236A07C7D3361D35271B4DFEA5F17C7E80B888EA339B936C4475194BBE35DD9AF3BE112201AC21C9F5858E4F4C39A0FCFF0EB31C +110: 1F995515755C98C5EB95818DAF0C55B51192BD8D752FA35EBBF51176F05ADFDC32E2FA845C1821B6110F7EC1F1D1EA963433194BB978285CA4344A5F989113EF +111: 3F5855B07A4288497533924165E7EAD3D91A16F5E832FB341F5373C118D5ED7E0EF8D837FEF594C2039F08A7870EC1C2770B7C4E7185246908976B62A416DE5B +112: 1541B5A9C84B684BBDB543F77CF384473D007992F37498F07709EE68033E41829E29109E7C77E252C241C78AF41C790E40696206D58B2FDEE768E5B321362F4E +113: 6DA9AC8390F4264064947684F53A1ADB49314E0619509298CFFEA1729A944990BE2D4C0988BD6E8BD1062D574879218ED8FC4801877D637ED3B5383C069A29D9 +114: BA0A194D5078019B21910C37AFB81A890C4FECE7B1F4E722CF855A6F2F8B82E4EAD37B7B58C07ACEF1EA2B76B146811732EBE1BC0F76A146207B8213802DFB28 +115: 20631BF1D6555C7BA761B0581BBCDCA5A7B1BAACA1B3D3E5B4D70D0C9B0A279BAF00DE093AB1334ED5994FC17386D0B2BE9E0FB67AC1038704891769AE530BB6 +116: F31F66E176DF632694A6F7E16ED8F15CE88908EF1D1F0067CC8A5C805370B9CACE0BDC78B1CEF06630012B3A35D129C4E2AA4F7302E1A122C7E53C51DA7F795D +117: 18B5417DC4CEE4387338C63156C34BBAFF19A2BB962E4248B1A1AFF1FF145BA47D84C6C8570D072BBC57D912C8048E0ED50060CA33408A00722A65C194178387 +118: 2AE09DC52D7BB9E692822A6FB3D582B805E5ECD2C1C4813F94F555BA2210429B615A2301B3EB7C491153D68AE33AD9D28F2FC11B6C61700D79BC7DDB251BD15F +119: 534390ED2DA55D45402F828D6035819C4528768DBFFAE1039CF0D18F89BEAA867589F78871FBC746E43B59E7886FDF734364DEC4193AABF56E8BEDD801E60D89 +120: 231597B2B71E6BE567C86DFE31ADD7B31332BEDA930C4921C4817B7DEBB0282A12D23B076F4783EA840D890F6C571760E70E143F8565561062877D95BD0FF941 +121: D60A1481686AB8F889EACF2E9F66BC32271E70E3E04B91ACA6CFB90375860E0BFC5AD9A627BA0C763CD7576811CDE2921E9A63C0F0A7A26E763F7EC7902308E7 +122: BA65BE7D1EF697281736B3AFA97FF675CD776C125CB01028EC2894EC2EFB9908835A3882E5E57BD44ACA09DC3B0580145EB2265E1724DA6F01AF5F93022D5774 +123: 0DEE2EBEBAA770891C14346A26834CF40212531EDDD64A21EF9FBD62F4728A16E18C673DC8CE3883156F51854A0ACC341DDEE6A0B71C4CBF797CD5327056AAD9 +124: 0717C9EDCC2FAEE525A684EAAB79653DD83BF46ECB285E6B154DFCB8A0C9F8D4B28FA200A6C224B4620CB0AB5B33B9C8BE77B2B5A04DB1A3EF8A5951EC46607C +125: BADCAAE4F76006290B9090AC81B807E7251EAC041E6CB10A2C5B58C4F4B2386E065E6D55C46CD888396C86606FACC82DE2F3F88904E15D549101AC7FFBA057D3 +126: 751F6366EFC97218AC2E0675E7F375444C8D82AE7A139E78305E14148E07100F5B7EF93B576DCE546A7BAFCE24FE148B248BE072031F89B6AE7BA9CC559E9C9B +127: EC0FCB3E124C482CC8D86BA2CDDE931E521F0B6F3E7F333C4388E7448A7F196D95766CEB8A49A90E46B592958BB85BD7495747E71508877975EB1454A4EBD57E +128: CDEEE6EC4D67DD8698B72C13735657EE9F78BB0E1DD37D0CF06063717DA9DCD617C5F4FF7656AA48CB3F697E36B3904F496136A2B04E19726DEF9D3406F8A84A +129: 81BB692EAF7F5176B6A0E5F2DFC01A045A917649D0B23B22C180BD78672F37F8E562FD006A00AF2D7AF0AFE15C8D191339AE28FF2797E64A3809400E2E73A785 +130: 04A8456D131499586CF7B9FC45C2EC96859F3F4BB8240ECD93E439EFD5DDE1DE7B67B688B583598D7FD50CB179D318D4C05EDE04F6FA318AA1E9DD7D4E279307 +131: E5C9D55B686DD9D7B1819A6144F6272B1FB5BB3B3034AB9D1BF34391283BA614D57894925C3D589A7FAC0CA1B1E98A12E9DFDDC2BCD85D1E7F2980709EF25719 +132: 2C6EF2E1C179BFA8295197371C474081790A63AFAA194E459CDC27AD4453B3A8C0110F9229BBDD4BBA5D6E80F2CEA71059334A97EA34F96810A2EBFCC3B177B8 +133: AAD54FE02E67080851DC84E20F7661E42ADB610D0B105B3EA6EB6654DAF64458B7E0F756392196AE2B40626CC2B0D82E47D74D3C50A607F4402C6C6A62999324 +134: CF210EE9A800943EAAF4EFE15DB7DEB696233A4DD62206D46BD9C84A7EB13B5EA43FF3CE15ADD8FC4BCFF022196197D1D097B7A893A79C6640135929FCEF10F6 +135: C81761EBF3235F4D56697B19F62B4F7445C8FDCE3D7999F3249493D50C19CA57C5FC84CD35CF794F58DDB6AC86E8BD53350BA9676AB63B88214162C8E11C16AF +136: 8E56EB131EFA286A92078F5A3667BC6669D6A7FD9746CA5F208EE38D5265CF27076C1624ED0F98D486C55C28A4FB89C7B667AAC505CA1CFE1E841184615B7602 +137: B6CAF44F87688E9E3651C2C98E840264464DE9DFE1F3E4CE5C1BEAD46C7D9D747DFFE282D775E101591A7254112C2DFD543E44B41E72EFEE30B032E5E015150A +138: 8E7851F56585595ABD2B3EBA5AE713672093A3120798506ADD1ACAA3ADD92D737F9AE155B8A5166C0F047801A93731D4B807DFE15F08D67DEF31A7B808601D6E +139: B36B6689A5F391688DA3A0756A15AF15E6E66701E2132CF6F06326AE9C91A0BBAA35664B28BC5B936D2BF1E6653848C5DB57654685124A08C79FD03ACC0681D1 +140: 24A23CE3A90C8EC3D10330EBDA47763B1B03035F9E4AAE0AD336169A2F464E067B026D94ED4B9723E969C8AAE7F404F7B4481C48EF7545EAAE4E648525A68751 +141: C7ADE61F21133886EE0E0B14438F070DA398B3A5387CABF98B0802662F3BD3AAA8738D36CCC0D3EA25BBE9DD3B59062BDF4BE2740482BF6D4C21D0E0FD7B0679 +142: 17EEAD5930DB3A1F8E123AD2E72C38209824F977674A52F380843442F0A5C82B55F8A362527BF5324124401648BEF5E9E26E08050B1FE80886E3856F98AC1EF8 +143: 9DE4F43CA8F7E528FFF9F4EF5897652323AEB95DF80049AFBA189C3D142CFF55AE340358A71B01797A8B72F478276E6353421E1C0C22EBDEA0C044EA60865784 +144: E259BE34C467B471C94B612EA6BD99A3F7EDE58E237DABA6A6656F7F7EB5466DAF908B7759027C277BD9234ECBB23C5C62DD2C9D248C1AE52865D66B5C256756 +145: E49099FC970994F8293E71467BFB1D241FE99322075795FCACFDBFAB396392E37BA09E66BF492684642FF2A03F8CF92E0ACF4677C21AC1C236DDCA103F0B5A69 +146: 4338E438D419D8694FC40383EB1045FD9DFEBC6F18A9A03B4914687A8639322E3B050F48E872BB7E2AD9013D374D68BDBBDD0B177024C1185320D04598515ADF +147: A36238A5C795B23F42D0833A5152770A4B0094BC19DFA72C935D32D02FAF5D136BF55D92B022D01949FF04B78507FB203302833AA7103729771A112E4FD1584F +148: 47180F9E838B129A7732A8DAD763B8CC5437BAEF77EFD34D3B33C63C09F6314B87B3A1436C6866614C3B3A693BC7926E9AE876C7BDE9D712FB5198D6417FCEF6 +149: A87064FF5DA177F3651488A139E568F6C75722ECF97507316BDAC36393724525291682776843B8563A6B014646F6B19F040B17B62BEE4A0711A7B06A67DF75C3 +150: F358321DC6A376ED500A2DABA60096B817D13B59AA02B56C1F51E2C6804F5D2DE2028409964D5755BFC6424287504994C7605749A5E5D9D802BB42922F444D76 +151: AC4A9999133546B8452047EE31B398F623E01DCACED7BAE4CB0B4DF0DD53B8E4921109308DE53C0924E0006361BC8A480AACF798D6B403F338357E8DB676AFBA +152: 0E73ABBEB68982F163257C1145FA2E465FD6E720EEAF5E532DDD1ACCC690B37A8FAEFF8D7D41564A9C86C2F185E0FBD0FCE75259D34A5E96B8C514EC83CA1382 +153: 094503A1B90D71960F83C91D76754BA6B05D670EC6A8EEE1D3CDC652DA6E52B196E155F3BCB62A9E4EF8C507F377AC1321C4C0D7A03F7D8A5286C0019C358E92 +154: 12803349F15FCBD53F2FE11B67DABCF3F470B8E3AFE8A855D7A918E611A2D5F4DAE8FE847ED1FAF834BB3678C6253111636100A991A80C1EAD0D35E28DB3AC85 +155: F489665F4D8A4AAA679D5E5A1B7C501DECE2E0B228630AEEAA1F5643FC4BCCB9E2F018FC2D7C44ABC4AC0861EBA8B7700A49B42486DD13263D978F8A7C9CA306 +156: D9DFBC3DBF0E3D247C95E16D376E7098A92EC59A54FAB482C330139EC6E06ED514D5C74F9604D1171A127502811A16D1D3039BD03C4DBED20BB765EFD34C5F0F +157: BA56A64D01FCF392A6E2F73D791D6C5A57AB40A376E73388CECBFDB910402043B4DB2F2D2B86E3510986CF1DEC3880E3C739175D5C0AA1DCEA18959135E2CF48 +158: F4B07B0A063AB240E5A64F1C494FCD9839276FD9689AA6720A94B83E579EF1044997F6506C1AD82C2CABB9384CEEA0B77D3970C1B7E13F8DE98AFA869F1F4D2A +159: CB4F232024B2D0C48E415D73193CD83C1A6BB9806CA336AC4F3B8FF7BF992B200504ED5E539CAAE68B1E47D4D8ACFD2E6B4BBC1B518689BBB5BB4311C96FE06A +160: 1E67E36D2EC5D0591C0171E7426A88919EA5A17470DA305CBA7BAEE90002E23043FAE1F4BE003EDDC2520A404E639B03880E3CCC68243C60E243A0E7A02E2CA0 +161: 40E46A8F257265A1E57A09B43890FEEFA57F56BB47551BAB38BE2BA8D143C176749484ADEB2D833EC9D6B70FBE872FA53618E64CF0AED24D51BA982D29E730C8 +162: F399712E5EFBA3FDF6B7D04600C16F69260179AB79545F44EF5849308E6FA589721CF7E6FE384461D05EF02BE51E50FA93C5FEEE9279A953C57EC07CFBE53E1D +163: 58DEEE13BF73ADD8B49EBBA90A8EDCE7030C17D6E6C449726D094F90A35A07759A3BEA031EEAF963C4753522EBBED1482789833D15D6EED7F5214E1AB93C174B +164: 13B2F766E6B796C44429A747CB46D99A9866115C78D2E94DAB52BBC9269B6584D26676CFECC2A9F026AE8E0162B6BB8DCB2242659EDA67CF793BF66963C69021 +165: 992B995865F57633665483C7C3ACD34BD108B5DDF151CED97C0D7AD134A8D9250CA8DC17C5C2A76C1C07989228F8B474814FB116C98D25D8F291D10CE259570E +166: 1C5D5E9C29DD91877E279DB679ACF0EFD8464B0A58EC9A3036EDB2621E8106FCF2A81719FDD1B89F13FCBD20960387754DD0F12876DAA911E793DF8F1991C043 +167: FE7F98A1D7839BB417CFF65A45E2DE806C74ADF2636385FEB16A34C890B524A75452EC096849EF0F905FFB38A0319D31A886DD840FE2FA66E16AC7C68B0D7FCC +168: EC67530458F01366BE95049FCFBF65465CEC9AD7D12332CF898DD72ED4D275F9C9EE96AD02603E8032F9B3B12615329CF0FEA564D278B1DC3B47EF304BF901B7 +169: 77BB3F5E58AF174DED0B31627648A1C7B5B8092C829020A6FE4CFD42CB51143E9DE20E3D827FB070DEDDA94D39BD0D330604DCB190E7252B12B03F48072B7E27 +170: CF33E5358E518807B70D6DCFBFB1CBAFBA7B2BDD20931B2A3B08BF8C6755367AB3BBB2FDCAE305F04812460FAD37E9AF70F1905D2F0D3E7628DD1FA453E5AE63 +171: 0739D32112107994BF3E6EC3A107AE3BDB9E2BBDA1D7C10D9AD6AE32952649007F68D28BA0DDD1F1C45F7128C1D3C42EBFDB1975A143A42949C7D97D9F9D3BA1 +172: A4F0B775988038E50429428C8526793AD8B6EC1F0F3AB7F6B33F716C61B7DFC49E254EAA01FFA422A31D30A8268E1BE99D385907479C7E2E0492681B6851DE1B +173: D2472E93989E1F29BE0DCF991A65BFE0E772CE77850A2F96FC6114EBCD78252DFC17712AF193FC5ECBA371B8FD27B0DAC44AFF6140923885F403904F1664AAD4 +174: 6696E09A153B0077D3586705E4A19FA6B3B2DD8621F5D13D7003017A0C569B7483C8CD9218ED1A252EB160C3620FE96A00E267DA0FA8996B417F64DD4A22153B +175: 2337E38B460CDDB026CB81B59B99572D45BCA4A43949440AA5C9F2502DBD8906453FEE23AC0AE47AB77214E52E7CF06ACE73DD8565BDD315F49A460996E08DE9 +176: 068CAEDFA329C1FB00BA02C80877E0E2B1CB6127FA2224BD14FAE5AD0AAE6FBAE052A145F5A8340B446F54AC9BB2108CF6582AFA0FADE91CD3568B604F68F470 +177: EBD69C96F4F2DB05350B74A475CA8C1FDC671B018A47072A11A8DC082C418EB20466720AF12E113C2D507F02596CB022D2BECC4EF8486CB54260020EB6C36481 +178: DB0770922005DE66FBC2B05B1F863ADA569B76DA9B8CA433C99C2F2B4AD60BD28B19A5B3820C0D8B6B2E443CF54A942B961E5EF1D53BAC4CA379964D701070D3 +179: D435D7240B8C6A6AABCB026EA53BB8DE58C5DB471EDD8173AE30C81BEFA9CCDE8E30758CBD7DED822410576115C2415D9DA7FD8A83CBEAE337E5908A012AE1E7 +180: 838AFEF97BBCFF7692C731D55442140D58CABFBE81BE76D41652106E215AF4E934691DC20F181C2123CF091B6D7552115F59937E165F1645CE0E14DEDB864B11 +181: 771815708A3D7BBE5E00FD677E4EB76B2B9A03A09412284A236401E7FCB19B340782C81D1A49371609DDCD7E38F9448FA657533D53280B3D6B492984E9C9CBC3 +182: 649EAB3244AEDAA18CF0A1FFF6619D63BBB66955C5D58E3A592E53F537FA74C60616B9E4483BCBB08AD7D1F5B6B91ED3176E89C03C224F94E5D3893FB6D01CFB +183: B4B6C653D90EDFEC3BEA0FE1FD766D5736DAFA184C360C8B036B7CC842E8C76BECFBAA7046AF087831E322FFC181073C19360A269851FF4DFFB4712E68560C3A +184: B0C0061EC50BBC67DA4765FEBD4033B8A204260177F9CFD451E97B93F19736D4B0B7478E29FBE76BE17AA6B0DFE9C4CB9C6E4734DCC8AA5EA825F101E5C9B02C +185: 54EB4D2C9B26B8B17818AD702E065407A19A711E22C8E66163E7311D8ECFA54448453890194C3EE892A599125AAFE1CB230C6EA268ED68ACD86DBBD17432352C +186: C049743F49D57D9226AFD26B94BFE9165BE5A8CEA9DCCD101F837F29C63A4201B1D4478EB5C4CE9D8F5D6E91BF89D09E6A0D918EE7A6D58CCD0A46D36963BCAB +187: F11AED8EC2B1C003B8E35F8F2A05861D9DD6B7DED02E28EFA4EDBB0BDA0DAA76EAD810CF1C78F50668D50DBE2AE65009C2E12504DFCE9F9BFA9A14969E1D0622 +188: 1CEB4106BC700F76F4825E6790959CC6EC85AD93D6FBB9783098E367E5C9676AA0D6B8CF9A7DCC67565284E71205551650557D556870B421273772524463245B +189: 9711275100A787D9678CEB38981A2246112C2FB1F0EEC1F844DF1703DE5B0FAD995FAC983526E7E3336B8CDC9DCE56FD66B73811201A2DA6783309AB6B9C0546 +190: 81E9DC0CBF71797104A44E72841FAF7F9CCF35C18EFEEF873450A25AE56564B0E9DA98598C527D5629EEF7F0571D9AD929BAB87A27539CE9898ABF4C57C9EBB5 +191: 28F4214D1C8C5B9291F2E1F7FCE732C3290A691432A65A01F7EAB1A313B83936DC98A3B39B5F7712DDEEB8968001C93A102C7FCFB8AD7D49B29661C9A9867109 +192: 78C7A025ADB85145CA8C6E417C4E68A9DB83FA78A23D0CC3DF20AD1409B936686FF756EB51BD8901157B1D031DE6848D97DC2E0F137BCA1D49EE3FB2D5A5E83F +193: E2C25FC61AFC794F65AA57DCCC4111D4B15331842493F93E9500AF01E2017CB226444E208BA9C841DF6D7ED28955B318511335F842AF3C2C0573227AFD790739 +194: 50D768C744CDD318B950986E305BF74B77396FDABCAF63AB786893B5F4104C2525F2F69905955A35234BD6BD85DB17B94AE7008F2E2C368E9639ABE8BAFEE4CA +195: C4F1BF6C56C494351A880172B9CBB59BB0D1A5955352E10A868D3C33BFEA0484EDF6ADDD009A20C8D7B59B7ABD5115D595B026CCA6442921038D9BE860C44CBE +196: C782CE6A141EF9E6CAA61853588B8C75B3A39CE191C161F43D7C5F88FB77BD5055B21F37D4A49D65CCDBD0E6BFD98193FC0092A34C21D5ED0CAA5F129D462073 +197: 1B2F68D7DC7563C286612B3D708AA725923FC9A2FEDCD4B1F1E2557CC70F3BF65944A2BAD9705303207B00F6DBCCE245C6E653C38EA0896DEF4150DA118A699E +198: C1248D0A6B75BEFFFD70EF17F2D0F3CE3628BCFB6A634C93E8F0ED97BBFDB48F6E5608511AD7091D7B062B795EBEDEC67696679EA092F7B84A64C99BB224D387 +199: 20A3D3F3676947173C7FB824B40069A202ED3A5637DB41C97ABFE9E7036D6C009BDDD5BFFF97FE80EBC40355A535D7D3A4B2FDC09B809D3BAE2DC31803413B27 +200: B85500CB777B14592A4562A26B13AF3F08CE74E03372D9622E29C1FB7988A86B8C00DDB2049C1395B43B17CD5C415A5AEDD71E05CC0980EB9520D4CAABBD6FDC +201: DB553A36A3EAABF7BE6FAF85DB96D3D0F207EA1E5B55DE589A116DB80C21AE5B1826A5FF3BB9D84C26A403A1E5C00BC7D2F6DE3F6A9661899D6D75373ED76B71 +202: 5580422E6393475B7C1F5010FA7F4395B969E190AEA056ECC88783A8B5FAB8ACF130DFF39DC0175E9BA8B63B4FABA7E4A36FC55FA1504468727086B2D26B5818 +203: 1CA3DD194E7BCA2591AD1B95D0CD4CF7938334C95A1EBE2C8C1A9B75E6A85F534C094E652248048923CBAB97CB1581E9A2D1AB8375C506159B724F74447A3201 +204: DC525D0EC1E62EA68C013470D77B61377398EDCA82A91C1C3E4D7E5D910A9D556B3AC810FB1457BDD70A18B063523C39BD806A2227C7E057CC6B018DDABFF73E +205: 2F0B9523725B27245D2A1B635DB5A3A3800099546ABFDD95C8E86C67C378D91E4711AD1927E90CC9B50A1A7BE3D60414E487E72445936FD0FA2BBF541F1394EC +206: AB6EB21BC802EB0854F61346F7BFCFFF738EA39829AB2785976D869830DBAC367D59D50C3873B960AC5185F3DBCEABD4E4E594C5C2916A8DC304207E887473C5 +207: 8E1C160A334D41F08918EC084BE12872DE79D00473D1B6ACADABD67E2A6827FB1DDDACAD9BFCF27430AA84F3F7A0D6CF2FFC91E7758F471F2739D51B60125D46 +208: C135532CFE84849FE9F40799E1F2CA05568868C0D44E6832A05C29ED17C5F6D0FB844485CBAE5E50A67F2319C30526DB444F4B45CDAE01A9D0542427731DC175 +209: B1FBEE68843D42FB558D1D9E0B759C168D6F84D07B2E90B646F45F1708B0D6AFF7BA8959EBB6AE4D5DF9A9951D139C81BBE602671CFDC618AA1EB63288DAD72D +210: DC11C3D993F59473F64F16F87D5F085E834306FC1C40D12CE7D6E44C59C31318C694282B0FE53B4B60E1E5DB546D930AB741A8DAAB8ED67C3D87E8E76B8C025C +211: 85BFAE07EEA80F939D52CB18C970C8ED9D4035B57391739C44D7973223C51344B9BE28C16EA29B35AF74A2F8F7581C766D61525DE5922A83A1BB600D97F7A3F2 +212: 26E52AFEE0F11DD79061EA3E4F97205729E6B61E50B69CC2894CABB08CFD3A10C41662CA6F6FEC9B5B80ACACBF968C5B75BB8CFA31D06C82D9CFE97F6E1F43FD +213: 74F18E92D85D9AE79BD62C4B8FFB2116DA8157E17A6927BE2B2D0D79CA101F7CAD6A25CD623C8756D49B9CBB903477B9CAC67734F84F0915ACA9025A9D5C6DD2 +214: A51B45BC09382F85334EA58CF7E7747457B517118042D53D773C66668CD6D5059B9997DB183B1C0F2900AC9949028D8F76DD8B7259149388FBF340834A3BF4FA +215: 59DC88A518FE44A7FD0F316BC8B5C865D370A8BC82533037C9872B24390F7969ECA530911463520218D00B415409AFA90A63F88EE729A252F1B747C414414091 +216: 146FBF362ACCEB8DF79A761285A0653484C38585817E26A7B8906FBBEAD70031160C7B924D3BD3A9ACE28A5712ED0E6E89CE4E71493B27F87BF73BF592D80600 +217: 74B6738B2F0904FD59F3A680CFBFE4E466FB5094037AA1942DB3A0017260D75AC5916E044CAC6BD0E25D176FDA267542B2C7EA201F7237E18B9D00723E98A239 +218: E821A4033FAF0FEFE525115109D0B836A22C287E3B157EC302768BEF7989AACE853218E5AF7DEE9F6E234AD50ABCC8A9658A0EE4D9FE050235341C94308D7A4D +219: C3EDD652D2F831B1C783CE1B8BB8CEF9453FC71F519A4800EC2362ECDBE9EC142F768185D55E322A32AF421DC84EF84615F7F3DBE6BC6E702B4BC8625CEB5BF3 +220: 6A3CA0B5A43EF42A1D6526C2F1507785248374C7D2602079A923C841F775A652724C29E788695B52387778CF2E2BBE2213B2FE212D729E3718D946238FF0E57E +221: C425148335AF813E36D072DC64C7EF6782D7DB981C5142B5D32D6D4338E06AC64363E86E88DF018968FD659DBF50A4B77BE2A02E71B243D65024B36CD71C1796 +222: B796D1F5AB11389EC7EC8DD4D1D5AAF17262C8522A4AACF454B44A7ED71E20F7028169F3164AABEE4C716B38271D72D7ACA3E54B30B9E05616AC51594995F61D +223: 113A56E96ED6F8613705B5CCA6CC4F2138204D7BC0C8965162597C1FD2F6E8143F57FF1160F4B482F7430536A349D20918064AAD2BB38A9D4403C16977B9616D +224: 9590A3BD7A0613381159E1E26342C150DD9B0A937855BF78FBF625648448B540158196A2855E7FCB967F22F5AE927D60E97D0C1C17A01E8D07284FF985F54B8A +225: 74B11968CC7CD925E21037DF011F1C93B2EC34C34A3224AA281ACE7D6F1B10F2A755DD6DDF33F1A4630123BC1CF875894FBD8D8B70AC05F8C3C1076E346A45B6 +226: 85A08D6993B7E5C014C3CA957D6B53EC1B8A5CEADD5060BBCC350915D3278F28E238425DA3A95AEF725A23B1BBD43E5D8832382BF76603F7E2E4FF711D540980 +227: BEFB08F621281473943AF153124256386570261916E5238FAFE44A72801D7C204A974B38696C102748CD1DF65BE3EA8C45A40021C28C7E4BB143800A3F38A93F +228: AFB97494318F31A4C6813246D125217242247D4EB6CF884B244E59655DF866B2820A8E1A7123DCCDE98ECBDF1F6125EC5B95A0D9F85F05CB09537B3FCFC2CF3D +229: E8C2E1D342E6503D77328A2C1336F95939B0E8855F75CFC61D4B03F4AF2305AB57C7DB383055A51E61AFB75494C222B01967BC74B4574B8208FC337E09E57075 +230: 0B396D0F15F49E60994DF4FB1E7E526A272A5B41FAB67EB8A41547CA6CE5B7F3FCE404B6A46BE79AAE37B4DF2C2EF68EAB71F39D5908760FB2124C7C83B0AAFA +231: FE86580438E8EE3459A62E73AF0E14F00F4F0FAD0447921FAEB2B77A0D8786784659B1F6D3044538300C759EBEF7066F9218F9386FF6C8099E6C71B5EC6B721B +232: C7E45B1737EBCA62C87A8F0C46F661BF7D3FC020C3B4B91988FC36C38BBC8DE05A22D4BF148F96D31115605D7B04D4CC8AB3F8738B652E933D76CD6966604CAE +233: 2C43F84381FB618512EDA0278FD382AABBA41FCF5546312DA565F4503CACB86B8A704B3B49C0C86B2207E4641F71FB5E72654B0AEE705C52ECB2E8FAF109FDF0 +234: ABC4EED8635DDFFD9900F5DF8C6246CAF12D8CD9333F38647255DCC52A20B6DE8D4109957CBCC2F48F52346579E008091628FD7CAFA092F2568828F424EABF26 +235: 14672F19BEEF8896F751B0BCF40FEED78A8093AA4DCB590D7AA588DDEB3170460381FDEF3CFB608D55F9E8A295A36DD64DE058C9EFF30B1D1F1A3671388B0AB8 +236: DB87424F975B03F925D8B99A1DD0967D2283E408B6B0155851DCFD53C0C00B05A42CFE14B10408E0F5985809813D35D7AA7C70C1A7BC852C7F254F0303103628 +237: 095D34066A6E202C896EF29F3481EFACBBFA622676F58E90FCD5A0591124E489BE3804AFA9BD3E4C92A9653EBE878A88B275BF9B5C8EF8EA0F01C89CF40E5FE0 +238: BB5BC80C718B85BB3C3DCE95D186711D5B90827B2097DE63C647E5B6C14B4766BF8EE8ED395103030F72ADF0C8992AE836086571908DB4A6258616EDB4BDA878 +239: 9A18D6DD0F97B7407DB0F17896DB2A2751B76C69B6F91E821A0DD717DFDEF630EEC1427C2D190C095DDB07601DC0EC8687B7411D735A9A6EF0EEB84A60948BAC +240: 60A614BC40A7DE580B6ADD05279A68DDCAE79EC3DDDD2C6FFF7B77BE9DD0260DA5241660982B77BA9C4B904075F39612F514BC86DF6F68E189FAE2C84A32CCE7 +241: 5CFCD44DECBE3D74708C620C70DA807C5AD58072F7558D950F519691FC96F98B760B02897C3A85F68EE37B2735931660106670C4DC7FA98EE2E18B6DED532A9F +242: AFBE6D9871AFFE6D201E2E61435703856424301ADD5152DC745D96D1BAA3ADD4C78F2D7C5057F1AE8B21FB91879562050C84144A2042AB2CD273025FA03839F5 +243: CE9C1B19D0E0FFD3085D28C5B2176A741A3034C1B76C54740AAC3470C1C8C6E77BA765AC4D6D90D4DAB0A89AFB17A8863A2917674F5A189A5CBF721C14F5D637 +244: F2F065927839C22DF56960845E27868BA8F272A464619EFFD9AEBAF1E40A72DDA81CFC67DEE13C351736C407F59DAE8EE6F2BDA17521CF66F10C73566B7DA891 +245: 24CD3AFA2218863437C5518021D1B96E0A80EBD14EBF2FA161A5E7032FD985BF71EA59DC5E35DEDE5EEE3098EAF6A16698F5BD5903C4ED218868D1E96E4B8096 +246: 1C6AC311730640FE427C1F23B60E817C25E1318109643A8AB51DA74995FFC3F156F098AEF97F37CD9746002DAD22FBED1A1F222511B92AB5F39DA9B53BD62AF2 +247: 37609371EB63AEF0CA6EACED8388D187203A88C379F24970434D87950C9B7DF9A68B618E9E83E3EB10376504F8FEE2505830EFE3FFBD23EFBE081325AA171482 +248: F0C06F6A2C7AC3F0EE428D7D1BA893E73D4D2F417999043BEFBB3CED51F95F7EA3CA882B9E8C1C973DD8A7F450CD60BB5A0B30D44A574E43E71D2533EFAEC6B5 +249: 3A9D1BD43CB3B7D3E9364F05987DF4CD99D573C036BF1337988751658EAF2896244DF5E4DD8984DD494709E587A75EA8AFF93681787AD738A95C5E98616115F6 +250: D42E2D57B36095F0CFE8F771A9B198C7B7E0433763341D35033F32D21C638CD948D8DBE75F533391347C440F208D17F20614309DBF1091DCA10801E16F5D03B5 +251: FBB964B7865A889433E99C4B61D3CD069DEB99E44673068771030EB1B8F1FD3B3ECAED1DCE8ADFA44F9A625472CD4D987EC7ED7FDA0DA912C8AFF5B20BED7F04 +252: 13F67CAD96C3304FF3C2E45D71A2D69301695516EA384F6001850A46A7F93CB74C5A4CBC1C56544166ABB6C9BBF90B9559320F5F75ABBBDE34C7B8B45C783BC1 +253: 78A609196BB40EEEBEBC04A8794C840A6F831680864D65FAAB093A499A3CF152EAC96865747ACA28392E9F102962C49247E0EDA424A345C4AC6F4B60CC3D2597 +254: F199515CF806EA25237EB93D658BEDC994E61EF70F5665CC2F230E7A40EADA14BFA00D56C1249F2E5C8920977A6C85017F8663BE9422762CF88487B76EE7EF9B +255: E8702ADD4B9034BCA0590FF897C10022C56D08FC4EEE0A43BA85E9E9C2086616B1BE7B6F928A3C53755506ED2D9D62DF5BA4A1862FBCDBA20683931A2244AFBE +256: 6E6A3CDE12F2CB3A42EC8A5D21B435C4DA4DF6CA7E41537D361D8169158287BF1D2241581DE07F88FE92F5AE4E96EB9C489FC3B258EA3842EA2D511CE883883E + +HMAC-rmd128 + 0: E9BF401EB338AE9ECE9F2DE9CC104A5C + 1: 9536B19B029E60F979B3A6B3052685BE + 2: B52F90B48846959EF56051CB6ED21588 + 3: 0811D2108413D9B64ADFA78B05EDF1C8 + 4: E06414189CCE13B61A2FC3CE9BC11938 + 5: 8BA02647A4914BF4248F6C799055ABA8 + 6: A3D5D44CBE30E23D20643E865F28B7CF + 7: 459DC8A812BBB840CA10A49E10F240E8 + 8: 26131CE4DEA7D66E5B3E6ECB1DDA4329 + 9: 5EB41B6A8F140E49BB4EBCB76EFAA0A4 + 10: C5E076890071C872B071E2D068EAD1E3 + 11: 476474365DEBAFE39DE7830A0BC3ADCE + 12: 3E9E0D4B41D740310572562E5F7F0CFF + 13: 9BA99B782F7B79C9C19D40EB27033941 + 14: 8E9931A75435B113C7E17E94E22D0B7C + 15: 1977BEFFFBF378633AD22D9E489FFB90 + 16: 9CA06536713225F3A5F67CB6510FB165 + 17: F46F54B012982621E33BA13A871F82F8 + 18: 73F925BD50E603A66B17D8D926CAD1FF + 19: AC74EC692DDBEF86570044E1B5F31EF2 + 20: 4F4F95BC7487A8F07B23C11F700F9C4A + 21: 02CE78131B27AB77474CFAE5EEA37055 + 22: 1D66BAD41487BA6C238BDAFC04E9963F + 23: 79058EE7D70C9D19058BE2E1D5383F39 + 24: 773EB9C677055286C84B39D2344C43FE + 25: 414A4816C124BB62DBA3BF65B6276208 + 26: 350DE5DF46801BAF8B12D4516E82EF43 + 27: F31C58CD73A3D8AC050BFFA5FDB6200C + 28: 5D7489AAD6537DB3DC27D43F698F6E79 + 29: EEF7FC37DCF2AB96328E62B8097203B6 + 30: 8FD428368B9B52F25C47E74C0327DA52 + 31: 923B6ECABD0337E39E6D068CC98F71A8 + 32: ECF2239FC767105FC69F46FDA5BA37CB + 33: EAEEFEDEC3B1E74A029683FC21F03B40 + 34: 9620C4913123F3A718D61C956673FB23 + 35: 59283EDEA3804ECD6471EA41EAF89A8E + 36: FB5B60685DC1DAF0C6557325DBBB32C4 + 37: DB71D12AA3B97C421FCBE45F8232F3E7 + 38: B0849EE5F1F9484514F5512BD928148C + 39: C73A777E20CC49AD33DBCBB16DC59A84 + 40: 600BF6FB779EA2F7108D1F7B8FE89F45 + 41: 0BD76F07D4C433E5BB9FC98B7FE49A2C + 42: 209E2124DAAAB3B5C6D2DD9A79A36E4F + 43: 907E4E2540A6794D6526A44FA08CAAC3 + 44: BA1BCEBA60F32ABD0EED0A1A56748248 + 45: 31F8527CCDD022CB9439F8B39ED70D11 + 46: 05F429D6AA9FBB1723D81AB268F95963 + 47: 7B91D5409357FF13F9B92ED2C6D63B66 + 48: 30AA88DDC6D49AEF0D4058616EEFD9D9 + 49: 16C0B4F46936AD501EEB5BEC8C699EB3 + 50: 782DDC3AA9B3E498767AA310D7C32CDB + 51: FABED92C454544588965E4CBBBDCDAC5 + 52: 7B04EC847F160BE26FB4A7C6B111EF91 + 53: C20AC6220BD352F8D53F0DEDBCA97862 + 54: 2EB8A89C854AD2412E5E2DB8638550C1 + 55: 390DC3D1C6EA4CD7A381BDD9F0B505A5 + 56: 1D86B9AAE5246182EF76456E9A8F2CC3 + 57: 1759BE8033CD082D771127CC81435696 + 58: 4F230D4174BBB11231ABD4AB58D6FB80 + 59: 9FA21699DE8CDE39FE4C9DF25271A87C + 60: 7658883C002D62D33EA21AC43E26C355 + 61: ED1CD4C63C40453677804FD66BE3E068 + 62: D715E8E09CF4C5A34793FCFF0A7EF0F9 + 63: 86C450794C4F920138A8CF2DD9221826 + 64: 2AE1A808F63CF7AFF39FE9595BE540EC + 65: C8E550F520B0662100FF767FC0FC38E4 + 66: 1A4CA5249BA8BF8E4AF50BD01B89C13C + 67: 25A3566CEE5E0921857048F4A54BF745 + 68: 4D76448CE2C08EBCF6C21FD304973DB1 + 69: 83BBC6D82633974D76A1B0994DD8891E + 70: 9F322885EB927B8C4F93AAC081C7F378 + 71: 7E0DFB22C9433A0A66A673ABB3E81B4A + 72: FD3DE62829CCF2AC389581D9932E1B94 + 73: CADF66BDE69903E9E3117DFE75EB1C6C + 74: 71DD9BF191A5A1A0311BA19BF0568727 + 75: EEC05781AEED255A8DA730399ABE8929 + 76: 07E7E6E57A239F659A6B17B695161878 + 77: 6E7DC67642EB72C295EC12C009902577 + 78: F6AD3BF571AEC27B2C99AAD4A22B9654 + 79: 0F38A5596BC9BFA1ABB7318A35E5841A + 80: 987BA29276694A84DF6F3448D2FA36B1 + 81: 3661D8F157DCBA761D1292FC2FB332C5 + 82: 81834820599DE6624EC116A651FFA2A4 + 83: 59E556C023829D31F76ECB5D2D5050FC + 84: 9389597634228E243808C1CCCC71627D + 85: FFD30A17850DB17BBDE7C3EBC8482A95 + 86: 0297895965B8C96F95A77E6A1BEB5FA5 + 87: 46185FBA371A282AD8251A8DA93E7A10 + 88: 34940377228A73C2CDA178635B8A4827 + 89: 0737C31BEFDE68780EB3A5504F295809 + 90: 3DEE2B38EAF96BC620785551C926E9AF + 91: 719B32410E625DC65AB4E422E24C8663 + 92: 5B9AEA802EFFE00D19E746E0684993CC + 93: EE96F9B8F8FFC084C0EF8C28ED0EEC4C + 94: C6575E5F4CDEE50C0C2F41ECC33BC9E0 + 95: 000DCE0FA82C1422ABF37EF1971B4B1F + 96: 83D1C6EBEF52D1B9DFA3F439BF8DCE25 + 97: 657AFE5CA6D54F9083F02C257CE7E3DB + 98: 9E65239503BEAB92716D5B504358352A + 99: D8375320E32FAE3BBABD4620B1231315 +100: CC8914472A9B5862287D695AD0A88BE6 +101: B0E0D8EDA1BDBEBCD0A78678AD7D6A64 +102: C8EBE9364129E651BD4FB491FE035433 +103: 2A6DF032E0D615DB3BE890B0B6D3349D +104: 975F0E184517902F1C239684EBC06314 +105: 5A86E403AD3D0B9EE5CF87C32482C6FA +106: D3E986B5231A204C88D7C2FD1ECA40C5 +107: 891ABD274D024F8B04143DE588A02AC7 +108: EA619405003DD17F13ED5BFB29587568 +109: EF5CD5EF1164A2E5BBC2D96360E55B87 +110: 07C74397955571A7E4025BB9EC555846 +111: B5F20FB0AC1C1DAA0DEF8EF78A9BDDB5 +112: 88D91C18A4AD272B4C1E2C76BE217BFA +113: AC548888F0E5E559777568ECE71E2007 +114: 816071E2B807CE6EF526E423BBA252D5 +115: 0585A675BADFDD749ECADE66BFFD0546 +116: 964CA97939664EE55B8B973D044D7695 +117: BB8FAACCE9D3238714C3934E6FEE2386 +118: 2BB26CD61B24CB5CB9E2C5FF40C51A00 +119: F5332DEBA64EB35CE3B5C7134C4C8495 +120: ADE7A5C99757D216D10E1F13E3A91F1F +121: AE98C3C4FD874CE0B8501FE4C428282A +122: 04D7625B67AC3F9D117AA45FEF6C6AC1 +123: A05D3C933DC8C8A1CF48290A5D52644E +124: 078F882264317B0C00383FBA7E079301 +125: 44023F3B109763A53FDEFF1822488855 +126: CA535702BAAB858D5FB5B79895E0E1E0 +127: FE1C2C02B7665895DBD2F4D2C22A7232 +128: 75A182DB4FD99599022F5A03F1427289 + +HMAC-rmd160 + 0: 33528FDB4FD0640B4C4363CEF1DE795719EBC7EE + 1: 514DF566C6204373EEE6020054AE7DDE2B0934DB + 2: CC8A5C8D2EBA02BF4474A4CC05CC2D863F1AA392 + 3: 27D731E218C369A32BE4B2BB29D2F1A0988BA583 + 4: 091245BFADF5C6635298702F233ECB3265E85460 + 5: BD2C07FA2197201DCA309063881F2EAC9D925A21 + 6: 480886856354E6FF34B3AFAF9E63FB794BAC4521 + 7: 258D58532BEB5EAD28E9BCA52AA4C0444CC2467A + 8: DB7513F824B42A9E1FFC1369F22F61054A3EB7F0 + 9: 3A4A258F23675EE02E1AC1F72197D1A11F32DE21 + 10: 9315ACAAAA8DC91A9AAF8DDD4CD000AE04F70E1D + 11: 57D60D77E1D78D23D3F184740D9DE392FC6C3C40 + 12: 950395C815A3D1A4A8BB25322333FECA15445BFB + 13: F8201A01C30F3B569B7497B5191AE16D1705085D + 14: 08DEA1A0CD4BD6C9031C84FD2005F15810FF088B + 15: CF41D88EB3921FA137F0203C2CB8BC5200FDE7BE + 16: A07100AAACF5253501A6643452D07C7DE2EA824E + 17: 19DE22082D1F4535A733F16262A135358D651737 + 18: D50BD92902AE0127AC8DD85E9A81ADB7EF3F1E64 + 19: 3FA34A3C02E06DE451794AB87C4FCE6877458CDA + 20: 5928329E4D830E8B2F7608A4ED46DCCFD5798425 + 21: 2825DBD7989A8978904A654E6AF125608B0BEBC1 + 22: 9C812424417D47ED7C78C7A049D4E6CB906DCF3C + 23: 9518A473A902DB6BB56F7A767ABA13C8DF306D37 + 24: 439C444C7AB4395C4DBA32E4F8CF4F76207E5BB4 + 25: 9021FCB087269457ABAA8105D4DAD8DF8904A2F6 + 26: 8B7B686199BC73A175940686BD57F45B2329D895 + 27: 0F50FB7AA9425975BFBB6AD65CF96284F768BB75 + 28: BAA1B7749A9CCAD7105E9ADEE499058A7BE4BA70 + 29: FBD3413CE89DFFE2F0A869036F5C4265D5B14743 + 30: 7CDB257E051ED0EFB761A5A044ECE5B0C1F12033 + 31: BB1E5D495074594534AD523987D8438CF1632425 + 32: CE6D7BEAD1496190F0F0E99B0B0C9BECFB7D9173 + 33: F8BE617A3256EB1C4BFC04CD386EB7FA46603926 + 34: D1A1F489434C458344239A75DA4241A3A94BEBA2 + 35: BEDD951DC98BD5C4138C1F8531D8288BA3C51B87 + 36: 9C2357E832CE87A227F6919B50A0A9D3A29B7CAF + 37: C9FCBB9A1AC48B71B2AA20AC992821531F1141EF + 38: 0B58D56923F9620BCD072703FBA71EC2172EEAD2 + 39: D97480E09FA6473AF9AAFA14FA9589AF65E62328 + 40: 4D5C56D0EB0BAD64FD0B0FB7F87D05EB551951CE + 41: B7EC2D13EDD3603D1BBC8CD29F32B43AEAF6EB4E + 42: 9BD5300B02C9432F686842E7900F3D2A085C5008 + 43: 7E8787C8780C64009216324802958E1D845332FB + 44: 1A3BC1AE95380D609571B01D8C3458B2566B74A5 + 45: 9672BD12EBBB12F398CEFA089BD3282A2D2892FB + 46: D5D3CAD705E2B0B6E0CBFBB0E8C22CD8EB1DC4C5 + 47: 408D84FE0B28A3B3CF16F60D6207A94B36219F81 + 48: 0B7E3D35C292D295797E3ED1F3D8BD5FD92A71BF + 49: 18AC1EA3406D69CD9E9C801F471AEA3A31C69D51 + 50: 98E40CE293ABE4ACFADE7D81371FA92AFA69248C + 51: D95E38F2D0C5ADB478A9BFF9F8E7B10064455C31 + 52: 6246C69FF502D453950BFEB5DBEF68CE76D70F12 + 53: 9D788F02EEE675F47AB4498B1337C6D83A37F64A + 54: 139387D749674D0E84F3C2BFBAFB3F0CDC4CA273 + 55: 09406CEDC1C37D275EBFE02CC707229244086CA2 + 56: BACA138E6EB6E5BEF150083CE0EFC64FB163EBF4 + 57: 87CF4CC4500A691934C2C6607F3296A0BEC980F6 + 58: F8E4DB4FE6879870E9F47BA29F0DA843342953CE + 59: 52DDF305014F1C68A34ED514B10FAE3B1B91F383 + 60: 0D568164C300BB14A4571A73493C02E4165383E4 + 61: E1DD806961D718F8C085CEA11A140900FE8064A4 + 62: 6470CBC7FE079B684D108550698B7C5D265736D4 + 63: DAF83273B2F16DCC69FD55DC84835931E75FF5D8 + 64: 47F4D7724BF49DE885D23D84D582EA3A00E1C2DE + 65: DBD6BD40F804E38963EBD2E81CE5196F6E69AC48 + 66: BD96E9391148957BE64FE6DA89CBDFF45233FBCE + 67: 20975680C2E31D61D7F303215A25CFAB4479F646 + 68: FFC321ED45ECC1A9FCDBC28ABAE0DA1FD27A628A + 69: 99F90008F139FA442C152706E522CEB349EABB00 + 70: 288C57DAD9D1174F4EBA92F7815B93C0916E8157 + 71: 8380FD083E742776CC32971B9E088B894A6A0071 + 72: B0F44C66552ECE94502597B6B100CC64561E6F1F + 73: AA0465458FA1F285F5A4530035F84F844D545A75 + 74: C90EE3BAC92FA4986C850DED11D728A78BE85543 + 75: 3E525BBEB158B246A3F4918B6D634CE8EBE4503A + 76: 7B42675AAE1D0DA5A84623E47C618744249384E5 + 77: F50AC31B43BC93D1BE2A4D9C40FC4D3593F2551C + 78: A31AE398E0D6668A52DAFE37D019F7571E0F681B + 79: BF10B29B4DC7C848C5192631E59E0EED32B8D81C + 80: 77B214EB3617C372C191D1D284FCED04F5AE17BF + 81: 1B17DC33F5966621F4BFA93961B1A8FFEE1AC820 + 82: 5A07D9861EDA6D8698E12FE5250CCAD882628B44 + 83: 176F46FF2202307828D7F62D39330444D688FDAD + 84: 59E94CFA3AC2BE8DC6098840E888306764308DE2 + 85: 679F243847C647FCC3F4589CF87972558350DC98 + 86: DB97F5EF492C7380472E16E3B055567DAB630153 + 87: 359CF9515F6B2192BF0E85EDBBC81D51232210B7 + 88: 30B59B3CBFFC08DA7D9514AE7627460BBBDED722 + 89: F31D5E2866D9726051B6E5AC9B846DB36EB705FD + 90: 860A58DDB6119261646907E251D60760099CAA07 + 91: 22EA0278EA053175C2F12BA4ED172FB0B518F3BA + 92: EC68297334F421AB3F2EF3518684E8E1B548BF56 + 93: 5C1405CC33D9025DA265FF4F25942853721489E2 + 94: 8AEA8E9EAFBF3BA597B65BBCCEE59013C8E6AC8B + 95: ABF7CCD01374D5DDAD6EFFB19412EE772E663DE2 + 96: F7F28E05FAB93A3D089BBFF56D4E462F0BEDA41A + 97: B6C4199D504E72793EEB49611E28A82DF5CD7905 + 98: 0B0916C89F1D9F1134E9106FEBAF4169DC49F752 + 99: 4F18AA0E88A01ED162D08F35300B1C3FCE1FE8B8 +100: 5D4F3C473D5859C16F70C1566F9800B3DBBBC643 +101: 02C1A5F34232B8900E6C7DF2BED957BCAE529784 +102: CDD46E434331D7869A27EA096CAEBF586D93CC2E +103: 492C04E69F0204F150B63022C7DBD28116458F97 +104: CDDAB90168E934E69E942B1F1EC0D0AD7BFB5B43 +105: F433642FA8091FB2517F3357DD30308B4A2AEF53 +106: 537B2118792B6A419C438E58CBB6C5BA887AE257 +107: 753728CB39813C27498033A07DEC03D1FA720FE9 +108: 119A6C5BF3EA8F7A78DA9ED2DE7ED9AE3942964A +109: A501EB611542A2A2CCC68AE754D2EAC17942BD8D +110: 158FB54E37C7DF54B29928B5DFA53A560DC09A5A +111: 15F5380252E23B5C37EE7E8D1F5963FBF8788577 +112: 735F2C3CF7680C63F33AE2D4F3569FA8EB45EB93 +113: 67AFC501C6582DF2A9DBD713F206041E5F3E1DEB +114: 7CAEFEC1C6E8232BCB90E3FE3523EE06496F36A3 +115: CC90ADFCF3F9AE777B30EAA6206A34EF54F74C02 +116: 974E0E85B47CCB870A511810DDEFE81CB85B28D3 +117: 516D6BA01E0186CB7D796FCD9DD169C45B63A93E +118: A1CE534BDD6591AF4EBF61ED75636C7BFF670658 +119: 1E4B241D6EADD77E046BDCCD25F70AAC969262D3 +120: 7F2F1B4B77C3170A9E015DF4E8C6EDFE736DFFC3 +121: 89A3BF181EF195464DBEF9576873CA2DF7D16268 +122: E1F96A7C9115E3DBF28E10D62F2D6EC89415B6D7 +123: D75C1081B3C2720D030EC5DE13093357A0EE6E51 +124: C11603CDAD8DF271093CACDFB5AA4E113A270EA5 +125: 39A9E659DFFDC2ABC88ADA2B6A7445090C7EFBF7 +126: 4132330C5E3344818AF5C054AD55309FF7B767A2 +127: B107A8B0C7B68581969A0F6DB95DB2F790098F1D +128: AD090CC9A6B381C0B3D87035274FBC056012A4E6 + +HMAC-whirlpool + 0: 5C36BE24B458FD3713761955F28353E433B1B818C8EF90F5B7582E249ED0F8C7C518ECF713410885E3FA2B1987B5DEE0FBAC210A007DA0FE995717F8FEA98995 + 1: 30C66EA7CE95764F4CFCFBBE4C166E80A1F23E8C88D2DB7FAC118BCA9EE28299778610D94CD545C18C114A2A144F9E933CD80238E9F1AC737F7149BA232FB846 + 2: A61FAC4DAAADF3DB746DCDC24CACDD8C2B74429CA812D86091B5E7F8186753B34532047B3263D2E231074CCDFB18188747B657E0B685693901CBBEC524949244 + 3: AC3BBA8D998C234F9BCE9A96643E8EFC342F4772DF5606A812C1C6CFD644E8F2B8F9BD724CBC8D769B74C52669705BD3AD390CA61DBC7EBE4438726A91FB2455 + 4: 59AD4171B4C33E09312A01B97B3BC2B7DA43F8791561E32A9186C9B0C418BBC31DF54D6A9ACA00910C0F3DF5D7C2DD7CF5634B76506646B7D4EE5C60AA7C7950 + 5: EDFD9FB5B7BCB39811D87A890171096AD2237B78862C4921191F8B0B137DE5178BE8DA898B6A895FA6C4F401714D2AAC743F512F8989E39081F02A2A0F9F6137 + 6: 6BBE26824C7582213F89F773C520710AE400F01B99BCE126C5F3ABDE79C8B304139352427A3E25A313A5F753A94B55F1EE9D3A0300E8E987E98004F58707F73F + 7: EB89DDACA2BA68940C4616B3B1BDFC25D94A78B8C3A533F1231A259BAF6A6706E1B90CBC2F21A76210C0322C7E4286E393B167A2455DB24C6B52B0CEF3EB78A5 + 8: E8AF385440589959D67746FCD40E295026E942E44259169780B3954D20CBFE2586D2A8BBE408AC2D707B0FE539DB43B3E9B29A8D26D09A41FA6F191999A45186 + 9: F6B9CF6E0A337906517DB09EFA31E91D57D6B908ED5116C13B49B8F1F3C3A872EF42DED53F939CC4EA4122FD8580D528AD2DA72BE063251CC89FB52741E2AEB2 + 10: 274FEF3E5EF7AD7AFB1161A29492F0DF44BA9E1C30E1E88CD708A5D27F2B35C45085A200E9F42F340B0D9B3A1A354B1F5F6D0D1A754D51DFC39CB2EE213112DF + 11: E2EF7A0A64A3F384F95823201823BC95060707F273E395F46F3C0627E1CD2BCE97DB2984C0EE7A11B22E617F0CF64A3F44BE9FD6B38C3A07A504DDC1D33C73B4 + 12: 681D72B9BCA446200BA7578E038A8FC418225BE5F02D8DA3CF085182628B7BE587DCAD4851863CE1CE8653E4916047F8E92E91A6B0D7FFB065F316DA93C4F44A + 13: 2CC82F237ECC1B9B0B9FB76E6B9651C56AE57CAA072A0C20B968F2A74FCA6A9749FA264331F4F2612AE0DF32810B0CAE95E5861473F4675766459B7380F7B9A7 + 14: 1F3818CFB04AA3882442FDF1F5CB0DB2FA9604228D3CCA1F14DA16B35D9B2071B372996A176AF0592F00175EEA4C16A6E0162DE62DE30E8A80FA669FAE9A33CD + 15: BFE4BF868A8AFED289DED5F6E7B21E6856107EBEFAEAB5CD644FB5634181D52D8DEAA203C468ABD279E9BE73507A690C0B715869F6E722C4512E815FA4EF641C + 16: CCBA3834AC7BF06B16675376ECCD96A0F91E3E3C588C5BEE1711A00C107B35D603B20DA8E5CC5FBA6937A24DA53D8F55C907F3E53F0F255E080396426E7ADF9B + 17: B09F6898640E5CF77B6DD3D5A8A4452F4F1D25C90F7AA55A205EFF2C319EC0BE245CEB4190F11D85C2F7234BEB899BDA465C95A1C59568987C4C020B9A7AFC00 + 18: AA7FEEC56E16AD79990B003AD51626C87C9CCB90EBFD748DC268C0C8C1DEE1BDCA1C8064FE7570A5C624AA0CB6BEC163E63680377A16AD49D1AE166090DC0D80 + 19: F755304A4694DBBEB0E59B978943F3D4E429F8123B3D6CE27AB400D3C4BD81A13A8C3C0BA0FA7E5F13BCB0B48290933A05DCB49A5907C074039427F0EC9004FC + 20: CB8B5804EF0478645400B1655DC6E194C8DC26112EF76C57823A02F39C8ADB42F1225B130FF0D40F580DA8CA95D82C0441E3A82C206D9D8D6DBD63B4BB1BCCE2 + 21: 4EEA4AF294C458BDBA7F49AC0826BC295BAF5B16D16F40D379F6B7C3456EF4145B5EC7F7CFB85638F641CF4D07FE3904DA891E68288FC11C0C72F54430915024 + 22: EC52FC8CC0F849E633E3F7339031DCBCEAB69B6634D3E54E7C153CC63DF7D3D3F93B13C8E751E79290ED4845FAA3D5A79A7DE6B100F538E0FFF470A51CD630E4 + 23: D44419C0A36FBFD0FB441B596E8821D3F543D80FC7EB5A3389037BE0139921027571502B5C53BA30D31D4A053E830E610A394842229E08485A2376CB9766313D + 24: 3F4BDBC8A4C86B3F646CC445E2CD54B4C786BAEDEE9FD91A879640B4085D46FEBEECECC95E819ECF6AA9085C2309E79DE1A988C6B68930ABCB9BBAB90F1C2F85 + 25: E5EBC015269E0E61BBD1717618C15D44953AB6F854D962A04FE88865626DCDDEC5F094AAEDCB708D947A9547A985F0B287CA0FBBE3FF2ECCC4C0C4FEE4FE74CB + 26: 010C622DF84E677805108A2C5FB1E8BF5922D35CFAC2408F2AE174D353AF169A40169709C39BFE90E51B095C8C0D2886B4F10B37BEFF805D384E29CECE89C4C8 + 27: 3E9C7BE96E03C48DEA773204E1EC3721EE817ED2403E3C8F950A4C447949438037E2AF0A030CDB983D3FBE5B82226F510FD91CF8830F59212F8CF26C2B5E4DFE + 28: 8797C9C14CD2DE3CB1D29808DA9F23A5502A7BA579586DE9513B980FC06990DE0E29837ED06E24B15DD0000697666B8D3DDC556D818E87F84D125697D5E2F8FE + 29: 93DFA3DEB3258FC7C4F5362D36C2AE21AC0471AF8B895B5AD1C407E8D50DDCD0111AF76EC500D7BE035E6F9CE932190712A3F52FBA4BB0DFCE74400C82D1BD8F + 30: 5587EF7A31353C0E9C346C837EA645770BC5F5C541B72886844B4B0789FF1D95134F558B29385B35960AFDFEA7E3AA40562C12683CB7DD9A410873565CA10880 + 31: 052CB0FAABB263A49516E39525023E2A02DCDB2D5FC78948E042E59F89363FAAF1869D42EC9D7AFB0DADB7D4E99544BEDA92E3270544900A5641F059571B6238 + 32: 2FAEBF049CC4C9C2770E859739B1774EB6E6AC2EAF1AF7D3EB55774C03ADC4C865A65C82E795959CBC4BF00A64AFD2AE0CCA16D58AEB874E253FB9FB9A266790 + 33: 82FBFD2A46F2102AC27089B6889024FA9172FA691C1E3BA9B44A394D52EBF5A7A8BB2321708ED9AF2776D8BAEA13A5F2E9EA4AAF420A24B6F59E2F583D54A797 + 34: B306D18161C766DBDC734FCEB08D14248EBCC63FCBB5B9CC0AE9D690E20E7152D771B3D623D7ECA1CBD305A31EE10C220FCDDC2CE76B578E2F15DE4741E9C9AE + 35: F527D57F0A5F13D7FC6A30A84BF414712044B56FB8F6C1E1375A09783968A851DBD495D51C693590E7A8BB570A7F1C0C9ADAADB74EF8EC71A0093D8D1A4285EE + 36: 0D9F9DB43A0FB4BDF70487002943A6CD3BF200518500B6934BA518B3B0958095930EF59BAC48C84C1E1ADB815A6569FBBE7E61F039BFD8C2F727EF4636542A5D + 37: 614CFB257400128FBBB7B56550E86198155A5647FC11111FB4D36073BB57AE4D9C0A54BCF0DCDB8B54ADE4FF8AE5645821CF9C83F7FA9468FC2CCB552E30BEDF + 38: 7032724503FA5B0765D610D3FA4609F4537F6EAB75D7CC4E2A15D2B1421293D9411C9E8F38999F7D64D607EFE95224331E47FAD4F9BDB6AC19CD3ADE47C17E7D + 39: A8E4316126475B429E72432073CBF26E94DA450DB553D46667D597F0AACB99325C9EDDB94F8CE33551857827AF3935F2DFFE1EE69A20884D58E095390C04B925 + 40: E7E90B19E76017EE80E4979FE56A488AAEEA011DE9DC068DBE53AF06ED44DA4CA3BF662358F191FE2842B083BC5DF2D4183668F4E7FA9E2750869DECA7302202 + 41: 818D734A02A0AE76A0012D7BFE983B17CACE37D4890214C7C53A81CA9F42EF0A472101D609BE5D3DF4F0A55DAF154C20A1A97D53112E22D136C03004FE09149C + 42: 0B9F5B2D4BC3DF781F55ECEE149470F3BF68FC51D121D021DF0CB8D4A5EDA42EA6840DD735ADF8DED72B325662BCEECC6195AE831D169A891F6663F8D7C6E0D3 + 43: 7A5AE42C635B250598C536E531FDAA1746DE2EC7984DC1BE488DE4766D0CD544AB51AB1E62A8A170D120999A61CC6920DB96935F295817851A4CE285D2755112 + 44: 95093085CFE52D746C54DDF8D2FBE33EC00D71C39BE0865B896C331C7E5682FBC0DD84ED15B3F790166D537A9A68EEE5FEEC63FC761EB854018CEB68245CCB90 + 45: 8BA177C495E9832CA8EB55E67E5D7F34C59C4C59D56D50BF6982B36AC341CBFDFBF5A98BBEBC26A9509FBDFB239312DF3B3D5BCE70386EF0E593E17A621F41F5 + 46: 6DD39D94235D012C89FD030341392AE42BE7702C4D8E725C4229940BC273EBB8EDA7A6893B4FF86D1EF84DFA119058BC6C8CA47675492A0D37C859E6D9BD5471 + 47: 13A2FBE3DBAEFCAC5AB8BBAF91BAFDEF5FE38B7F2EBA8BFF0F44B4BBB236613B8BB122BECAD9852BF7638E48F0FC656F9C432D9A66C1188DF3FD1D2A88161139 + 48: 33B9B7EF63B302C1C79E0A43D77487C55D38C53F29C800B4CC287A99A440435121C7ED78BE7406349E65AAF991EA0EF19D06C1AFBB814FE4E0BD68613AF0C760 + 49: 720E1005ACE28903D9C2B6EDE02A52F89860788AFB35208B4B7C147E43BAB3D06445DA138606F334624C606DFF288B0C70B487679685D1DDD26F1DA0A5F6839F + 50: 2A742F1E8CE6CDB501E8AD9BD256786A42E7F1888D9803AA8D5750817B3EA101331D7266298962FA28AF2232BF956FAC7C1C0B1C3DE4C5B3FDDF8E63BEB02185 + 51: 05CF6361A4A238091A1FD011336F7F53B9ACF78BA1B96997EE49B99FE36F0F1163E04B446EEFC117B377593EE078B85BB9588918C76612E2A6F9515E0CA244B2 + 52: F510C877546FD2D022051364A09F2051523F8E7FDCD3E9D2AC5158205FB36CF25A9E0FC394ED2FACA7CB4F0639B33B706FD4D072D62F6EB229E4D7879DFB45CD + 53: 2664476D94776DB52BAAF3B2DE05A36D3E35EF44ABB6F09670F37EEE00C2C54B38F70D06359B20F7E40E22B42901863864EF89EA473A1F3C834D22176E87E617 + 54: 62620CBDA92EC8241DD3A6A0EFB28254B0CEBF3E2351B10CF93029244A6A3D1DCE10D9A895EB6E8A33108DDBAA897DFF2703757DA3706209A7871F4274901E3F + 55: 51282A90B63998F7AE7ADE4787D957992A81D3009D6AC5BF824DD1507B53F6918E9AB6AA1F36373D5E5D3EF8D01AF9D05FBC224781C62C1DCB4A2089BFF5496F + 56: FE1C4394AE26E4B85752045DB14E0AD378726BC1C985C8805222B614C62721E40B2A0D21983FF40AACE8E5F9CD57BA62C37C8F0968EE12FAE14267D6AE906A7A + 57: E570E1183CC6AD7A2C73D7D0E96D3AE0605039603B6F6467FA5CA62E4C1424BC14B17E9614F0ACACCAFC2B1B39D8C081B05DFE2B9796F32C0C742FB09DC7B8DD + 58: E690D667A94344E267A6EA7F3F7A6A5385C961BB6139800CD5257BFD6C4A672DB576B52335D22160A372987D652741EC3AA9439B35D8975AEA49698F8D5528E8 + 59: 59FE977EC1D9927FB09389E3D31272E625F089AA75401D1B541DDCE8C6983A363622CA4F2AA9741F0D1484195CA31D6D315DF6B66E74888D111FEFD249FA0174 + 60: 2CAA990D06814CA73ACEFE0D9A815589958398999707BD52C3773F61B2DC2F20EE7AB7F66D643BD9686C4C460AF45D58BE9F8DFC1B5CFE3A5C2DC2C93D9491A3 + 61: F198E9238E9592A97DDFE1B0B56DE5DC05D358940672D84F15E1CE71ECFD3854CDD38762DF11E1871EE615EB6080E329495B37B23710DCA9F4179F5F95F3E2A3 + 62: 3D7C45603510C6916226B192C81B90EC213D30C11AA21C8520437CA5639D00EAB529A4C443C9A39C5E40DFEEA0F685B3D0E1277BEBDDBF80C3D5F9C8326765D9 + 63: BA081CA12FFBE3CA8F1E2703C96587634F8EB3BA140F93D997B6D0FAD1C1915ECF7D77CC0421E639B083451EDA605571D68DE81E7A4BFC183D7A53A07122168E + 64: CEFE2203F6428D267CD2E284C3B8C31E1946558A56A33291508093DCBF64FD5FA4D33FB723ED49CBA02D97743312138FA77AE960EDF5910E3ADBD02B1203FD97 + 65: DE0379336B1C7421AB4A7F5708BAA3D4E15CE75CEEB8C7349265E71942A963216559FD628C52F71356134AC328D0315ACB63A06382D4251A28127380CCEB08FA + 66: 95FD3399270415A80C2F295957C0BD8E33E35C679C31B2118DFABD542EF02F6E2E432559ED4066954AFBF90C982F60D73DA8BCC94DD48BEDBB00A8E458CCB6B8 + 67: DE49AD8262EACF733B567D8F7752711ECB5D0FF5CB18E5A99C6C35442E652643149A51C820E6D4481AFE63F5B6955105F8173DA57DEFA392E43F7285799A32B9 + 68: BED41AF0733EED85BB26E8A06949AFA1CBCA9BA87C085BDE29FD38F94709F4AC20360F7C7958457D2C49BC5A38FBA06D6A6AF77ACC883783B357032FBA9F93CD + 69: CE72D475D983EB5E528C4D71EEE48EF337E1723DEFDF142598E4CEB3B2978B1B4E36A69EAB6CEE8F3DB2EB353CBD27BF7D41F73FB184CC8785DDCE8EC22E9741 + 70: 24A8A7C759F59CD3DE2E3BA953EA975B60079D9B331AEC4D1F4586FFAD190EF53C2EC6BAB566660EB5D652D7D54265B8584C6BBF986537F54F9D8E4068C01F67 + 71: A7CBE72C99EEEACB387D4532BDB651EB46B8D30A9D5DB8095C9B3422D9D5C9480AA820CFAFE4047AA0546C03DBF07424FCF7B812274B3CDFDC76B9FBBBF08190 + 72: 16D536D1D673F74D9E298B16AE65C65E467131FDE5B4356FE16E3FC36624E19FA7B55727240C51C20491F3122A1AB073B98E095A24F4B3260EBE5211EA2DCB0F + 73: 692189C1FF6DA5862657623BC862F5041D63A2A1EC8986139CCBCAB114427B1A2500B152CC611C5D5599E9792F014A640FBF7C6D944EDA811CD92374326B2C52 + 74: 273E18F4B94E624988C47CC45820E4552DCC53BB40A9A24F744A14E56FB1DADD3EA4087A785AEDB5400A65971709DA1AAB9C18EF534087EA73A1FC8FDC865170 + 75: 8F048230B202743FF1DEBAFEF8CC93244687A58A8E5E3E6F7D85237ADBC724641431783E63FC8EF2FBEF9DE9CD50C9FB294341654706DBEFE6B05CA8588E1A3C + 76: 7AEF7701439F9DB556AD3B166B0B25A51795638A83E0EE25E5244BBE9D2E8CB6A8242D81E78E4906AC9CA0AD4FECD1006D89C5A8582D1BF51C278EE7A357232D + 77: 55CE718F7686A0692B3727BB5C24B16FCB87D8E8EC943A80236CF3E9B37A4A20194243E461B453CF03AD846A0B3287A2005D6603D5E080D700ED2FA25F0FCA87 + 78: 3378B07E0563CA7BCB91F29C8ECA876AD748760748AD07DE0208BAC227E0EED4A4834B8879F3DFE51FFA27B70AAD1F3E9FE1586B1D6B2B9757D545D9CC5DFBB2 + 79: 040E1EC767CDD85FEED2AC6767F0B3C17CE4579FD9525213A682A9B49ED03979144CCE2B94026AAF7D401355B90B25259954163E0C9739CB9E756177ABA053CE + 80: D1CAE0E4FB245C1AC27659C2EE86BADCE26228CF8EA24AA62B69995FF02F9A59B1ACC1C959EF91A7B6EC90EA9D57F49CD0E7621D09E4016676953A3F9B9D40E9 + 81: B41EAC0850797959C62DA2750F2BCAECCDFBAB843D56C034E4E0DC15C961FA611C50F22BBC135E5D99DC4E4B7634A8DF4B0262829593A8A86EF6C265DB9AE907 + 82: 66BE82FD1582736D0DE7861D9DF74715658CF3CD2BCED12868EC4D92F4B015B7BACBB331ACA8D58386AE6B0642C3740BF5F3CB26E76551541AD57E1C303D4527 + 83: C38BC2639AFEC1964C89CB92DE5ECB78E0B2994EF37F839D0A61EA688CCEB068B1A590D6CCC929EFF1145F5A5925A17BF2FC0AD352801CB92651F08352A992D5 + 84: B699ADFC29C54F178B3EFFBF8FE8BFBCD722F2997AC30754A8FC5CC6D51352AFFF7F31D7F71FD9D136E78D1C1E040B05E25CCB75C7AEEF714018F51663C7AD91 + 85: FDC4207E97D12B7A8D05F5073D47EF32BA32961568599ED34CA160F2EDC87726C53087711A63F6BB7E840F305477B931D1CBC1939A8B80205565D453675FCFD7 + 86: 07E1DDE64790A279B69873C6887FBFCA69B87C97BC25B969E2B16040CDD2051BCF43637F490EF1B051CD882B64E22DA55C253A5E796528526EC62A305FB05621 + 87: 3ABE353A4291A3A0ECF204994D49443C1FCC60C80BF6096026551048533E02C475B905046C7708F4852645168C88125221504E174A8B7E67AE424C0077163E0D + 88: 33793697140180A04DA72C0F74E1F845139937CD6F05AF74E3F3C5031D1D2DE571BD72916CBE67859FE501C0E56354C1360E3EBC36EBC11D11C1EE08D158247C + 89: 9E5A386AA9C4C5A2419B902D239E49ED84E542A6F949895C88129DFC2844FC77FB132592C7C1474E619C55FC2835F0810F227799984777CE99D586C158C8F9ED + 90: 6E0D9841C04BB47DEE30F6AB430E53FA1637421E460BBBD7BC8EA167B9A341DDC5E933B6983A025226B1FB3CC663EDC3477F8F0C8FA109A8B97B4B17AF3C2774 + 91: AA0218FD54533314F62390B8C02219D26801C249D394E33981E3B853C5735E331826FA02697DF54C9268B891592DBD876E25C8D985DE8752ADAA0CBE55AE7FFB + 92: 23905B9273CA17D80D9C877DD78150B5382744896B073DC636618C540876B9BA51EC60F5E45DD53BE210B6076554238A3B5EA95DCE3481F0FCF2825B852BDE3E + 93: 1815D1AA4018626EAFF051AFBB92E91F6D6D136F58E8DB160C9E85BEC027B6CC92F0F0760DFD722BE12A97F7D29EEC341BD309F230B55B81D146B409EAEEB7D0 + 94: A2358789A04795BB20D2EDBF95D5DA28A1FBAB329F99DFD0B103304F868CE5AA2DC1F52FE98CC84EB095B9C5ACBD6DC05FD03CFBB3F1D26675D0A8F652D38236 + 95: 2C4DEF028098A0680DF15DEBFE6A7FA42C7A7D75CF410340ADD5257037F0B2F98FB5A068361DF33010FD48A4B41E0E40A2730FF2148C45FA568FAA182589A543 + 96: 360F3B6819EAFD9B3D6BC469F4272F9458C0791759EC1136FAD500F3FCB4FA0598204669E865D7D5F8C289043A2A1CCB47F55CEEFAEAD98C7FDEF38FB22D3A29 + 97: 1CB2E98EE8795761EDB7579583EF86E7223A2109267E5234663BCAAF9FBF28EAE35FE362AE9AD075023C1D36672002E08CB36189A603C174D73BB9489E13355F + 98: 9B3F2D2B2E3D0401229F11E6DED451A1289C631122684BB32B8C0450043ED2267AAEA20E950F52B44EA5941C507F38D23CA76E212593B65BAB347841179BED1D + 99: 2E27C53324017626F7EE7EE26BB0C88450B3D882C2D8823647ECA7650CADDFF3E4201D7DFA2A07A51B9372FCB04C1A79A264DCD3D260DE135D08DBABD2C5869A +100: 0B3D7FFC5DC1CB18B867D995E3D02FB2FBA0DE27BCC85E49A3B01C5581EB3B14C19254C87D92D2EEF952C98E4E6F51C9662CDB982BC95B88C11CB2EECF032576 +101: 85C0B9C8AB8C670C01E179F495DE26F818EE772AAF6FCE4ECBDB4FFADEB1CFD8EA86E42020B47894301920B86082DE52A7E7CDC6DB4904F8F0D383D9CDA312E7 +102: 0C6637D399CFE2734AF7B63F81B7493158B7842E3C5B72E6CEA4388A5C6DB7222D46727B92FB82D88551A227703B8BB6A1AAF47247661E074CF6AE4277D586DB +103: DC54B4ABBB7942C502BF3275E37570947FF7162B6831AA430566E69AA80658C6E792B78EA081611256C64552A9E15A66000632116AC83769B7C58B809FD96021 +104: 532372848D0F525884E5ACED9A727E96A8D92B484DC2D4089206B001CF9EC52902E49E6FD9FDE634941BDF5AA2B45B0787D0B183B895470BF1E79B57DC976EE0 +105: 4B6CEB5AA2174E6486ECB185044629BE6C280807F102CE52D2CE2DCCCFE96E5586A6888DF7500614896C9FE70CF7BC83FE755E88170B3D39EF9B218BE809E495 +106: 6D506B4BD3F079EF4818FCFDA519E7E2AB6A03293525711142C3CDC5236A7CD82A880D9CEDCBC089F7A3D5D3E48BD75DCCA7ADC53B13A2FC9CAC80C037F2CE5D +107: B8ABE308840CC901C6C5FD908E2680886AAA0BDF7085C1A6ABC257186AFC52C522528BD7BF4E82553D9E64CBEE09B9318995E13715AB1F7809EF185E8473D70E +108: 9790A198DA7616F4D8ACDE68DE19635A555874EAE77AD4ECFEF7207DC305D475FD250F308F466B189425AB6A9722D744AEF14541FEB83698943E87E8A39DF838 +109: 816678F1D7484660F4701CE77F4C5E13E5DFADEE6622411BE86DBA4EB71A110DD1087AF7D3F37B8ECB1B9C44A3BD5EA73901C21AAB51E569E61EFF25B5E955F9 +110: 51881FF4B150EDC3542CA12CE6554A40415AFFAA1197FE7CA4B8B065A4FB1DC3B924A444CA31776CED52514C525261269895EBD8584C29747F8D527213534E49 +111: 6D8902F285029EE683CE1803B2D9C6BF6E4B7B59C0ADBFBCED3346782A35652DE3F304ABBDE9F22E4960DF6049431139EC6AA023EE2B013A426DB9A816D92699 +112: 06E5847A060BBC4FCE1375DCC15AEAFBF514EE1ADCDF42AFF932AA277DC09EF614651255E35C499D6BA1BB875EA3E80F80AABF8B7710AA5696B058BE91B99B01 +113: CB1859580DCA13556FAB791572E523C2E888115C18C043B0E33F2268DD0056F9A60EDBB65DD9C8B552CE2299E847ED4617BEF3A453ED2AC3B5366B4D9A651B61 +114: 39778F80D346E53D1B0E60FF7B36A92639D9E7F11548C9326A59D9311D57BF09F33BFD6AC5352F2F041BD07A6D26A181419F5FCD1D5FF8AD38E485DA7DBD5419 +115: E508C9A77F53E36F76F0E477DFF076DE810F9F1599A16A3EFF1840332B26D6C7CC40E03CA8CC212FDA776F4DF968FCF92CE492AEBAABD65F069D1AEBECD11B7B +116: 4659D0E1F9E5318D7B92FCF7700C467429B63F27188C0BA168F0D5696DC764FBFE2C5EFFCF6DF11EA77A17B0565CADC04F95FFB0485CE6900161B82608B1647B +117: B3DB7FF2F08F57F0CBF2195BB9600E9AE5D86A15921EB164A98D25D559BAF5FD740D68430653DE73F3277425DD77CC3FB0CB44ACC5FDE693D59D5FA6DED84597 +118: CA4559843946A7583F944D51E31FDF32BBDBBFC049724454C090A6DB9C356739F2B7E254CF9746521D965593FBBCFB26092069FBFB0D17A1593416D69681B687 +119: 27CB8A2143D1073AC17009C31B28DB95DC195E20AD7D245D8AD880789898F043F0565FE41485EDC239C7129E4B7FB693D9044B2C3D34C5648E4FD8447E85FD71 +120: 99811490C7FC83A10AAD197E95D3618ABF5018E9AF7EA0AA2CC0C771FC11FCEF9FD6070A0962A563D260E8CCFDB77B48745C8C27018F9140870F146F124FF14B +121: A1537FDAD7E18F732181CD9EC9BFD3993FAF5F994A8809A106B59D13BB70FD8D7D4E6A4BEDFA806A9D434AAB0368DE840FD64395B4A9A874DB39405707AE3AE3 +122: FB0D6D962055B47D3A72371BDAF77BE7BF965EA7D53018CAE086E3536804AC748E706E89772DB60896EB8FE2ED8F580866BAF3108CA0C97938B69830FFBC14E3 +123: 3C947F4136D9E780A7572CA4D5D7998DD82D3890CC3F1BCB59A7FE230E31DE322DBA7CF7C1DACB33A3EB1F7E75297C056570D2846EDF756D36C1AE92F8DF6954 +124: BC1BDEFFC6AB779A7ACFE53A3F9DD588CD3C77C740F944C69E331C38F162607E0D4A0CA874AC3D1D74965468843133AA9F961FBFCBF59B58818577132B863181 +125: 51143DA8F5D6E68EC97CE22A4961EF43B3AB658711280587D9ACEE701CA65CAE90D34B66DB52D779A8E2BB6204FFCBCA945C6B98B2C17C8375551FAAFE4C8A44 +126: 2550FCF54872616ED31C60FB3FD97B9AEC7A27B3CEC07D774FCE694ED9D60C43A968251C5F3C5B50E6214426B00C55D7DB1DB31CFC4BC07F6ACEA222052AB796 +127: 1D8B2525E519A3FF8BDAAF31E80EE695F5914B78E7DAB801729B5D84C3A7A2B36A33803F5E0723981CF8A9586EC1BEABC58154EFD919AFF08935FBD756327AAB +128: 4AABF1C3F24C20FFAA61D6106E32EF1BB7CDEB607354BD4B6251893941730054244E198EECD4943C77082CC9B406A2E12271BCA455DF15D3613336615C36B22E + +HMAC-chc_hash + 0: 0607F24D43AA98A86FCC45B53DA04F9D + 1: BE4FB5E0BC4BD8132DB14BCBD7E4CD10 + 2: A3246C609FE39D7C9F7CFCF16185FB48 + 3: 3C7EA951205937240F0756BC0F2F4D1B + 4: 7F69A5DD411DFE6BB99D1B8391B31272 + 5: DCB4D4D7F3B9AF6F51F30DCF733068CC + 6: 1363B27E6B28BCD8AE3DCD0F55B387D7 + 7: BB525342845B1253CFE98F00237A85F3 + 8: 89FB247A36A9926FDA10F2013119151B + 9: 54EB023EF9CE37EDC986373E23A9ED16 + 10: 2358D8884471CB1D9E233107C7A7A4A0 + 11: 94BAB092B00574C5FBEB1D7E54B684C4 + 12: DF1819707621B8A66D9709397E92DC2F + 13: 3044DFFC7947787FDB12F62141B9E4FB + 14: 9EA9943FC2635AD852D1C5699234915D + 15: 1CC75C985BE6EDD3AD5907ED72ECE05E + 16: 1A826C4817FF59E686A59B0B96C9A619 + 17: 44DB2A64264B125DE535A182CB7B2B2C + 18: 4741D46F73F2A860F95751E7E14CC244 + 19: 13FDD4463084FEEB24F713DD9858E7F4 + 20: D3308382E65E588D576D970A792BAC61 + 21: 38E04BD5885FEA9E140F065F37DD09FC + 22: 5C309499657F24C1812FD8B926A419E2 + 23: D1FDB9E8AC245737DA836D68FA507736 + 24: F6924085988770FCC3BC9EEA8F72604E + 25: C72B261A79411F74D707C6B6F45823BD + 26: 2ED2333EBAC77F291FC6E844F2A7E42D + 27: CE0D3EF674917CEA5171F1A52EA62AAE + 28: 55EDEAC9F935ABEAF2956C8E83F3E447 + 29: 820B799CB66DC9763FFD9AB634D971EC + 30: E14B18AB25025BF5DF2C1A73C235AD8B + 31: DE9F394575B9F525A734F302F0DB0A42 + 32: 625ED3B09144ADFF57B6659BB2044FBE diff --git a/t/mac_omac.t b/t/mac_omac.t new file mode 100644 index 0000000..6f84bc8 --- /dev/null +++ b/t/mac_omac.t @@ -0,0 +1,81 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 72; + +use Crypt::Mac::OMAC qw( omac omac_hex omac_b64 omac_b64u ); + +is( unpack('H*', Crypt::Mac::OMAC->new('AES','1234567890123456')->add("")->mac), '0858f76009f57ad2c6fd771d1b93a21e', 'OMAC/oo+raw/1'); +is( Crypt::Mac::OMAC->new('AES','1234567890123456')->add("")->hexmac, '0858f76009f57ad2c6fd771d1b93a21e', 'OMAC/oo+hex/1'); +is( unpack('H*', omac('AES','1234567890123456',"")), '0858f76009f57ad2c6fd771d1b93a21e', 'OMAC/func+raw/1'); +is( omac_hex('AES','1234567890123456',""), '0858f76009f57ad2c6fd771d1b93a21e', 'OMAC/func+hex/1'); +is( omac_b64('AES','1234567890123456',""), 'CFj3YAn1etLG/XcdG5OiHg==', 'OMAC/func+b64/1'); +is( omac_b64u('AES','1234567890123456',""), 'CFj3YAn1etLG_XcdG5OiHg', 'OMAC/func+b64u/1'); +is( unpack('H*', Crypt::Mac::OMAC->new('AES','12345678901234561234567890123456')->add("")->mac), '659fa9f016ce9b4a2bf9f5ec4486732b', 'OMAC/oo+raw/2'); +is( Crypt::Mac::OMAC->new('AES','12345678901234561234567890123456')->add("")->hexmac, '659fa9f016ce9b4a2bf9f5ec4486732b', 'OMAC/oo+hex/2'); +is( unpack('H*', omac('AES','12345678901234561234567890123456',"")), '659fa9f016ce9b4a2bf9f5ec4486732b', 'OMAC/func+raw/2'); +is( omac_hex('AES','12345678901234561234567890123456',""), '659fa9f016ce9b4a2bf9f5ec4486732b', 'OMAC/func+hex/2'); +is( omac_b64('AES','12345678901234561234567890123456',""), 'ZZ+p8BbOm0or+fXsRIZzKw==', 'OMAC/func+b64/2'); +is( omac_b64u('AES','12345678901234561234567890123456',""), 'ZZ-p8BbOm0or-fXsRIZzKw', 'OMAC/func+b64u/2'); +is( unpack('H*', Crypt::Mac::OMAC->new('Blowfish','1234567890123456')->add("")->mac), 'a53ab7d313338f8f', 'OMAC/oo+raw/3'); +is( Crypt::Mac::OMAC->new('Blowfish','1234567890123456')->add("")->hexmac, 'a53ab7d313338f8f', 'OMAC/oo+hex/3'); +is( unpack('H*', omac('Blowfish','1234567890123456',"")), 'a53ab7d313338f8f', 'OMAC/func+raw/3'); +is( omac_hex('Blowfish','1234567890123456',""), 'a53ab7d313338f8f', 'OMAC/func+hex/3'); +is( omac_b64('Blowfish','1234567890123456',""), 'pTq30xMzj48=', 'OMAC/func+b64/3'); +is( omac_b64u('Blowfish','1234567890123456',""), 'pTq30xMzj48', 'OMAC/func+b64u/3'); +is( unpack('H*', Crypt::Mac::OMAC->new('Blowfish','12345678901234561234567890123456')->add("")->mac), 'a53ab7d313338f8f', 'OMAC/oo+raw/4'); +is( Crypt::Mac::OMAC->new('Blowfish','12345678901234561234567890123456')->add("")->hexmac, 'a53ab7d313338f8f', 'OMAC/oo+hex/4'); +is( unpack('H*', omac('Blowfish','12345678901234561234567890123456',"")), 'a53ab7d313338f8f', 'OMAC/func+raw/4'); +is( omac_hex('Blowfish','12345678901234561234567890123456',""), 'a53ab7d313338f8f', 'OMAC/func+hex/4'); +is( omac_b64('Blowfish','12345678901234561234567890123456',""), 'pTq30xMzj48=', 'OMAC/func+b64/4'); +is( omac_b64u('Blowfish','12345678901234561234567890123456',""), 'pTq30xMzj48', 'OMAC/func+b64u/4'); +is( unpack('H*', Crypt::Mac::OMAC->new('AES','1234567890123456')->add(123)->mac), 'cdda83e8105929d720615d2e2919f517', 'OMAC/oo+raw/5'); +is( Crypt::Mac::OMAC->new('AES','1234567890123456')->add(123)->hexmac, 'cdda83e8105929d720615d2e2919f517', 'OMAC/oo+hex/5'); +is( unpack('H*', omac('AES','1234567890123456',123)), 'cdda83e8105929d720615d2e2919f517', 'OMAC/func+raw/5'); +is( omac_hex('AES','1234567890123456',123), 'cdda83e8105929d720615d2e2919f517', 'OMAC/func+hex/5'); +is( omac_b64('AES','1234567890123456',123), 'zdqD6BBZKdcgYV0uKRn1Fw==', 'OMAC/func+b64/5'); +is( omac_b64u('AES','1234567890123456',123), 'zdqD6BBZKdcgYV0uKRn1Fw', 'OMAC/func+b64u/5'); +is( unpack('H*', Crypt::Mac::OMAC->new('AES','12345678901234561234567890123456')->add(123)->mac), '93cfd941f83b842afe81326332f25e32', 'OMAC/oo+raw/6'); +is( Crypt::Mac::OMAC->new('AES','12345678901234561234567890123456')->add(123)->hexmac, '93cfd941f83b842afe81326332f25e32', 'OMAC/oo+hex/6'); +is( unpack('H*', omac('AES','12345678901234561234567890123456',123)), '93cfd941f83b842afe81326332f25e32', 'OMAC/func+raw/6'); +is( omac_hex('AES','12345678901234561234567890123456',123), '93cfd941f83b842afe81326332f25e32', 'OMAC/func+hex/6'); +is( omac_b64('AES','12345678901234561234567890123456',123), 'k8/ZQfg7hCr+gTJjMvJeMg==', 'OMAC/func+b64/6'); +is( omac_b64u('AES','12345678901234561234567890123456',123), 'k8_ZQfg7hCr-gTJjMvJeMg', 'OMAC/func+b64u/6'); +is( unpack('H*', Crypt::Mac::OMAC->new('Blowfish','1234567890123456')->add(123)->mac), '357f9876a15825ec', 'OMAC/oo+raw/7'); +is( Crypt::Mac::OMAC->new('Blowfish','1234567890123456')->add(123)->hexmac, '357f9876a15825ec', 'OMAC/oo+hex/7'); +is( unpack('H*', omac('Blowfish','1234567890123456',123)), '357f9876a15825ec', 'OMAC/func+raw/7'); +is( omac_hex('Blowfish','1234567890123456',123), '357f9876a15825ec', 'OMAC/func+hex/7'); +is( omac_b64('Blowfish','1234567890123456',123), 'NX+YdqFYJew=', 'OMAC/func+b64/7'); +is( omac_b64u('Blowfish','1234567890123456',123), 'NX-YdqFYJew', 'OMAC/func+b64u/7'); +is( unpack('H*', Crypt::Mac::OMAC->new('Blowfish','12345678901234561234567890123456')->add(123)->mac), '357f9876a15825ec', 'OMAC/oo+raw/8'); +is( Crypt::Mac::OMAC->new('Blowfish','12345678901234561234567890123456')->add(123)->hexmac, '357f9876a15825ec', 'OMAC/oo+hex/8'); +is( unpack('H*', omac('Blowfish','12345678901234561234567890123456',123)), '357f9876a15825ec', 'OMAC/func+raw/8'); +is( omac_hex('Blowfish','12345678901234561234567890123456',123), '357f9876a15825ec', 'OMAC/func+hex/8'); +is( omac_b64('Blowfish','12345678901234561234567890123456',123), 'NX+YdqFYJew=', 'OMAC/func+b64/8'); +is( omac_b64u('Blowfish','12345678901234561234567890123456',123), 'NX-YdqFYJew', 'OMAC/func+b64u/8'); +is( unpack('H*', Crypt::Mac::OMAC->new('AES','1234567890123456')->add("test\0test\0test\n")->mac), '628848c1604f58010affc6ad6cf07135', 'OMAC/oo+raw/9'); +is( Crypt::Mac::OMAC->new('AES','1234567890123456')->add("test\0test\0test\n")->hexmac, '628848c1604f58010affc6ad6cf07135', 'OMAC/oo+hex/9'); +is( unpack('H*', omac('AES','1234567890123456',"test\0test\0test\n")), '628848c1604f58010affc6ad6cf07135', 'OMAC/func+raw/9'); +is( omac_hex('AES','1234567890123456',"test\0test\0test\n"), '628848c1604f58010affc6ad6cf07135', 'OMAC/func+hex/9'); +is( omac_b64('AES','1234567890123456',"test\0test\0test\n"), 'YohIwWBPWAEK/8atbPBxNQ==', 'OMAC/func+b64/9'); +is( omac_b64u('AES','1234567890123456',"test\0test\0test\n"), 'YohIwWBPWAEK_8atbPBxNQ', 'OMAC/func+b64u/9'); +is( unpack('H*', Crypt::Mac::OMAC->new('AES','12345678901234561234567890123456')->add("test\0test\0test\n")->mac), '20d6c5cc640730d2b8bb9308031c000b', 'OMAC/oo+raw/10'); +is( Crypt::Mac::OMAC->new('AES','12345678901234561234567890123456')->add("test\0test\0test\n")->hexmac, '20d6c5cc640730d2b8bb9308031c000b', 'OMAC/oo+hex/10'); +is( unpack('H*', omac('AES','12345678901234561234567890123456',"test\0test\0test\n")), '20d6c5cc640730d2b8bb9308031c000b', 'OMAC/func+raw/10'); +is( omac_hex('AES','12345678901234561234567890123456',"test\0test\0test\n"), '20d6c5cc640730d2b8bb9308031c000b', 'OMAC/func+hex/10'); +is( omac_b64('AES','12345678901234561234567890123456',"test\0test\0test\n"), 'INbFzGQHMNK4u5MIAxwACw==', 'OMAC/func+b64/10'); +is( omac_b64u('AES','12345678901234561234567890123456',"test\0test\0test\n"), 'INbFzGQHMNK4u5MIAxwACw', 'OMAC/func+b64u/10'); +is( unpack('H*', Crypt::Mac::OMAC->new('Blowfish','1234567890123456')->add("test\0test\0test\n")->mac), '40e6d018b49ada77', 'OMAC/oo+raw/11'); +is( Crypt::Mac::OMAC->new('Blowfish','1234567890123456')->add("test\0test\0test\n")->hexmac, '40e6d018b49ada77', 'OMAC/oo+hex/11'); +is( unpack('H*', omac('Blowfish','1234567890123456',"test\0test\0test\n")), '40e6d018b49ada77', 'OMAC/func+raw/11'); +is( omac_hex('Blowfish','1234567890123456',"test\0test\0test\n"), '40e6d018b49ada77', 'OMAC/func+hex/11'); +is( omac_b64('Blowfish','1234567890123456',"test\0test\0test\n"), 'QObQGLSa2nc=', 'OMAC/func+b64/11'); +is( omac_b64u('Blowfish','1234567890123456',"test\0test\0test\n"), 'QObQGLSa2nc', 'OMAC/func+b64u/11'); +is( unpack('H*', Crypt::Mac::OMAC->new('Blowfish','12345678901234561234567890123456')->add("test\0test\0test\n")->mac), '40e6d018b49ada77', 'OMAC/oo+raw/12'); +is( Crypt::Mac::OMAC->new('Blowfish','12345678901234561234567890123456')->add("test\0test\0test\n")->hexmac, '40e6d018b49ada77', 'OMAC/oo+hex/12'); +is( unpack('H*', omac('Blowfish','12345678901234561234567890123456',"test\0test\0test\n")), '40e6d018b49ada77', 'OMAC/func+raw/12'); +is( omac_hex('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), '40e6d018b49ada77', 'OMAC/func+hex/12'); +is( omac_b64('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), 'QObQGLSa2nc=', 'OMAC/func+b64/12'); +is( omac_b64u('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), 'QObQGLSa2nc', 'OMAC/func+b64u/12'); diff --git a/t/mac_omac_test_vectors_ltc.t b/t/mac_omac_test_vectors_ltc.t new file mode 100644 index 0000000..8576d8e --- /dev/null +++ b/t/mac_omac_test_vectors_ltc.t @@ -0,0 +1,562 @@ +use strict; +use warnings; + +use Test::More tests => 452; +use Crypt::Mac::OMAC; +use Crypt::Cipher; + +my $trans = { + "3des" => 'DES_EDE', + "safer+" => 'SAFERP', + "khazad" => 'Khazad', + "safer-k128" => 'SAFER_K128', + "safer-sk128"=> 'SAFER_SK128', + "rc6" => 'RC6', + "safer-k64" => 'SAFER_K64', + "safer-sk64" => 'SAFER_SK64', + "anubis" => 'Anubis', + "blowfish" => 'Blowfish', + "xtea" => 'XTEA', + "aes" => 'AES', + "rc5" => 'RC5', + "cast5" => 'CAST5', + "skipjack" => 'Skipjack', + "twofish" => 'Twofish', + "noekeon" => 'Noekeon', + "rc2" => 'RC2', + "des" => 'DES', + "camellia" => 'Camellia', +}; +my $tv; +my $name; +my $ks; + +while (my $l = ) { + $l =~ s/[\r\n]*$//; + $l =~ s/^[\s]*([^\s\r\n]+).*?/$1/; + $l =~ s/\s+//; + if ($l=~/^OMAC-([a-z0-9\+\-]+).*?(\d+)/i) { + $name = $1; + $ks = $2; + next; + } + my ($k, $v) = split /:/, $l; + next unless defined $k && defined $v; + $tv->{$name}->{$ks}->{$k} = $v if $name && $k =~ /\d+/; +} + +my $seq; +$seq .= pack('C',$_) for(0..255); +my $zeros = '\0' x 255; + +for my $n (sort keys %$tv) { + for my $ks (sort keys %{$tv->{$n}}) { + my $N = $trans->{$n} || die "FATAL: unknown name '$n'"; + my $key = substr($seq, 0, $ks); + for my $i (0..255) { + my $bytes = substr($seq, 0, $i); + next unless $tv->{$n}->{$ks}->{$i}; + my $result = Crypt::Mac::OMAC->new($N, $key)->add($bytes)->mac; + is(unpack('H*', $result), lc($tv->{$n}->{$ks}->{$i}), "$N/$i"); + $bytes = $result; + $key = substr($result x 100, 0, $ks); + } + } +} + +__DATA__ +OMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are OMAC'ed. The initial key is +of the same format (length specified per cipher). The OMAC key in step N+1 is the OMAC output of +step N (repeated as required to fill the array). + +OMAC-aes (16 byte key) + 0: 97DD6E5A882CBD564C39AE7D1C5A31AA + 1: F69346EEB9A76553172FC20E9DB18C63 + 2: 996B17202E2EDEBD63F414DD5E84F3AF + 3: D00D7DA967A2873589A7496503B3DBAB + 4: B43C24C0A82DAA12D328395C2ABD7CAE + 5: 9B902B6663B5FEDC6F9DCE74B35B91F2 + 6: 06A9678C65D7CE225E082ECA31788335 + 7: 7D67866CDB313DF65DED113DB02D6362 + 8: 259E28CF3E578AC47A21A77BA9EA8261 + 9: 32F23C8F93EA301C6D3FE0840CA8DB4B + 10: C2B06388AD6F8C43D19FE4F6A8ED21AE + 11: FA8622485DB2F62F84FF46E532A1A141 + 12: F312D9B2E6272578F406B66C79F30A0E + 13: 7A5DE06B2BFB75ADA665E96F680AC098 + 14: C3B00380F0BD8E2F5C9DD9945E0F36EE + 15: DDD87974A5FB2E7A4514241E94526B5B + 16: AD24FC47A0FEA84C54696DE997A94F4B + 17: 7538713D8AA2AE3726307EFF087BBF5E + 18: 7619A52B4C34A98440812F5F28F8DC4F + 19: 7E797B8846554888622CC5E400B2FA44 + 20: 61E8DD3E09145F5657DB4B8F7BD2D7D8 + 21: FDAE2A3FE60DDF1871C2613A293AB6F1 + 22: A186D6EFD10DFFD2C088480B0A784185 + 23: 3119D337865618CDA55C06FB992427CF + 24: 413E3EAD7E3F169A37C49F9CA92E235E + 25: 37A55AF22373B9A1E2F8368B2FB992CA + 26: 4941F604C40EEEE1A16CFE073C12D1FE + 27: 3E8F4A0876BF12A2DCA87157F15DC884 + 28: 5DFAE292D8EEB13D8FE5725E5D169742 + 29: 59160455E0C0B35D950BA67C77F9FB05 + 30: 5AC0D736A06A7DD146B137ADEE78EE06 + 31: 0CA1178F28B953045EE76E2E760036CA + 32: 025616215F870D1EF838AD1D2AE0C649 + +OMAC-blowfish (8 byte key) + 0: 2CFB5DE451FFE8CC + 1: A5AC339DB44D020C + 2: A3CE0CF62249444D + 3: 3076B7129CE3F6A1 + 4: 9E091A637DDF70E3 + 5: 275199AB20A5F09C + 6: CDEDA8D16A401E62 + 7: FC980516CF5C9E30 + 8: 659D0B31D21B622B + 9: 8306847B5E72E018 + 10: 7AD029BBF1D2919F + 11: 133181425C6808C9 + 12: FC5AC60E367F413A + 13: E0DF8BCCF0AD01D9 + 14: AC5015398FA64A85 + 15: 1F068F22AFFECEE1 + 16: 8E6831D5370678EF + +OMAC-xtea (16 byte key) + 0: A821403929958A1A + 1: 68C4A02D47C2E7C0 + 2: 7D37358141506DC1 + 3: 9BEA3AAE55B75F52 + 4: 884D053D05CC8DE4 + 5: E953747483FF4E0D + 6: B6E77E72C9738E4F + 7: 8AB67D2B24E3D512 + 8: 329C0B9D504A0D41 + 9: 50323DA8ACEF4164 + 10: FA3239C668C34DA3 + 11: B5A12FC81FC24084 + 12: 71A01A3ED3936934 + 13: F29B630CEB6AEDDB + 14: F8802F0D4504D55E + 15: F844B92162038F99 + 16: 99AECD7CA69F0465 + +OMAC-rc5 (8 byte key) + 0: E374E40562C3CB23 + 1: B46D83F69233E236 + 2: 7CB72B1D335F04B0 + 3: 94457CBC97B31328 + 4: 543D0EDFCDCD7C76 + 5: 5164EFA8412EAA5D + 6: 13CA0717EF95F9A7 + 7: 2AA49A7AA7719700 + 8: C9E7C56125C3D90F + 9: 2BE3E15FE58648AA + 10: 77D0B90372D6D0FD + 11: 17408F62ECD62F57 + 12: 7864EFFA59DC059B + 13: 3212E76E25E5DEA8 + 14: E2424C083CDE5A6A + 15: DE86FFDBDA65D138 + 16: 85482C24D61B8950 + +OMAC-rc6 (16 byte key) + 0: E103BD8BA47B7C1C010E1561712E6722 + 1: E51AEECFED3AF40443B3A1C011407736 + 2: FA6506C5ABE03381B045D28D1D828966 + 3: FAC4237FFE7772E2299D3D983BB130DD + 4: 3A7E24D41121A5D4F96FCECF0C2A4A10 + 5: AA44291E5500C1C8E1A14CB56E4F979A + 6: 4B8FDA6DA6B3266E39111F403C31754E + 7: 4DF5F1A1C8EBC7F56D0D12EEB63FF585 + 8: 46A6DDE419355EDE14D31045FCA1BA35 + 9: 71756D4D3DF59578B7F93FD4B5C08187 + 10: ADA292A19F8636A03A8BC58C26D65B0D + 11: 703190DAF17F8D08A67A11FDF0C2A622 + 12: D2B94CAD1AFC5CD012575964D1425BE6 + 13: 45FD0069FCA6F72E23E4DB41AA543091 + 14: 36F652600F5C9F226721400A7199E2BA + 15: E8CC6389ECF8EF1DBB90A0FD051B7570 + 16: 8125446B975DBDA742A903340D6B96C7 + 17: 00B55E4399EB930E592F507F896BF3DC + 18: 33E58F42A47C9543A851D6CA9324FEE0 + 19: 9F28FDEA3EC7F515128F5D0C0EB684C5 + 20: AC1DAF6C01AA28BCC0A819189FA949D7 + 21: D0532B5F54A179444D052A4D2AD6E4F9 + 22: 58B80A66549404C7B9F64D5AE3F798AB + 23: D0D6D586477F92311DDF667E0749D338 + 24: 0DFC0FAA67FF114398CE94D0688AE146 + 25: E163B8C00CF5CC9FA23ACACD62B53D64 + 26: ACE9270456AF9BD388BA72E98825CFE8 + 27: 4302EED9BAA19C7A296585E23A066A44 + 28: B3EEABEFAB25C7478419265564715387 + 29: 9F0630ADE9C74AB2981D63F3B69E85BF + 30: 1215A9446A275CCE2714F94F3C213BB7 + 31: AF43D7F748DE0E3458DB970BAC37E98D + 32: BF871AC9E892CE0DCD7C8C7ADDD854C6 + +OMAC-safer+ (16 byte key) + 0: A2C8C7FEA5529D01C3FF4E9359EF74F4 + 1: EAB87021118FF24FE79B69ABCCB14A8F + 2: 789566F467BAA68F4CC3C4B61901D6D4 + 3: 369F41EEAF7D628F9E0D77BE43BFC1D2 + 4: DC46A20E1F36F45006ED5B43BEC20DA6 + 5: 8F150CE34F57BBA2E6CE3431B78E4ACD + 6: 61CD154478BE20F33B26CD8FC58091A5 + 7: 4E6DAA575CF28F1F48B256262B7D558C + 8: D21FA4F1859571DB91E92767C5487AA2 + 9: E3D009DC7E71FBBB030B8FF0B544A2C9 + 10: 094C236EA48ABF7DBAE5A88AA3DE07D7 + 11: 00C401996F8224359566660AC1CEDAA1 + 12: D580EC60F712558D875F01643D96653F + 13: 8482298027C7B4D5969787A1DB1B1F2F + 14: AB726AE3DA95CB242E63EF876A4BC446 + 15: D668ED4919003F5E45590663FAED41DA + 16: E4CFFD7E0E7B176867C386001849FD6F + 17: 37B3C6DEFC5573879006D15F982A397C + 18: 0AB8847EE6A41A0E960080EF0D1BF1C5 + 19: 2C94FCA2A685F276A65ED286AE12FD9F + 20: 23383032032D7B5165A31ECA156DBD23 + 21: E1EECFB3D671DF694FFB05AE4305AD4C + 22: A0F6CA99B96CD1EDD04C52828C8A4D74 + 23: 12D6B7053417AF3E407EFD6EE1CC38FE + 24: A566D1C39AE7A1A0A77D5A1F56C5FAAB + 25: 81C9FAECEAEA326140AFCD569668F669 + 26: 6A00BF1D0DC893868378E4347CB4A1B9 + 27: 98842956DBE7AFB1BF49C46497BD54C7 + 28: 88EFCD5A1644B75BB0B3F5DD338849CE + 29: 77EC62C278C61163B1BEC595A11F047A + 30: 147424E817DC69413CC657E0CB292F7F + 31: A2946CBB910743EF62D8A3C7391B9B9B + 32: 00EEDA55520B8A5B88B76487E80EB6E1 + +OMAC-twofish (16 byte key) + 0: 0158EB365FCCFDD94EBA6BE42B6659C4 + 1: 17DA580917D147D10CB73DB6800B0E59 + 2: 3F185CC15EF3328D3E075665308C07C8 + 3: 5712A97ACC9D08FE9D2087D0CA16B0AD + 4: 90425A8CC1C026DDD896FC2131AF654B + 5: 30A43D4FEAE71F5396308C16DA081B4A + 6: 6839FEF605704D49F1A379A9E9595E6F + 7: 56A8F06DFEE543971B351B07430E2026 + 8: 36DD0E4B55C5314F9F2753D7EB6F0849 + 9: 8E319249A3CD456460F410F518F8CEDB + 10: 463978BE2A063C22E71DC71520723517 + 11: 1B735E45FD3DF636E0A6104D4A2E9CB8 + 12: 628A82213148AD9791153D5AAFBDDFDC + 13: 21AFDF08A36ADB6659B656C8EA0800E5 + 14: E5C3E58803DDBE174E0D4C2B8171AEF0 + 15: FC6981F2B4359BA05988D61822C0FA88 + 16: 7B03498FAFB04A6542248852225F9DAE + 17: 9B173E91E59A940186E57BB867B8307B + 18: 470BF2EE614C8423AA3FDF323F1C103E + 19: 6E664AFDFD8306547BBEDA036D267B79 + 20: F61AEC1144C3DD646169E16073700AC6 + 21: AE503B139707AFA494F7F2DE933EE81A + 22: A0A8BDD4ED0DCAE4A8E1DCEE56368FF0 + 23: 460B8207930DA434AE6AFECC305D9A26 + 24: 7F03F8C7BA5365CC65F7864A42693BC8 + 25: 31448849D6190484192F29A221700011 + 26: BDA941019C75551D858F70FB1362EB23 + 27: 2880CB3E62447AE8EACA76C17971BB18 + 28: FC8D710FA3990B56357E61C2A302EB84 + 29: 793CD15348D7DFF301C47BC6E6235E22 + 30: 6FB0CE69A15A3B6A933324A480077D35 + 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 + 2: EC82EAD195AAC38C + 3: 53DD52269B19E9A4 + 4: 9B86F64BF72A0647 + 5: 664A88A29F2898C6 + 6: AFEC3F71C1415666 + 7: 9BA1F2C1A2E765F9 + 8: 402A12120908B436 + 9: 03ECCD4C6AF44144 + 10: E8CA3529B5D9D6FC + 11: 951EE10779CC585D + 12: B9083CA88E7E819B + 13: AFFB9E884DACC5B7 + 14: E942E8BC241343D6 + 15: 9B190489091344FB + 16: 9330A9E05554A15A + +OMAC-des (8 byte key) + 0: C9085E99D74DF01D + 1: FAC84F0EFBEF8630 + 2: C37C5FECE671CF16 + 3: 45B2CBEE8701A5B1 + 4: 53665E1F024EB001 + 5: 357123CEDFC9FF61 + 6: BD2CFD33FB1F832B + 7: 1AAA9D8C9120BDBF + 8: EB9F589AE9D4E78F + 9: C8F9D2ACE691922D + 10: 81ED6F3611DDC0FD + 11: 2965ABEAC46839EE + 12: 2208B1E095F7AE2E + 13: C0414FE41800113E + 14: 653A24119CF43D97 + 15: 7FB7CE0862958B37 + 16: 55097816B10C549B + +OMAC-3des (24 byte key) + 0: 7F07A9EA8ECEDF9E + 1: 4E2A652EB5FBF5F8 + 2: 4F84E3779ACCB9F5 + 3: 7134AB3463115DC6 + 4: 82327BE8EA2D7E0B + 5: 24950B9C14D87CD9 + 6: B25A097BB7E0E18A + 7: ED51BAE55ED925E7 + 8: 56B79E7644556975 + 9: A65BD98E4D4E31E2 + 10: 11145BB51514482D + 11: 397486787E676BA6 + 12: BD1F6DEBAF6D9AEF + 13: 5CC3921F7DB815CF + 14: B0C0E60DA5F727F3 + 15: F8637AEEFF10F470 + 16: 0EA19531D42706EA + +OMAC-cast5 (8 byte key) + 0: 7413DCDB9F0C3100 + 1: 423799EDF1472B79 + 2: 03856F0CB4F11606 + 3: F152AE6360813DE0 + 4: 853998BD980AD146 + 5: AE6C3D667DB8B414 + 6: B5A4986A34BDE20F + 7: E5ABE5B979798942 + 8: BEE8DFED4555F405 + 9: 6B5339E952AF61BE + 10: 5E867CF34D9C1149 + 11: F9C55CB3BC655E08 + 12: EA09A2929AC7D915 + 13: CE8EB0E4370E1933 + 14: 749A424B2AA91B98 + 15: 8DDA93C2B814D5D1 + 16: E8B0B219D4CB699B + +OMAC-noekeon (16 byte key) + 0: A9F50A6567FAD338AB5727B3B94DEB82 + 1: C9EC17EF3656C9056E64E692A449AD24 + 2: 7D1F6A3373BF20D4E65804B745D40855 + 3: FE3484F11C338721F3FCB4DCC608BD6E + 4: C45670D31D48CE9AD70BADE9F7A6A5B3 + 5: 6AF86480F1AE638DCAC40939B864D4DE + 6: CBBAFED3A5891A7BD8692055E4C59444 + 7: B23439FC6D1CF0E3B04BE5201CAF9283 + 8: 385D2C64F55B3FE976E660155FAC4C90 + 9: 239D4B8F663248076E64CF743AC14EC0 + 10: B942C5E06C6E68866440EB10747643B6 + 11: 9B591FA2FD9A20C367FB03366150D1E7 + 12: F90183F872D062AB4642DCDCED399970 + 13: 86003C2F260EAFC81BC45A0614F88381 + 14: C80F88A148FF906D42E6D75A50049468 + 15: 0A81478238ED815D7CB04C0DC5A4A4D5 + 16: DFE74730DB9CF4F994084C88923A8931 + 17: 91194DAAAB458B5B34E991EF534D4BD8 + 18: DAA1CCA0B644AB9F8B4D889D7F1268FB + 19: A93AE4F41DFB6CA311FAAA148A9D53D9 + 20: 6FFD47B80A991A6C09775060E4A4B13E + 21: 4BE3101511BCA3251559ED6D3BFCC304 + 22: 3C1AA3485241175A9A17F440A1F2FF5F + 23: 11D2C5E4FC75639CC61C8FE66C2F5135 + 24: 3EDBF9F32259650ABC2C835301FA6556 + 25: 56FA9AA43C01CA5BA798780D3BF40FA1 + 26: 40AE1F352003026C6D4C5F44430DD5ED + 27: 264E11C88266029588A1B8369F0C5B73 + 28: 60CE0E6D2C2C74D122DBDE57B3EA44AB + 29: 5E4078E7CEFA94886E9CF0D083C4B468 + 30: CEC169560600ECEED6E5C8F06C76E702 + 31: B4209736F08EAAE6D5B4923D83EB3EE2 + 32: 5DC8D45C9954B82864F1C2388858D97B + +OMAC-skipjack (10 byte key) + 0: 84EDFA769040603C + 1: 7DA58A4CBD642627 + 2: 118F60115CFC8229 + 3: A7F7346D34DB2F0E + 4: 35615CCD526CD57F + 5: DE471601A3660844 + 6: 15FCCE6D6D883D1F + 7: C6F694861233151B + 8: 3B762B397F16E807 + 9: 976C6AB59FB3AB12 + 10: 6810791F2C595961 + 11: 7FA3478286917F17 + 12: 73DEE44A51C6B610 + 13: 89EE8B253B1ACE81 + 14: CDF2586A56C8A0B5 + 15: ED91F98DA98F42C4 + 16: D8D0FA5CE96B08BF + +OMAC-anubis (16 byte key) + 0: E672617CAA1E641C0E7B4B4CC4787455 + 1: C0C16E8FD63907C08A8ABBB7B73376D3 + 2: 23F97CED54939361830396224A7BDD91 + 3: 7FD87DEA9F05E07212DDF61292D9E13D + 4: 929A11A4D0991A6446B1051926A6048D + 5: 4EB74F1CC0150D86126BC6FE1FC8253D + 6: 33C2C3C072D05BB6D54F87579C23B116 + 7: DE350181C9E90A79879813A609BE77E2 + 8: DB519EB9EF0E154D9D248734FD3D3724 + 9: 4F7F2E6D3FC72BA94FE24EC0ABBF4E66 + 10: D646389DBCEEDD59EBB6E8F09C422930 + 11: 8547658AE1CE6A8B8D010A1E1FEA7AF4 + 12: C9BE2B7F3630EFDFBD3AEA6A108C86EA + 13: 290417C57096B8B9A1BA3C20FD91285B + 14: 9AF60E99692C5F911CBF969A6E11DC14 + 15: CDA433BE58C98E49EBA8A7108E50DE2B + 16: 7430D0EE631A4659351B8A4489A78D46 + 17: DCC74C0FD0415768FE00225CA14B7DC2 + 18: 0CF2432B1B465F2A8C5FACAAF2FEF619 + 19: DA020680C64E93AE5FCA3D71466D01C1 + 20: B9C33A86E6ED9FCCDCD973382DD1B6A3 + 21: 6631236B9F2F810DD4D97E6046F41AF2 + 22: 0312C322F4D634CF4FBC0C2624E3E9F2 + 23: 111E3E9F8FBDC1E4364622723F1CB524 + 24: 6D2608D7AAF243D5219E14513895BFF6 + 25: 683BD01B43CBC0430A007ACBAB357DC9 + 26: 01B8FC65C56B0F1A5BFEBEDCCF6748D9 + 27: 4D6298D63A80D55491697A6DD8E3694C + 28: 6F0205E4E083CAB00747D723300510DF + 29: 5183BAEEF05E9402A935EB9AFF0AA2A9 + 30: 1E673BFAD4944643A740C59D96A5925C + 31: 940FB4000E34EEE78E8DB402E4A76502 + 32: 87B0C48F3D155AD85D0502D94A4572DE + +OMAC-khazad (16 byte key) + 0: 4EBEFA460499424F + 1: 97AEEAD51E541D16 + 2: 29A35212910C9595 + 3: ABD1577D622074EA + 4: 70A537DE14DD765C + 5: 240A19016DE99C51 + 6: 4D42C10A9F803177 + 7: F464BC3E0DB5A909 + 8: 1C65A01A7C08DAC7 + 9: E49A1428C230C209 + 10: 16DD0FEB7A6505B8 + 11: 2DDDB3E35A05C220 + 12: EC88910C799AC6CC + 13: B2A65C9EF39BEC8A + 14: F0D2366BA91DFFD5 + 15: BCAB623CAB7AAA23 + 16: 9BCEAB857596E478 + +OMAC-camellia (16 byte key) + 0: B5664C5148FFB45297703BCC46C19E4E + 1: 126EC31A554E8B3B635DE4617092ECE8 + 2: FD57148685F4AA85AF48017AFD72B410 + 3: 1427607464A408C1775B4036509E9659 + 4: D8F5A7112CC8A9DF28B331FE7184BF08 + 5: 0E29B0F09409DABECF645F05C4A5717C + 6: C4155442FDC29685028AF4AADEDCC266 + 7: 92356ACB98AE2EDAABE0D3ED0C90772B + 8: AA3C828618F72258D91BC391876776C3 + 9: 189458BA4D98E85802E7028E5C57A25F + 10: EE652D70328DA00D63B42A5E85D70E63 + 11: F9D1E5F8E1539F2D657A047755CD232E + 12: 56FF5979FD3DEAD90EAAAF79A9AF1DCD + 13: 7E8B39D459D5AB449A8C5917B0CD0C4E + 14: 822D9B9C434C6FF7F0E5A25281740A91 + 15: 654909D2836CCB06501CB359C717C1B9 + 16: E8996FC89D47C91543B7BA3DC1C34B73 + 17: DC29D51B2372DD7564CF56AF8702924F + 18: AD74D081197644DFE2723CABC991B1AC + 19: 26145C6DF074CA53125F6F386FBEA373 + 20: 72C6C760A70FE410FAD113D8BE711D75 + 21: 099D3B5802D7FB699B6B8F031BE10B3F + 22: A9D5DD3988A18AA7BC6F9C050BDBE8D2 + 23: F7E99E4C3C7D127FF04FF325F7B06997 + 24: E99A2F7547B5C6EDF3BC2EC2B8F05198 + 25: 46C42FF49FCCFC49FBC99FEB08FEF10A + 26: DC349D600A754F73ACE6A7D2D00D3551 + 27: FC2E5434ABBA44ABD9D724A9BB6CA2A6 + 28: BA923927BF0074AD73BA8A6914194297 + 29: 7DAB39F8D7E5CB93265568E6713C7CCD + 30: 9F60259B759B68E1C8F89CC36C7E170E + 31: 7D611F8BFEF0491CED8815C0E3D4CAFF + 32: 31E04DE5F9D1403C660E39891DE0D8DE diff --git a/t/mac_pelican.t b/t/mac_pelican.t new file mode 100644 index 0000000..b46815f --- /dev/null +++ b/t/mac_pelican.t @@ -0,0 +1,81 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 72; + +use Crypt::Mac::Pelican qw( pelican pelican_hex pelican_b64 pelican_b64u ); + +is( unpack('H*', Crypt::Mac::Pelican->new('1234567890123456')->add("")->mac), '6b8e5fea81f2022a75357b1e9e8361f4', 'Pelican/oo+raw/1'); +is( Crypt::Mac::Pelican->new('1234567890123456')->add("")->hexmac, '6b8e5fea81f2022a75357b1e9e8361f4', 'Pelican/oo+hex/1'); +is( unpack('H*', pelican('1234567890123456',"")), '6b8e5fea81f2022a75357b1e9e8361f4', 'Pelican/func+raw/1'); +is( pelican_hex('1234567890123456',""), '6b8e5fea81f2022a75357b1e9e8361f4', 'Pelican/func+hex/1'); +is( pelican_b64('1234567890123456',""), 'a45f6oHyAip1NXsenoNh9A==', 'Pelican/func+b64/1'); +is( pelican_b64u('1234567890123456',""), 'a45f6oHyAip1NXsenoNh9A', 'Pelican/func+b64u/1'); +is( unpack('H*', Crypt::Mac::Pelican->new('12345678901234561234567890123456')->add("")->mac), 'cd253e77578c3a76d20a4f87a582c1c4', 'Pelican/oo+raw/2'); +is( Crypt::Mac::Pelican->new('12345678901234561234567890123456')->add("")->hexmac, 'cd253e77578c3a76d20a4f87a582c1c4', 'Pelican/oo+hex/2'); +is( unpack('H*', pelican('12345678901234561234567890123456',"")), 'cd253e77578c3a76d20a4f87a582c1c4', 'Pelican/func+raw/2'); +is( pelican_hex('12345678901234561234567890123456',""), 'cd253e77578c3a76d20a4f87a582c1c4', 'Pelican/func+hex/2'); +is( pelican_b64('12345678901234561234567890123456',""), 'zSU+d1eMOnbSCk+HpYLBxA==', 'Pelican/func+b64/2'); +is( pelican_b64u('12345678901234561234567890123456',""), 'zSU-d1eMOnbSCk-HpYLBxA', 'Pelican/func+b64u/2'); +is( unpack('H*', Crypt::Mac::Pelican->new('aaaaaaaaaaaaaaaa')->add("")->mac), '0976b1b1cbc3f4adae5254fb6626ffba', 'Pelican/oo+raw/3'); +is( Crypt::Mac::Pelican->new('aaaaaaaaaaaaaaaa')->add("")->hexmac, '0976b1b1cbc3f4adae5254fb6626ffba', 'Pelican/oo+hex/3'); +is( unpack('H*', pelican('aaaaaaaaaaaaaaaa',"")), '0976b1b1cbc3f4adae5254fb6626ffba', 'Pelican/func+raw/3'); +is( pelican_hex('aaaaaaaaaaaaaaaa',""), '0976b1b1cbc3f4adae5254fb6626ffba', 'Pelican/func+hex/3'); +is( pelican_b64('aaaaaaaaaaaaaaaa',""), 'CXaxscvD9K2uUlT7Zib/ug==', 'Pelican/func+b64/3'); +is( pelican_b64u('aaaaaaaaaaaaaaaa',""), 'CXaxscvD9K2uUlT7Zib_ug', 'Pelican/func+b64u/3'); +is( unpack('H*', Crypt::Mac::Pelican->new('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add("")->mac), 'b8811ef21aeba6a89ee179c8a2a08bf5', 'Pelican/oo+raw/4'); +is( Crypt::Mac::Pelican->new('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add("")->hexmac, 'b8811ef21aeba6a89ee179c8a2a08bf5', 'Pelican/oo+hex/4'); +is( unpack('H*', pelican('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"")), 'b8811ef21aeba6a89ee179c8a2a08bf5', 'Pelican/func+raw/4'); +is( pelican_hex('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',""), 'b8811ef21aeba6a89ee179c8a2a08bf5', 'Pelican/func+hex/4'); +is( pelican_b64('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',""), 'uIEe8hrrpqie4XnIoqCL9Q==', 'Pelican/func+b64/4'); +is( pelican_b64u('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',""), 'uIEe8hrrpqie4XnIoqCL9Q', 'Pelican/func+b64u/4'); +is( unpack('H*', Crypt::Mac::Pelican->new('1234567890123456')->add(123)->mac), 'fbb1d2c3aa308e82a14bfd8efc1cfdac', 'Pelican/oo+raw/5'); +is( Crypt::Mac::Pelican->new('1234567890123456')->add(123)->hexmac, 'fbb1d2c3aa308e82a14bfd8efc1cfdac', 'Pelican/oo+hex/5'); +is( unpack('H*', pelican('1234567890123456',123)), 'fbb1d2c3aa308e82a14bfd8efc1cfdac', 'Pelican/func+raw/5'); +is( pelican_hex('1234567890123456',123), 'fbb1d2c3aa308e82a14bfd8efc1cfdac', 'Pelican/func+hex/5'); +is( pelican_b64('1234567890123456',123), '+7HSw6owjoKhS/2O/Bz9rA==', 'Pelican/func+b64/5'); +is( pelican_b64u('1234567890123456',123), '-7HSw6owjoKhS_2O_Bz9rA', 'Pelican/func+b64u/5'); +is( unpack('H*', Crypt::Mac::Pelican->new('12345678901234561234567890123456')->add(123)->mac), '23c694903f3bce129255cc66a92fc0ca', 'Pelican/oo+raw/6'); +is( Crypt::Mac::Pelican->new('12345678901234561234567890123456')->add(123)->hexmac, '23c694903f3bce129255cc66a92fc0ca', 'Pelican/oo+hex/6'); +is( unpack('H*', pelican('12345678901234561234567890123456',123)), '23c694903f3bce129255cc66a92fc0ca', 'Pelican/func+raw/6'); +is( pelican_hex('12345678901234561234567890123456',123), '23c694903f3bce129255cc66a92fc0ca', 'Pelican/func+hex/6'); +is( pelican_b64('12345678901234561234567890123456',123), 'I8aUkD87zhKSVcxmqS/Ayg==', 'Pelican/func+b64/6'); +is( pelican_b64u('12345678901234561234567890123456',123), 'I8aUkD87zhKSVcxmqS_Ayg', 'Pelican/func+b64u/6'); +is( unpack('H*', Crypt::Mac::Pelican->new('aaaaaaaaaaaaaaaa')->add(123)->mac), '13b5ae418804ccc5c972069b56f3314e', 'Pelican/oo+raw/7'); +is( Crypt::Mac::Pelican->new('aaaaaaaaaaaaaaaa')->add(123)->hexmac, '13b5ae418804ccc5c972069b56f3314e', 'Pelican/oo+hex/7'); +is( unpack('H*', pelican('aaaaaaaaaaaaaaaa',123)), '13b5ae418804ccc5c972069b56f3314e', 'Pelican/func+raw/7'); +is( pelican_hex('aaaaaaaaaaaaaaaa',123), '13b5ae418804ccc5c972069b56f3314e', 'Pelican/func+hex/7'); +is( pelican_b64('aaaaaaaaaaaaaaaa',123), 'E7WuQYgEzMXJcgabVvMxTg==', 'Pelican/func+b64/7'); +is( pelican_b64u('aaaaaaaaaaaaaaaa',123), 'E7WuQYgEzMXJcgabVvMxTg', 'Pelican/func+b64u/7'); +is( unpack('H*', Crypt::Mac::Pelican->new('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add(123)->mac), 'b5d44a3b4e7fe8099ab63344dc906b2c', 'Pelican/oo+raw/8'); +is( Crypt::Mac::Pelican->new('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add(123)->hexmac, 'b5d44a3b4e7fe8099ab63344dc906b2c', 'Pelican/oo+hex/8'); +is( unpack('H*', pelican('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',123)), 'b5d44a3b4e7fe8099ab63344dc906b2c', 'Pelican/func+raw/8'); +is( pelican_hex('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',123), 'b5d44a3b4e7fe8099ab63344dc906b2c', 'Pelican/func+hex/8'); +is( pelican_b64('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',123), 'tdRKO05/6AmatjNE3JBrLA==', 'Pelican/func+b64/8'); +is( pelican_b64u('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',123), 'tdRKO05_6AmatjNE3JBrLA', 'Pelican/func+b64u/8'); +is( unpack('H*', Crypt::Mac::Pelican->new('1234567890123456')->add("test\0test\0test\n")->mac), '5d884e5a46bbd02497d0c9ecc2739822', 'Pelican/oo+raw/9'); +is( Crypt::Mac::Pelican->new('1234567890123456')->add("test\0test\0test\n")->hexmac, '5d884e5a46bbd02497d0c9ecc2739822', 'Pelican/oo+hex/9'); +is( unpack('H*', pelican('1234567890123456',"test\0test\0test\n")), '5d884e5a46bbd02497d0c9ecc2739822', 'Pelican/func+raw/9'); +is( pelican_hex('1234567890123456',"test\0test\0test\n"), '5d884e5a46bbd02497d0c9ecc2739822', 'Pelican/func+hex/9'); +is( pelican_b64('1234567890123456',"test\0test\0test\n"), 'XYhOWka70CSX0MnswnOYIg==', 'Pelican/func+b64/9'); +is( pelican_b64u('1234567890123456',"test\0test\0test\n"), 'XYhOWka70CSX0MnswnOYIg', 'Pelican/func+b64u/9'); +is( unpack('H*', Crypt::Mac::Pelican->new('12345678901234561234567890123456')->add("test\0test\0test\n")->mac), 'cf279a49ccf7798130d907840056d222', 'Pelican/oo+raw/10'); +is( Crypt::Mac::Pelican->new('12345678901234561234567890123456')->add("test\0test\0test\n")->hexmac, 'cf279a49ccf7798130d907840056d222', 'Pelican/oo+hex/10'); +is( unpack('H*', pelican('12345678901234561234567890123456',"test\0test\0test\n")), 'cf279a49ccf7798130d907840056d222', 'Pelican/func+raw/10'); +is( pelican_hex('12345678901234561234567890123456',"test\0test\0test\n"), 'cf279a49ccf7798130d907840056d222', 'Pelican/func+hex/10'); +is( pelican_b64('12345678901234561234567890123456',"test\0test\0test\n"), 'zyeaScz3eYEw2QeEAFbSIg==', 'Pelican/func+b64/10'); +is( pelican_b64u('12345678901234561234567890123456',"test\0test\0test\n"), 'zyeaScz3eYEw2QeEAFbSIg', 'Pelican/func+b64u/10'); +is( unpack('H*', Crypt::Mac::Pelican->new('aaaaaaaaaaaaaaaa')->add("test\0test\0test\n")->mac), 'c21e437bee0261e55e66735cb6d4bd56', 'Pelican/oo+raw/11'); +is( Crypt::Mac::Pelican->new('aaaaaaaaaaaaaaaa')->add("test\0test\0test\n")->hexmac, 'c21e437bee0261e55e66735cb6d4bd56', 'Pelican/oo+hex/11'); +is( unpack('H*', pelican('aaaaaaaaaaaaaaaa',"test\0test\0test\n")), 'c21e437bee0261e55e66735cb6d4bd56', 'Pelican/func+raw/11'); +is( pelican_hex('aaaaaaaaaaaaaaaa',"test\0test\0test\n"), 'c21e437bee0261e55e66735cb6d4bd56', 'Pelican/func+hex/11'); +is( pelican_b64('aaaaaaaaaaaaaaaa',"test\0test\0test\n"), 'wh5De+4CYeVeZnNcttS9Vg==', 'Pelican/func+b64/11'); +is( pelican_b64u('aaaaaaaaaaaaaaaa',"test\0test\0test\n"), 'wh5De-4CYeVeZnNcttS9Vg', 'Pelican/func+b64u/11'); +is( unpack('H*', Crypt::Mac::Pelican->new('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add("test\0test\0test\n")->mac), '8a798fcb2181d9f9ed81fcd2a7f6cd4e', 'Pelican/oo+raw/12'); +is( Crypt::Mac::Pelican->new('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add("test\0test\0test\n")->hexmac, '8a798fcb2181d9f9ed81fcd2a7f6cd4e', 'Pelican/oo+hex/12'); +is( unpack('H*', pelican('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n")), '8a798fcb2181d9f9ed81fcd2a7f6cd4e', 'Pelican/func+raw/12'); +is( pelican_hex('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n"), '8a798fcb2181d9f9ed81fcd2a7f6cd4e', 'Pelican/func+hex/12'); +is( pelican_b64('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n"), 'inmPyyGB2fntgfzSp/bNTg==', 'Pelican/func+b64/12'); +is( pelican_b64u('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n"), 'inmPyyGB2fntgfzSp_bNTg', 'Pelican/func+b64u/12'); diff --git a/t/mac_pmac.t b/t/mac_pmac.t new file mode 100644 index 0000000..19bec12 --- /dev/null +++ b/t/mac_pmac.t @@ -0,0 +1,81 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 72; + +use Crypt::Mac::PMAC qw( pmac pmac_hex pmac_b64 pmac_b64u ); + +is( unpack('H*', Crypt::Mac::PMAC->new('AES','1234567890123456')->add("")->mac), '877a45a3b73543ec5cfde831c82998b2', 'PMAC/oo+raw/1'); +is( Crypt::Mac::PMAC->new('AES','1234567890123456')->add("")->hexmac, '877a45a3b73543ec5cfde831c82998b2', 'PMAC/oo+hex/1'); +is( unpack('H*', pmac('AES','1234567890123456',"")), '877a45a3b73543ec5cfde831c82998b2', 'PMAC/func+raw/1'); +is( pmac_hex('AES','1234567890123456',""), '877a45a3b73543ec5cfde831c82998b2', 'PMAC/func+hex/1'); +is( pmac_b64('AES','1234567890123456',""), 'h3pFo7c1Q+xc/egxyCmYsg==', 'PMAC/func+b64/1'); +is( pmac_b64u('AES','1234567890123456',""), 'h3pFo7c1Q-xc_egxyCmYsg', 'PMAC/func+b64u/1'); +is( unpack('H*', Crypt::Mac::PMAC->new('AES','12345678901234561234567890123456')->add("")->mac), '4fd07f0e3726d907fea45ab72c276b04', 'PMAC/oo+raw/2'); +is( Crypt::Mac::PMAC->new('AES','12345678901234561234567890123456')->add("")->hexmac, '4fd07f0e3726d907fea45ab72c276b04', 'PMAC/oo+hex/2'); +is( unpack('H*', pmac('AES','12345678901234561234567890123456',"")), '4fd07f0e3726d907fea45ab72c276b04', 'PMAC/func+raw/2'); +is( pmac_hex('AES','12345678901234561234567890123456',""), '4fd07f0e3726d907fea45ab72c276b04', 'PMAC/func+hex/2'); +is( pmac_b64('AES','12345678901234561234567890123456',""), 'T9B/Djcm2Qf+pFq3LCdrBA==', 'PMAC/func+b64/2'); +is( pmac_b64u('AES','12345678901234561234567890123456',""), 'T9B_Djcm2Qf-pFq3LCdrBA', 'PMAC/func+b64u/2'); +is( unpack('H*', Crypt::Mac::PMAC->new('Blowfish','1234567890123456')->add("")->mac), '9b9a50f5d0362a8b', 'PMAC/oo+raw/3'); +is( Crypt::Mac::PMAC->new('Blowfish','1234567890123456')->add("")->hexmac, '9b9a50f5d0362a8b', 'PMAC/oo+hex/3'); +is( unpack('H*', pmac('Blowfish','1234567890123456',"")), '9b9a50f5d0362a8b', 'PMAC/func+raw/3'); +is( pmac_hex('Blowfish','1234567890123456',""), '9b9a50f5d0362a8b', 'PMAC/func+hex/3'); +is( pmac_b64('Blowfish','1234567890123456',""), 'm5pQ9dA2Kos=', 'PMAC/func+b64/3'); +is( pmac_b64u('Blowfish','1234567890123456',""), 'm5pQ9dA2Kos', 'PMAC/func+b64u/3'); +is( unpack('H*', Crypt::Mac::PMAC->new('Blowfish','12345678901234561234567890123456')->add("")->mac), '9b9a50f5d0362a8b', 'PMAC/oo+raw/4'); +is( Crypt::Mac::PMAC->new('Blowfish','12345678901234561234567890123456')->add("")->hexmac, '9b9a50f5d0362a8b', 'PMAC/oo+hex/4'); +is( unpack('H*', pmac('Blowfish','12345678901234561234567890123456',"")), '9b9a50f5d0362a8b', 'PMAC/func+raw/4'); +is( pmac_hex('Blowfish','12345678901234561234567890123456',""), '9b9a50f5d0362a8b', 'PMAC/func+hex/4'); +is( pmac_b64('Blowfish','12345678901234561234567890123456',""), 'm5pQ9dA2Kos=', 'PMAC/func+b64/4'); +is( pmac_b64u('Blowfish','12345678901234561234567890123456',""), 'm5pQ9dA2Kos', 'PMAC/func+b64u/4'); +is( unpack('H*', Crypt::Mac::PMAC->new('AES','1234567890123456')->add(123)->mac), '180cbe007c36eb4abce45430c079a4d4', 'PMAC/oo+raw/5'); +is( Crypt::Mac::PMAC->new('AES','1234567890123456')->add(123)->hexmac, '180cbe007c36eb4abce45430c079a4d4', 'PMAC/oo+hex/5'); +is( unpack('H*', pmac('AES','1234567890123456',123)), '180cbe007c36eb4abce45430c079a4d4', 'PMAC/func+raw/5'); +is( pmac_hex('AES','1234567890123456',123), '180cbe007c36eb4abce45430c079a4d4', 'PMAC/func+hex/5'); +is( pmac_b64('AES','1234567890123456',123), 'GAy+AHw260q85FQwwHmk1A==', 'PMAC/func+b64/5'); +is( pmac_b64u('AES','1234567890123456',123), 'GAy-AHw260q85FQwwHmk1A', 'PMAC/func+b64u/5'); +is( unpack('H*', Crypt::Mac::PMAC->new('AES','12345678901234561234567890123456')->add(123)->mac), 'b5c5ca8f2227bf207c4c5cb6f465b664', 'PMAC/oo+raw/6'); +is( Crypt::Mac::PMAC->new('AES','12345678901234561234567890123456')->add(123)->hexmac, 'b5c5ca8f2227bf207c4c5cb6f465b664', 'PMAC/oo+hex/6'); +is( unpack('H*', pmac('AES','12345678901234561234567890123456',123)), 'b5c5ca8f2227bf207c4c5cb6f465b664', 'PMAC/func+raw/6'); +is( pmac_hex('AES','12345678901234561234567890123456',123), 'b5c5ca8f2227bf207c4c5cb6f465b664', 'PMAC/func+hex/6'); +is( pmac_b64('AES','12345678901234561234567890123456',123), 'tcXKjyInvyB8TFy29GW2ZA==', 'PMAC/func+b64/6'); +is( pmac_b64u('AES','12345678901234561234567890123456',123), 'tcXKjyInvyB8TFy29GW2ZA', 'PMAC/func+b64u/6'); +is( unpack('H*', Crypt::Mac::PMAC->new('Blowfish','1234567890123456')->add(123)->mac), '9df08c664a191e9f', 'PMAC/oo+raw/7'); +is( Crypt::Mac::PMAC->new('Blowfish','1234567890123456')->add(123)->hexmac, '9df08c664a191e9f', 'PMAC/oo+hex/7'); +is( unpack('H*', pmac('Blowfish','1234567890123456',123)), '9df08c664a191e9f', 'PMAC/func+raw/7'); +is( pmac_hex('Blowfish','1234567890123456',123), '9df08c664a191e9f', 'PMAC/func+hex/7'); +is( pmac_b64('Blowfish','1234567890123456',123), 'nfCMZkoZHp8=', 'PMAC/func+b64/7'); +is( pmac_b64u('Blowfish','1234567890123456',123), 'nfCMZkoZHp8', 'PMAC/func+b64u/7'); +is( unpack('H*', Crypt::Mac::PMAC->new('Blowfish','12345678901234561234567890123456')->add(123)->mac), '9df08c664a191e9f', 'PMAC/oo+raw/8'); +is( Crypt::Mac::PMAC->new('Blowfish','12345678901234561234567890123456')->add(123)->hexmac, '9df08c664a191e9f', 'PMAC/oo+hex/8'); +is( unpack('H*', pmac('Blowfish','12345678901234561234567890123456',123)), '9df08c664a191e9f', 'PMAC/func+raw/8'); +is( pmac_hex('Blowfish','12345678901234561234567890123456',123), '9df08c664a191e9f', 'PMAC/func+hex/8'); +is( pmac_b64('Blowfish','12345678901234561234567890123456',123), 'nfCMZkoZHp8=', 'PMAC/func+b64/8'); +is( pmac_b64u('Blowfish','12345678901234561234567890123456',123), 'nfCMZkoZHp8', 'PMAC/func+b64u/8'); +is( unpack('H*', Crypt::Mac::PMAC->new('AES','1234567890123456')->add("test\0test\0test\n")->mac), '86bb8eeec8f0ece63582f64f14a9e60c', 'PMAC/oo+raw/9'); +is( Crypt::Mac::PMAC->new('AES','1234567890123456')->add("test\0test\0test\n")->hexmac, '86bb8eeec8f0ece63582f64f14a9e60c', 'PMAC/oo+hex/9'); +is( unpack('H*', pmac('AES','1234567890123456',"test\0test\0test\n")), '86bb8eeec8f0ece63582f64f14a9e60c', 'PMAC/func+raw/9'); +is( pmac_hex('AES','1234567890123456',"test\0test\0test\n"), '86bb8eeec8f0ece63582f64f14a9e60c', 'PMAC/func+hex/9'); +is( pmac_b64('AES','1234567890123456',"test\0test\0test\n"), 'hruO7sjw7OY1gvZPFKnmDA==', 'PMAC/func+b64/9'); +is( pmac_b64u('AES','1234567890123456',"test\0test\0test\n"), 'hruO7sjw7OY1gvZPFKnmDA', 'PMAC/func+b64u/9'); +is( unpack('H*', Crypt::Mac::PMAC->new('AES','12345678901234561234567890123456')->add("test\0test\0test\n")->mac), '465b8c31fe8f9f6c9089497e2a312c50', 'PMAC/oo+raw/10'); +is( Crypt::Mac::PMAC->new('AES','12345678901234561234567890123456')->add("test\0test\0test\n")->hexmac, '465b8c31fe8f9f6c9089497e2a312c50', 'PMAC/oo+hex/10'); +is( unpack('H*', pmac('AES','12345678901234561234567890123456',"test\0test\0test\n")), '465b8c31fe8f9f6c9089497e2a312c50', 'PMAC/func+raw/10'); +is( pmac_hex('AES','12345678901234561234567890123456',"test\0test\0test\n"), '465b8c31fe8f9f6c9089497e2a312c50', 'PMAC/func+hex/10'); +is( pmac_b64('AES','12345678901234561234567890123456',"test\0test\0test\n"), 'RluMMf6Pn2yQiUl+KjEsUA==', 'PMAC/func+b64/10'); +is( pmac_b64u('AES','12345678901234561234567890123456',"test\0test\0test\n"), 'RluMMf6Pn2yQiUl-KjEsUA', 'PMAC/func+b64u/10'); +is( unpack('H*', Crypt::Mac::PMAC->new('Blowfish','1234567890123456')->add("test\0test\0test\n")->mac), '3797cde072a8e286', 'PMAC/oo+raw/11'); +is( Crypt::Mac::PMAC->new('Blowfish','1234567890123456')->add("test\0test\0test\n")->hexmac, '3797cde072a8e286', 'PMAC/oo+hex/11'); +is( unpack('H*', pmac('Blowfish','1234567890123456',"test\0test\0test\n")), '3797cde072a8e286', 'PMAC/func+raw/11'); +is( pmac_hex('Blowfish','1234567890123456',"test\0test\0test\n"), '3797cde072a8e286', 'PMAC/func+hex/11'); +is( pmac_b64('Blowfish','1234567890123456',"test\0test\0test\n"), 'N5fN4HKo4oY=', 'PMAC/func+b64/11'); +is( pmac_b64u('Blowfish','1234567890123456',"test\0test\0test\n"), 'N5fN4HKo4oY', 'PMAC/func+b64u/11'); +is( unpack('H*', Crypt::Mac::PMAC->new('Blowfish','12345678901234561234567890123456')->add("test\0test\0test\n")->mac), '3797cde072a8e286', 'PMAC/oo+raw/12'); +is( Crypt::Mac::PMAC->new('Blowfish','12345678901234561234567890123456')->add("test\0test\0test\n")->hexmac, '3797cde072a8e286', 'PMAC/oo+hex/12'); +is( unpack('H*', pmac('Blowfish','12345678901234561234567890123456',"test\0test\0test\n")), '3797cde072a8e286', 'PMAC/func+raw/12'); +is( pmac_hex('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), '3797cde072a8e286', 'PMAC/func+hex/12'); +is( pmac_b64('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), 'N5fN4HKo4oY=', 'PMAC/func+b64/12'); +is( pmac_b64u('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), 'N5fN4HKo4oY', 'PMAC/func+b64u/12'); diff --git a/t/mac_pmac_test_vectors_ltc.t b/t/mac_pmac_test_vectors_ltc.t new file mode 100644 index 0000000..c892a93 --- /dev/null +++ b/t/mac_pmac_test_vectors_ltc.t @@ -0,0 +1,562 @@ +use strict; +use warnings; + +use Test::More tests => 452; +use Crypt::Mac::PMAC; +use Crypt::Cipher; + +my $trans = { + "3des" => 'DES_EDE', + "safer+" => 'SAFERP', + "khazad" => 'Khazad', + "safer-k128" => 'SAFER_K128', + "safer-sk128"=> 'SAFER_SK128', + "rc6" => 'RC6', + "safer-k64" => 'SAFER_K64', + "safer-sk64" => 'SAFER_SK64', + "anubis" => 'Anubis', + "blowfish" => 'Blowfish', + "xtea" => 'XTEA', + "aes" => 'AES', + "rc5" => 'RC5', + "cast5" => 'CAST5', + "skipjack" => 'Skipjack', + "twofish" => 'Twofish', + "noekeon" => 'Noekeon', + "rc2" => 'RC2', + "des" => 'DES', + "camellia" => 'Camellia', +}; +my $tv; +my $name; +my $ks; + +while (my $l = ) { + $l =~ s/[\r\n]*$//; + $l =~ s/^[\s]*([^\s\r\n]+).*?/$1/; + $l =~ s/\s+//; + if ($l=~/^PMAC-([a-z0-9\+\-]+).*?(\d+)/i) { + $name = $1; + $ks = $2; + next; + } + my ($k, $v) = split /:/, $l; + next unless defined $k && defined $v; + $tv->{$name}->{$ks}->{$k} = $v if $name && $k =~ /\d+/; +} + +my $seq; +$seq .= pack('C',$_) for(0..255); +my $zeros = '\0' x 255; + +for my $n (sort keys %$tv) { + for my $ks (sort keys %{$tv->{$n}}) { + my $N = $trans->{$n} || die "FATAL: unknown name '$n'"; + my $key = substr($seq, 0, $ks); + for my $i (0..255) { + my $bytes = substr($seq, 0, $i); + next unless $tv->{$n}->{$ks}->{$i}; + my $result = Crypt::Mac::PMAC->new($N, $key)->add($bytes)->mac; + is(unpack('H*', $result), lc($tv->{$n}->{$ks}->{$i}), "$N/$i"); + $bytes = $result; + $key = substr($result x 100, 0, $ks); + } + } +} + +__DATA__ +PMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are PMAC'ed. The initial key is +of the same format (length specified per cipher). The PMAC key in step N+1 is the PMAC output of +step N (repeated as required to fill the array). + +PMAC-aes (16 byte key) + 0: 4399572CD6EA5341B8D35876A7098AF7 + 1: 580F7AA4AA45857C79BA2FB892228893 + 2: 24D2D1DBABDB25F9F2D391BB61F4204A + 3: 083BF95E310B42A89751BC8E65ABA8B5 + 4: 69BEB9268CD7FD3D7AB820BD7E226955 + 5: FD71B0E647ADB4BB3F587E82B8B3401A + 6: 07EA46271081840737CEB1AC9E5E22E3 + 7: FFA12AD9A9FDB5EE126084F82B381B10 + 8: 8A11AF301AAFEAC8A75984ED16BB3292 + 9: 368BDC3F4220E89B54C5F9D09FFB8F34 + 10: 8B6DBFF776FD526147D1C4655626374F + 11: C538C09FC10DF38217CD8E799D8D1DC9 + 12: FC1264A2051DEF73339432EA39443CFD + 13: 8AF37ED2FB2E8E30E9C4B75C1F1363E1 + 14: 4295541FC62F6774068B8194CC9D9A46 + 15: CFAF4D8EA09BB342F07131344DB0AA52 + 16: B6CBD6E95959B2A8E22DE07E38B64D8D + 17: 3124E42DE3273B0F4806FB72A50F3E54 + 18: 252D49403509B618AB3A6A1D99F9E9FA + 19: 9CDA75594CB696EB19C022DDA7324C10 + 20: 33BB8AE43B7BC179E85F157FA19607D0 + 21: 12FE91BCF2F2875379DC671C6F1B403E + 22: 416A3E519D1E406C92F8BB0DDBBBB6BF + 23: 6F98DCCD5A8D60DEAF612ACCEDD7E465 + 24: FFCE7604609B2C3C050921854C638B7E + 25: DD2BB10AA07A5EC8D326BB7BF8D407F4 + 26: 468BFE669FCDF354E4F9768FE1EAF8F6 + 27: 01724D2F2C61EB4F380852218212E892 + 28: 2D90EC658F57138505598C659C539A3E + 29: 6301EAA0E1500FFEB86752744EFFF23D + 30: 3CCB177486377616056D835F6F857F7C + 31: BFB3C7755C1F4543B516EB8610CB219F + 32: D5C505847D7CFFD8CED848F6CB613105 + +PMAC-blowfish (8 byte key) + 0: 3B7E4EFE92FA46AF + 1: 746840017C38C892 + 2: 3B6A92C731465B64 + 3: D89D3B05143B6704 + 4: 43F70D54B808B7CE + 5: 84E4063AB32F046C + 6: A7E78CD5CCD23805 + 7: A78FB083475FEF10 + 8: D4F6C26B5386BA25 + 9: 184768A079853C90 + 10: 0702E6C8140C5D3B + 11: 786D94565AA0DF4B + 12: F6D36D3A2F4FB2C1 + 13: 7BB3A0592E02B391 + 14: 5B575C77A470946B + 15: 686DAD633B5A8CC3 + 16: BDFE0C7F0254BAD5 + +PMAC-xtea (16 byte key) + 0: F5E28630DFDE34E0 + 1: FFCC52D905DA5198 + 2: 25198AB18B2B290D + 3: 18914E50791161E9 + 4: 200F832212AD6747 + 5: A9D09C41D734DDF7 + 6: 32D7CCA3F4BD8215 + 7: 91A1AA9389CD5D02 + 8: 35CB1F77D7C25E2F + 9: D91EEE6D0A3874F3 + 10: A42872686A8FF6F2 + 11: 7568908634A79CBD + 12: 5B91A633D919BC34 + 13: 32DCD17176896F1D + 14: 2BBBA64F30E672B6 + 15: AFEB07DBC636AEED + 16: 7A417347CA03C598 + +PMAC-rc5 (8 byte key) + 0: C6B48F8DEC631F7C + 1: F7AA62C39972C358 + 2: 0E26EC105D99F417 + 3: 7D3C942798F20B8C + 4: 415CDA53E1DE3888 + 5: A314BA5BCA9A67AC + 6: 02A5D00A3E371326 + 7: E210F0A597A639E5 + 8: D4A15EED872B78A2 + 9: AC5F99886123F7DC + 10: 69AEB2478B58FFDF + 11: 8AB167DFC9EF7854 + 12: 945786A136B98E07 + 13: F3822AB46627CAB5 + 14: 23833793C3A83DA9 + 15: 70E6AB9E6734E5A6 + 16: 0705C312A4BB6EDE + +PMAC-rc6 (16 byte key) + 0: C7715A17012401DE248DC944DEEBD551 + 1: 5B804C6CCDF97BB28811C9ED24FE6157 + 2: 7528378C052F4346253CB0DFA3D251C7 + 3: 6DA86EE0B28606861B1A954D7429A93C + 4: B4DFF84C25937FB50EE79D4037323160 + 5: A60FD9BE5E1FF67EC9734776C8781096 + 6: 81D3F8EDC0A197DD3739EAE648F38580 + 7: 8BAF47F02120E898916D678DBD0C1641 + 8: 7A9EEC96F10B7CF557B61EF35BB55B08 + 9: B88C11221014F8AE048E56C427DF4A46 + 10: 4BBA8EED89F357861A265006816D9B04 + 11: 8497C1D55010A65ED8C3688B75A7CABF + 12: 95E1720C06A373CAD1A22F432F26BCCA + 13: A175FB732692831E96AFB587BC49E18C + 14: 54EBC04FCFD90302907BF77C4D8AC77C + 15: EA9F13EE5548CDF771C354527CDDA09B + 16: 4EDBCFD0E2E6B321530EB31B3E8C2FE4 + 17: F412304C1A5B9005CC3B7900A597DFB5 + 18: 3B9247C12BB25DF048BF5541E91E1A78 + 19: 39626488635D0A6224CD23C13B25AE8E + 20: 40305F5C2FCEF34E764E33EF635A3DC5 + 21: F84499804086033E85633A1EF9908617 + 22: C4D263CDC7E0969B8AC6FA9AD9D65CB8 + 23: 6137DC840E61EA6A288D017EFB9646FC + 24: 8619960428EB29B1D5390F40173C152F + 25: F0464509D0FBDBECEC9DFC57A820016D + 26: 630EED23E87059051E564194831BAEF6 + 27: 4B792B412458DC9411F281D5DD3A8DF6 + 28: F2349FA4418BC89853706B35A9F887BA + 29: FEAC41D48AEAB0955745DC2BE1E024D5 + 30: A67A135B4E6043CB7C9CAFBFA25D1828 + 31: EC12C9574BDE5B0001EE3895B53716E2 + 32: 44903C5737EE6B08FD7D7A3937CC840D + +PMAC-safer+ (16 byte key) + 0: E8603C78F9324E9D294DA13C1C6E6E9B + 1: 3F1178DFC2A10567D4BCC817D35D1E16 + 2: 27FE01F90E09237B4B888746199908EE + 3: 4F5172E3D8A58CD775CD480D85E70835 + 4: 74BED75EFAAB3E8AA0027D6730318521 + 5: 54B003AB0BE29B7C69F7C7494E4E9623 + 6: 8A2DAD967747AEA24670141B52494E2F + 7: 69EB054A24EE814E1FB7E78395339781 + 8: E59C2D16B76B700DC62093F0A7F716CC + 9: AB227D6303007FD2001D0B6A9E2BFEB7 + 10: AE107117D9457A1166C6DFD27A819B44 + 11: F84DE551B480CED350458851BAE20541 + 12: B0EB5103E7559B967D06A081665421E0 + 13: CDB14F3AD1170CE8C6091947BE89DE7B + 14: 24FA2F476407094152D528FCF124E438 + 15: 440144B31EC09BD8791BFE02E24EA170 + 16: 697D268A46E8B33CEC0BAB8CAF43F52D + 17: 587CBDE7608449BD162184020FBFCC8D + 18: 3EA999C2169CC65735737F50FCD7956B + 19: C6D692698CD8BEEBF2387C6A35A261B0 + 20: 46DAB3AD3C4E2EF712FAC38F846C63E1 + 21: 7261E68B530D10DDC9AD4C9AB5D95693 + 22: 4D0BA5773E988C2B7B2302BBA0A9D368 + 23: 8617154626362736698613151D1FD03A + 24: 23CF25F68B281E21777DC409FE3B774A + 25: CA626956C97DC4207D968A8CC85940B8 + 26: 24C39BE160BDBB753513F949C238014E + 27: 83CD65C010FB69A77EEDEA022A650530 + 28: 1A72DC8438B927464125C0DFEACDE75D + 29: 546054936A2CB5BFBB5E25FFD07C9B51 + 30: 0EB81A268F1BB91997CB9809D7F9F2AD + 31: 7D08B4DE960CADC483D55745BB4B2C17 + 32: FD45061D378A31D0186598B088F6261B + +PMAC-twofish (16 byte key) + 0: D2D40F078CEDC1A330279CB71B0FF12B + 1: D1C1E80FD5F38212C3527DA3797DA71D + 2: 071118A5A87F637D627E27CB581AD58C + 3: C8CFA166A9B300F720590382CE503B94 + 4: 3965342C5A6AC5F7B0A40DC3B89ED4EB + 5: 6830AB8969796682C3705E368B2BDF74 + 6: FF4DCC4D16B71AFEEA405D0097AD6B89 + 7: ADB77760B079C010889F79AA02190D70 + 8: 5F2FCD6AA2A22CEECAA4671EE0403B88 + 9: 70DD6D396330904A0A03E19046F4C0BF + 10: 8A2C9D88FA0303123275C704445A7F47 + 11: BA0B2F6D029DCD72566821AB884A8427 + 12: C8DF45FF13D7A2E4CFE1546279172300 + 13: 512659AD40DC2B9D31D299A1B00B3DAD + 14: A8A0E99D2E231180949FC4DFB4B79ED4 + 15: CA161AFB2BC7D891AAE268D167897EF2 + 16: D6C19BBDFFC5822663B604B1F836D8BD + 17: 4BF115F409A41A26E89C8D758BBF5F68 + 18: 02E3196D888D5A8DE818DBCBAD6E6DC7 + 19: 995C9DD698EC711A73BD41CAAE8EB633 + 20: A031857FADC8C8AFEABF14EF663A712D + 21: 124695C9A8132618B10E9800A4EFACC5 + 22: 997E5E41798648B8CE0C398EF9135A2C + 23: 42C92154B71FB4E133F8F5B2A2007AB2 + 24: 945DC568188D036AC91051A11AC92BBF + 25: D5A860CC4C3087E9F4988B25D1F7FAAE + 26: 6CD6ABF8EDF3102659AFFBE476E2CBE8 + 27: 45ECD0C37091414E28153AA5AFA3E0B2 + 28: CBA6FE296DDE36FE689C65667F67A038 + 29: C4022281633F2FC438625540B2EE4EB8 + 30: 864E27045F9CC79B5377FDF80A6199CF + 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 + 2: DDB95E9486C4B034 + 3: 9764761DC2AAD5C0 + 4: 1B1CD2E799D44B4F + 5: 4F80FE32256CF2EC + 6: 7B70CF31C81CD384 + 7: 9BC10DD9332CF3BB + 8: 628189801879FDD8 + 9: 5FC17C555E2AE28B + 10: E20E68327ABEAC32 + 11: 5D375CA59E7E2A7C + 12: A9F4CFC684113161 + 13: 3A0E069940DDD13C + 14: EAC25B6351941674 + 15: CB8B5CF885D838CF + 16: DCBCDDFC06D3DB9A + +PMAC-des (8 byte key) + 0: 086A2A7CFC08E28E + 1: F66A1FB75AF18EC9 + 2: B58561DE2BEB96DF + 3: 9C50856F571B3167 + 4: 6CC645BF3FB00754 + 5: 0E4BEE62B2972C5A + 6: D2215E451649F11F + 7: E83DDC61D12F3995 + 8: 155B20BDA899D2CF + 9: 2567071973052B1D + 10: DB9C20237A2D8575 + 11: DAF4041E5674A48C + 12: 552DB7A627E8ECC4 + 13: 1E8B7F823488DEC0 + 14: 84AA15713793B25D + 15: FCE22E6CAD528B49 + 16: 993884FB9B3FB620 + +PMAC-3des (24 byte key) + 0: E42CCBC9C9457DF6 + 1: FE766F7930557708 + 2: B9011E8AF7CD1E16 + 3: 5AE38B037BEA850B + 4: A6B2C586E1875116 + 5: BF8BA4F1D53A4473 + 6: 3EB4A079E4E39AD5 + 7: 80293018AC36EDBF + 8: CC3F5F62C2CEE93C + 9: EE6AA24CE39BE821 + 10: 487A6EAF915966EA + 11: D94AD6393DF44F00 + 12: F4BFCCC818B4E20D + 13: 2BE9BC57412591AA + 14: 7F7CC8D87F2CDAB7 + 15: B13BFD07E7A202CB + 16: 58A6931335B4B2C2 + +PMAC-cast5 (8 byte key) + 0: 0654F2F4BC1F7470 + 1: 3F725B162A1C8E6B + 2: BCFBDC680A20F379 + 3: 027922705BCACDEE + 4: 44E2F4BE59774BA4 + 5: 3ABD1AFC8EE291F7 + 6: D96347E717921E96 + 7: 96257299FCE55BC6 + 8: C2C1DA176EE98170 + 9: FD415C122E604589 + 10: DCBCA228D45AEDA4 + 11: 7801FBCFAAB9DF75 + 12: D38CB38574474B7F + 13: F5C5A23FF3E80F37 + 14: 83FA4DAD55D092F5 + 15: BDC0A27EE0CB1657 + 16: 87D907CACA80A138 + +PMAC-noekeon (16 byte key) + 0: 276019CC8E43A1B3F300C47B55B7AA22 + 1: B93E353A2CC21CEAD81C91EC2FCD348E + 2: E8B9737CAD705C499F246744DCFE9641 + 3: EF36B0FFB5439FF8668F35FD1822D0EA + 4: B7F5AD89538FC3F03923E98ADF95D0CC + 5: 558FCA30F602B4BC6697F44053875204 + 6: 6B2D6D5A1CF670BE80E4BBB945CD3871 + 7: 9CFA28FCA22EA12A13AC1093EF5D5EB9 + 8: 04EDA6C71B9F1177F4A5368684FBBAFB + 9: 43C56B31D440EBECE4C74B90750A4653 + 10: 23D5FA9AFFB2DC3DD372F22690487BAC + 11: FD61731F27CF8E791535AAB579A018B4 + 12: 502D3A64FDED3CA2A2C8A5E986B27E03 + 13: 1EABBC65B0A08F6CB15218E7153A6003 + 14: B05DBC66CF92B045FC99395E9D405C4F + 15: EE841A0BF2C91C1E2078F06D022F2E6C + 16: EA749FBAC6BA9F672796C9D58A8C3294 + 17: BBEF3CDFB93E5F462773579986F08374 + 18: B17F7645F80BF5A2817C228987B43C03 + 19: C995A102DFBB38FA397A4E508B85093D + 20: 9011CA395AC3FCD8594C13E67C22E95B + 21: 364BF53974D68B8BCF53CAADC5469DEC + 22: 5BAD7041372F28DE28BAAAC1A89C10A8 + 23: 77874E908BFCE6F5E36888A484A754C0 + 24: 9BDA525416A3129C55886134B79BAEDE + 25: 84E3201FA7958223B302D1BC2AC57D55 + 26: 2B8FA1A95DADB4DC2F7A308D8E3D8C81 + 27: F74EBF0ACCC187569BDE549F5FC96C36 + 28: 7023D209F1965EC32253D11835CDFFA5 + 29: C3C6397D9B0A1D741335882ACDFAC20D + 30: 7BC92905F2AF6754256BE087CC4F54DB + 31: 0BBA0A507767530F26C3A465DAB11359 + 32: D2891C8EA1F574A6B2AB091057E0FB2C + +PMAC-skipjack (10 byte key) + 0: 9CD94B75BC43B647 + 1: B069ACB82B12BC7B + 2: 6DD40E71EB03E311 + 3: 74CBED61D77DBA7D + 4: DD1B7E0D181537FE + 5: ACB5B96FA0AD1786 + 6: B34E01EB2567D381 + 7: 9623DAADE57B9549 + 8: 8BA384BABB798344 + 9: B147AA9D5C5C67CF + 10: 0033C520F4C67523 + 11: 42DAC184BEABC3E5 + 12: 428029311004AEBB + 13: AC2BB1C0F0ED649B + 14: F7CAA9A3BF749C1A + 15: 2C5BD475AAC44C77 + 16: FEB892DA66D31A84 + +PMAC-anubis (16 byte key) + 0: DF33EE541FFEE6A97FE3A1F72F7A38FC + 1: 0AB28675AC3923C6DD9F5A8E1E2928D0 + 2: 2DABF75D6403E1E1CFAB3E6869FB1088 + 3: 95835D49E09740180B79E394FC2AA744 + 4: F364D6DC2C2078A519E5BAEFE858AFCA + 5: DA4C66A4805FC91FABAECC0D3AEAD850 + 6: 487660FADCAC7B326C492AA051A1DF49 + 7: BF07835AA1A548FA7312509AF35CE3F3 + 8: 3CE8A8B1F324A700923AC0B830D53D99 + 9: 3C54D99AACFAB26E34FC1B0B6BB9EB22 + 10: 0A559F9D107ED76FD19227FDD0752B8A + 11: BFD9E74ADC40B9C7446FDD09558FA584 + 12: F1130F663BC0FA3B1066129E0D1910E9 + 13: 535EAD786F0D211DE7AA78F3CB480803 + 14: CDF5855F00A4C310D95B26751B01A28B + 15: EF6686E999D5A9C35A96D25BB9DBBF57 + 16: E795733AA0AAF16D8F7AB1A8E9C55E54 + 17: E03CA85727D5CF06F56BB6465BB3E5C5 + 18: 6EDDDB6D2292EFF584E382E1BACD1A49 + 19: 7B7FE0D8821836C1AA95578071FF2FD2 + 20: 5F8CC568338400746B61A9286B7CF262 + 21: 32DEE5A11E9EDB04BDF911837CE0FA4D + 22: F1A99914F13B17ABF383F36157FEB170 + 23: 99F541647F382390043CAE5332E3114D + 24: 34C5EBB85693A1979F8CFDF8B431A5BB + 25: 1BA7266568F1E7B4A77A869D3021AC0F + 26: 0FC675C99C24E859F8CE714E86BF5289 + 27: CBFAB21F5ABC47356A43BED806D873C0 + 28: 9659AB1A4D334B622629721F98EECE3A + 29: 644C8BEE41F03BDE7652B03CAEA31E37 + 30: 5B3447AFAD934B4D1E4910A8DFD588E7 + 31: BFF403342E8D50D0447627AEA2F56B23 + 32: 19F468F0FB05184D00FABD40A18DB7B2 + +PMAC-khazad (16 byte key) + 0: F40CEF2E392BEAEB + 1: C6E086BD1CFA0992 + 2: 513F2851583AD69A + 3: 07279D57695D78FF + 4: 051E94FE4CC847B6 + 5: 5E9AAA5989D5C951 + 6: 310D5D740143369A + 7: 9BB1EA8ECD4AF34B + 8: CF886800AF0526C8 + 9: 0B03E2C94729E643 + 10: 42815B308A900EC7 + 11: 9A38A58C438D26DD + 12: 044BFF68FD2BFF76 + 13: 7F5ABBDC29852729 + 14: F81A7D6F7B788A5D + 15: 93098DA8A180AA35 + 16: BACE2F4DA8A89E32 + +PMAC-camellia (16 byte key) + 0: 33C03F6AA205F3816A17DA92BEE0BAD2 + 1: AD1EC293DD032511579235B2F29CC909 + 2: E71363EAF5A311DCFB035C69BBCE5DC0 + 3: 22661D6CD3496FB5C9B3D89FC62E3981 + 4: B142A96AF9C481B61E55B7B5896847C4 + 5: A286C0769989120F8A31A8DAD7574F22 + 6: 09E711382FDB6B938C802D11A66EF657 + 7: DF9ABA4F5CF5B0647F045C3AA631BB62 + 8: 499A8F68DAEC7FE56E64DB59B0993741 + 9: AFFDA4F40A1BDF673EE9123CAE321F16 + 10: B6F2E39D0126AA85D9152C4457365235 + 11: 2922AAC2FF4F0B77DEE4B3E28EF5094F + 12: 369D18F985D18B5ADDFFFC1151DE6BBA + 13: 1B7641D1A38C4114EE829B7D25BF0EFF + 14: DEF9092BA185FD5238A25C6FCF410C52 + 15: D59FEE8047D64032329318DC7A2277B8 + 16: B4561A4A092E031F8FE998FAC87F9BFB + 17: F27EF7D0823B056F692BA369D1B2E7B4 + 18: F62C4F7B749CF31A6F5485BFDED7EEBD + 19: 22BD3AB334BE6E04C84D6197FF69CAE3 + 20: E617D108BED8E9ACBA55FAF60863F8C3 + 21: 0DB60AE0725D37855F3AF1DDF78E98EB + 22: C76DD5A075AB30AB66FC448BD19B6588 + 23: 60231366598BEB2D16D33A1A8019B9A1 + 24: 247E925C96064801490A1D062A0C1F18 + 25: 1C1081E20DE3BE26FF24BEC3DFBA9BF2 + 26: 3B16562B3CD862C00A03B7ADC99E46C5 + 27: C1E8BA560851254640D523A0CEE846AF + 28: C36E8CF324A0A4EBC6C76EA01CDFD158 + 29: EAED84E721777F5E30184E496DA2C0FA + 30: 6655CA0D8741440212AA0DB218E5C7FE + 31: D5C0143E1BA233BA5F862EE6E11A8F58 + 32: C8DAF08BD68F4AE401C6663393C257CB diff --git a/t/mac_poly1305.t b/t/mac_poly1305.t new file mode 100644 index 0000000..ed29f56 --- /dev/null +++ b/t/mac_poly1305.t @@ -0,0 +1,45 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 36; + +use Crypt::Mac::Poly1305 qw( poly1305 poly1305_hex poly1305_b64 poly1305_b64u ); + +is( unpack('H*', Crypt::Mac::Poly1305->new('12345678901234561234567890123456')->add("")->mac), '31323334353637383930313233343536', 'Poly1305/oo+raw/1'); +is( Crypt::Mac::Poly1305->new('12345678901234561234567890123456')->add("")->hexmac, '31323334353637383930313233343536', 'Poly1305/oo+hex/1'); +is( unpack('H*', poly1305('12345678901234561234567890123456',"")), '31323334353637383930313233343536', 'Poly1305/func+raw/1'); +is( poly1305_hex('12345678901234561234567890123456',""), '31323334353637383930313233343536', 'Poly1305/func+hex/1'); +is( poly1305_b64('12345678901234561234567890123456',""), 'MTIzNDU2Nzg5MDEyMzQ1Ng==', 'Poly1305/func+b64/1'); +is( poly1305_b64u('12345678901234561234567890123456',""), 'MTIzNDU2Nzg5MDEyMzQ1Ng', 'Poly1305/func+b64u/1'); +is( unpack('H*', Crypt::Mac::Poly1305->new('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add("")->mac), '61616161616161616161616161616161', 'Poly1305/oo+raw/2'); +is( Crypt::Mac::Poly1305->new('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add("")->hexmac, '61616161616161616161616161616161', 'Poly1305/oo+hex/2'); +is( unpack('H*', poly1305('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"")), '61616161616161616161616161616161', 'Poly1305/func+raw/2'); +is( poly1305_hex('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',""), '61616161616161616161616161616161', 'Poly1305/func+hex/2'); +is( poly1305_b64('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',""), 'YWFhYWFhYWFhYWFhYWFhYQ==', 'Poly1305/func+b64/2'); +is( poly1305_b64u('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',""), 'YWFhYWFhYWFhYWFhYWFhYQ', 'Poly1305/func+b64u/2'); +is( unpack('H*', Crypt::Mac::Poly1305->new('12345678901234561234567890123456')->add(123)->mac), '57af993261c8bf93c336380cce322860', 'Poly1305/oo+raw/3'); +is( Crypt::Mac::Poly1305->new('12345678901234561234567890123456')->add(123)->hexmac, '57af993261c8bf93c336380cce322860', 'Poly1305/oo+hex/3'); +is( unpack('H*', poly1305('12345678901234561234567890123456',123)), '57af993261c8bf93c336380cce322860', 'Poly1305/func+raw/3'); +is( poly1305_hex('12345678901234561234567890123456',123), '57af993261c8bf93c336380cce322860', 'Poly1305/func+hex/3'); +is( poly1305_b64('12345678901234561234567890123456',123), 'V6+ZMmHIv5PDNjgMzjIoYA==', 'Poly1305/func+b64/3'); +is( poly1305_b64u('12345678901234561234567890123456',123), 'V6-ZMmHIv5PDNjgMzjIoYA', 'Poly1305/func+b64u/3'); +is( unpack('H*', Crypt::Mac::Poly1305->new('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add(123)->mac), '01095f71ce6c2b70ce6c2b70ce6c2b70', 'Poly1305/oo+raw/4'); +is( Crypt::Mac::Poly1305->new('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add(123)->hexmac, '01095f71ce6c2b70ce6c2b70ce6c2b70', 'Poly1305/oo+hex/4'); +is( unpack('H*', poly1305('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',123)), '01095f71ce6c2b70ce6c2b70ce6c2b70', 'Poly1305/func+raw/4'); +is( poly1305_hex('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',123), '01095f71ce6c2b70ce6c2b70ce6c2b70', 'Poly1305/func+hex/4'); +is( poly1305_b64('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',123), 'AQlfcc5sK3DObCtwzmwrcA==', 'Poly1305/func+b64/4'); +is( poly1305_b64u('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',123), 'AQlfcc5sK3DObCtwzmwrcA', 'Poly1305/func+b64u/4'); +is( unpack('H*', Crypt::Mac::Poly1305->new('12345678901234561234567890123456')->add("test\0test\0test\n")->mac), '49181f1f65d313a44a2b224fd5fc0abd', 'Poly1305/oo+raw/5'); +is( Crypt::Mac::Poly1305->new('12345678901234561234567890123456')->add("test\0test\0test\n")->hexmac, '49181f1f65d313a44a2b224fd5fc0abd', 'Poly1305/oo+hex/5'); +is( unpack('H*', poly1305('12345678901234561234567890123456',"test\0test\0test\n")), '49181f1f65d313a44a2b224fd5fc0abd', 'Poly1305/func+raw/5'); +is( poly1305_hex('12345678901234561234567890123456',"test\0test\0test\n"), '49181f1f65d313a44a2b224fd5fc0abd', 'Poly1305/func+hex/5'); +is( poly1305_b64('12345678901234561234567890123456',"test\0test\0test\n"), 'SRgfH2XTE6RKKyJP1fwKvQ==', 'Poly1305/func+b64/5'); +is( poly1305_b64u('12345678901234561234567890123456',"test\0test\0test\n"), 'SRgfH2XTE6RKKyJP1fwKvQ', 'Poly1305/func+b64u/5'); +is( unpack('H*', Crypt::Mac::Poly1305->new('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add("test\0test\0test\n")->mac), '4c02cea60201d83ae4b2d644789422e5', 'Poly1305/oo+raw/6'); +is( Crypt::Mac::Poly1305->new('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')->add("test\0test\0test\n")->hexmac, '4c02cea60201d83ae4b2d644789422e5', 'Poly1305/oo+hex/6'); +is( unpack('H*', poly1305('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n")), '4c02cea60201d83ae4b2d644789422e5', 'Poly1305/func+raw/6'); +is( poly1305_hex('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n"), '4c02cea60201d83ae4b2d644789422e5', 'Poly1305/func+hex/6'); +is( poly1305_b64('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n"), 'TALOpgIB2DrkstZEeJQi5Q==', 'Poly1305/func+b64/6'); +is( poly1305_b64u('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n"), 'TALOpgIB2DrkstZEeJQi5Q', 'Poly1305/func+b64u/6'); diff --git a/t/mac_xcbc.t b/t/mac_xcbc.t new file mode 100644 index 0000000..50686c4 --- /dev/null +++ b/t/mac_xcbc.t @@ -0,0 +1,81 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 72; + +use Crypt::Mac::XCBC qw( xcbc xcbc_hex xcbc_b64 xcbc_b64u ); + +is( unpack('H*', Crypt::Mac::XCBC->new('AES','1234567890123456')->add("")->mac), '16f66d6127b7fc067e623d157a86b822', 'XCBC/oo+raw/1'); +is( Crypt::Mac::XCBC->new('AES','1234567890123456')->add("")->hexmac, '16f66d6127b7fc067e623d157a86b822', 'XCBC/oo+hex/1'); +is( unpack('H*', xcbc('AES','1234567890123456',"")), '16f66d6127b7fc067e623d157a86b822', 'XCBC/func+raw/1'); +is( xcbc_hex('AES','1234567890123456',""), '16f66d6127b7fc067e623d157a86b822', 'XCBC/func+hex/1'); +is( xcbc_b64('AES','1234567890123456',""), 'FvZtYSe3/AZ+Yj0Veoa4Ig==', 'XCBC/func+b64/1'); +is( xcbc_b64u('AES','1234567890123456',""), 'FvZtYSe3_AZ-Yj0Veoa4Ig', 'XCBC/func+b64u/1'); +is( unpack('H*', Crypt::Mac::XCBC->new('AES','12345678901234561234567890123456')->add("")->mac), '744807bdb50aca24685b6bc78161c229', 'XCBC/oo+raw/2'); +is( Crypt::Mac::XCBC->new('AES','12345678901234561234567890123456')->add("")->hexmac, '744807bdb50aca24685b6bc78161c229', 'XCBC/oo+hex/2'); +is( unpack('H*', xcbc('AES','12345678901234561234567890123456',"")), '744807bdb50aca24685b6bc78161c229', 'XCBC/func+raw/2'); +is( xcbc_hex('AES','12345678901234561234567890123456',""), '744807bdb50aca24685b6bc78161c229', 'XCBC/func+hex/2'); +is( xcbc_b64('AES','12345678901234561234567890123456',""), 'dEgHvbUKyiRoW2vHgWHCKQ==', 'XCBC/func+b64/2'); +is( xcbc_b64u('AES','12345678901234561234567890123456',""), 'dEgHvbUKyiRoW2vHgWHCKQ', 'XCBC/func+b64u/2'); +is( unpack('H*', Crypt::Mac::XCBC->new('Blowfish','1234567890123456')->add("")->mac), '9ef018b3c33f6f35', 'XCBC/oo+raw/3'); +is( Crypt::Mac::XCBC->new('Blowfish','1234567890123456')->add("")->hexmac, '9ef018b3c33f6f35', 'XCBC/oo+hex/3'); +is( unpack('H*', xcbc('Blowfish','1234567890123456',"")), '9ef018b3c33f6f35', 'XCBC/func+raw/3'); +is( xcbc_hex('Blowfish','1234567890123456',""), '9ef018b3c33f6f35', 'XCBC/func+hex/3'); +is( xcbc_b64('Blowfish','1234567890123456',""), 'nvAYs8M/bzU=', 'XCBC/func+b64/3'); +is( xcbc_b64u('Blowfish','1234567890123456',""), 'nvAYs8M_bzU', 'XCBC/func+b64u/3'); +is( unpack('H*', Crypt::Mac::XCBC->new('Blowfish','12345678901234561234567890123456')->add("")->mac), '9ef018b3c33f6f35', 'XCBC/oo+raw/4'); +is( Crypt::Mac::XCBC->new('Blowfish','12345678901234561234567890123456')->add("")->hexmac, '9ef018b3c33f6f35', 'XCBC/oo+hex/4'); +is( unpack('H*', xcbc('Blowfish','12345678901234561234567890123456',"")), '9ef018b3c33f6f35', 'XCBC/func+raw/4'); +is( xcbc_hex('Blowfish','12345678901234561234567890123456',""), '9ef018b3c33f6f35', 'XCBC/func+hex/4'); +is( xcbc_b64('Blowfish','12345678901234561234567890123456',""), 'nvAYs8M/bzU=', 'XCBC/func+b64/4'); +is( xcbc_b64u('Blowfish','12345678901234561234567890123456',""), 'nvAYs8M_bzU', 'XCBC/func+b64u/4'); +is( unpack('H*', Crypt::Mac::XCBC->new('AES','1234567890123456')->add(123)->mac), 'bc9e0ee2a05a751b5ab25ddf0da158ea', 'XCBC/oo+raw/5'); +is( Crypt::Mac::XCBC->new('AES','1234567890123456')->add(123)->hexmac, 'bc9e0ee2a05a751b5ab25ddf0da158ea', 'XCBC/oo+hex/5'); +is( unpack('H*', xcbc('AES','1234567890123456',123)), 'bc9e0ee2a05a751b5ab25ddf0da158ea', 'XCBC/func+raw/5'); +is( xcbc_hex('AES','1234567890123456',123), 'bc9e0ee2a05a751b5ab25ddf0da158ea', 'XCBC/func+hex/5'); +is( xcbc_b64('AES','1234567890123456',123), 'vJ4O4qBadRtasl3fDaFY6g==', 'XCBC/func+b64/5'); +is( xcbc_b64u('AES','1234567890123456',123), 'vJ4O4qBadRtasl3fDaFY6g', 'XCBC/func+b64u/5'); +is( unpack('H*', Crypt::Mac::XCBC->new('AES','12345678901234561234567890123456')->add(123)->mac), 'c0a87d7fa68bb2a7e18ad56808ec4eb3', 'XCBC/oo+raw/6'); +is( Crypt::Mac::XCBC->new('AES','12345678901234561234567890123456')->add(123)->hexmac, 'c0a87d7fa68bb2a7e18ad56808ec4eb3', 'XCBC/oo+hex/6'); +is( unpack('H*', xcbc('AES','12345678901234561234567890123456',123)), 'c0a87d7fa68bb2a7e18ad56808ec4eb3', 'XCBC/func+raw/6'); +is( xcbc_hex('AES','12345678901234561234567890123456',123), 'c0a87d7fa68bb2a7e18ad56808ec4eb3', 'XCBC/func+hex/6'); +is( xcbc_b64('AES','12345678901234561234567890123456',123), 'wKh9f6aLsqfhitVoCOxOsw==', 'XCBC/func+b64/6'); +is( xcbc_b64u('AES','12345678901234561234567890123456',123), 'wKh9f6aLsqfhitVoCOxOsw', 'XCBC/func+b64u/6'); +is( unpack('H*', Crypt::Mac::XCBC->new('Blowfish','1234567890123456')->add(123)->mac), '21e88fbfb47a3200', 'XCBC/oo+raw/7'); +is( Crypt::Mac::XCBC->new('Blowfish','1234567890123456')->add(123)->hexmac, '21e88fbfb47a3200', 'XCBC/oo+hex/7'); +is( unpack('H*', xcbc('Blowfish','1234567890123456',123)), '21e88fbfb47a3200', 'XCBC/func+raw/7'); +is( xcbc_hex('Blowfish','1234567890123456',123), '21e88fbfb47a3200', 'XCBC/func+hex/7'); +is( xcbc_b64('Blowfish','1234567890123456',123), 'IeiPv7R6MgA=', 'XCBC/func+b64/7'); +is( xcbc_b64u('Blowfish','1234567890123456',123), 'IeiPv7R6MgA', 'XCBC/func+b64u/7'); +is( unpack('H*', Crypt::Mac::XCBC->new('Blowfish','12345678901234561234567890123456')->add(123)->mac), '21e88fbfb47a3200', 'XCBC/oo+raw/8'); +is( Crypt::Mac::XCBC->new('Blowfish','12345678901234561234567890123456')->add(123)->hexmac, '21e88fbfb47a3200', 'XCBC/oo+hex/8'); +is( unpack('H*', xcbc('Blowfish','12345678901234561234567890123456',123)), '21e88fbfb47a3200', 'XCBC/func+raw/8'); +is( xcbc_hex('Blowfish','12345678901234561234567890123456',123), '21e88fbfb47a3200', 'XCBC/func+hex/8'); +is( xcbc_b64('Blowfish','12345678901234561234567890123456',123), 'IeiPv7R6MgA=', 'XCBC/func+b64/8'); +is( xcbc_b64u('Blowfish','12345678901234561234567890123456',123), 'IeiPv7R6MgA', 'XCBC/func+b64u/8'); +is( unpack('H*', Crypt::Mac::XCBC->new('AES','1234567890123456')->add("test\0test\0test\n")->mac), '94cf668c4bbbb2bc0fc0bf14612084b9', 'XCBC/oo+raw/9'); +is( Crypt::Mac::XCBC->new('AES','1234567890123456')->add("test\0test\0test\n")->hexmac, '94cf668c4bbbb2bc0fc0bf14612084b9', 'XCBC/oo+hex/9'); +is( unpack('H*', xcbc('AES','1234567890123456',"test\0test\0test\n")), '94cf668c4bbbb2bc0fc0bf14612084b9', 'XCBC/func+raw/9'); +is( xcbc_hex('AES','1234567890123456',"test\0test\0test\n"), '94cf668c4bbbb2bc0fc0bf14612084b9', 'XCBC/func+hex/9'); +is( xcbc_b64('AES','1234567890123456',"test\0test\0test\n"), 'lM9mjEu7srwPwL8UYSCEuQ==', 'XCBC/func+b64/9'); +is( xcbc_b64u('AES','1234567890123456',"test\0test\0test\n"), 'lM9mjEu7srwPwL8UYSCEuQ', 'XCBC/func+b64u/9'); +is( unpack('H*', Crypt::Mac::XCBC->new('AES','12345678901234561234567890123456')->add("test\0test\0test\n")->mac), '438ad752323bdaab774e5051556b2336', 'XCBC/oo+raw/10'); +is( Crypt::Mac::XCBC->new('AES','12345678901234561234567890123456')->add("test\0test\0test\n")->hexmac, '438ad752323bdaab774e5051556b2336', 'XCBC/oo+hex/10'); +is( unpack('H*', xcbc('AES','12345678901234561234567890123456',"test\0test\0test\n")), '438ad752323bdaab774e5051556b2336', 'XCBC/func+raw/10'); +is( xcbc_hex('AES','12345678901234561234567890123456',"test\0test\0test\n"), '438ad752323bdaab774e5051556b2336', 'XCBC/func+hex/10'); +is( xcbc_b64('AES','12345678901234561234567890123456',"test\0test\0test\n"), 'Q4rXUjI72qt3TlBRVWsjNg==', 'XCBC/func+b64/10'); +is( xcbc_b64u('AES','12345678901234561234567890123456',"test\0test\0test\n"), 'Q4rXUjI72qt3TlBRVWsjNg', 'XCBC/func+b64u/10'); +is( unpack('H*', Crypt::Mac::XCBC->new('Blowfish','1234567890123456')->add("test\0test\0test\n")->mac), '98276a4a6aafd86b', 'XCBC/oo+raw/11'); +is( Crypt::Mac::XCBC->new('Blowfish','1234567890123456')->add("test\0test\0test\n")->hexmac, '98276a4a6aafd86b', 'XCBC/oo+hex/11'); +is( unpack('H*', xcbc('Blowfish','1234567890123456',"test\0test\0test\n")), '98276a4a6aafd86b', 'XCBC/func+raw/11'); +is( xcbc_hex('Blowfish','1234567890123456',"test\0test\0test\n"), '98276a4a6aafd86b', 'XCBC/func+hex/11'); +is( xcbc_b64('Blowfish','1234567890123456',"test\0test\0test\n"), 'mCdqSmqv2Gs=', 'XCBC/func+b64/11'); +is( xcbc_b64u('Blowfish','1234567890123456',"test\0test\0test\n"), 'mCdqSmqv2Gs', 'XCBC/func+b64u/11'); +is( unpack('H*', Crypt::Mac::XCBC->new('Blowfish','12345678901234561234567890123456')->add("test\0test\0test\n")->mac), '98276a4a6aafd86b', 'XCBC/oo+raw/12'); +is( Crypt::Mac::XCBC->new('Blowfish','12345678901234561234567890123456')->add("test\0test\0test\n")->hexmac, '98276a4a6aafd86b', 'XCBC/oo+hex/12'); +is( unpack('H*', xcbc('Blowfish','12345678901234561234567890123456',"test\0test\0test\n")), '98276a4a6aafd86b', 'XCBC/func+raw/12'); +is( xcbc_hex('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), '98276a4a6aafd86b', 'XCBC/func+hex/12'); +is( xcbc_b64('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), 'mCdqSmqv2Gs=', 'XCBC/func+b64/12'); +is( xcbc_b64u('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), 'mCdqSmqv2Gs', 'XCBC/func+b64u/12'); diff --git a/t/mbi_ltm/bigfltpm.inc b/t/mbi_ltm/bigfltpm.inc new file mode 100644 index 0000000..10d0513 --- /dev/null +++ b/t/mbi_ltm/bigfltpm.inc @@ -0,0 +1,2087 @@ +#include this file into another test for subclass testing... + +use strict; +use warnings; + +our ($CLASS, $CALC); + +is($CLASS->config()->{lib}, $CALC, "$CLASS->config()->{lib}"); + +my ($x, $y, $z, @args, $try, $want, $got); +my ($f, $setup); + +while () { + s/#.*$//; # remove comments + s/\s+$//; # remove trailing whitespace + next unless length; # skip empty lines + + + if (s/^&//) { + $f = $_; + next; + } + + if (/^\$/) { + $setup = $_; + $setup =~ s/\$/\$${CLASS}::/g; # round_mode, div_scale + #print "\$setup== $setup\n"; + next; + } + + if (m|^(.*?):(/.+)$|) { + $want = $2; + @args = split(/:/, $1, 99); + } else { + @args = split(/:/, $_, 99); + $want = pop(@args); + } + + $try = qq|\$x = $CLASS->new("$args[0]");|; + if ($f eq "bnorm") { + $try .= qq| \$x;|; + } elsif ($f =~ /^is_(zero|one|negative|positive|odd|even|nan|int)$/) { + $try .= qq| \$x->$f();|; + } elsif ($f eq "is_inf") { + $try .= qq| \$x->is_inf("$args[1]");|; + } elsif ($f eq "binf") { + $try .= qq| \$x->binf("$args[1]");|; + } elsif ($f eq "bone") { + $try .= qq| \$x->bone("$args[1]");|; + } elsif ($f eq "bstr") { + $try .= qq| \$x->accuracy($args[1]); \$x->precision($args[2]);|; + $try .= ' $x->bstr();'; + # some unary ops + } elsif ($f =~ /^b(nan|sstr|neg|floor|ceil|int|abs)$/) { + $try .= qq| \$x->$f();|; + # overloaded functions + } elsif ($f =~ /^(log|exp|sin|cos|atan2|int|neg|abs|sqrt)$/) { + $try .= qq| \$x = $f(\$x);|; + } elsif ($f eq "parts") { + # ->bstr() to see if an object is returned + $try .= ' ($a, $b) = $x->parts(); $a = $a->bstr(); $b = $b->bstr();'; + $try .= ' "$a $b";'; + } elsif ($f eq "exponent") { + # ->bstr() to see if an object is returned + $try .= ' $x->exponent()->bstr();'; + } elsif ($f eq "mantissa") { + # ->bstr() to see if an object is returned + $try .= ' $x->mantissa()->bstr();'; + } elsif ($f =~ /^(numify|length|as_number|as_hex|as_bin)$/) { + $try .= qq| \$x->$f();|; + } elsif ($f eq "bpi") { + $try .= qq| $CLASS->bpi(\$x);|; + } elsif ($f eq "binc") { + $try .= ' ++$x;'; + } elsif ($f eq "bdec") { + $try .= ' --$x;'; + } elsif ($f eq "bround") { + $try .= qq| $setup; \$x->bround($args[1]);|; + } elsif ($f eq "bfround") { + $try .= qq| $setup; \$x->bfround($args[1]);|; + } elsif ($f eq "bsqrt") { + $try .= qq| $setup; \$x->bsqrt();|; + } elsif ($f eq "bfac") { + $try .= qq| $setup; \$x->bfac();|; + } elsif ($f eq "blog") { + if (defined $args[1] && $args[1] ne '') { + $try .= qq| \$y = $CLASS->new($args[1]);|; + $try .= qq| $setup; \$x->blog(\$y);|; + } else { + $try .= qq| $setup; \$x->blog();|; + } + } else { + # binary operators + $try .= qq| \$y = $CLASS->new("$args[1]");|; + + if ($f eq "bgcd") { + if (defined $args[2]) { + $try .= qq| \$z = $CLASS->new("$args[2]");|; + } + $try .= qq| $CLASS\::bgcd(\$x, \$y|; + $try .= qq|, \$z| if defined $args[2]; + $try .= qq|);|; + } elsif ($f eq "blcm") { + if (defined $args[2]) { + $try .= qq| \$z = $CLASS->new("$args[2]");|; + } + $try .= qq| $CLASS\::blcm(\$x, \$y|; + $try .= qq|, \$z| if defined $args[2]; + $try .= qq|);|; + } elsif ($f eq "bcmp") { + $try .= ' $x->bcmp($y);'; + } elsif ($f eq "bacmp") { + $try .= ' $x->bacmp($y);'; + } elsif ($f eq "bpow") { + $try .= ' $x ** $y;'; + } elsif ($f eq "bnok") { + $try .= ' $x->bnok($y);'; + } elsif ($f eq "bcos") { + $try .= ' $x->bcos($y);'; + } elsif ($f eq "bsin") { + $try .= ' $x->bsin($y);'; + } elsif ($f eq "batan") { + $try .= ' $x->batan($y);'; + } elsif ($f eq "broot") { + $try .= qq| $setup; \$x->broot(\$y);|; + } elsif ($f eq "badd") { + $try .= ' $x + $y;'; + } elsif ($f eq "bsub") { + $try .= ' $x - $y;'; + } elsif ($f eq "bmul") { + $try .= ' $x * $y;'; + } elsif ($f eq "bdiv") { + $try .= qq| $setup; \$x / \$y;|; + } elsif ($f eq "bdiv-list") { + $try .= qq| $setup; join(",", \$x->bdiv(\$y));|; + } elsif ($f eq "brsft") { + $try .= ' $x >> $y;'; + } elsif ($f eq "blsft") { + $try .= ' $x << $y;'; + } elsif ($f eq "bmod") { + $try .= ' $x % $y;'; + } else { + # Functions with three arguments + $try .= qq| \$z = $CLASS->new("$args[2]");|; + + if ($f eq "bmodpow") { + $try .= ' $x->bmodpow($y, $z);'; + } elsif ($f eq "bmuladd") { + $try .= ' $x->bmuladd($y, $z);'; + } elsif ($f eq "batan2") { + $try .= ' $x->batan2($y, $z);'; + } else { + warn qq|Unknown op "$f"|; + } + } + } + + $got = eval $try; + print "# Error: $@\n" if $@; + + if ($want =~ m|^/(.*)$|) { + my $pat = $1; + like($got, qr/$pat/, $try); + } else { + if ($want eq "") { + is($got, undef, $try); + } else { + is($got, $want, $try); + if (ref($got) eq $CLASS) { + # float numbers are normalized (for now), so mantissa shouldn't + # have trailing zeros print $got->_trailing_zeros(), "\n"; + is($CALC->_zeros($got->{_m}), 0, $try); + } + } + } # end pattern or string + +} # end while + +# check whether $CLASS->new(Math::BigInt->new()) destroys it +# ($y == 12 in this case) +$x = Math::BigInt->new(1200); +$y = $CLASS->new($x); +is($y, 1200, + q|$x = Math::BigInt->new(1200); $y = $CLASS->new($x); # check $y|); +is($x, 1200, + q|$x = Math::BigInt->new(1200); $y = $CLASS->new($x); # check $x|); + +############################################################################### +# Really huge, big, ultra-mega-biggy-monster exponents. Technically, the +# exponents should not be limited (they are Math::BigInt objects), but +# practically there are a few places were they are limited to a Perl scalar. +# This is sometimes for speed, sometimes because otherwise the number wouldn't +# fit into your memory (just think of 1e123456789012345678901234567890 + 1!) +# anyway. We don't test everything here, but let's make sure it just basically +# works. + +my $monster = '1e1234567890123456789012345678901234567890'; + +# new and exponent +is($CLASS->new($monster)->bsstr(), + '1e+1234567890123456789012345678901234567890', + qq|$CLASS->new("$monster")->bsstr()|); +is($CLASS->new($monster)->exponent(), + '1234567890123456789012345678901234567890', + qq|$CLASS->new("$monster")->exponent()|); + +# cmp +is($CLASS->new($monster) > 0, 1, qq|$CLASS->new("$monster") > 0|); + +# sub/mul +is($CLASS->new($monster)->bsub($monster), 0, + qq|$CLASS->new("$monster")->bsub("$monster")|); +is($CLASS->new($monster)->bmul(2)->bsstr(), + '2e+1234567890123456789012345678901234567890', + qq|$CLASS->new("$monster")->bmul(2)->bsstr()|); + +# mantissa +$monster = '1234567890123456789012345678901234567890e2'; +is($CLASS->new($monster)->mantissa(), + '123456789012345678901234567890123456789', + qq|$CLASS->new("$monster")->mantissa()|); + +############################################################################### +# zero, inf, one, nan + +$x = $CLASS->new(2); +$x->bzero(); +is($x->{_a}, undef, qq|\$x = $CLASS->new(2); \$x->bzero(); \$x->{_a}|); +is($x->{_p}, undef, qq|\$x = $CLASS->new(2); \$x->bzero(); \$x->{_p}|); + +$x = $CLASS->new(2); +$x->binf(); +is($x->{_a}, undef, qq|\$x = $CLASS->new(2); \$x->binf(); \$x->{_a}|); +is($x->{_p}, undef, qq|\$x = $CLASS->new(2); \$x->binf(); \$x->{_p}|); + +$x = $CLASS->new(2); +$x->bone(); +is($x->{_a}, undef, qq|\$x = $CLASS->new(2); \$x->bone(); \$x->{_a}|); +is($x->{_p}, undef, qq|\$x = $CLASS->new(2); \$x->bone(); \$x->{_p}|); + +$x = $CLASS->new(2); +$x->bnan(); +is($x->{_a}, undef, qq|\$x = $CLASS->new(2); \$x->bnan(); \$x->{_a}|); +is($x->{_p}, undef, qq|\$x = $CLASS->new(2); \$x->bnan(); \$x->{_p}|); + +############################################################################### +# bone/binf etc as plain calls (Lite failed them) + +is($CLASS->bzero(), 0, qq|$CLASS->bzero()|); +is($CLASS->bone(), 1, qq|$CLASS->bone()|); +is($CLASS->bone("+"), 1, qq|$CLASS->bone("+")|); +is($CLASS->bone("-"), -1, qq|$CLASS->bone("-")|); +is($CLASS->bnan(), "NaN", qq|$CLASS->bnan()|); +is($CLASS->binf(), "inf", qq|$CLASS->binf()|); +is($CLASS->binf("+"), "inf", qq|$CLASS->binf("+")|); +is($CLASS->binf("-"), "-inf", qq|$CLASS->binf("-")|); +is($CLASS->binf("-inf"), "-inf", qq|$CLASS->binf("-inf")|); + +$CLASS->accuracy(undef); # reset +$CLASS->precision(undef); # reset + +############################################################################### +# bug in bsstr()/numify() showed up in after-rounding in bdiv() + +$x = $CLASS->new("0.008"); +$y = $CLASS->new(2); +$x->bdiv(3, $y); +is($x, "0.0027", + qq|\$x = $CLASS->new("0.008"); \$y = $CLASS->new(2); \$x->bdiv(3, \$y);|); + +############################################################################### +# Verify that numify() returns a normalized value, and underflows and +# overflows when given "extreme" values. + +like($CLASS->new("12345e67")->numify(), qr/^1\.2345e\+?0*71$/, + qq|$CLASS->new("12345e67")->numify()|); + +# underflow +like($CLASS->new("1e-9999")->numify(), qr/^\+?0$/, + qq|$CLASS->new("1e-9999")->numify()|); + +# overflow +unlike($CLASS->new("1e9999")->numify(), qr/^1(\.0*)?e\+?9+$/, + qq|$CLASS->new("1e9999")->numify()|); + +############################################################################### +# Check numify on non-finite objects. + +{ + require Math::Complex; + my $inf = Math::Complex::Inf(); + my $nan = $inf - $inf; + is($CLASS -> binf("+") -> numify(), $inf, "numify of +Inf"); + is($CLASS -> binf("-") -> numify(), -$inf, "numify of -Inf"); + is($CLASS -> bnan() -> numify(), $nan, "numify of NaN"); +} + +############################################################################### +# bsqrt() with set global A/P or A/P enabled on $x, also a test whether bsqrt() +# correctly modifies $x + +$x = $CLASS->new(12); +$CLASS->precision(-2); +$x->bsqrt(); +is($x, '3.46', + qq|\$x = $CLASS->new(12); $CLASS->precision(-2); \$x->bsqrt();|); + +$CLASS->precision(undef); +$x = $CLASS->new(12); +$CLASS->precision(0); +$x->bsqrt(); +is($x, '3', + qq|$CLASS->precision(undef); \$x = $CLASS->new(12);| . + qq| $CLASS->precision(0); \$x->bsqrt();|); + +$CLASS->precision(-3); +$x = $CLASS->new(12); +$x->bsqrt(); +is($x, '3.464', + qq|$CLASS->precision(-3); \$x = $CLASS->new(12); \$x->bsqrt();|); + +{ + no strict 'refs'; + # A and P set => NaN + ${${CLASS}.'::accuracy'} = 4; + $x = $CLASS->new(12); + $x->bsqrt(3); + is($x, 'NaN', "A and P set => NaN"); + + # supplied arg overrides set global + $CLASS->precision(undef); + $x = $CLASS->new(12); + $x->bsqrt(3); + is($x, '3.46', "supplied arg overrides set global"); + + # reset for further tests + $CLASS->accuracy(undef); + $CLASS->precision(undef); +} + +############################################################################# +# can we call objectify (broken until v1.52) + +{ + no strict; + $try = '@args' + . " = $CLASS" + . "::objectify(2, $CLASS, 4, 5);" + . ' join(" ", @args);'; + $want = eval $try; + is($want, "$CLASS 4 5", $try); +} + +############################################################################# +# is_one('-') (broken until v1.64) + +is($CLASS->new(-1)->is_one(), 0, qq|$CLASS->new(-1)->is_one()|); +is($CLASS->new(-1)->is_one("-"), 1, qq|$CLASS->new(-1)->is_one("-")|); + +############################################################################# +# bug 1/0.5 leaving 2e-0 instead of 2e0 + +is($CLASS->new(1)->bdiv("0.5")->bsstr(), "2e+0", + qq|$CLASS->new(1)->bdiv("0.5")->bsstr()|); + +############################################################################### +# [perl #30609] bug with $x -= $x not being 0, but 2*$x + +$x = $CLASS->new(3); +$x -= $x; +is($x, 0, qq|\$x = $CLASS->new(3); \$x -= \$x;|); + +$x = $CLASS->new(-3); +$x -= $x; +is($x, 0, qq|\$x = $CLASS->new(-3); \$x -= \$x;|); + +$x = $CLASS->new(3); +$x += $x; +is($x, 6, qq|\$x = $CLASS->new(3); \$x += \$x;|); + +$x = $CLASS->new(-3); +$x += $x; +is($x, -6, qq|\$x = $CLASS->new(-3); \$x += \$x;|); + +$x = $CLASS->new("NaN"); +$x -= $x; +is($x->is_nan(), 1, qq|\$x = $CLASS->new("NaN"); \$x -= \$x;|); + +$x = $CLASS->new("inf"); +$x -= $x; +is($x->is_nan(), 1, qq|\$x = $CLASS->new("inf"); \$x -= \$x;|); + +$x = $CLASS->new("-inf"); +$x -= $x; +is($x->is_nan(), 1, qq|\$x = $CLASS->new("-inf"); \$x -= \$x;|); + +$x = $CLASS->new("NaN"); +$x += $x; +is($x->is_nan(), 1, qq|\$x = $CLASS->new("NaN"); \$x += \$x;|); + +$x = $CLASS->new("inf"); +$x += $x; +is($x->is_inf(), 1, qq|\$x = $CLASS->new("inf"); \$x += \$x;|); + +$x = $CLASS->new("-inf"); +$x += $x; +is($x->is_inf("-"), 1, qq|\$x = $CLASS->new("-inf"); \$x += \$x;|); + +$x = $CLASS->new("3.14"); +$x -= $x; +is($x, 0, qq|\$x = $CLASS->new("3.14"); \$x -= \$x;|); + +$x = $CLASS->new("-3.14"); +$x -= $x; +is($x, 0, qq|\$x = $CLASS->new("-3.14"); \$x -= \$x;|); + +$x = $CLASS->new("3.14"); +$x += $x; +is($x, "6.28", qq|$x = $CLASS->new("3.14"); $x += $x;|); + +$x = $CLASS->new("-3.14"); +$x += $x; +is($x, "-6.28", qq|$x = $CLASS->new("-3.14"); $x += $x;|); + +$x = $CLASS->new("3.14"); +$x *= $x; +is($x, "9.8596", qq|$x = $CLASS->new("3.14"); $x *= $x;|); + +$x = $CLASS->new("-3.14"); +$x *= $x; +is($x, "9.8596", qq|$x = $CLASS->new("-3.14"); $x *= $x;|); + +$x = $CLASS->new("3.14"); +$x /= $x; +is($x, "1", qq|$x = $CLASS->new("3.14"); $x /= $x;|); + +$x = $CLASS->new("-3.14"); +$x /= $x; +is($x, "1", qq|$x = $CLASS->new("-3.14"); $x /= $x;|); + +$x = $CLASS->new("3.14"); +$x %= $x; +is($x, "0", qq|$x = $CLASS->new("3.14"); $x %= $x;|); + +$x = $CLASS->new("-3.14"); +$x %= $x; +is($x, "0", qq|$x = $CLASS->new("-3.14"); $x %= $x;|); + +############################################################################### +# the following two were reported by "kenny" via hotmail.com: + +#perl -MMath::BigFloat -wle 'print Math::BigFloat->new(0)->bpow(".1")' +#Use of uninitialized value in numeric le (<=) at BigFloat.pm line 1851. + +$x = $CLASS->new(0); +$y = $CLASS->new("0.1"); +is($x ** $y, 0, + qq|\$x = $CLASS->new(0); \$y = $CLASS->new("0.1"); \$x ** \$y|); + +#perl -MMath::BigFloat -lwe 'print Math::BigFloat->new(".222222222222222222222222222222222222222222")->bceil()' +#Use of uninitialized value in numeric le (<=) at BigFloat.pm line 1851. + +$x = $CLASS->new(".222222222222222222222222222222222222222222"); +is($x->bceil(), 1, + qq|$x = $CLASS->new(".222222222222222222222222222222222222222222");| . + qq| $x->bceil();|); + +############################################################################### +# test **=, <<=, >>= + +# ((2**148)+1)/17 +$x = $CLASS->new(2); +$x **= 148; +$x++; +$x->bdiv(17, 60)->bfloor(); +$x->accuracy(undef); +is($x, "20988936657440586486151264256610222593863921", + "value of ((2**148)+1)/17"); +is($x->length(), length("20988936657440586486151264256610222593863921"), + "number of digits in ((2**148)+1)/17"); + +$x = $CLASS->new("2"); +$y = $CLASS->new("18"); +is($x <<= $y, 2 << 18, + qq|\$x = $CLASS->new("2"); \$y = $CLASS->new("18");| + . q| $x <<= $y|); +is($x, 2 << 18, + qq|\$x = $CLASS->new("2"); \$y = $CLASS->new("18");| + . q| $x <<= $y; $x|); +is($x >>= $y, 2, + qq|\$x = $CLASS->new("2"); \$y = $CLASS->new("18");| + . q| $x <<= $y; $x >>= $y|); +is($x, 2, + qq|\$x = $CLASS->new("2"); \$y = $CLASS->new("18");| + . q| $x <<= $y; $x >>= $y; $x|); + +$x = $CLASS->new("2"); +$y = $CLASS->new("18.2"); + +# 2 * (2 ** 18.2); +$x <<= $y; +is($x->copy()->bfround(-9), "602248.763144685", + qq|\$x = $CLASS->new("2"); \$y = $CLASS->new("18.2");| . + q| $x <<= $y; $x->copy()->bfround(-9);|); + +# 2 * (2 ** 18.2) / (2 ** 18.2) => 2 +is($x >>= $y, 2, + qq|\$x = $CLASS->new("2"); \$y = $CLASS->new("18.2");| . + q| $x <<= $y; $x->copy()->bfround(-9); $x >>= $y|); +is($x, 2, + qq|\$x = $CLASS->new("2"); \$y = $CLASS->new("18.2");| . + q| $x <<= $y; $x->copy()->bfround(-9); $x >>= $y; $x|); + +__DATA__ + +&bgcd +inf:12:NaN +-inf:12:NaN +12:inf:NaN +12:-inf:NaN +inf:inf:NaN +inf:-inf:NaN +-inf:-inf:NaN +abc:abc:NaN +abc:+0:NaN ++0:abc:NaN ++0:+0:0 ++0:+1:1 ++1:+0:1 ++1:+1:1 ++2:+3:1 ++3:+2:1 +-3:+2:1 +-3:-2:1 +-144:-60:12 +144:-60:12 +144:60:12 +100:625:25 +4096:81:1 +1034:804:2 +27:90:56:1 +27:90:54:9 + +&blcm +abc:abc:NaN +abc:+0:NaN ++0:abc:NaN ++0:+0:NaN ++1:+0:0 ++0:+1:0 ++27:+90:270 ++1034:+804:415668 +$div_scale = 40 + +&bcos +1.2:10:0.3623577545 +2.4:12:-0.737393715541 +0:10:1 +0:20:1 +1:10:0.5403023059 +1:12:0.540302305868 + +&bsin +1:10:0.8414709848 +0:10:0 +0:20:0 +2.1:12:0.863209366649 +1.2:13:0.9320390859672 +0.2:13:0.1986693307951 +3.2:12:-0.0583741434276 + +&batan +NaN:10:NaN +inf:14:1.5707963267949 +-inf:14:-1.5707963267949 +0:14:0 +0:10:0 +0.1:14:0.099668652491162 +0.2:13:0.1973955598499 +0.2:14:0.19739555984988 +0.5:14:0.46364760900081 +1:14:0.78539816339744 +-1:14:-0.78539816339744 +1.5:14:0.98279372324732 +2.0:14:1.1071487177941 +2.5:14:1.1902899496825 +3.0:14:1.2490457723982 +6.0:14:1.4056476493803 +12:14:1.4876550949064 +24:14:1.5291537476963 +48:14:1.5499660067587 + +&batan2 + +NaN:1:10:NaN +NaN:NaN:10:NaN +1:NaN:10:NaN + +-inf:-inf:14:-2.3561944901923 +-inf:-1:14:-1.5707963267949 +-inf:0:14:-1.5707963267949 +-inf:+1:14:-1.5707963267949 +-inf:+inf:14:-0.78539816339745 + +-1:-inf:14:-3.1415926535898 +-1:-1:14:-2.3561944901923 +-1:0:14:-1.5707963267949 +-1:+1:14:-0.78539816339745 +-1:+inf:14:0 + +0:-inf:14:3.1415926535898 +0:-1:14:3.1415926535898 +0:0:14:0 +0:+1:14:0 +0:+inf:14:0 + ++1:-inf:14:3.1415926535898 ++1:-1:14:2.3561944901923 ++1:0:14:1.5707963267949 ++1:+1:14:0.78539816339745 ++1:+inf:14:0 + ++inf:-inf:14:2.3561944901923 ++inf:-1:14:1.5707963267949 ++inf:0:14:1.5707963267949 ++inf:+1:14:1.5707963267949 ++inf:+inf:14:0.78539816339745 + +1:5:13:0.1973955598499 +1:5:14:0.19739555984988 +0:2:14:0 +5:0:14:1.5707963267949 +-1:0:11:-1.5707963268 +-2:0:77:-1.5707963267948966192313216916397514420985846996875529104874722961539082031431 +2:0:77:1.5707963267948966192313216916397514420985846996875529104874722961539082031431 +-1:5:14:-0.19739555984988 +1:5:14:0.19739555984988 +-1:8:14:-0.12435499454676 +1:8:14:0.12435499454676 +# test an argument X > 1 and one X < 1 +1:2:24:0.463647609000806116214256 +2:1:14:1.1071487177941 +-2:1:14:-1.1071487177941 + +&bpi +150:3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940813 +77:3.1415926535897932384626433832795028841971693993751058209749445923078164062862 ++0:3.141592653589793238462643383279502884197 +11:3.1415926536 + +&bnok ++inf:10:inf +NaN:NaN:NaN +NaN:1:NaN +1:NaN:NaN +1:1:1 +# k > n +1:2:0 +2:3:0 +# k < 0 +1:-2:0 +# 7 over 3 = 35 +7:3:35 +7:6:7 +100:90:17310309456440 +100:95:75287520 +2:0:1 +7:0:1 +2:1:2 + +&blog +0::-inf +-1::NaN +-2::NaN +# base > 0, base != 1 +2:-1:NaN +2:0:0 +2:1:NaN +# log(1) +1::0 +1:1:NaN +1:2:0 +2::0.6931471805599453094172321214581765680755 +2.718281828::0.9999999998311266953289851340574956564911 +$div_scale = 20 +2.718281828::0.99999999983112669533 +$div_scale = 15 +123::4.81218435537242 +10::2.30258509299405 +1000::6.90775527898214 +100::4.60517018598809 +2::0.693147180559945 +3.1415::1.14470039286086 +12345::9.42100640177928 +0.001::-6.90775527898214 +# bug until v1.71: +10:10:1 +100:100:1 +# reset for further tests +$div_scale = 40 +1::0 + +&brsft +NaNbrsft:2:NaN +0:2:0 +1:1:0.5 +2:1:1 +4:1:2 +123:1:61.5 +32:3:4 + +&blsft +NaNblsft:0:NaN +2:1:4 +4:3:32 +5:3:40 +1:2:4 +0:5:0 + +&bnorm +1:1 +-0:0 +bnormNaN:NaN ++inf:inf +-inf:-inf +123:123 +-123.4567:-123.4567 +# invalid inputs +1__2:NaN +1E1__2:NaN +11__2E2:NaN +.2E-3.:NaN +1e3e4:NaN +# strange, but valid +.2E2:20 +1.E3:1000 +# some inputs that result in zero +0e0:0 ++0e0:0 ++0e+0:0 +-0e+0:0 +0e-0:0 +-0e-0:0 ++0e-0:0 +000:0 +00e2:0 +00e02:0 +000e002:0 +000e1230:0 +00e-3:0 +00e+3:0 +00e-03:0 +00e+03:0 +-000:0 +-00e2:0 +-00e02:0 +-000e002:0 +-000e1230:0 +-00e-3:0 +-00e+3:0 +-00e-03:0 +-00e+03:0 + +&as_number +0:0 +1:1 +1.2:1 +2.345:2 +-2:-2 +-123.456:-123 +-200:-200 +-inf:-inf +inf:inf +NaN:NaN +71243225429896467497217836789578596379:71243225429896467497217836789578596379 +# test for bug in brsft() not handling cases that return 0 +0.000641:0 +0.0006412:0 +0.00064123:0 +0.000641234:0 +0.0006412345:0 +0.00064123456:0 +0.000641234567:0 +0.0006412345678:0 +0.00064123456789:0 +0.1:0 +0.01:0 +0.001:0 +0.0001:0 +0.00001:0 +0.000001:0 +0.0000001:0 +0.00000001:0 +0.000000001:0 +0.0000000001:0 +0.00000000001:0 +0.12345:0 +0.123456:0 +0.1234567:0 +0.12345678:0 +0.123456789:0 + +&binf +1:+:inf +2:-:-inf +3:abc:inf + +&as_hex ++inf:inf +-inf:-inf +hexNaN:NaN +0:0x0 +5:0x5 +-5:-0x5 + +&as_bin ++inf:inf +-inf:-inf +hexNaN:NaN +0:0b0 +5:0b101 +-5:-0b101 + +&numify +# uses bsstr() so 5 => 5e+0 to be compatible w/ Perls output +0:0 ++1:1 +1234:1234 +-5:-5 +100:100 +-100:-100 + +&bnan +abc:NaN +2:NaN +-2:NaN +0:NaN + +&bone +2:+:1 +-2:-:-1 +-2:+:1 +2:-:-1 +0::1 +-2::1 +abc::1 +2:abc:1 + +&bsstr ++inf:inf +-inf:-inf +abcfsstr:NaN +-abcfsstr:NaN +1234.567:1234567e-3 +123:123e+0 +-5:-5e+0 +-100:-1e+2 + +&bstr ++inf:::inf +-inf:::-inf +abcfstr:::NaN +1234.567:9::1234.56700 +1234.567::-6:1234.567000 +12345:5::12345 +0.001234:6::0.00123400 +0.001234::-8:0.00123400 +0:4::0 +0::-4:0.0000 + +&bnorm +inf:inf ++inf:inf +-inf:-inf ++infinity:inf ++-inf:NaN +abc:NaN + 1 a:NaN +1bcd2:NaN +11111b:NaN ++1z:NaN +-1z:NaN +0e999:0 +0e-999:0 +-0e999:0 +-0e-999:0 +0:0 ++0:0 ++00:0 ++0_0_0:0 +000000_0000000_00000:0 +-0:0 +-0000:0 ++1:1 ++01:1 ++001:1 ++00000100000:100000 +123456789:123456789 +-1:-1 +-01:-1 +-001:-1 +-123456789:-123456789 +-00000100000:-100000 +123.456a:NaN +123.456:123.456 +0.01:0.01 +.002:0.002 ++.2:0.2 +-0.0003:-0.0003 +-.0000000004:-0.0000000004 +123456E2:12345600 +123456E-2:1234.56 +-123456E2:-12345600 +-123456E-2:-1234.56 +1e1:10 +2e-11:0.00000000002 +# exercise _split + .02e-1:0.002 + 000001:1 + -00001:-1 + -1:-1 + 000.01:0.01 + -000.0023:-0.0023 + 1.1e1:11 +-3e111:-3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +-4e-1111:-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004 + +&bpow +NaN:1:NaN +1:NaN:NaN +NaN:-1:NaN +-1:NaN:NaN +NaN:-21:NaN +-21:NaN:NaN +NaN:21:NaN +21:NaN:NaN +0:0:1 +0:1:0 +0:9:0 +0:-2:inf +2:2:4 +1:2:1 +1:3:1 +-1:2:1 +-1:3:-1 +123.456:2:15241.383936 +2:-2:0.25 +2:-3:0.125 +128:-2:0.00006103515625 +abc:123.456:NaN +123.456:abc:NaN ++inf:123.45:inf +-inf:123.45:-inf ++inf:-123.45:inf +-inf:-123.45:-inf +-2:2:4 +-2:3:-8 +-2:4:16 +-2:5:-32 +-3:2:9 +-3:3:-27 +-3:4:81 +-3:5:-243 +# 2 ** 0.5 == sqrt(2) +# 1.41..7 and not 1.4170 since fallback (bsqrt(9) is '3', not 3.0...0) +2:0.5:1.41421356237309504880168872420969807857 +#2:0.2:1.148698354997035006798626946777927589444 +#6:1.5:14.6969384566990685891837044482353483518 +$div_scale = 20 +#62.5:12.5:26447206647554886213592.3959144 +$div_scale = 40 + +&bneg +bnegNaN:NaN ++inf:-inf +-inf:inf ++0:0 ++1:-1 +-1:1 ++123456789:-123456789 +-123456789:123456789 ++123.456789:-123.456789 +-123456.789:123456.789 + +&babs +babsNaN:NaN ++inf:inf +-inf:inf ++0:0 ++1:1 +-1:1 ++123456789:123456789 +-123456789:123456789 ++123.456789:123.456789 +-123456.789:123456.789 + +&bround +$round_mode = "trunc" ++inf:5:inf +-inf:5:-inf +0:5:0 +NaNfround:5:NaN ++10123456789:5:10123000000 +-10123456789:5:-10123000000 ++10123456789.123:5:10123000000 +-10123456789.123:5:-10123000000 ++10123456789:9:10123456700 +-10123456789:9:-10123456700 ++101234500:6:101234000 +-101234500:6:-101234000 +$round_mode = "zero" ++20123456789:5:20123000000 +-20123456789:5:-20123000000 ++20123456789.123:5:20123000000 +-20123456789.123:5:-20123000000 ++20123456789:9:20123456800 +-20123456789:9:-20123456800 ++201234500:6:201234000 +-201234500:6:-201234000 +$round_mode = "+inf" ++30123456789:5:30123000000 +-30123456789:5:-30123000000 ++30123456789.123:5:30123000000 +-30123456789.123:5:-30123000000 ++30123456789:9:30123456800 +-30123456789:9:-30123456800 ++301234500:6:301235000 +-301234500:6:-301234000 +$round_mode = "-inf" ++40123456789:5:40123000000 +-40123456789:5:-40123000000 ++40123456789.123:5:40123000000 +-40123456789.123:5:-40123000000 ++40123456789:9:40123456800 +-40123456789:9:-40123456800 ++401234500:6:401234000 +-401234500:6:-401235000 +$round_mode = "odd" ++50123456789:5:50123000000 +-50123456789:5:-50123000000 ++50123456789.123:5:50123000000 +-50123456789.123:5:-50123000000 ++50123456789:9:50123456800 +-50123456789:9:-50123456800 ++501234500:6:501235000 +-501234500:6:-501235000 +$round_mode = "even" ++60123456789:5:60123000000 +-60123456789:5:-60123000000 ++60123456789:9:60123456800 +-60123456789:9:-60123456800 ++601234500:6:601234000 +-601234500:6:-601234000 ++60123456789.0123:5:60123000000 +-60123456789.0123:5:-60123000000 +$round_mode = "common" ++60123456789:5:60123000000 +-60123456789:5:-60123000000 ++60123456789:6:60123500000 +-60123456789:6:-60123500000 ++60123456789:9:60123456800 +-60123456789:9:-60123456800 ++601234500:6:601235000 +-601234500:6:-601235000 ++601234400:6:601234000 +-601234400:6:-601234000 ++601234600:6:601235000 +-601234600:6:-601235000 ++601234300:6:601234000 ++60123456789.0123:5:60123000000 +-60123456789.0123:5:-60123000000 + +&bfround +$round_mode = "trunc" ++inf:5:inf +-inf:5:-inf +0:5:0 +NaNffround:5:NaN ++1.23:-1:1.2 ++1.234:-1:1.2 ++1.2345:-1:1.2 ++1.23:-2:1.23 ++1.234:-2:1.23 ++1.2345:-2:1.23 ++1.23:-3:1.230 ++1.234:-3:1.234 ++1.2345:-3:1.234 +-1.23:-1:-1.2 ++1.27:-1:1.2 +-1.27:-1:-1.2 ++1.25:-1:1.2 +-1.25:-1:-1.2 ++1.35:-1:1.3 +-1.35:-1:-1.3 +-0.0061234567890:-1:0.0 +-0.0061:-1:0.0 +-0.00612:-1:0.0 +-0.00612:-2:0.00 +-0.006:-1:0.0 +-0.006:-2:0.00 +-0.0006:-2:0.00 +-0.0006:-3:0.000 +-0.0065:-3:/-0\.006|-6e-03 +-0.0065:-4:/-0\.006(?:5|49{5}\d+)|-6\.5e-03 +-0.0065:-5:/-0\.006(?:5|49{5}\d+)|-6\.5e-03 +0.05:0:0 +0.5:0:0 +0.51:0:0 +0.41:0:0 +$round_mode = "zero" ++2.23:-1:/2.2(?:0{5}\d+)? +-2.23:-1:/-2.2(?:0{5}\d+)? ++2.27:-1:/2.(?:3|29{5}\d+) +-2.27:-1:/-2.(?:3|29{5}\d+) ++2.25:-1:/2.2(?:0{5}\d+)? +-2.25:-1:/-2.2(?:0{5}\d+)? ++2.35:-1:/2.(?:3|29{5}\d+) +-2.35:-1:/-2.(?:3|29{5}\d+) +-0.0065:-1:0.0 +-0.0065:-2:/-0\.01|-1e-02 +-0.0065:-3:/-0\.006|-6e-03 +-0.0065:-4:/-0\.006(?:5|49{5}\d+)|-6\.5e-03 +-0.0065:-5:/-0\.006(?:5|49{5}\d+)|-6\.5e-03 +0.05:0:0 +0.5:0:0 +0.51:0:1 +0.41:0:0 +$round_mode = "+inf" ++3.23:-1:/3.2(?:0{5}\d+)? +-3.23:-1:/-3.2(?:0{5}\d+)? ++3.27:-1:/3.(?:3|29{5}\d+) +-3.27:-1:/-3.(?:3|29{5}\d+) ++3.25:-1:/3.(?:3|29{5}\d+) +-3.25:-1:/-3.2(?:0{5}\d+)? ++3.35:-1:/3.(?:4|39{5}\d+) +-3.35:-1:/-3.(?:3|29{5}\d+) +-0.0065:-1:0.0 +-0.0065:-2:/-0\.01|-1e-02 +-0.0065:-3:/-0\.006|-6e-03 +-0.0065:-4:/-0\.006(?:5|49{5}\d+)|-6\.5e-03 +-0.0065:-5:/-0\.006(?:5|49{5}\d+)|-6\.5e-03 +0.05:0:0 +0.5:0:1 +0.51:0:1 +0.41:0:0 +$round_mode = "-inf" ++4.23:-1:/4.2(?:0{5}\d+)? +-4.23:-1:/-4.2(?:0{5}\d+)? ++4.27:-1:/4.(?:3|29{5}\d+) +-4.27:-1:/-4.(?:3|29{5}\d+) ++4.25:-1:/4.2(?:0{5}\d+)? +-4.25:-1:/-4.(?:3|29{5}\d+) ++4.35:-1:/4.(?:3|29{5}\d+) +-4.35:-1:/-4.(?:4|39{5}\d+) +-0.0065:-1:0.0 +-0.0065:-2:/-0\.01|-1e-02 +-0.0065:-3:/-0\.007|-7e-03 +-0.0065:-4:/-0\.006(?:5|49{5}\d+)|-6\.5e-03 +-0.0065:-5:/-0\.006(?:5|49{5}\d+)|-6\.5e-03 +0.05:0:0 +0.5:0:0 +0.51:0:1 +0.41:0:0 +$round_mode = "odd" ++5.23:-1:/5.2(?:0{5}\d+)? +-5.23:-1:/-5.2(?:0{5}\d+)? ++5.27:-1:/5.(?:3|29{5}\d+) +-5.27:-1:/-5.(?:3|29{5}\d+) ++5.25:-1:/5.(?:3|29{5}\d+) +-5.25:-1:/-5.(?:3|29{5}\d+) ++5.35:-1:/5.(?:3|29{5}\d+) +-5.35:-1:/-5.(?:3|29{5}\d+) +-0.0065:-1:0.0 +-0.0065:-2:/-0\.01|-1e-02 +-0.0065:-3:/-0\.007|-7e-03 +-0.0065:-4:/-0\.006(?:5|49{5}\d+)|-6\.5e-03 +-0.0065:-5:/-0\.006(?:5|49{5}\d+)|-6\.5e-03 +0.05:0:0 +0.5:0:1 +0.51:0:1 +0.41:0:0 +$round_mode = "even" ++6.23:-1:/6.2(?:0{5}\d+)? +-6.23:-1:/-6.2(?:0{5}\d+)? ++6.27:-1:/6.(?:3|29{5}\d+) +-6.27:-1:/-6.(?:3|29{5}\d+) ++6.25:-1:/6.(?:2(?:0{5}\d+)?|29{5}\d+) +-6.25:-1:/-6.(?:2(?:0{5}\d+)?|29{5}\d+) ++6.35:-1:/6.(?:4|39{5}\d+|29{8}\d+) +-6.35:-1:/-6.(?:4|39{5}\d+|29{8}\d+) +-0.0065:-1:0.0 +-0.0065:-2:/-0\.01|-1e-02 +-0.0065:-3:/-0\.006|-7e-03 +-0.0065:-4:/-0\.006(?:5|49{5}\d+)|-6\.5e-03 +-0.0065:-5:/-0\.006(?:5|49{5}\d+)|-6\.5e-03 +0.05:0:0 +0.5:0:0 +0.51:0:1 +0.41:0:0 +0.01234567:-3:0.012 +0.01234567:-4:0.0123 +0.01234567:-5:0.01235 +0.01234567:-6:0.012346 +0.01234567:-7:0.0123457 +0.01234567:-8:0.01234567 +0.01234567:-9:0.012345670 +0.01234567:-12:0.012345670000 + +&bcmp +bcmpNaN:bcmpNaN: +bcmpNaN:+0: ++0:bcmpNaN: ++0:+0:0 +-1:+0:-1 ++0:-1:1 ++1:+0:1 ++0:+1:-1 +-1:+1:-1 ++1:-1:1 +-1:-1:0 ++1:+1:0 +-1.1:0:-1 ++0:-1.1:1 ++1.1:+0:1 ++0:+1.1:-1 ++123:+123:0 ++123:+12:1 ++12:+123:-1 +-123:-123:0 +-123:-12:-1 +-12:-123:1 ++123:+124:-1 ++124:+123:1 +-123:-124:1 +-124:-123:-1 +0:0.01:-1 +0:0.0001:-1 +0:-0.0001:1 +0:-0.1:1 +0.1:0:1 +0.00001:0:1 +-0.0001:0:-1 +-0.1:0:-1 +0:0.0001234:-1 +0:-0.0001234:1 +0.0001234:0:1 +-0.0001234:0:-1 +0.0001:0.0005:-1 +0.0005:0.0001:1 +0.005:0.0001:1 +0.001:0.0005:1 +0.000001:0.0005:-1 +0.00000123:0.0005:-1 +0.00512:0.0001:1 +0.005:0.000112:1 +0.00123:0.0005:1 +1.5:2:-1 +2:1.5:1 +1.54321:234:-1 +234:1.54321:1 +1e1234567890987654321:1e1234567890987654320:1 +1e-1234567890987654321:1e-1234567890987654320:-1 +# infinity +-inf:5432112345:-1 ++inf:5432112345:1 +-inf:-5432112345:-1 ++inf:-5432112345:1 +-inf:54321.12345:-1 ++inf:54321.12345:1 +-inf:-54321.12345:-1 ++inf:-54321.12345:1 ++inf:+inf:0 +-inf:-inf:0 ++inf:-inf:1 +-inf:+inf:-1 +# return undef ++inf:NaN: +NaN:inf: +-inf:NaN: +NaN:-inf: + +&bacmp +bcmpNaN:bcmpNaN: +bcmpNaN:+0: ++0:bcmpNaN: ++0:+0:0 +-1:+0:1 ++0:-1:-1 ++1:+0:1 ++0:+1:-1 +-1:+1:0 ++1:-1:0 +-1:-1:0 ++1:+1:0 +-1.1:0:1 ++0:-1.1:-1 ++1.1:+0:1 ++0:+1.1:-1 ++123:+123:0 ++123:+12:1 ++12:+123:-1 +-123:-123:0 +-123:-12:1 +-12:-123:-1 ++123:+124:-1 ++124:+123:1 +-123:-124:-1 +-124:-123:1 +0:0.01:-1 +0:0.0001:-1 +0:-0.0001:-1 +0:-0.1:-1 +0.1:0:1 +0.00001:0:1 +-0.0001:0:1 +-0.1:0:1 +0:0.0001234:-1 +0:-0.0001234:-1 +0.0001234:0:1 +-0.0001234:0:1 +0.0001:0.0005:-1 +0.0005:0.0001:1 +0.005:0.0001:1 +0.001:0.0005:1 +0.000001:0.0005:-1 +0.00000123:0.0005:-1 +0.00512:0.0001:1 +0.005:0.000112:1 +0.00123:0.0005:1 +1.5:2:-1 +2:1.5:1 +1.54321:234:-1 +234:1.54321:1 +# infinity +-inf:5432112345:1 ++inf:5432112345:1 +-inf:-5432112345:1 ++inf:-5432112345:1 +-inf:54321.12345:1 ++inf:54321.12345:1 +-inf:-54321.12345:1 ++inf:-54321.12345:1 ++inf:+inf:0 +-inf:-inf:0 ++inf:-inf:0 +-inf:+inf:0 +5:inf:-1 +-1:inf:-1 +5:-inf:-1 +-1:-inf:-1 +# return undef ++inf:bacmpNaN: +bacmpNaN:inf: +-inf:bacmpNaN: +bacmpNaN:-inf: + +&bdec +bdecNaN:NaN ++inf:inf +-inf:-inf ++0:-1 ++1:0 +-1:-2 +1.23:0.23 +-1.23:-2.23 +100:99 +101:100 +-100:-101 +-99:-100 +-98:-99 +99:98 + +&binc +bincNaN:NaN ++inf:inf +-inf:-inf ++0:1 ++1:2 +-1:0 +1.23:2.23 +-1.23:-0.23 +100:101 +-100:-99 +-99:-98 +-101:-100 +99:100 + +&badd +abc:abc:NaN +abc:+0:NaN ++0:abc:NaN ++inf:-inf:NaN +-inf:+inf:NaN ++inf:+inf:inf +-inf:-inf:-inf +baddNaN:+inf:NaN +baddNaN:+inf:NaN ++inf:baddNaN:NaN +-inf:baddNaN:NaN ++0:+0:0 ++1:+0:1 ++0:+1:1 ++1:+1:2 +-1:+0:-1 ++0:-1:-1 +-1:-1:-2 +-1:+1:0 ++1:-1:0 ++9:+1:10 ++99:+1:100 ++999:+1:1000 ++9999:+1:10000 ++99999:+1:100000 ++999999:+1:1000000 ++9999999:+1:10000000 ++99999999:+1:100000000 ++999999999:+1:1000000000 ++9999999999:+1:10000000000 ++99999999999:+1:100000000000 ++10:-1:9 ++100:-1:99 ++1000:-1:999 ++10000:-1:9999 ++100000:-1:99999 ++1000000:-1:999999 ++10000000:-1:9999999 ++100000000:-1:99999999 ++1000000000:-1:999999999 ++10000000000:-1:9999999999 ++123456789:+987654321:1111111110 +-123456789:+987654321:864197532 +-123456789:-987654321:-1111111110 ++123456789:-987654321:-864197532 +0.001234:0.0001234:0.0013574 + +&bsub +abc:abc:NaN +abc:+0:NaN ++0:abc:NaN ++inf:-inf:inf +-inf:+inf:-inf ++inf:+inf:NaN +-inf:-inf:NaN +baddNaN:+inf:NaN +baddNaN:+inf:NaN ++inf:baddNaN:NaN +-inf:baddNaN:NaN ++0:+0:0 ++1:+0:1 ++0:+1:-1 ++1:+1:0 +-1:+0:-1 ++0:-1:1 +-1:-1:0 +-1:+1:-2 ++1:-1:2 ++9:+1:8 ++99:+1:98 ++999:+1:998 ++9999:+1:9998 ++99999:+1:99998 ++999999:+1:999998 ++9999999:+1:9999998 ++99999999:+1:99999998 ++999999999:+1:999999998 ++9999999999:+1:9999999998 ++99999999999:+1:99999999998 ++10:-1:11 ++100:-1:101 ++1000:-1:1001 ++10000:-1:10001 ++100000:-1:100001 ++1000000:-1:1000001 ++10000000:-1:10000001 ++100000000:-1:100000001 ++1000000000:-1:1000000001 ++10000000000:-1:10000000001 ++123456789:+987654321:-864197532 +-123456789:+987654321:-1111111110 +-123456789:-987654321:864197532 ++123456789:-987654321:1111111110 + +&bmuladd +abc:abc:0:NaN +abc:+0:0:NaN ++0:abc:0:NaN ++0:0:abc:NaN +NaNmul:+inf:0:NaN +NaNmul:-inf:0:NaN +-inf:NaNmul:0:NaN ++inf:NaNmul:0:NaN ++inf:+inf:0:inf ++inf:-inf:0:-inf +-inf:+inf:0:-inf +-inf:-inf:0:inf ++0:+0:0:0 ++0:+1:0:0 ++1:+0:0:0 ++0:-1:0:0 +-1:+0:0:0 +123456789123456789:0:0:0 +0:123456789123456789:0:0 +-1:-1:0:1 +-1:-1:0:1 +-1:+1:0:-1 ++1:-1:0:-1 ++1:+1:0:1 ++2:+3:0:6 +-2:+3:0:-6 ++2:-3:0:-6 +-2:-3:0:6 +111:111:0:12321 +10101:10101:0:102030201 +1001001:1001001:0:1002003002001 +100010001:100010001:0:10002000300020001 +10000100001:10000100001:0:100002000030000200001 +11111111111:9:0:99999999999 +22222222222:9:0:199999999998 +33333333333:9:0:299999999997 +44444444444:9:0:399999999996 +55555555555:9:0:499999999995 +66666666666:9:0:599999999994 +77777777777:9:0:699999999993 +88888888888:9:0:799999999992 +99999999999:9:0:899999999991 +11111111111:9:1:100000000000 +22222222222:9:1:199999999999 +33333333333:9:1:299999999998 +44444444444:9:1:399999999997 +55555555555:9:1:499999999996 +66666666666:9:1:599999999995 +77777777777:9:1:699999999994 +88888888888:9:1:799999999993 +99999999999:9:1:899999999992 +-3:-4:-5:7 +3:-4:-5:-17 +-3:4:-5:-17 +3:4:-5:7 +-3:4:5:-7 +3:-4:5:-7 +9999999999999999999:10000000000000000000:1234567890:99999999999999999990000000001234567890 +3.2:5.7:8.9:27.14 +-3.2:5.197:6.05:-10.5804 + +&bmodpow +3:4:8:1 +3:4:7:4 +3:4:7:4 +77777:777:123456789:99995084 +3.2:6.2:5.2:2.970579856718063040273642739529400818 + +&bmul +abc:abc:NaN +abc:+0:NaN ++0:abc:NaN ++inf:NaNmul:NaN ++inf:NaNmul:NaN +NaNmul:+inf:NaN +NaNmul:-inf:NaN ++inf:+inf:inf ++inf:-inf:-inf ++inf:-inf:-inf ++inf:+inf:inf ++inf:123.34:inf ++inf:-123.34:-inf +-inf:123.34:-inf +-inf:-123.34:inf +123.34:+inf:inf +-123.34:+inf:-inf +123.34:-inf:-inf +-123.34:-inf:inf ++0:+0:0 ++0:+1:0 ++1:+0:0 ++0:-1:0 +-1:+0:0 ++123456789123456789:+0:0 ++0:+123456789123456789:0 +-1:-1:1 +-1:+1:-1 ++1:-1:-1 ++1:+1:1 ++2:+3:6 +-2:+3:-6 ++2:-3:-6 +-2:-3:6 ++111:+111:12321 ++10101:+10101:102030201 ++1001001:+1001001:1002003002001 ++100010001:+100010001:10002000300020001 ++10000100001:+10000100001:100002000030000200001 ++11111111111:+9:99999999999 ++22222222222:+9:199999999998 ++33333333333:+9:299999999997 ++44444444444:+9:399999999996 ++55555555555:+9:499999999995 ++66666666666:+9:599999999994 ++77777777777:+9:699999999993 ++88888888888:+9:799999999992 ++99999999999:+9:899999999991 +6:120:720 +10:10000:100000 + +&bdiv-list +0:0:NaN,0 +0:1:0,0 +9:4:2,1 +9:5:1,4 +# bug in v1.74 with bdiv in list context, when $y is 1 or -1 +2.1:-1:-2.1,0 +2.1:1:2.1,0 +-2.1:-1:2.1,0 +-2.1:1:-2.1,0 + +&bdiv +$div_scale = 40; $round_mode = "even" +abc:abc:NaN +abc:+1:abc:NaN ++1:abc:NaN +-1:abc:NaN +0:abc:NaN ++0:+0:NaN ++0:+1:0 ++1:+0:inf ++3214:+0:inf ++0:-1:0 +-1:+0:-inf +-3214:+0:-inf ++1:+1:1 +-1:-1:1 ++1:-1:-1 +-1:+1:-1 ++1:+2:0.5 ++2:+1:2 +123:+inf:0 +123:-inf:0 ++10:+5:2 ++100:+4:25 ++1000:+8:125 ++10000:+16:625 ++10000:-16:-625 ++999999999999:+9:111111111111 ++999999999999:+99:10101010101 ++999999999999:+999:1001001001 ++999999999999:+9999:100010001 ++999999999999999:+99999:10000100001 ++1000000000:+9:111111111.1111111111111111111111111111111 ++2000000000:+9:222222222.2222222222222222222222222222222 ++3000000000:+9:333333333.3333333333333333333333333333333 ++4000000000:+9:444444444.4444444444444444444444444444444 ++5000000000:+9:555555555.5555555555555555555555555555556 ++6000000000:+9:666666666.6666666666666666666666666666667 ++7000000000:+9:777777777.7777777777777777777777777777778 ++8000000000:+9:888888888.8888888888888888888888888888889 ++9000000000:+9:1000000000 ++35500000:+113:314159.2920353982300884955752212389380531 ++71000000:+226:314159.2920353982300884955752212389380531 ++106500000:+339:314159.2920353982300884955752212389380531 ++1000000000:+3:333333333.3333333333333333333333333333333 +2:25.024996000799840031993601279744051189762:0.07992009269196593320152084692285869265447 +123456:1:123456 +$div_scale = 20 ++1000000000:+9:111111111.11111111111 ++2000000000:+9:222222222.22222222222 ++3000000000:+9:333333333.33333333333 ++4000000000:+9:444444444.44444444444 ++5000000000:+9:555555555.55555555556 ++6000000000:+9:666666666.66666666667 ++7000000000:+9:777777777.77777777778 ++8000000000:+9:888888888.88888888889 ++9000000000:+9:1000000000 +1:10:0.1 +1:100:0.01 +1:1000:0.001 +1:10000:0.0001 +1:504:0.001984126984126984127 +2:1.987654321:1.0062111801179738436 +123456789.123456789123456789123456789:1:123456789.12345678912 +# the next two cases are the "old" behaviour, but are now (>v0.01) different +#+35500000:+113:314159.292035398230088 +#+71000000:+226:314159.292035398230088 ++35500000:+113:314159.29203539823009 ++71000000:+226:314159.29203539823009 ++106500000:+339:314159.29203539823009 ++1000000000:+3:333333333.33333333333 +$div_scale = 1 +# round to accuracy 1 after bdiv ++124:+3:40 +123456789.1234:1:100000000 +# reset scale for further tests +$div_scale = 40 + +&bmod ++9:4:1 ++9:5:4 ++9000:56:40 ++56:9000:56 +# inf handling, see table in doc +0:inf:0 +0:-inf:0 +5:inf:5 +5:-inf:-inf +-5:inf:inf +-5:-inf:-5 +inf:5:NaN +-inf:5:NaN +inf:-5:NaN +-inf:-5:NaN +5:5:0 +-5:-5:0 +inf:inf:NaN +-inf:-inf:NaN +-inf:inf:NaN +inf:-inf:NaN +8:0:8 +inf:0:inf +-inf:0:-inf +-8:0:-8 +0:0:0 +abc:abc:NaN +abc:1:abc:NaN +1:abc:NaN +0:1:0 +1:0:1 +0:-1:0 +-1:0:-1 +1:1:0 +-1:-1:0 +1:-1:0 +-1:1:0 +1:2:1 +2:1:0 +1000000000:9:1 +2000000000:9:2 +3000000000:9:3 +4000000000:9:4 +5000000000:9:5 +6000000000:9:6 +7000000000:9:7 +8000000000:9:8 +9000000000:9:0 +35500000:113:33 +71000000:226:66 +106500000:339:99 +1000000000:3:1 +10:5:0 +100:4:0 +1000:8:0 +10000:16:0 +999999999999:9:0 +999999999999:99:0 +999999999999:999:0 +999999999999:9999:0 +999999999999999:99999:0 +-9:+5:1 ++9:-5:-1 +-9:-5:-4 +-5:3:1 +-2:3:1 +4:3:1 +1:3:1 +-5:-3:-2 +-2:-3:-2 +4:-3:-2 +1:-3:-2 +4095:4095:0 +100041000510123:3:0 +152403346:12345:4321 +87654321:87654321:0 +# now some floating point tests +123:2.5:0.5 +1230:2.5:0 +123.4:2.5:0.9 +123e1:25:5 +-2.1:1:0.9 +2.1:1:0.1 +-2.1:-1:-0.1 +2.1:-1:-0.9 +-3:1:0 +3:1:0 +-3:-1:0 +3:-1:0 + +&bfac +Nanfac:NaN +-1:NaN ++inf:inf +-inf:NaN +0:1 +1:1 +2:2 +3:6 +4:24 +5:120 +6:720 +10:3628800 +11:39916800 +12:479001600 + +&broot +# sqrt() ++0:2:0 ++1:2:1 +-1:2:NaN +# -$x ** (1/2) => -$y, but not in broot() +-123.456:2:NaN ++inf:2:inf +-inf:2:NaN +2:2:1.41421356237309504880168872420969807857 +-2:2:NaN +4:2:2 +9:2:3 +16:2:4 +100:2:10 +123.456:2:11.11107555549866648462149404118219234119 +15241.38393:2:123.4559999756998444766131352122991626468 +1.44:2:1.2 +12:2:3.464101615137754587054892683011744733886 +0.49:2:0.7 +0.0049:2:0.07 +# invalid ones +1:NaN:NaN +-1:NaN:NaN +0:NaN:NaN +-inf:NaN:NaN ++inf:NaN:NaN +NaN:0:NaN +NaN:2:NaN +NaN:inf:NaN +NaN:inf:NaN +12:-inf:NaN +12:inf:NaN ++0:0:NaN ++1:0:NaN +-1:0:NaN +-2:0:NaN +-123.45:0:NaN ++inf:0:NaN +12:1:12 +-12:1:NaN +8:-1:NaN +-8:-1:NaN +# cubic root +8:3:2 +-8:3:NaN +# fourths root +16:4:2 +81:4:3 +# see t/bigroot() for more tests + +&bsqrt ++0:0 +-1:NaN +-2:NaN +-16:NaN +-123.45:NaN +nanbsqrt:NaN ++inf:inf +-inf:NaN +1:1 +2:1.41421356237309504880168872420969807857 +4:2 +9:3 +16:4 +100:10 +123.456:11.11107555549866648462149404118219234119 +15241.38393:123.4559999756998444766131352122991626468 +1.44:1.2 +# sqrt(1.44) = 1.2, sqrt(e10) = e5 => 12e4 +1.44E10:120000 +2e10:141421.356237309504880168872420969807857 +144e20:120000000000 +# proved to be an endless loop under 7-9 +12:3.464101615137754587054892683011744733886 +0.49:0.7 +0.0049:0.07 + +&is_nan +123:0 +abc:1 +NaN:1 +-123:0 + +&is_inf ++inf::1 +-inf::1 +abc::0 +1::0 +NaN::0 +-1::0 ++inf:-:0 ++inf:+:1 +-inf:-:1 +-inf:+:0 +-inf:-inf:1 +-inf:+inf:0 ++inf:-inf:0 ++inf:+inf:1 ++iNfInItY::1 +-InFiNiTy::1 + +&is_odd +abc:0 +0:0 +-1:1 +-3:1 +1:1 +3:1 +1000001:1 +1000002:0 ++inf:0 +-inf:0 +123.45:0 +-123.45:0 +2:0 + +&is_int +NaNis_int:0 +0:1 +1:1 +2:1 +-2:1 +-1:1 +-inf:0 ++inf:0 +123.4567:0 +-0.1:0 +-0.002:0 + +&is_even +abc:0 +0:1 +-1:0 +-3:0 +1:0 +3:0 +1000001:0 +1000002:1 +2:1 ++inf:0 +-inf:0 +123.456:0 +-123.456:0 +0.01:0 +-0.01:0 +120:1 +1200:1 +-1200:1 + +&is_positive +0:0 +1:1 +-1:0 +-123:0 +NaN:0 +-inf:0 ++inf:1 + +&is_negative +0:0 +1:0 +-1:1 +-123:1 +NaN:0 +-inf:1 ++inf:0 + +&parts +0:0 0 +1:1 0 +123:123 0 +-123:-123 0 +-1200:-12 2 +NaNparts:NaN NaN ++inf:inf inf +-inf:-inf inf + +&exponent +0:0 +1:0 +123:0 +-123:0 +-1200:2 ++inf:inf +-inf:inf +NaNexponent:NaN + +&mantissa +0:0 +1:1 +123:123 +-123:-123 +-1200:-12 ++inf:inf +-inf:-inf +NaNmantissa:NaN + +&length +123:3 +-123:3 +0:1 +1:1 +12345678901234567890:20 + +&is_zero +NaNzero:0 ++inf:0 +-inf:0 +0:1 +-1:0 +1:0 + +&is_one +NaNone:0 ++inf:0 +-inf:0 +0:0 +2:0 +1:1 +-1:0 +-2:0 + +&bfloor +0:0 +abc:NaN ++inf:inf +-inf:-inf +1:1 +-51:-51 +-51.2:-52 +12.2:12 +0.12345:0 +0.123456:0 +0.1234567:0 +0.12345678:0 +0.123456789:0 + +&bceil +0:0 +abc:NaN ++inf:inf +-inf:-inf +1:1 +-51:-51 +-51.2:-51 +12.2:13 +-0.4:0 + +&bint +0:0 +NaN:NaN ++inf:inf +-inf:-inf +1:1 +-51:-51 +-51.2:-51 +12.2:12 +-0.4:0 +# overloaded functions + +&log +-1:NaN +0:-inf +1:0 +2:0.6931471805599453094172321214581765680755 +3:1.098612288668109691395245236922525704647 +123456789:18.63140176616801803319393334796320420971 +1234567890987654321:41.657252696908474880343847955484513481 +-inf:inf +inf:inf +NaN:NaN + +&exp + +&sin + +&cos + +&atan2 + +&int + +&neg + +&abs + +&sqrt diff --git a/t/mbi_ltm/bigintpm.inc b/t/mbi_ltm/bigintpm.inc new file mode 100644 index 0000000..0798e54 --- /dev/null +++ b/t/mbi_ltm/bigintpm.inc @@ -0,0 +1,3085 @@ +#include this file into another for subclass testing + +use strict; +use warnings; + +our ($CLASS, $CALC); + +############################################################################## +# for testing inheritance of _swap + +package Math::Foo; + +use Math::BigInt lib => $main::CALC; +our @ISA = (qw/Math::BigInt/); + +use overload + # customized overload for sub, since original does not use swap there + '-' => sub { my @a = ref($_[0])->_swap(@_); + $a[0]->bsub($a[1]); + }; + +sub _swap { + # a fake _swap, which reverses the params + my $self = shift; # for override in subclass + if ($_[2]) { + my $c = ref($_[0]) || 'Math::Foo'; + return( $_[0]->copy(), $_[1] ); + } else { + return( Math::Foo->new($_[1]), $_[0] ); + } +} + +############################################################################## +package main; + +is($CLASS->config()->{lib}, $CALC, "$CLASS->config()->{lib}"); + +my ($x, $y, $z, @args, $try, $got, $want); +my ($f, $round_mode, $expected_class); + +while () { + s/#.*$//; # remove comments + s/\s+$//; # remove trailing whitespace + next unless length; # skip empty lines + + my ($m, $e); + + if (s/^&//) { + $f = $_; + next; + } + + if (/^\$/) { + $round_mode = $_; + $round_mode =~ s/^\$/$CLASS\->/; + next; + } + + @args = split(/:/, $_, 99); + $want = pop(@args); + $expected_class = $CLASS; + + if ($want =~ /(.*?)=(.*)/) { + $expected_class = $2; + $want = $1; + } + + $try = qq|\$x = $CLASS->new("$args[0]");|; + if ($f eq "bnorm") { + $try = qq|\$x = $CLASS->bnorm("$args[0]");|; + } elsif ($f =~ /^is_(zero|one|odd|even|negative|positive|nan|int)$/) { + $try .= " \$x->$f() || 0;"; + } elsif ($f eq "is_inf") { + $try .= qq| \$x->is_inf("$args[1]");|; + } elsif ($f eq "binf") { + $try .= qq| \$x->binf("$args[1]");|; + } elsif ($f eq "bone") { + $try .= qq| \$x->bone("$args[1]");|; + # some unary ops + } elsif ($f =~ /^b(nan|floor|ceil|int|sstr|neg|abs|sgn|inc|dec|not|sqrt|fac)$/) { + $try .= " \$x->$f();"; + # overloaded functions + } elsif ($f =~ /^(log|exp|sin|cos|atan2|int|neg|abs|sqrt)$/) { + $try .= " \$x = $f(\$x);"; + } elsif ($f =~ /^(numify|length|stringify|as_hex|as_bin|as_oct)$/) { + $try .= " \$x->$f();"; + } elsif ($f eq "exponent") { + # ->bstr() to see if an object is returned + $try .= ' $x = $x->exponent()->bstr();'; + } elsif ($f eq "mantissa") { + # ->bstr() to see if an object is returned + $try .= ' $x = $x->mantissa()->bstr();'; + } elsif ($f eq "parts") { + $try .= ' ($m, $e) = $x->parts();'; + # ->bstr() to see if an object is returned + $try .= ' $m = $m->bstr(); $m = "NaN" if !defined $m;'; + $try .= ' $e = $e->bstr(); $e = "NaN" if !defined $e;'; + $try .= ' "$m,$e";'; + } elsif ($f eq "bexp") { + $try .= " \$x->bexp();"; + } elsif ($f eq "bpi") { + $try .= " $CLASS\->bpi(\$x);"; + } else { + # binary operators + $try .= qq| \$y = $CLASS->new("$args[1]");|; + if ($f eq "bcmp") { + $try .= ' $x->bcmp($y);'; + } elsif ($f eq "bround") { + $try .= " $round_mode; \$x->bround(\$y);"; + } elsif ($f eq "bacmp") { + $try .= ' $x->bacmp($y);'; + } elsif ($f eq "badd") { + $try .= ' $x + $y;'; + } elsif ($f eq "bsub") { + $try .= ' $x - $y;'; + } elsif ($f eq "bmul") { + $try .= ' $x * $y;'; + } elsif ($f eq "bdiv") { + $try .= ' $x / $y;'; + } elsif ($f eq "bdiv-list") { + $try .= ' join (",", $x->bdiv($y));'; + # overload via x= + } elsif ($f =~ /^.=$/) { + $try .= " \$x $f \$y;"; + # overload via x + } elsif ($f =~ /^.$/) { + $try .= " \$x $f \$y;"; + } elsif ($f eq "bmod") { + $try .= ' $x % $y;'; + } elsif ($f eq "bgcd") { + if (defined $args[2]) { + $try .= qq| \$z = $CLASS->new("$args[2]");|; + } + $try .= " $CLASS\::bgcd(\$x, \$y"; + $try .= ", \$z" if defined $args[2]; + $try .= ");"; + } elsif ($f eq "blcm") { + if (defined $args[2]) { + $try .= qq| \$z = $CLASS->new("$args[2]");|; + } + $try .= " $CLASS\::blcm(\$x, \$y"; + $try .= ", \$z" if defined $args[2]; + $try .= ");"; + } elsif ($f eq "blsft") { + if (defined $args[2]) { + $try .= " \$x->blsft(\$y, $args[2]);"; + } else { + $try .= " \$x << \$y;"; + } + } elsif ($f eq "brsft") { + if (defined $args[2]) { + $try .= " \$x->brsft(\$y, $args[2]);"; + } else { + $try .= " \$x >> \$y;"; + } + } elsif ($f eq "bnok") { + $try .= " \$x->bnok(\$y);"; + } elsif ($f eq "broot") { + $try .= " \$x->broot(\$y);"; + } elsif ($f eq "blog") { + $try .= " \$x->blog(\$y);"; + } elsif ($f eq "band") { + $try .= " \$x & \$y;"; + } elsif ($f eq "bior") { + $try .= " \$x | \$y;"; + } elsif ($f eq "bxor") { + $try .= " \$x ^ \$y;"; + } elsif ($f eq "bpow") { + $try .= " \$x ** \$y;"; + } elsif ( $f eq "bmodinv") { + $try .= " \$x->bmodinv(\$y);"; + } elsif ($f eq "digit") { + $try .= " \$x->digit(\$y);"; + } elsif ($f eq "batan2") { + $try .= " \$x->batan2(\$y);"; + } else { + # Functions with three arguments + $try .= qq| \$z = $CLASS->new("$args[2]");|; + + if ( $f eq "bmodpow") { + $try .= " \$x->bmodpow(\$y, \$z);"; + } elsif ($f eq "bmuladd") { + $try .= " \$x->bmuladd(\$y, \$z);"; + } else { + warn "Unknown op '$f'"; + } + } + } # end else all other ops + + $got = eval $try; + print "# Error: $@\n" if $@; + + # convert hex/binary targets to decimal + if ($want =~ /^(0x0x|0b0b)/) { + $want =~ s/^0[xb]//; + $want = Math::BigInt->new($want)->bstr(); + } + if ($want eq "") { + is($got, undef, $try); + } else { + # print "try: $try ans: $got $want\n"; + is($got, $want, $try); + is(ref($got), $expected_class, + qq|output is a "$expected_class" object|) + if $expected_class ne $CLASS; + } + # check internal state of number objects + is_valid($got, $f) if ref $got; +} # endwhile data tests +close DATA; + +# test whether self-multiplication works correctly (result is 2**64) +$try = qq|\$x = $CLASS->new("4294967296");|; +$try .= ' $a = $x->bmul($x);'; +$got = eval $try; +is($got, $CLASS->new(2) ** 64, $try); + +# test self-pow +$try = qq|\$x = $CLASS->new(10);|; +$try .= ' $a = $x->bpow($x);'; +$got = eval $try; +is($got, $CLASS->new(10) ** 10, $try); + +############################################################################### +# test whether op destroys args or not (should better not) + +$x = $CLASS->new(3); +$y = $CLASS->new(4); +$z = $x & $y; +is($x, 3, '$z = $x & $y; $x'); +is($y, 4, '$z = $x & $y; $y'); +is($z, 0, '$z = $x & $y; $z'); + +$z = $x | $y; +is($x, 3, '$z = $x | $y; $x'); +is($y, 4, '$z = $x | $y; $y'); +is($z, 7, '$z = $x | $y; $z'); + +$x = $CLASS->new(1); +$y = $CLASS->new(2); +$z = $x | $y; +is($x, 1, '$z = $x | $y; $x'); +is($y, 2, '$z = $x | $y; $y'); +is($z, 3, '$z = $x | $y; $z'); + +$x = $CLASS->new(5); +$y = $CLASS->new(4); +$z = $x ^ $y; +is($x, 5, '$z = $x ^ $y; $x'); +is($y, 4, '$z = $x ^ $y; $y'); +is($z, 1, '$z = $x ^ $y; $z'); + +$x = $CLASS->new(-5); +$y = -$x; +is($x, -5, '$y = -$x; $x'); + +$x = $CLASS->new(-5); +$y = abs($x); +is($x, -5, '$y = abs($x); $x'); + +$x = $CLASS->new(8); +$y = $CLASS->new(-1); +$z = $CLASS->new(5033); +my $u = $x->copy()->bmodpow($y, $z); +is($u, 4404, '$x->copy()->bmodpow($y, $z); $u'); +is($y, -1, '$x->copy()->bmodpow($y, $z); $y'); +is($z, 5033, '$x->copy()->bmodpow($y, $z); $z'); + +$x = $CLASS->new(-5); +$y = -$x; +is($x, -5, '$y = -$x; $x'); +is($y, 5, '$y = -$x; $y'); + +$x = $CLASS->new(-5); +$y = $x->copy()->bneg(); +is($x, -5, '$y = $x->copy()->bneg(); $x'); +is($y, 5, '$y = $x->copy()->bneg(); $y'); + +$x = $CLASS->new(-5); +$y = $CLASS->new(3); +$x->bmul($y); +is($x, -15, '$x->bmul($y); $x'); +is($y, 3, '$x->bmul($y); $y'); + +$x = $CLASS->new(-5); +$y = $CLASS->new(3); +$x->badd($y); +is($x, -2, '$x->badd($y); $x'); +is($y, 3, '$x->badd($y); $y'); + +$x = $CLASS->new(-5); +$y = $CLASS->new(3); +$x->bsub($y); +is($x, -8, '$x->bsub($y); $x'); +is($y, 3, '$x->bsub($y); $y'); + +$x = $CLASS->new(-15); +$y = $CLASS->new(3); +$x->bdiv($y); +is($x, -5, '$x->bdiv($y); $x'); +is($y, 3, '$x->bdiv($y); $y'); + +$x = $CLASS->new(-5); +$y = $CLASS->new(3); +$x->bmod($y); +is($x, 1, '$x->bmod($y); $x'); +is($y, 3, '$x->bmod($y); $y'); + +$x = $CLASS->new(5); +$y = $CLASS->new(3); +$x->bmul($y); +is($x, 15, '$x->bmul($y); $x'); +is($y, 3, '$x->bmul($y); $y'); + +$x = $CLASS->new(5); +$y = $CLASS->new(3); +$x->badd($y); +is($x, 8, '$x->badd($y); $x'); +is($y, 3, '$x->badd($y); $y'); + +$x = $CLASS->new(5); +$y = $CLASS->new(3); +$x->bsub($y); +is($x, 2, '$x->bsub($y); $x'); +is($y, 3, '$x->bsub($y); $y'); + +$x = $CLASS->new(15); +$y = $CLASS->new(3); +$x->bdiv($y); +is($x, 5, '$x->bdiv($y); $x'); +is($y, 3, '$x->bdiv($y); $y'); + +$x = $CLASS->new(5); +$y = $CLASS->new(3); +$x->bmod($y); +is($x, 2, '$x->bmod($y); $x'); +is($y, 3, '$x->bmod($y); $y'); + +$x = $CLASS->new(5); +$y = $CLASS->new(-3); +$x->bmul($y); +is($x, -15, '$x->bmul($y); $x'); +is($y, -3, '$x->bmul($y); $y'); + +$x = $CLASS->new(5); +$y = $CLASS->new(-3); +$x->badd($y); +is($x, 2, '$x->badd($y); $x'); +is($y, -3, '$x->badd($y); $y'); + +$x = $CLASS->new(5); +$y = $CLASS->new(-3); +$x->bsub($y); +is($x, 8, '$x->bsub($y); $x'); +is($y, -3, '$x->bsub($y); $y'); + +$x = $CLASS->new(15); +$y = $CLASS->new(-3); +$x->bdiv($y); +is($x, -5, '$x->bdiv($y); $x'); +is($y, -3, '$x->bdiv($y); $y'); + +$x = $CLASS->new(5); +$y = $CLASS->new(-3); +$x->bmod($y); +is($x, -1, '$x->bmod($y); $x'); +is($y, -3, '$x->bmod($y); $y'); + +############################################################################### +# check whether overloading cmp works +$try = '$x = $CLASS->new(0);'; +$try .= ' $y = 10;'; +$try .= ' $x ne $y;'; +$want = eval $try; +ok($want, "overloading cmp works"); + +# We can't test for working cmpt with other objects here, we would need a dummy +# object with stringify overload for this. See Math::String tests as example. + +############################################################################### +# check reversed order of arguments + +$try = "\$x = $CLASS->new(10); \$x = 2 ** \$x; \$x == 1024;"; +$want = eval $try; +ok($want, $try); + +$try = "\$x = $CLASS->new(10); \$x = 2 * \$x; \$x == 20;"; +$want = eval $try; +ok($want, $try); + +$try = "\$x = $CLASS->new(10); \$x = 2 + \$x; \$x == 12;"; +$want = eval $try; +ok($want, $try); + +$try = "\$x = $CLASS\->new(10); \$x = 2 - \$x; \$x == -8;"; +$want = eval $try; +ok($want, $try); + +$try = "\$x = $CLASS\->new(10); \$x = 20 / \$x; \$x == 2;"; +$want = eval $try; +ok($want, $try); + +$try = "\$x = $CLASS\->new(3); \$x = 20 % \$x; \$x == 2;"; +$want = eval $try; +ok($want, $try); + +$try = "\$x = $CLASS\->new(7); \$x = 20 & \$x; \$x == 4;"; +$want = eval $try; +ok($want, $try); + +$try = "\$x = $CLASS\->new(7); \$x = 0x20 | \$x; \$x == 0x27;"; +$want = eval $try; +ok($want, $try); + +$try = "\$x = $CLASS\->new(7); \$x = 0x20 ^ \$x; \$x == 0x27;"; +$want = eval $try; +ok($want, $try); + +############################################################################### +# check badd(4, 5) form + +$try = "\$x = $CLASS\->badd(4, 5); \$x == 9;"; +$want = eval $try; +ok($want, $try); + +############################################################################### +# check undefs: NOT DONE YET + +############################################################################### +# bool + +$x = $CLASS->new(1); +if ($x) { + pass("\$x = $CLASS->new(1); \$x is true"); +} else { + fail("\$x = $CLASS->new(1); \$x is true"); +} + +$x = $CLASS->new(0); +if (!$x) { + pass("\$x = $CLASS->new(0); !\$x is false"); +} else { + fail("\$x = $CLASS->new(0); !\$x is false"); +} + +############################################################################### +# objectify() + +@args = Math::BigInt::objectify(2, 4, 5); +is(scalar(@args), 3, "objectify(2, 4, 5) gives $CLASS, 4, 5"); +like($args[0], qr/^Math::BigInt/, "first arg matches /^Math::BigInt/"); +is($args[1], 4, "second arg is 4"); +is($args[2], 5, "third arg is 5"); + +@args = Math::BigInt::objectify(0, 4, 5); +is(scalar(@args), 3, "objectify(0, 4, 5) gives $CLASS, 4, 5"); +like($args[0], qr/^Math::BigInt/, "first arg matches /^Math::BigInt/"); +is($args[1], 4, "second arg is 4"); +is($args[2], 5, "third arg is 5"); + +@args = Math::BigInt::objectify(2, 4, 5); +is(scalar(@args), 3, "objectify(2, 4, 5) gives $CLASS, 4, 5"); +like($args[0], qr/^Math::BigInt/, "first arg matches /^Math::BigInt/"); +is($args[1], 4, "second arg is 4"); +is($args[2], 5, "third arg is 5"); + +@args = Math::BigInt::objectify(2, 4, 5, 6, 7); +is(scalar(@args), 5, + "objectify(2, 4, 5, 6, 7) gives $CLASS, 4, 5, 6, 7"); +like($args[0], qr/^Math::BigInt/, "first arg matches /^Math::BigInt/"); +is($args[1], 4, "second arg is 4"); +is(ref($args[1]), $args[0], "second arg is a $args[0] object"); +is($args[2], 5, "third arg is 5"); +is(ref($args[2]), $args[0], "third arg is a $args[0] object"); +is($args[3], 6, "fourth arg is 6"); +is(ref($args[3]), '', "fourth arg is a scalar"); +is($args[4], 7, "fifth arg is 7"); +is(ref($args[4]), '', "fifth arg is a scalar"); + +@args = Math::BigInt::objectify(2, $CLASS, 4, 5, 6, 7); +is(scalar(@args), 5, + "objectify(2, $CLASS, 4, 5, 6, 7) gives $CLASS, 4, 5, 6, 7"); +is($args[0], $CLASS, "first arg is $CLASS"); +is($args[1], 4, "second arg is 4"); +is(ref($args[1]), $args[0], "second arg is a $args[0] object"); +is($args[2], 5, "third arg is 5"); +is(ref($args[2]), $args[0], "third arg is a $args[0] object"); +is($args[3], 6, "fourth arg is 6"); +is(ref($args[3]), '', "fourth arg is a scalar"); +is($args[4], 7, "fifth arg is 7"); +is(ref($args[4]), '', "fifth arg is a scalar"); + +############################################################################### +# test whether an opp calls objectify properly or not (or at least does what +# it should do given non-objects, w/ or w/o objectify()) + +is($CLASS->new(123)->badd(123), 246, + qq|$CLASS->new(123)->badd(123) = 246|);; +is($CLASS->badd(123, 321), 444, + qq|$CLASS->badd(123, 321) = 444|);; +is($CLASS->badd(123, $CLASS->new(321)), 444, + qq|$CLASS->badd(123, $CLASS->new(321)) = 444|);; + +is($CLASS->new(123)->bsub(122), 1, + qq|$CLASS->new(123)->bsub(122) = 1|);; +is($CLASS->bsub(321, 123), 198, + qq|$CLASS->bsub(321, 123) = 198|);; +is($CLASS->bsub(321, $CLASS->new(123)), 198, + qq|$CLASS->bsub(321, $CLASS->new(123)) = 198|);; + +is($CLASS->new(123)->bmul(123), 15129, + qq|$CLASS->new(123)->bmul(123) = 15129|);; +is($CLASS->bmul(123, 123), 15129, + qq|$CLASS->bmul(123, 123) = 15129|);; +is($CLASS->bmul(123, $CLASS->new(123)), 15129, + qq|$CLASS->bmul(123, $CLASS->new(123)) = 15129|);; + +is($CLASS->new(15129)->bdiv(123), 123, + qq|$CLASS->new(15129)->bdiv(123) = 123|);; +is($CLASS->bdiv(15129, 123), 123, + qq|$CLASS->bdiv(15129, 123) = 123|);; +is($CLASS->bdiv(15129, $CLASS->new(123)), 123, + qq|$CLASS->bdiv(15129, $CLASS->new(123)) = 123|);; + +is($CLASS->new(15131)->bmod(123), 2, + qq|$CLASS->new(15131)->bmod(123) = 2|);; +is($CLASS->bmod(15131, 123), 2, + qq|$CLASS->bmod(15131, 123) = 2|);; +is($CLASS->bmod(15131, $CLASS->new(123)), 2, + qq|$CLASS->bmod(15131, $CLASS->new(123)) = 2|);; + +is($CLASS->new(2)->bpow(16), 65536, + qq|$CLASS->new(2)->bpow(16) = 65536|);; +is($CLASS->bpow(2, 16), 65536, + qq|$CLASS->bpow(2, 16) = 65536|);; +is($CLASS->bpow(2, $CLASS->new(16)), 65536, + qq|$CLASS->bpow(2, $CLASS->new(16)) = 65536|);; + +is($CLASS->new(2**15)->brsft(1), 2**14, + qq|$CLASS->new(2**15)->brsft(1) = 2**14|);; +is($CLASS->brsft(2**15, 1), 2**14, + qq|$CLASS->brsft(2**15, 1) = 2**14|);; +is($CLASS->brsft(2**15, $CLASS->new(1)), 2**14, + qq|$CLASS->brsft(2**15, $CLASS->new(1)) = 2**14|);; + +is($CLASS->new(2**13)->blsft(1), 2**14, + qq|$CLASS->new(2**13)->blsft(1) = 2**14|);; +is($CLASS->blsft(2**13, 1), 2**14, + qq|$CLASS->blsft(2**13, 1) = 2**14|);; +is($CLASS->blsft(2**13, $CLASS->new(1)), 2**14, + qq|$CLASS->blsft(2**13, $CLASS->new(1)) = 2**14|);; + +############################################################################### +# test for floating-point input (other tests in bnorm() below) + +$z = 1050000000000000; # may be int on systems with 64bit? +$x = $CLASS->new($z); +is($x->bsstr(), '105e+13', # not 1.05e+15 + qq|\$x = $CLASS->new($z); \$x->bsstr() = "105e+13"|); +$z = 1e+129; # definitely a float (may fail on UTS) +# don't compare to $z, since some Perl versions stringify $z into something +# like '1.e+129' or something equally ugly +$x = $CLASS->new($z); +is($x->bsstr(), '1e+129', + qq|\$x = $CLASS->new($z); \$x->bsstr() = "1e+129"|); + +############################################################################### +# test for whitespace including newlines to be handled correctly + +# is($Math::BigInt::strict, 1); # the default + +foreach my $c (qw/1 12 123 1234 12345 123456 1234567 + 12345678 123456789 1234567890/) +{ + my $m = $CLASS->new($c); + is($CLASS->new("$c"), $m, qq|$CLASS->new("$c") = $m|); + is($CLASS->new(" $c"), $m, qq|$CLASS->new(" $c") = $m|); + is($CLASS->new("$c "), $m, qq|$CLASS->new("$c ") = $m|); + is($CLASS->new(" $c "), $m, qq|$CLASS->new(" $c ") = $m|); + is($CLASS->new("\n$c"), $m, qq|$CLASS->new("\\n$c") = $m|); + is($CLASS->new("$c\n"), $m, qq|$CLASS->new("$c\\n") = $m|); + is($CLASS->new("\n$c\n"), $m, qq|$CLASS->new("\\n$c\\n") = $m|); + is($CLASS->new(" \n$c\n"), $m, qq|$CLASS->new(" \\n$c\\n") = $m|); + is($CLASS->new(" \n$c \n"), $m, qq|$CLASS->new(" \\n$c \\n") = $m|); + is($CLASS->new(" \n$c\n "), $m, qq|$CLASS->new(" \\n$c\\n ") = $m|); + is($CLASS->new(" \n$c\n1"), 'NaN', qq|$CLASS->new(" \\n$c\\n1") = 'NaN'|); + is($CLASS->new("1 \n$c\n1"), 'NaN', qq|$CLASS->new("1 \\n$c\\n1") = 'NaN'|); +} + +############################################################################### +# prime number tests, also test for **= and length() +# found on: http://www.utm.edu/research/primes/notes/by_year.html + +# ((2^148)+1)/17 +$x = $CLASS->new(2); +$x **= 148; +$x++; +$x = $x / 17; +is($x, "20988936657440586486151264256610222593863921", + "value of ((2^148)+1)/17"); +is($x->length(), length("20988936657440586486151264256610222593863921"), + "number of digits in ((2^148)+1)/17"); + +# MM7 = 2^127-1 +$x = $CLASS->new(2); +$x **= 127; +$x--; +is($x, "170141183460469231731687303715884105727", "value of 2^127-1"); + +$x = $CLASS->new('215960156869840440586892398248'); +($x, $y) = $x->length(); +is($x, 30, "number of digits in 2^127-1"); +is($y, 0, "number of digits in fraction part of 2^127-1"); + +$x = $CLASS->new('1_000_000_000_000'); +($x, $y) = $x->length(); +is($x, 13, "number of digits in 1_000_000_000_000"); +is($y, 0, "number of digits in fraction part of 1_000_000_000_000"); + +# test <<=, >>= +$x = $CLASS->new('2'); +$y = $CLASS->new('18'); +is($x <<= $y, 2 << 18, "2 <<= 18 with $CLASS objects"); +is($x, 2 << 18, "2 <<= 18 with $CLASS objects"); +is($x >>= $y, 2, "2 >>= 18 with $CLASS objects"); +is($x, 2, "2 >>= 18 with $CLASS objects"); + +# I am afraid the following is not yet possible due to slowness +# Also, testing for 2 meg output is a bit hard ;) +#$x = $CLASS->new(2); +#$x **= 6972593; +#$x--; + +# 593573509*2^332162+1 has exactly 1,000,000 digits +# takes about 24 mins on 300 Mhz, so cannot be done yet ;) +#$x = $CLASS->new(2); +#$x **= 332162; +#$x *= "593573509"; +#$x++; +#is($x->length(), 1_000_000); + +############################################################################### +# inheritance and overriding of _swap + +$x = Math::Foo->new(5); +$x = $x - 8; # 8 - 5 instead of 5-8 +is($x, 3, '$x = Math::Foo->new(5); $x = $x - 8; $x = 3'); +is(ref($x), 'Math::Foo', '$x is an object of class "Math::Foo"'); + +$x = Math::Foo->new(5); +$x = 8 - $x; # 5 - 8 instead of 8 - 5 +is($x, -3, '$x = Math::Foo->new(5); $x = 8 - $x; $x = -3'); +is(ref($x), 'Math::Foo', '$x is an object of class "Math::Foo"'); + +############################################################################### +# Check numify on non-finite objects. + +{ + require Math::Complex; + my $inf = Math::Complex::Inf(); + my $nan = $inf - $inf; + is($CLASS -> binf("+") -> numify(), $inf, "numify of +Inf"); + is($CLASS -> binf("-") -> numify(), -$inf, "numify of -Inf"); + is($CLASS -> bnan() -> numify(), $nan, "numify of NaN"); +} + +############################################################################### +# Test whether +inf eq inf +# +# This tried to test whether Math::BigInt inf equals Perl inf. Unfortunately, +# Perl hasn't (before 5.7.3 at least) a consistent way to say inf, and some +# things like 1e100000 crash on some platforms. So simple test for the string +# 'inf'. + +$x = $CLASS->new('+inf'); +is($x, 'inf', qq|$CLASS->new("+inf") = "inf"|); + +############################################################################### +# numify() and 64 bit integer support + +require Config; +SKIP: { + skip("no 64 bit integer support", 4) + if ! $Config::Config{use64bitint} || ! $Config::Config{use64bitall} + || $] <= 5.006002; + + # The following should not give "1.84467440737096e+19". + + $x = $CLASS -> new(2) -> bpow(64) -> bdec(); + is($x -> bstr(), "18446744073709551615", "bigint 2**64-1 as string"); + is($x -> numify(), "18446744073709551615", "bigint 2**64-1 as number"); + + # The following should not give "-9.22337203685478e+18". + + $x = $CLASS -> new(2) -> bpow(63) -> bneg(); + is($x -> bstr(), "-9223372036854775808", "bigint -2**63 as string"); + is($x -> numify(), "-9223372036854775808", "bigint -2**63 as number"); +}; + +############################################################################### +############################################################################### +# the following tests only make sense with Math::BigInt::Calc or BareCalc or +# FastCalc + +SKIP: { + # skip GMP, Pari et al. + skip("skipping tests not intended for the backend $CALC", 50) + unless $CALC =~ /^Math::BigInt::(Bare|Fast)?Calc$/; + + ########################################################################### + # check proper length of internal arrays + + my $bl = $CALC->_base_len(); + my $BASE = '9' x $bl; + my $MAX = $BASE; + $BASE++; + + # f.i. 9999 + $x = $CLASS->new($MAX); + is_valid($x); + + # 10000 + $x += 1; + is($x, $BASE, "\$x == $BASE"); + is_valid($x); + + # 9999 again + $x -= 1; + is($x, $MAX, "\$x == $MAX"); + is_valid($x); + + ########################################################################### + # check numify + + $x = $CLASS->new($BASE-1); + is($x->numify(), $BASE-1, q|$x->numify() = $BASE-1|); + + $x = $CLASS->new(-($BASE-1)); + is($x->numify(), -($BASE-1), q|$x->numify() = -($BASE-1)|); + + # +0 is to protect from 1e15 vs 100000000 (stupid to_string aaarglburbll...) + $x = $CLASS->new($BASE); + is($x->numify()+0, $BASE+0, q|$x->numify()+0 = $BASE+0|); + + $x = $CLASS->new(-$BASE); + is($x->numify(), -$BASE, q|$x->numify() = -$BASE|); + + $x = $CLASS->new(-($BASE*$BASE*1+$BASE*1+1)); + is($x->numify(), -($BASE*$BASE*1+$BASE*1+1), + q|$x->numify() = -($BASE*$BASE*1+$BASE*1+1))|); + + ########################################################################### + # test bug in _digits with length($c[-1]) where $c[-1] was "00001" instead + # of 1 + + $x = $CLASS->new($BASE - 2); + $x++; + $x++; + $x++; + $x++; + ok($x > $BASE, '$x > $BASE'); + + $x = $CLASS->new($BASE + 3); + $x++; + ok($x > $BASE, '$x > $BASE'); + + # test for +0 instead of int(): + $x = $CLASS->new($MAX); + is($x->length(), length($MAX), q|$x->length() = length($MAX)|); + + ########################################################################### + # test bug that $CLASS->digit($string) did not work + + is($CLASS->digit(123, 2), 1, qq|$CLASS->digit(123, 2) = 1|); + + ########################################################################### + # bug in sub where number with at least 6 trailing zeros after any op failed + + $x = $CLASS->new(123456); + $z = $CLASS->new(10000); + $z *= 10; + $x -= $z; + is($z, 100000, "testing bug in sub"); + is($x, 23456, "testing bug in sub"); + + ########################################################################### + # bug in shortcut in mul() + + # construct a number with a zero-hole of BASE_LEN_SMALL + { + my @bl = $CALC->_base_len(); + my $bl = $bl[5]; + + $x = '1' x $bl . '0' x $bl . '1' x $bl . '0' x $bl; + $y = '1' x (2 * $bl); + $x = $CLASS->new($x)->bmul($y); + # result is 123..$bl . $bl x (3*bl-1) . $bl...321 . '0' x $bl + $y = ''; + my $d = ''; + for (my $i = 1; $i <= $bl; $i++) { + $y .= $i; + $d = $i . $d; + } + $y .= $bl x (3 * $bl - 1) . $d . '0' x $bl; + is($x, $y, "testing number with a zero-hole of BASE_LEN_SMALL"); + + ######################################################################### + # see if mul shortcut for small numbers works + + $x = '9' x $bl; + $x = $CLASS->new($x); + # 999 * 999 => 998 . 001, 9999*9999 => 9998 . 0001 + is($x * $x, '9' x ($bl - 1) . '8' . '0' x ($bl - 1) . '1', + "see if mul shortcut for small numbers works"); + } + + ########################################################################### + # bug with rest "-0" in div, causing further div()s to fail + + $x = $CLASS->new('-322056000'); + ($x, $y) = $x->bdiv('-12882240'); + + is($y, '0', '-322056000 / -12882240 has remainder 0'); + is_valid($y); # $y not '-0' + + ########################################################################### + # bug in $x->bmod($y) + + # if $x < 0 and $y > 0 + $x = $CLASS->new('-629'); + is($x->bmod(5033), 4404, q|$x->bmod(5033) = 4404|); + + ########################################################################### + # bone/binf etc as plain calls (Lite failed them) + + is($CLASS->bzero(), 0, qq|$CLASS->bzero() = 0|); + is($CLASS->bone(), 1, qq|$CLASS->bone() = 1|); + is($CLASS->bone("+"), 1, qq|$CLASS->bone("+") = 1|); + is($CLASS->bone("-"), -1, qq|$CLASS->bone("-") = -1|); + is($CLASS->bnan(), "NaN", qq|$CLASS->bnan() = "NaN"|); + is($CLASS->binf(), "inf", qq|$CLASS->binf() = "inf"|); + is($CLASS->binf("+"), "inf", qq|$CLASS->binf("+") = "inf"|); + is($CLASS->binf("-"), "-inf", qq|$CLASS->binf("-") = "-inf"|); + is($CLASS->binf("-inf"), "-inf", qq|$CLASS->binf("-inf") = "-inf"|); + + ########################################################################### + # is_one("-") + + is($CLASS->new(1)->is_one("-"), 0, qq|$CLASS->new(1)->is_one("-") = 0|); + is($CLASS->new(-1)->is_one("-"), 1, qq|$CLASS->new(-1)->is_one("-") = 1|); + is($CLASS->new(1)->is_one(), 1, qq|$CLASS->new(1)->is_one() = 1|); + is($CLASS->new(-1)->is_one(), 0, qq|$CLASS->new(-1)->is_one() = 0|); + + ########################################################################### + # [perl #30609] bug with $x -= $x not being 0, but 2*$x + + $x = $CLASS->new(3); + $x -= $x; + is($x, 0, qq|\$x = $CLASS->new(3); \$x -= \$x; = 0|); + + $x = $CLASS->new(-3); + $x -= $x; + is($x, 0, qq|\$x = $CLASS->new(-3); \$x -= \$x; = 0|); + + $x = $CLASS->new("NaN"); + $x -= $x; + is($x->is_nan(), 1, + qq|\$x = $CLASS->new("NaN"); \$x -= \$x; \$x->is_nan() = 1|); + + $x = $CLASS->new("inf"); + $x -= $x; + is($x->is_nan(), 1, + qq|\$x = $CLASS->new("inf"); \$x -= \$x; \$x->is_nan() = 1|); + + $x = $CLASS->new("-inf"); + $x -= $x; + is($x->is_nan(), 1, + qq|\$x = $CLASS->new("-inf"); \$x -= \$x; \$x->is_nan() = 1|); + + $x = $CLASS->new("NaN"); + $x += $x; + is($x->is_nan(), 1, + qq|\$x = $CLASS->new("NaN"); \$x += \$x; \$x->is_nan() = 1|); + + $x = $CLASS->new("inf"); + $x += $x; + is($x->is_inf(), 1, + qq|\$x = $CLASS->new("inf"); \$x += \$x; \$x->is_inf() = 1|); + + $x = $CLASS->new("-inf"); + $x += $x; + is($x->is_inf("-"), 1, + qq|\$x = $CLASS->new("-inf"); \$x += \$x; \$x->is_inf("-") = 1|); + + $x = $CLASS->new(3); + $x += $x; + is($x, 6, qq|\$x = $CLASS->new(3); \$x += \$x; \$x = 6|); + + $x = $CLASS->new(-3); + $x += $x; + is($x, -6, qq|\$x = $CLASS->new(-3); \$x += \$x; \$x = -6|); + + $x = $CLASS->new(3); + $x *= $x; + is($x, 9, qq|\$x = $CLASS->new(3); \$x *= \$x; \$x = 9|); + + $x = $CLASS->new(-3); + $x *= $x; + is($x, 9, qq|\$x = $CLASS->new(-3); \$x *= \$x; \$x = 9|); + + $x = $CLASS->new(3); + $x /= $x; + is($x, 1, qq|\$x = $CLASS->new(3); \$x /= \$x; \$x = 1|); + + $x = $CLASS->new(-3); + $x /= $x; + is($x, 1, qq|\$x = $CLASS->new(-3); \$x /= \$x; \$x = 1|); + + $x = $CLASS->new(3); + $x %= $x; + is($x, 0, qq|\$x = $CLASS->new(3); \$x %= \$x; \$x = 0|); + + $x = $CLASS->new(-3); + $x %= $x; + is($x, 0, qq|\$x = $CLASS->new(-3); \$x %= \$x; \$x = 0|); +} + +############################################################################### +# all tests done + +1; + +############################################################################### +# sub to check validity of a Math::BigInt internally, to ensure that no op +# leaves a number object in an invalid state (f.i. "-0") + +sub is_valid { + my ($x, $f) = @_; + + my $e = 0; # error? + + # allow the check to pass for all Lite, and all MBI and subclasses + # ok as reference? + $e = 'Not a reference to Math::BigInt' if ref($x) !~ /^Math::BigInt/; + + if (ref($x) ne 'Math::BigInt::Lite') { + # has ok sign? + $e = qq|Illegal sign $x->{sign}| + . qq| (expected: "+", "-", "-inf", "+inf" or "NaN"| + if $e eq '0' && $x->{sign} !~ /^(\+|-|\+inf|-inf|NaN)$/; + + $e = "-0 is invalid!" if $e ne '0' && $x->{sign} eq '-' && $x == 0; + $e = $CALC->_check($x->{value}) if $e eq '0'; + } + + # test done, see if error did crop up + if ($e eq '0') { + pass('is a valid object'); + return; + } + + fail($e . " after op '$f'"); +} + +__DATA__ + +&.= +1234:-345:1234-345 + +&+= +1:2:3 +-1:-2:-3 + +&-= +1:2:-1 +-1:-2:1 + +&*= +2:3:6 +-1:5:-5 + +&%= +100:3:1 +8:9:8 +-629:5033:4404 + +&/= +100:3:33 +-8:2:-4 + +&|= +2:1:3 + +&&= +5:7:5 + +&^= +5:7:2 + +&blog +# +NaNlog:2:NaN +122:NaNlog:NaN +NaNlog1:NaNlog:NaN +# +122:inf:0 +inf:122:inf +122:-inf:0 +-inf:122:inf +-inf:-inf:NaN +0:4:-inf +-21:4:NaN +21:-21:NaN +# +0:-inf:NaN +0:-1:NaN +0:0:NaN +0:1:NaN +0:inf:NaN +# +1:-inf:0 +1:-1:0 +1:0:0 +1:1:NaN +1:4:0 +1:inf:0 +# +inf:-inf:NaN +inf:-1:NaN +inf:0:NaN +inf:1:NaN +inf:4:inf +inf:inf:NaN +# +# normal results +1024:2:10 +81:3:4 +# 3.01.. truncate +82:3:4 +# 3.9... truncate +80:3:3 +4096:2:12 +15625:5:6 +15626:5:6 +15624:5:5 +1000:10:3 +10000:10:4 +100000:10:5 +1000000:10:6 +10000000:10:7 +100000000:10:8 +8916100448256:12:12 +8916100448257:12:12 +8916100448255:12:11 +2251799813685248:8:17 +72057594037927936:2:56 +144115188075855872:2:57 +288230376151711744:2:58 +576460752303423488:2:59 +1329227995784915872903807060280344576:2:120 +# $x == $base => result 1 +3:3:1 +# $x < $base => result 0 ($base ** 0 <= $x) +3:4:0 +# $x == 1 => result 0 +1:5:0 + +&is_negative +0:0 +-1:1 +1:0 ++inf:0 +-inf:1 +NaNneg:0 + +&is_positive +0:0 +-1:0 +1:1 ++inf:1 +-inf:0 +NaNneg:0 + +&is_int +-inf:0 ++inf:0 +NaNis_int:0 +1:1 +0:1 +123e12:1 + +&is_odd +abc:0 +0:0 +1:1 +3:1 +-1:1 +-3:1 +10000001:1 +10000002:0 +2:0 +120:0 +121:1 + +&is_even +abc:0 +0:1 +1:0 +3:0 +-1:0 +-3:0 +10000001:0 +10000002:1 +2:1 +120:1 +121:0 + +&bacmp ++0:-0:0 ++0:+1:-1 +-1:+1:0 ++1:-1:0 +-1:+2:-1 ++2:-1:1 +-123456789:+987654321:-1 ++123456789:-987654321:-1 ++987654321:+123456789:1 +-987654321:+123456789:1 +-123:+4567889:-1 +# NaNs +acmpNaN:123: +123:acmpNaN: +acmpNaN:acmpNaN: +# infinity ++inf:+inf:0 +-inf:-inf:0 ++inf:-inf:0 +-inf:+inf:0 ++inf:123:1 +-inf:123:1 ++inf:-123:1 +-inf:-123:1 +123:-inf:-1 +-123:inf:-1 +-123:-inf:-1 +123:inf:-1 +# return undef ++inf:NaN: +NaN:inf: +-inf:NaN: +NaN:-inf: + +&bnorm +0e999:0 +0e-999:0 +-0e999:0 +-0e-999:0 +123:123 +123.000:123 +123e0:123 +123e+0:123 +123e-0:123 +123.000e0:123 +123.000e+0:123 +123.000e-0:123 +# binary input +0babc:NaN +0b123:NaN +0b0:0 +-0b0:0 +-0b1:-1 +0b0001:1 +0b001:1 +0b011:3 +0b101:5 +0b1001:9 +0b10001:17 +0b100001:33 +0b1000001:65 +0b10000001:129 +0b100000001:257 +0b1000000001:513 +0b10000000001:1025 +0b100000000001:2049 +0b1000000000001:4097 +0b10000000000001:8193 +0b100000000000001:16385 +0b1000000000000001:32769 +0b10000000000000001:65537 +0b100000000000000001:131073 +0b1000000000000000001:262145 +0b10000000000000000001:524289 +0b100000000000000000001:1048577 +0b1000000000000000000001:2097153 +0b10000000000000000000001:4194305 +0b100000000000000000000001:8388609 +0b1000000000000000000000001:16777217 +0b10000000000000000000000001:33554433 +0b100000000000000000000000001:67108865 +0b1000000000000000000000000001:134217729 +0b10000000000000000000000000001:268435457 +0b100000000000000000000000000001:536870913 +0b1000000000000000000000000000001:1073741825 +0b10000000000000000000000000000001:2147483649 +0b100000000000000000000000000000001:4294967297 +0b1000000000000000000000000000000001:8589934593 +0b10000000000000000000000000000000001:17179869185 +0b__101:NaN +0b1_0_1:5 +0b0_0_0_1:1 +# hex input +-0x0:0 +0xabcdefgh:NaN +0x1234:4660 +0xabcdef:11259375 +-0xABCDEF:-11259375 +-0x1234:-4660 +0x12345678:305419896 +0x1_2_3_4_56_78:305419896 +0xa_b_c_d_e_f:11259375 +0x__123:NaN +0x9:9 +0x11:17 +0x21:33 +0x41:65 +0x81:129 +0x101:257 +0x201:513 +0x401:1025 +0x801:2049 +0x1001:4097 +0x2001:8193 +0x4001:16385 +0x8001:32769 +0x10001:65537 +0x20001:131073 +0x40001:262145 +0x80001:524289 +0x100001:1048577 +0x200001:2097153 +0x400001:4194305 +0x800001:8388609 +0x1000001:16777217 +0x2000001:33554433 +0x4000001:67108865 +0x8000001:134217729 +0x10000001:268435457 +0x20000001:536870913 +0x40000001:1073741825 +0x80000001:2147483649 +0x100000001:4294967297 +0x200000001:8589934593 +0x400000001:17179869185 +0x800000001:34359738369 +# bug found by Mark Lakata in Calc.pm creating too big one-element numbers +# in _from_hex() +0x2dd59e18a125dbed30a6ab1d93e9c855569f44f75806f0645dc9a2e98b808c3:1295719234436071846486578237372801883390756472611551858964079371952886122691 +# inf input +inf:inf ++inf:inf +-inf:-inf +0inf:NaN +# abnormal input +:NaN +abc:NaN + 1 a:NaN +1bcd2:NaN +11111b:NaN ++1z:NaN +-1z:NaN +# only one underscore between two digits +_123:NaN +_123_:NaN +123_:NaN +1__23:NaN +1E1__2:NaN +1_E12:NaN +1E_12:NaN +1_E_12:NaN ++_1E12:NaN ++0_1E2:100 ++0_0_1E2:100 +-0_0_1E2:-100 +-0_0_1E+0_0_2:-100 +E1:NaN +E23:NaN +1.23E1:NaN +1.23E-1:NaN +# bug with two E's in number being valid +1e2e3:NaN +1e2r:NaN +1e2.0:NaN +# bug with two '.' in number being valid +1.2.2:NaN +1.2.3e1:NaN +-1.2.3:NaN +-1.2.3e-4:NaN +1.2e3.4:NaN +1.2e-3.4:NaN +1.2.3.4:NaN +1.2.t:NaN +1..2:NaN +1..2e1:NaN +1..2e1..1:NaN +12e1..1:NaN +..2:NaN +.-2:NaN +# leading zeros +012:12 +0123:123 +01234:1234 +012345:12345 +0123456:123456 +01234567:1234567 +012345678:12345678 +0123456789:123456789 +01234567891:1234567891 +012345678912:12345678912 +0123456789123:123456789123 +01234567891234:1234567891234 +# some inputs that result in zero +0e0:0 ++0e0:0 ++0e+0:0 +-0e+0:0 +0e-0:0 +-0e-0:0 ++0e-0:0 +000:0 +00e2:0 +00e02:0 +000e002:0 +000e1230:0 +00e-3:0 +00e+3:0 +00e-03:0 +00e+03:0 +-000:0 +-00e2:0 +-00e02:0 +-000e002:0 +-000e1230:0 +-00e-3:0 +-00e+3:0 +-00e-03:0 +-00e+03:0 +# normal input +0:0 ++0:0 ++00:0 ++000:0 +000000000000000000:0 +-0:0 +-0000:0 ++1:1 ++01:1 ++001:1 ++00000100000:100000 +123456789:123456789 +-1:-1 +-01:-1 +-001:-1 +-123456789:-123456789 +-00000100000:-100000 +1_2_3:123 +10000000000E-1_0:1 +1E2:100 +1E1:10 +1E0:1 +1.23E2:123 +100E-1:10 +# floating point input +# .2e2:20 +1.E3:1000 +1.01E2:101 +1010E-1:101 +-1010E0:-1010 +-1010E1:-10100 +1234.00:1234 +# non-integer numbers +-1010E-2:NaN +-1.01E+1:NaN +-1.01E-1:NaN +1E-999999:NaN +0.5:NaN + +&bnan +1:NaN +2:NaN +abc:NaN + +&bone +2:+:1 +2:-:-1 +boneNaN:-:-1 +boneNaN:+:1 +2:abc:1 +3::1 + +&binf +1:+:inf +2:-:-inf +3:abc:inf + +&is_nan +123:0 +abc:1 +NaN:1 +-123:0 + +&is_inf ++inf::1 +-inf::1 +abc::0 +1::0 +NaN::0 +-1::0 ++inf:-:0 ++inf:+:1 +-inf:-:1 +-inf:+:0 +-inf:-inf:1 +-inf:+inf:0 ++inf:-inf:0 ++inf:+inf:1 ++iNfInItY::1 +-InFiNiTy::1 + +&blsft +abc:abc:NaN ++2:+2:8 ++1:+32:4294967296 ++1:+48:281474976710656 ++8:-2:NaN +# exercise base 10 ++12345:4:10:123450000 +-1234:0:10:-1234 ++1234:0:10:1234 ++2:2:10:200 ++12:2:10:1200 ++1234:-3:10:NaN +1234567890123:12:10:1234567890123000000000000 +-3:1:2:-6 +-5:1:2:-10 +-2:1:2:-4 +-102533203:1:2:-205066406 + +&brsft +abc:abc:NaN ++8:+2:2 ++4294967296:+32:1 ++281474976710656:+48:1 ++2:-2:NaN +# exercise base 10 +-1234:0:10:-1234 ++1234:0:10:1234 ++200:2:10:2 ++1234:3:10:1 ++1234:2:10:12 ++1234:-3:10:NaN +310000:4:10:31 +12300000:5:10:123 +1230000000000:10:10:123 +09876123456789067890:12:10:9876123 +1234561234567890123:13:10:123456 +820265627:1:2:410132813 +# test shifting negative numbers in base 2 +-15:1:2:-8 +-14:1:2:-7 +-13:1:2:-7 +-12:1:2:-6 +-11:1:2:-6 +-10:1:2:-5 +-9:1:2:-5 +-8:1:2:-4 +-7:1:2:-4 +-6:1:2:-3 +-5:1:2:-3 +-4:1:2:-2 +-3:1:2:-2 +-2:1:2:-1 +-1:1:2:-1 +-1640531254:2:2:-410132814 +-1640531254:1:2:-820265627 +-820265627:1:2:-410132814 +-205066405:1:2:-102533203 + +&bsstr ++inf:inf +-inf:-inf +1e+34:1e+34 +123.456E3:123456e+0 +100:1e+2 +bsstrabc:NaN +-5:-5e+0 +-100:-1e+2 + +&numify +5:5 +-5:-5 +100:100 +-100:-100 + +&bneg +bnegNaN:NaN ++inf:-inf +-inf:inf +abd:NaN +0:0 +1:-1 +-1:1 ++123456789:-123456789 +-123456789:123456789 + +&babs +babsNaN:NaN ++inf:inf +-inf:inf +0:0 +1:1 +-1:1 ++123456789:123456789 +-123456789:123456789 + +&bsgn +NaN:NaN ++inf:1 +-inf:-1 +0:0 ++123456789:1 +-123456789:-1 + +&bcmp +bcmpNaN:bcmpNaN: +bcmpNaN:0: +0:bcmpNaN: +0:0:0 +-1:0:-1 +0:-1:1 +1:0:1 +0:1:-1 +-1:1:-1 +1:-1:1 +-1:-1:0 +1:1:0 +123:123:0 +123:12:1 +12:123:-1 +-123:-123:0 +-123:-12:-1 +-12:-123:1 +123:124:-1 +124:123:1 +-123:-124:1 +-124:-123:-1 +100:5:1 +-123456789:987654321:-1 ++123456789:-987654321:1 +-987654321:123456789:-1 +-inf:5432112345:-1 ++inf:5432112345:1 +-inf:-5432112345:-1 ++inf:-5432112345:1 ++inf:+inf:0 +-inf:-inf:0 ++inf:-inf:1 +-inf:+inf:-1 +5:inf:-1 +5:inf:-1 +-5:-inf:1 +-5:-inf:1 +# return undef ++inf:NaN: +NaN:inf: +-inf:NaN: +NaN:-inf: + +&binc +abc:NaN ++inf:inf +-inf:-inf ++0:1 ++1:2 +-1:0 + +&bdec +abc:NaN ++inf:inf +-inf:-inf ++0:-1 ++1:0 +-1:-2 + +&badd +abc:abc:NaN +abc:0:NaN ++0:abc:NaN ++inf:-inf:NaN +-inf:+inf:NaN ++inf:+inf:inf +-inf:-inf:-inf +baddNaN:+inf:NaN +baddNaN:+inf:NaN ++inf:baddNaN:NaN +-inf:baddNaN:NaN +0:0:0 +1:0:1 +0:1:1 +1:1:2 +-1:0:-1 +0:-1:-1 +-1:-1:-2 +-1:+1:0 ++1:-1:0 ++9:+1:10 ++99:+1:100 ++999:+1:1000 ++9999:+1:10000 ++99999:+1:100000 ++999999:+1:1000000 ++9999999:+1:10000000 ++99999999:+1:100000000 ++999999999:+1:1000000000 ++9999999999:+1:10000000000 ++99999999999:+1:100000000000 ++10:-1:9 ++100:-1:99 ++1000:-1:999 ++10000:-1:9999 ++100000:-1:99999 ++1000000:-1:999999 ++10000000:-1:9999999 ++100000000:-1:99999999 ++1000000000:-1:999999999 ++10000000000:-1:9999999999 ++123456789:987654321:1111111110 +-123456789:987654321:864197532 +-123456789:-987654321:-1111111110 ++123456789:-987654321:-864197532 +-1:10001:10000 +-1:100001:100000 +-1:1000001:1000000 +-1:10000001:10000000 +-1:100000001:100000000 +-1:1000000001:1000000000 +-1:10000000001:10000000000 +-1:100000000001:100000000000 +-1:1000000000001:1000000000000 +-1:10000000000001:10000000000000 +-1:-10001:-10002 +-1:-100001:-100002 +-1:-1000001:-1000002 +-1:-10000001:-10000002 +-1:-100000001:-100000002 +-1:-1000000001:-1000000002 +-1:-10000000001:-10000000002 +-1:-100000000001:-100000000002 +-1:-1000000000001:-1000000000002 +-1:-10000000000001:-10000000000002 + +&bsub +abc:abc:NaN +abc:+0:NaN ++0:abc:NaN ++inf:-inf:inf +-inf:+inf:-inf ++inf:+inf:NaN +-inf:-inf:NaN ++0:+0:0 ++1:+0:1 ++0:+1:-1 ++1:+1:0 +-1:+0:-1 ++0:-1:1 +-1:-1:0 +-1:+1:-2 ++1:-1:2 ++9:+1:8 ++99:+1:98 ++999:+1:998 ++9999:+1:9998 ++99999:+1:99998 ++999999:+1:999998 ++9999999:+1:9999998 ++99999999:+1:99999998 ++999999999:+1:999999998 ++9999999999:+1:9999999998 ++99999999999:+1:99999999998 ++10:-1:11 ++100:-1:101 ++1000:-1:1001 ++10000:-1:10001 ++100000:-1:100001 ++1000000:-1:1000001 ++10000000:-1:10000001 ++100000000:-1:100000001 ++1000000000:-1:1000000001 ++10000000000:-1:10000000001 ++123456789:+987654321:-864197532 +-123456789:+987654321:-1111111110 +-123456789:-987654321:864197532 ++123456789:-987654321:1111111110 +10001:1:10000 +100001:1:100000 +1000001:1:1000000 +10000001:1:10000000 +100000001:1:100000000 +1000000001:1:1000000000 +10000000001:1:10000000000 +100000000001:1:100000000000 +1000000000001:1:1000000000000 +10000000000001:1:10000000000000 +10001:-1:10002 +100001:-1:100002 +1000001:-1:1000002 +10000001:-1:10000002 +100000001:-1:100000002 +1000000001:-1:1000000002 +10000000001:-1:10000000002 +100000000001:-1:100000000002 +1000000000001:-1:1000000000002 +10000000000001:-1:10000000000002 + +&bmuladd +abc:abc:0:NaN +abc:+0:0:NaN ++0:abc:0:NaN ++0:0:abc:NaN +NaNmul:+inf:0:NaN +NaNmul:-inf:0:NaN +-inf:NaNmul:0:NaN ++inf:NaNmul:0:NaN ++inf:+inf:0:inf ++inf:-inf:0:-inf +-inf:+inf:0:-inf +-inf:-inf:0:inf ++0:+0:0:0 ++0:+1:0:0 ++1:+0:0:0 ++0:-1:0:0 +-1:+0:0:0 +123456789123456789:0:0:0 +0:123456789123456789:0:0 +-1:-1:0:1 +-1:-1:0:1 +-1:+1:0:-1 ++1:-1:0:-1 ++1:+1:0:1 ++2:+3:0:6 +-2:+3:0:-6 ++2:-3:0:-6 +-2:-3:0:6 +111:111:0:12321 +10101:10101:0:102030201 +1001001:1001001:0:1002003002001 +100010001:100010001:0:10002000300020001 +10000100001:10000100001:0:100002000030000200001 +11111111111:9:0:99999999999 +22222222222:9:0:199999999998 +33333333333:9:0:299999999997 +44444444444:9:0:399999999996 +55555555555:9:0:499999999995 +66666666666:9:0:599999999994 +77777777777:9:0:699999999993 +88888888888:9:0:799999999992 +99999999999:9:0:899999999991 +11111111111:9:1:100000000000 +22222222222:9:1:199999999999 +33333333333:9:1:299999999998 +44444444444:9:1:399999999997 +55555555555:9:1:499999999996 +66666666666:9:1:599999999995 +77777777777:9:1:699999999994 +88888888888:9:1:799999999993 +99999999999:9:1:899999999992 +-3:-4:-5:7 +3:-4:-5:-17 +-3:4:-5:-17 +3:4:-5:7 +-3:4:5:-7 +3:-4:5:-7 +9999999999999999999:10000000000000000000:1234567890:99999999999999999990000000001234567890 +2:3:12345678901234567890:12345678901234567896 + +&bmul +abc:abc:NaN +abc:+0:NaN ++0:abc:NaN +NaNmul:+inf:NaN +NaNmul:-inf:NaN +-inf:NaNmul:NaN ++inf:NaNmul:NaN ++inf:+inf:inf ++inf:-inf:-inf +-inf:+inf:-inf +-inf:-inf:inf ++0:+0:0 ++0:+1:0 ++1:+0:0 ++0:-1:0 +-1:+0:0 +123456789123456789:0:0 +0:123456789123456789:0 +-1:-1:1 +-1:+1:-1 ++1:-1:-1 ++1:+1:1 ++2:+3:6 +-2:+3:-6 ++2:-3:-6 +-2:-3:6 +111:111:12321 +10101:10101:102030201 +1001001:1001001:1002003002001 +100010001:100010001:10002000300020001 +10000100001:10000100001:100002000030000200001 +11111111111:9:99999999999 +22222222222:9:199999999998 +33333333333:9:299999999997 +44444444444:9:399999999996 +55555555555:9:499999999995 +66666666666:9:599999999994 +77777777777:9:699999999993 +88888888888:9:799999999992 +99999999999:9:899999999991 ++25:+25:625 ++12345:+12345:152399025 ++99999:+11111:1111088889 +9999:10000:99990000 +99999:100000:9999900000 +999999:1000000:999999000000 +9999999:10000000:99999990000000 +99999999:100000000:9999999900000000 +999999999:1000000000:999999999000000000 +9999999999:10000000000:99999999990000000000 +99999999999:100000000000:9999999999900000000000 +999999999999:1000000000000:999999999999000000000000 +9999999999999:10000000000000:99999999999990000000000000 +99999999999999:100000000000000:9999999999999900000000000000 +999999999999999:1000000000000000:999999999999999000000000000000 +9999999999999999:10000000000000000:99999999999999990000000000000000 +99999999999999999:100000000000000000:9999999999999999900000000000000000 +999999999999999999:1000000000000000000:999999999999999999000000000000000000 +9999999999999999999:10000000000000000000:99999999999999999990000000000000000000 + +&bdiv-list +100:20:5,0 +4095:4095:1,0 +-4095:-4095:1,0 +4095:-4095:-1,0 +-4095:4095:-1,0 +123:2:61,1 +9:5:1,4 +9:4:2,1 +# inf handling and general remainder +5:8:0,5 +0:8:0,0 +11:2:5,1 +11:-2:-6,-1 +-11:2:-6,1 +# see table in documentation in MBI +0:inf:0,0 +0:-inf:0,0 +5:inf:0,5 +5:-inf:-1,-inf +-5:inf:-1,inf +-5:-inf:0,-5 +inf:5:inf,NaN +-inf:5:-inf,NaN +inf:-5:-inf,NaN +-inf:-5:inf,NaN +5:5:1,0 +-5:-5:1,0 +inf:inf:NaN,NaN +-inf:-inf:NaN,NaN +-inf:inf:NaN,NaN +inf:-inf:NaN,NaN +8:0:inf,8 +inf:0:inf,inf +# exceptions to remainder rule +-8:0:-inf,-8 +-inf:0:-inf,-inf +0:0:NaN,0 +# test the shortcut in Calc if @$x == @$yorg +1234567812345678:123456712345678:10,688888898 +12345671234567:1234561234567:10,58888897 +123456123456:12345123456:10,4888896 +1234512345:123412345:10,388895 +1234567890999999999:1234567890:1000000000,999999999 +1234567890000000000:1234567890:1000000000,0 +1234567890999999999:9876543210:124999998,9503086419 +1234567890000000000:9876543210:124999998,8503086420 +96969696969696969696969696969678787878626262626262626262626262:484848484848484848484848486666666666666689898989898989898989:199,484848484848484848484848123012121211954972727272727272727451 +# bug in v1.76 +1267650600228229401496703205375:1267650600228229401496703205376:0,1267650600228229401496703205375 +# exercise shortcut for numbers of the same length in div +999999999999999999999999999999999:999999999999999999999999999999999:1,0 +999999999999999999999999999999999:888888888888888888888888888888888:1,111111111111111111111111111111111 +999999999999999999999999999999999:777777777777777777777777777777777:1,222222222222222222222222222222222 +999999999999999999999999999999999:666666666666666666666666666666666:1,333333333333333333333333333333333 +999999999999999999999999999999999:555555555555555555555555555555555:1,444444444444444444444444444444444 +999999999999999999999999999999999:444444444444444444444444444444444:2,111111111111111111111111111111111 +999999999999999999999999999999999:333333333333333333333333333333333:3,0 +999999999999999999999999999999999:222222222222222222222222222222222:4,111111111111111111111111111111111 +999999999999999999999999999999999:111111111111111111111111111111111:9,0 +9999999_9999999_9999999_9999999:3333333_3333333_3333333_3333333:3,0 +9999999_9999999_9999999_9999999:3333333_0000000_0000000_0000000:3,999999999999999999999 +9999999_9999999_9999999_9999999:3000000_0000000_0000000_0000000:3,999999999999999999999999999 +9999999_9999999_9999999_9999999:2000000_0000000_0000000_0000000:4,1999999999999999999999999999 +9999999_9999999_9999999_9999999:1000000_0000000_0000000_0000000:9,999999999999999999999999999 +9999999_9999999_9999999_9999999:100000_0000000_0000000_0000000:99,99999999999999999999999999 +9999999_9999999_9999999_9999999:10000_0000000_0000000_0000000:999,9999999999999999999999999 +9999999_9999999_9999999_9999999:1000_0000000_0000000_0000000:9999,999999999999999999999999 +9999999_9999999_9999999_9999999:100_0000000_0000000_0000000:99999,99999999999999999999999 +9999999_9999999_9999999_9999999:10_0000000_0000000_0000000:999999,9999999999999999999999 +9999999_9999999_9999999_9999999:1_0000000_0000000_0000000:9999999,999999999999999999999 + +&bdiv +abc:abc:NaN +abc:1:NaN +1:abc:NaN +0:0:NaN +# inf handling (see table in doc) +0:inf:0 +0:-inf:0 +5:inf:0 +5:-inf:-1 +-5:inf:-1 +-5:-inf:0 +inf:5:inf +-inf:5:-inf +inf:-5:-inf +-inf:-5:inf +5:5:1 +-5:-5:1 +inf:inf:NaN +-inf:-inf:NaN +-inf:inf:NaN +inf:-inf:NaN +8:0:inf +inf:0:inf +-8:0:-inf +-inf:0:-inf +0:0:NaN +11:2:5 +-11:-2:5 +-11:2:-6 +11:-2:-6 +0:1:0 +0:-1:0 +1:1:1 +-1:-1:1 +1:-1:-1 +-1:1:-1 +1:2:0 +2:1:2 +1:26:0 +1000000000:9:111111111 +2000000000:9:222222222 +3000000000:9:333333333 +4000000000:9:444444444 +5000000000:9:555555555 +6000000000:9:666666666 +7000000000:9:777777777 +8000000000:9:888888888 +9000000000:9:1000000000 +35500000:113:314159 +71000000:226:314159 +106500000:339:314159 +1000000000:3:333333333 ++10:+5:2 ++100:+4:25 ++1000:+8:125 ++10000:+16:625 +999999999999:9:111111111111 +999999999999:99:10101010101 +999999999999:999:1001001001 +999999999999:9999:100010001 +999999999999999:99999:10000100001 ++1111088889:99999:11111 +-5:-3:1 +-5:3:-2 +4:3:1 +4:-3:-2 +1:3:0 +1:-3:-1 +-2:-3:0 +-2:3:-1 +8:3:2 +-8:3:-3 +14:-3:-5 +-14:3:-5 +-14:-3:4 +14:3:4 +# bug in Calc with '99999' vs $BASE-1 +10000000000000000000000000000000000000000000000000000000000000000000000000000000000:10000000375084540248994272022843165711074:999999962491547381984643365663244474111576 +# test the shortcut in Calc if @$x == @$yorg +1234567812345678:123456712345678:10 +12345671234567:1234561234567:10 +123456123456:12345123456:10 +1234512345:123412345:10 +1234567890999999999:1234567890:1000000000 +1234567890000000000:1234567890:1000000000 +1234567890999999999:9876543210:124999998 +1234567890000000000:9876543210:124999998 +96969696969696969696969696969678787878626262626262626262626262:484848484848484848484848486666666666666689898989898989898989:199 +# bug up to v0.35 in Calc (--$q one too many) +84696969696969696956565656566184292929292929292847474747436308080808080808086765396464646464646465:13131313131313131313131313131394949494949494949494949494943535353535353535353535:6449999999999999999 +84696969696969696943434343434871161616161616161452525252486813131313131313143230042929292929292930:13131313131313131313131313131394949494949494949494949494943535353535353535353535:6449999999999999998 +84696969696969696969696969697497424242424242424242424242385803030303030303030300750000000000000000:13131313131313131313131313131394949494949494949494949494943535353535353535353535:6450000000000000000 +84696969696969696930303030303558030303030303030057575757537318181818181818199694689393939393939395:13131313131313131313131313131394949494949494949494949494943535353535353535353535:6449999999999999997 +# exercise shortcut for numbers of the same length in div +999999999999999999999999999999999:999999999999999999999999999999999:1 +999999999999999999999999999999999:888888888888888888888888888888888:1 +999999999999999999999999999999999:777777777777777777777777777777777:1 +999999999999999999999999999999999:666666666666666666666666666666666:1 +999999999999999999999999999999999:555555555555555555555555555555555:1 +999999999999999999999999999999999:444444444444444444444444444444444:2 +999999999999999999999999999999999:333333333333333333333333333333333:3 +999999999999999999999999999999999:222222222222222222222222222222222:4 +999999999999999999999999999999999:111111111111111111111111111111111:9 +9999999_9999999_9999999_9999999:3333333_3333333_3333333_3333333:3 +9999999_9999999_9999999_9999999:3333333_0000000_0000000_0000000:3 +9999999_9999999_9999999_9999999:3000000_0000000_0000000_0000000:3 +9999999_9999999_9999999_9999999:2000000_0000000_0000000_0000000:4 +9999999_9999999_9999999_9999999:1000000_0000000_0000000_0000000:9 +9999999_9999999_9999999_9999999:100000_0000000_0000000_0000000:99 +9999999_9999999_9999999_9999999:10000_0000000_0000000_0000000:999 +9999999_9999999_9999999_9999999:1000_0000000_0000000_0000000:9999 +9999999_9999999_9999999_9999999:100_0000000_0000000_0000000:99999 +9999999_9999999_9999999_9999999:10_0000000_0000000_0000000:999999 +9999999_9999999_9999999_9999999:1_0000000_0000000_0000000:9999999 +# bug with shortcut in Calc 0.44 +949418181818187070707070707070707070:181818181853535353535353535353535353:5 + +&bmodinv +# format: number:modulus:result +# bmodinv Data errors +abc:abc:NaN +abc:5:NaN +5:abc:NaN +# bmodinv Expected Results from normal use +1:5:1 +3:5:2 +3:-5:-3 +-2:5:2 +8:5033:4404 +1234567891:13:6 +-1234567891:13:7 +324958749843759385732954874325984357439658735983745:2348249874968739:1741662881064902 +-2:1:0 +-1:1:0 +0:1:0 +1:1:0 +2:1:0 +3:1:0 +4:1:0 +-2:3:1 +-1:3:2 +0:3:NaN +1:3:1 +2:3:2 +3:3:NaN +4:3:1 +-2:4:NaN +-1:4:3 +0:4:NaN +1:4:1 +2:4:NaN +3:4:3 +4:4:NaN +## bmodinv Error cases / useless use of function +inf:5:NaN +5:inf:NaN +-inf:5:NaN +5:-inf:NaN + +&bmodpow +# format: number:exponent:modulus:result +# bmodpow Data errors +abc:abc:abc:NaN +5:abc:abc:NaN +abc:5:abc:NaN +abc:abc:5:NaN +5:5:abc:NaN +5:abc:5:NaN +abc:5:5:NaN +3:5:0:3 +# bmodpow Expected results +0:0:2:1 +1:0:2:1 +0:3:5:0 +-2:-2:1:0 +-1:-2:1:0 +0:-2:1:0 +1:-2:1:0 +2:-2:1:0 +3:-2:1:0 +4:-2:1:0 +-2:-1:1:0 +-1:-1:1:0 +0:-1:1:0 +1:-1:1:0 +2:-1:1:0 +3:-1:1:0 +4:-1:1:0 +-2:0:1:0 +-1:0:1:0 +0:0:1:0 +1:0:1:0 +2:0:1:0 +3:0:1:0 +4:0:1:0 +-2:1:1:0 +-1:1:1:0 +0:1:1:0 +1:1:1:0 +2:1:1:0 +3:1:1:0 +4:1:1:0 +-2:2:1:0 +-1:2:1:0 +0:2:1:0 +1:2:1:0 +2:2:1:0 +3:2:1:0 +4:2:1:0 +-2:3:1:0 +-1:3:1:0 +0:3:1:0 +1:3:1:0 +2:3:1:0 +3:3:1:0 +4:3:1:0 +-2:4:1:0 +-1:4:1:0 +0:4:1:0 +1:4:1:0 +2:4:1:0 +3:4:1:0 +4:4:1:0 +-2:-2:3:1 +-1:-2:3:1 +0:-2:3:NaN +1:-2:3:1 +2:-2:3:1 +3:-2:3:NaN +4:-2:3:1 +-2:-1:3:1 +-1:-1:3:2 +0:-1:3:NaN +1:-1:3:1 +2:-1:3:2 +3:-1:3:NaN +4:-1:3:1 +-2:0:3:1 +-1:0:3:1 +0:0:3:1 +1:0:3:1 +2:0:3:1 +3:0:3:1 +4:0:3:1 +-2:1:3:1 +-1:1:3:2 +0:1:3:0 +1:1:3:1 +2:1:3:2 +3:1:3:0 +4:1:3:1 +-2:2:3:1 +-1:2:3:1 +0:2:3:0 +1:2:3:1 +2:2:3:1 +3:2:3:0 +4:2:3:1 +-2:3:3:1 +-1:3:3:2 +0:3:3:0 +1:3:3:1 +2:3:3:2 +3:3:3:0 +4:3:3:1 +-2:4:3:1 +-1:4:3:1 +0:4:3:0 +1:4:3:1 +2:4:3:1 +3:4:3:0 +4:4:3:1 +-2:-2:4:NaN +-1:-2:4:1 +0:-2:4:NaN +1:-2:4:1 +2:-2:4:NaN +3:-2:4:1 +4:-2:4:NaN +-2:-1:4:NaN +-1:-1:4:3 +0:-1:4:NaN +1:-1:4:1 +2:-1:4:NaN +3:-1:4:3 +4:-1:4:NaN +-2:0:4:1 +-1:0:4:1 +0:0:4:1 +1:0:4:1 +2:0:4:1 +3:0:4:1 +4:0:4:1 +-2:1:4:2 +-1:1:4:3 +0:1:4:0 +1:1:4:1 +2:1:4:2 +3:1:4:3 +4:1:4:0 +-2:2:4:0 +-1:2:4:1 +0:2:4:0 +1:2:4:1 +2:2:4:0 +3:2:4:1 +4:2:4:0 +-2:3:4:0 +-1:3:4:3 +0:3:4:0 +1:3:4:1 +2:3:4:0 +3:3:4:3 +4:3:4:0 +-2:4:4:0 +-1:4:4:1 +0:4:4:0 +1:4:4:1 +2:4:4:0 +3:4:4:1 +4:4:4:0 +8:-1:16:NaN +8:-1:5033:4404 +8:7:5032:3840 +8:8:-5:-4 +1e50:1:1:0 +98436739867439843769485798542749827593285729587325:43698764986460981048259837659386739857456983759328457:6943857329857295827698367:3104744730915914415259518 +# bmodpow Error cases +inf:5:13:NaN +5:inf:13:NaN + +&bmod +# inf handling, see table in doc +0:inf:0 +0:-inf:0 +5:inf:5 +5:-inf:-inf +-5:inf:inf +-5:-inf:-5 +inf:5:NaN +-inf:5:NaN +inf:-5:NaN +-inf:-5:NaN +5:5:0 +-5:-5:0 +inf:inf:NaN +-inf:-inf:NaN +-inf:inf:NaN +inf:-inf:NaN +8:0:8 +inf:0:inf +-inf:0:-inf +-8:0:-8 +0:0:0 +abc:abc:NaN +abc:1:abc:NaN +1:abc:NaN +0:1:0 +1:0:1 +0:-1:0 +-1:0:-1 +1:1:0 +-1:-1:0 +1:-1:0 +-1:1:0 +1:2:1 +2:1:0 +1000000000:9:1 +2000000000:9:2 +3000000000:9:3 +4000000000:9:4 +5000000000:9:5 +6000000000:9:6 +7000000000:9:7 +8000000000:9:8 +9000000000:9:0 +35500000:113:33 +71000000:226:66 +106500000:339:99 +1000000000:3:1 +10:5:0 +100:4:0 +1000:8:0 +10000:16:0 +999999999999:9:0 +999999999999:99:0 +999999999999:999:0 +999999999999:9999:0 +999999999999999:99999:0 +-9:+5:1 ++9:-5:-1 +-9:-5:-4 +-5:3:1 +-2:3:1 +4:3:1 +1:3:1 +-5:-3:-2 +-2:-3:-2 +4:-3:-2 +1:-3:-2 +4095:4095:0 +100041000510123:3:0 +152403346:12345:4321 +9:5:4 +# test shortcuts in Calc +# 1ex % 9 is always == 1, 1ex % 113 is != 1 for x = (4..9), 1ex % 10 = 0 +1234:9:1 +123456:9:3 +12345678:9:0 +1234567891:9:1 +123456789123:9:6 +12345678912345:9:6 +1234567891234567:9:1 +123456789123456789:9:0 +1234:10:4 +123456:10:6 +12345678:10:8 +1234567891:10:1 +123456789123:10:3 +12345678912345:10:5 +1234567891234567:10:7 +123456789123456789:10:9 +1234:113:104 +123456:113:60 +12345678:113:89 +1234567891:113:64 +123456789123:113:95 +12345678912345:113:53 +1234567891234567:113:56 +123456789123456789:113:39 +# bug in bmod() not modifying the variable in place +-629:5033:4404 +# bug in bmod() in Calc in the _div_use_div() shortcut code path, +# when X == X and X was big +111111111111111111111111111111:111111111111111111111111111111:0 +12345678901234567890:12345678901234567890:0 + +&bgcd +inf:12:NaN +-inf:12:NaN +12:inf:NaN +12:-inf:NaN +inf:inf:NaN +inf:-inf:NaN +-inf:-inf:NaN +abc:abc:NaN +abc:+0:NaN ++0:abc:NaN ++0:+0:0 ++0:+1:1 ++1:+0:1 ++1:+1:1 ++2:+3:1 ++3:+2:1 +-3:+2:1 +-3:-2:1 +-144:-60:12 +144:-60:12 +144:60:12 +100:625:25 +4096:81:1 +1034:804:2 +27:90:56:1 +27:90:54:9 + +&blcm +abc:abc:NaN +abc:+0:NaN ++0:abc:NaN +#+0:+0:0 ++1:+0:0 ++0:+1:0 ++27:+90:270 ++1034:+804:415668 + +&band +abc:abc:NaN +abc:0:NaN +0:abc:NaN +1:2:0 +3:2:2 ++8:+2:0 ++281474976710656:0:0 ++281474976710656:1:0 ++281474976710656:+281474976710656:281474976710656 +281474976710656:-1:281474976710656 +-2:-3:-4 +-1:-1:-1 +-6:-6:-6 +-7:-4:-8 +-7:4:0 +-4:7:4 +# negative argument is bitwise shorter than positive [perl #26559] +30:-3:28 +123:-1:123 +# equal arguments are treated special, so also do some test with unequal ones +0xFFFF:0xFFFF:0x0xFFFF +0xFFFFFF:0xFFFFFF:0x0xFFFFFF +0xFFFFFFFF:0xFFFFFFFF:0x0xFFFFFFFF +0xFFFFFFFFFF:0xFFFFFFFFFF:0x0xFFFFFFFFFF +0xFFFFFFFFFFFF:0xFFFFFFFFFFFF:0x0xFFFFFFFFFFFF +0xF0F0:0xF0F0:0x0xF0F0 +0x0F0F:0x0F0F:0x0x0F0F +0xF0F0F0:0xF0F0F0:0x0xF0F0F0 +0x0F0F0F:0x0F0F0F:0x0x0F0F0F +0xF0F0F0F0:0xF0F0F0F0:0x0xF0F0F0F0 +0x0F0F0F0F:0x0F0F0F0F:0x0x0F0F0F0F +0xF0F0F0F0F0:0xF0F0F0F0F0:0x0xF0F0F0F0F0 +0x0F0F0F0F0F:0x0F0F0F0F0F:0x0x0F0F0F0F0F +0xF0F0F0F0F0F0:0xF0F0F0F0F0F0:0x0xF0F0F0F0F0F0 +0x0F0F0F0F0F0F:0x0F0F0F0F0F0F:0x0x0F0F0F0F0F0F +0x1F0F0F0F0F0F:0x3F0F0F0F0F0F:0x0x1F0F0F0F0F0F + +&bior +abc:abc:NaN +abc:0:NaN +0:abc:NaN +1:2:3 ++8:+2:10 ++281474976710656:0:281474976710656 ++281474976710656:1:281474976710657 ++281474976710656:281474976710656:281474976710656 +-2:-3:-1 +-1:-1:-1 +-6:-6:-6 +-7:4:-3 +-4:7:-1 ++281474976710656:-1:-1 +30:-3:-1 +30:-4:-2 +300:-76:-68 +-76:300:-68 +# equal arguments are treated special, so also do some test with unequal ones +0xFFFF:0xFFFF:0x0xFFFF +0xFFFFFF:0xFFFFFF:0x0xFFFFFF +0xFFFFFFFF:0xFFFFFFFF:0x0xFFFFFFFF +0xFFFFFFFFFF:0xFFFFFFFFFF:0x0xFFFFFFFFFF +0xFFFFFFFFFFFF:0xFFFFFFFFFFFF:0x0xFFFFFFFFFFFF +0:0xFFFF:0x0xFFFF +0:0xFFFFFF:0x0xFFFFFF +0:0xFFFFFFFF:0x0xFFFFFFFF +0:0xFFFFFFFFFF:0x0xFFFFFFFFFF +0:0xFFFFFFFFFFFF:0x0xFFFFFFFFFFFF +0xFFFF:0:0x0xFFFF +0xFFFFFF:0:0x0xFFFFFF +0xFFFFFFFF:0:0x0xFFFFFFFF +0xFFFFFFFFFF:0:0x0xFFFFFFFFFF +0xFFFFFFFFFFFF:0:0x0xFFFFFFFFFFFF +0xF0F0:0xF0F0:0x0xF0F0 +0x0F0F:0x0F0F:0x0x0F0F +0xF0F0:0x0F0F:0x0xFFFF +0xF0F0F0:0xF0F0F0:0x0xF0F0F0 +0x0F0F0F:0x0F0F0F:0x0x0F0F0F +0x0F0F0F:0xF0F0F0:0x0xFFFFFF +0xF0F0F0F0:0xF0F0F0F0:0x0xF0F0F0F0 +0x0F0F0F0F:0x0F0F0F0F:0x0x0F0F0F0F +0x0F0F0F0F:0xF0F0F0F0:0x0xFFFFFFFF +0xF0F0F0F0F0:0xF0F0F0F0F0:0x0xF0F0F0F0F0 +0x0F0F0F0F0F:0x0F0F0F0F0F:0x0x0F0F0F0F0F +0x0F0F0F0F0F:0xF0F0F0F0F0:0x0xFFFFFFFFFF +0xF0F0F0F0F0F0:0xF0F0F0F0F0F0:0x0xF0F0F0F0F0F0 +0x0F0F0F0F0F0F:0x0F0F0F0F0F0F:0x0x0F0F0F0F0F0F +0x0F0F0F0F0F0F:0xF0F0F0F0F0F0:0x0xFFFFFFFFFFFF +0x1F0F0F0F0F0F:0xF0F0F0F0F0F0:0x0xFFFFFFFFFFFF + +&bxor +abc:abc:NaN +abc:0:NaN +0:abc:NaN +1:2:3 ++8:+2:10 ++281474976710656:0:281474976710656 ++281474976710656:1:281474976710657 ++281474976710656:281474976710656:0 +-2:-3:3 +-1:-1:0 +-6:-6:0 +-7:4:-3 +-4:7:-5 +4:-7:-3 +-4:-7:5 +30:-3:-29 +30:-4:-30 +300:-76:-360 +-76:300:-360 +# equal arguments are treated special, so also do some test with unequal ones +0xFFFF:0xFFFF:0 +0xFFFFFF:0xFFFFFF:0 +0xFFFFFFFF:0xFFFFFFFF:0 +0xFFFFFFFFFF:0xFFFFFFFFFF:0 +0xFFFFFFFFFFFF:0xFFFFFFFFFFFF:0 +0:0xFFFF:0x0xFFFF +0:0xFFFFFF:0x0xFFFFFF +0:0xFFFFFFFF:0x0xFFFFFFFF +0:0xFFFFFFFFFF:0x0xFFFFFFFFFF +0:0xFFFFFFFFFFFF:0x0xFFFFFFFFFFFF +0xFFFF:0:0x0xFFFF +0xFFFFFF:0:0x0xFFFFFF +0xFFFFFFFF:0:0x0xFFFFFFFF +0xFFFFFFFFFF:0:0x0xFFFFFFFFFF +0xFFFFFFFFFFFF:0:0x0xFFFFFFFFFFFF +0xF0F0:0xF0F0:0 +0x0F0F:0x0F0F:0 +0xF0F0:0x0F0F:0x0xFFFF +0xF0F0F0:0xF0F0F0:0 +0x0F0F0F:0x0F0F0F:0 +0x0F0F0F:0xF0F0F0:0x0xFFFFFF +0xF0F0F0F0:0xF0F0F0F0:0 +0x0F0F0F0F:0x0F0F0F0F:0 +0x0F0F0F0F:0xF0F0F0F0:0x0xFFFFFFFF +0xF0F0F0F0F0:0xF0F0F0F0F0:0 +0x0F0F0F0F0F:0x0F0F0F0F0F:0 +0x0F0F0F0F0F:0xF0F0F0F0F0:0x0xFFFFFFFFFF +0xF0F0F0F0F0F0:0xF0F0F0F0F0F0:0 +0x0F0F0F0F0F0F:0x0F0F0F0F0F0F:0 +0x0F0F0F0F0F0F:0xF0F0F0F0F0F0:0x0xFFFFFFFFFFFF + +&bnot +abc:NaN ++0:-1 ++8:-9 ++281474976710656:-281474976710657 +-1:0 +-2:1 +-12:11 + +&digit +0:0:0 +12:0:2 +12:1:1 +123:0:3 +123:1:2 +123:2:1 +123:-1:1 +123:-2:2 +123:-3:3 +123456:0:6 +123456:1:5 +123456:2:4 +123456:3:3 +123456:4:2 +123456:5:1 +123456:-1:1 +123456:-2:2 +123456:-3:3 +100000:-3:0 +100000:0:0 +100000:1:0 + +&mantissa +abc:NaN +1e4:1 +2e0:2 +123:123 +-1:-1 +-2:-2 ++inf:inf +-inf:-inf + +&exponent +abc:NaN +1e4:4 +2e0:0 +123:0 +-1:0 +-2:0 +0:0 ++inf:inf +-inf:inf + +&parts +abc:NaN,NaN +1e4:1,4 +2e0:2,0 +123:123,0 +-1:-1,0 +-2:-2,0 +0:0,0 ++inf:inf,inf +-inf:-inf,inf + +&bfac +-1:NaN +NaNfac:NaN ++inf:inf +-inf:NaN +0:1 +1:1 +2:2 +3:6 +4:24 +5:120 +6:720 +7:5040 +8:40320 +9:362880 +10:3628800 +11:39916800 +12:479001600 +20:2432902008176640000 +22:1124000727777607680000 +69:171122452428141311372468338881272839092270544893520369393648040923257279754140647424000000000000000 + +&bpow +abc:12:NaN +12:abc:NaN +0:0:1 +0:1:0 +0:2:0 +0:-1:inf +0:-2:inf +1:0:1 +1:1:1 +1:2:1 +1:3:1 +1:-1:1 +1:-2:1 +1:-3:1 +2:0:1 +2:1:2 +2:2:4 +2:3:8 +3:3:27 +-2:2:4 +-2:3:-8 +-2:4:16 +-2:5:-32 +2:-1:NaN +-2:-1:NaN +2:-2:NaN +-2:-2:NaN +# inf tests ++inf:1234500012:inf +-inf:1234500012:inf +-inf:1234500013:-inf ++inf:-12345000123:inf +-inf:-12345000123:-inf +# -inf * -inf = inf +-inf:2:inf +-inf:0:NaN +-inf:-1:0 +-inf:inf:NaN +2:inf:inf +2:-inf:0 +0:inf:0 +0:-inf:inf +-1:-inf:NaN +-1:inf:NaN +-2:inf:NaN +-2:-inf:0 +NaN:inf:NaN +NaN:-inf:NaN +-inf:NaN:NaN +inf:NaN:NaN +inf:-inf:NaN +1:inf:1 +1:-inf:1 +# 1 ** -x => 1 / (1 ** x) +-1:0:1 +-2:0:1 +-1:1:-1 +-1:2:1 +-1:3:-1 +-1:4:1 +-1:5:-1 +-1:-1:-1 +-1:-2:1 +-1:-3:-1 +-1:-4:1 +10:2:100 +10:3:1000 +10:4:10000 +10:5:100000 +10:6:1000000 +10:7:10000000 +10:8:100000000 +10:9:1000000000 +10:20:100000000000000000000 +123456:2:15241383936 +-2:2:4 +-2:3:-8 +-2:4:16 +-2:5:-32 +-3:2:9 +-3:3:-27 +-3:4:81 +-3:5:-243 + +&length +100:3 +10:2 +1:1 +0:1 +12345:5 +10000000000000000:17 +-123:3 +215960156869840440586892398248:30 + +&broot +# sqrt() ++0:2:0 ++1:2:1 +-1:2:NaN +# -$x ** (1/2) => -$y, but not in broot() +-123:2:NaN ++inf:2:inf +-inf:2:NaN +2:2:1 +-2:2:NaN +4:2:2 +9:2:3 +16:2:4 +100:2:10 +123:2:11 +15241:2:123 +144:2:12 +12:2:3 +# invalid ones +1:NaN:NaN +-1:NaN:NaN +0:NaN:NaN +-inf:NaN:NaN ++inf:NaN:NaN +NaN:0:NaN +NaN:2:NaN +NaN:inf:NaN +NaN:inf:NaN +12:-inf:NaN +12:inf:NaN ++0:0:NaN ++1:0:NaN +-1:0:NaN +-2:0:NaN +-123.45:0:NaN ++inf:0:NaN +12:1:12 +-12:1:NaN +8:-1:NaN +-8:-1:NaN +# cubic root +8:3:2 +-8:3:NaN +# fourths root +16:4:2 +81:4:3 +# 2 ** 64 +18446744073709551616:4:65536 +18446744073709551616:8:256 +18446744073709551616:16:16 +18446744073709551616:32:4 +18446744073709551616:64:2 +18446744073709551616:128:1 +# 213 ** 15 +84274086103068221283760416414557757:15:213 + +# see t/bigroot.t for more tests +&bsqrt +145:12 +144:12 +143:11 +16:4 +170:13 +169:13 +168:12 +4:2 +3:1 +2:1 +9:3 +12:3 +256:16 +100000000:10000 +4000000000000:2000000 +152399026:12345 +152399025:12345 +152399024:12344 +# 2 ** 64 => 2 ** 32 +18446744073709551616:4294967296 +84274086103068221283760416414557757:290299993288095377 +1:1 +0:0 +-2:NaN +-123:NaN +Nan:NaN ++inf:inf +-inf:NaN + +# see t/biglog.t for more tests +&bexp +NaN:NaN +inf:inf +1:2 +2:7 + +&batan2 +NaN:1:10:NaN +NaN:NaN:10:NaN +1:NaN:10:NaN +inf:1:14:1 +-inf:1:14:-1 +0:-inf:14:3 +-1:-inf:14:-3 +1:-inf:14:3 +0:inf:14:0 +inf:-inf:14:2 +-inf:-inf:14:-2 +# +- 0.78.... +inf:+inf:14:0 +-inf:+inf:14:0 +1:5:13:0 +1:5:14:0 +0:0:10:0 +0:1:14:0 +0:2:14:0 +1:0:14:1 +5:0:14:1 +-1:0:11:-1 +-2:0:77:-1 +2:0:77:1 +-1:5:14:0 +1:5:14:0 +-1:8:14:0 +1:8:14:0 +-1:1:14:0 + +&bpi +77:3 ++0:3 +11:3 + +# see t/bignok.t for more tests +&bnok ++inf:10:inf +NaN:NaN:NaN +NaN:1:NaN +1:NaN:NaN +1:1:1 +# k > n +1:2:0 +2:3:0 +# k < 0 +1:-2:0 +# 7 over 3 = 35 +7:3:35 +7:6:7 +100:90:17310309456440 +100:95:75287520 +2:0:1 +7:0:1 +2:1:2 + +&bround +$round_mode("trunc") +0:12:0 +NaNbround:12:NaN ++inf:12:inf +-inf:12:-inf +1234:0:1234 +1234:2:1200 +123456:4:123400 +123456:5:123450 +123456:6:123456 ++10123456789:5:10123000000 +-10123456789:5:-10123000000 ++10123456789:9:10123456700 +-10123456789:9:-10123456700 ++101234500:6:101234000 +-101234500:6:-101234000 +#+101234500:-4:101234000 +#-101234500:-4:-101234000 +$round_mode("zero") ++20123456789:5:20123000000 +-20123456789:5:-20123000000 ++20123456789:9:20123456800 +-20123456789:9:-20123456800 ++201234500:6:201234000 +-201234500:6:-201234000 +#+201234500:-4:201234000 +#-201234500:-4:-201234000 ++12345000:4:12340000 +-12345000:4:-12340000 +$round_mode("+inf") ++30123456789:5:30123000000 +-30123456789:5:-30123000000 ++30123456789:9:30123456800 +-30123456789:9:-30123456800 ++301234500:6:301235000 +-301234500:6:-301234000 +#+301234500:-4:301235000 +#-301234500:-4:-301234000 ++12345000:4:12350000 +-12345000:4:-12340000 +$round_mode("-inf") ++40123456789:5:40123000000 +-40123456789:5:-40123000000 ++40123456789:9:40123456800 +-40123456789:9:-40123456800 ++401234500:6:401234000 ++401234500:6:401234000 +#-401234500:-4:-401235000 +#-401234500:-4:-401235000 ++12345000:4:12340000 +-12345000:4:-12350000 +$round_mode("odd") ++50123456789:5:50123000000 +-50123456789:5:-50123000000 ++50123456789:9:50123456800 +-50123456789:9:-50123456800 ++501234500:6:501235000 +-501234500:6:-501235000 +#+501234500:-4:501235000 +#-501234500:-4:-501235000 ++12345000:4:12350000 +-12345000:4:-12350000 +$round_mode("even") ++60123456789:5:60123000000 +-60123456789:5:-60123000000 ++60123456789:9:60123456800 +-60123456789:9:-60123456800 ++601234500:6:601234000 +-601234500:6:-601234000 +#+601234500:-4:601234000 +#-601234500:-4:-601234000 +#-601234500:-9:0 +#-501234500:-9:0 +#-601234500:-8:0 +#-501234500:-8:0 ++1234567:7:1234567 ++1234567:6:1234570 ++12345000:4:12340000 +-12345000:4:-12340000 +$round_mode("common") ++60123456789:5:60123000000 ++60123199999:5:60123000000 ++60123299999:5:60123000000 ++60123399999:5:60123000000 ++60123499999:5:60123000000 ++60123500000:5:60124000000 ++60123600000:5:60124000000 ++60123700000:5:60124000000 ++60123800000:5:60124000000 ++60123900000:5:60124000000 +-60123456789:5:-60123000000 +-60123199999:5:-60123000000 +-60123299999:5:-60123000000 +-60123399999:5:-60123000000 +-60123499999:5:-60123000000 +-60123500000:5:-60124000000 +-60123600000:5:-60124000000 +-60123700000:5:-60124000000 +-60123800000:5:-60124000000 +-60123900000:5:-60124000000 + +&is_zero +0:1 +NaNzero:0 ++inf:0 +-inf:0 +123:0 +-1:0 +1:0 + +&is_one +0:0 +NaNone:0 ++inf:0 +-inf:0 +1:1 +2:0 +-1:0 +-2:0 + +# floor, ceil, and int are pretty pointless in integer space, but play safe +&bfloor +0:0 +NaNfloor:NaN ++inf:inf +-inf:-inf +-1:-1 +-2:-2 +2:2 +3:3 +abc:NaN + +&bceil +NaNceil:NaN ++inf:inf +-inf:-inf +0:0 +-1:-1 +-2:-2 +2:2 +3:3 +abc:NaN + +&bint +NaN:NaN ++inf:inf +-inf:-inf +0:0 +-1:-1 +-2:-2 +2:2 +3:3 + +&as_hex +128:0x80 +-128:-0x80 +0:0x0 +-0:0x0 +1:0x1 +0x123456789123456789:0x123456789123456789 ++inf:inf +-inf:-inf +NaNas_hex:NaN + +&as_bin +128:0b10000000 +-128:-0b10000000 +0:0b0 +-0:0b0 +1:0b1 +0b1010111101010101010110110110110110101:0b1010111101010101010110110110110110101 +0x123456789123456789:0b100100011010001010110011110001001000100100011010001010110011110001001 ++inf:inf +-inf:-inf +NaNas_bin:NaN + +&as_oct +128:0200 +-128:-0200 +0:00 +-0:00 +1:01 +0b1010111101010101010110110110110110101:01275252666665 +0x123456789123456789:044321263611044321263611 ++inf:inf +-inf:-inf +NaNas_oct:NaN + +# overloaded functions +&log +-1:NaN +0:-inf +1:0 +2:0 +3:1 +123456789:18 +1234567890987654321:41 +-inf:inf +inf:inf +NaN:NaN + +&exp + +&sin + +&cos + +&atan2 + +&int + +&neg + +&abs + +&sqrt diff --git a/t/mbi_ltm_01load.t b/t/mbi_ltm_01load.t new file mode 100644 index 0000000..f4fccb4 --- /dev/null +++ b/t/mbi_ltm_01load.t @@ -0,0 +1,13 @@ +#!perl + +use strict; # restrict unsafe constructs +use warnings; # enable optional warnings + +use Test::More tests => 2; + +BEGIN { + use_ok('Math::BigInt::LTM'); + use_ok('Math::BigInt'); # Math::BigInt is required for the tests +}; + +diag "Math::BigInt VERSION=$Math::BigInt::VERSION\n"; \ No newline at end of file diff --git a/t/mbi_ltm_bigfltpm.t b/t/mbi_ltm_bigfltpm.t new file mode 100644 index 0000000..f63c98c --- /dev/null +++ b/t/mbi_ltm_bigfltpm.t @@ -0,0 +1,41 @@ +#!perl + +use strict; +use warnings; + +use Test::More; + +BEGIN { + plan skip_all => "requires Math::BigFloat 1.999715+" unless eval { require Math::BigFloat && eval($Math::BigFloat::VERSION) >= 1.999715 }; + plan tests => 2409 # tests in require'd file + + 5; # tests in this file +} + +use Math::BigInt lib => 'LTM'; +use Math::BigFloat; + +our $CLASS = "Math::BigFloat"; +our $CALC = "Math::BigInt::LTM"; # backend + +is($CLASS->config()->{class}, $CLASS, "$CLASS->config()->{class}"); +is($CLASS->config()->{with}, $CALC, "$CLASS->config()->{with}"); + +# bug #17447: Can't call method Math::BigFloat->bsub, not a valid method +my $c = Math::BigFloat->new('123.3'); +is($c->bsub(123), '0.3', + qq|\$c = Math::BigFloat -> new("123.3"); \$y = \$c -> bsub("123")|); + +# Bug until Math::BigInt v1.86, the scale wasn't treated as a scalar: +$c = Math::BigFloat->new('0.008'); +my $d = Math::BigFloat->new(3); +my $e = $c->bdiv(Math::BigFloat->new(3), $d); + +is($e, '0.00267', '0.008 / 3 = 0.0027'); + +SKIP: { + skip("skipping test which is not for this backend", 1) + unless $CALC eq 'Math::BigInt::Calc'; + is(ref($e->{_e}->[0]), '', '$e->{_e}->[0] is a scalar'); +} + +require './t/mbi_ltm/bigfltpm.inc'; # all tests here for sharing diff --git a/t/mbi_ltm_bigintg.t b/t/mbi_ltm_bigintg.t new file mode 100644 index 0000000..afeb4f0 --- /dev/null +++ b/t/mbi_ltm_bigintg.t @@ -0,0 +1,565 @@ +#!/usr/bin/perl -w + +use strict; +use Test; + +BEGIN { + $| = 1; + chdir 't' if -d 't'; + unshift @INC, '../lib'; # for running manually + unshift @INC, '../blib/arch'; # for running manually + plan tests => 356; +} + +use Math::BigInt::LTM; + +# testing of Math::BigInt::LTM + +my $C = 'Math::BigInt::LTM'; # pass classname to sub's + +# _new and _str +my $x = $C->_new("123"); +my $y = $C->_new("321"); +ok(ref($x), 'Math::BigInt::LTM'); +ok($C->_str($x), 123); +ok($C->_str($y), 321); + +############################################################################### +# _set + +my $b = $C->_new("123"); +$C->_set($b, 12); +ok($C->_str($b), 12); + +############################################################################### +# _add, _sub, _mul, _div +ok($C->_str($C->_add($x, $y)), 444); +ok($C->_str($C->_sub($x, $y)), 123); +ok($C->_str($x), 123); +ok($C->_str($y), 321); +ok($C->_str($C->_mul($x, $y)), 39483); +ok($C->_str(scalar $C->_div($x, $y)), 123); + +# check that mul/div doesn't change $y +# and returns the same reference, not something new + +ok($C->_str($C->_mul($x, $y)), 39483); +ok($C->_str($x), 39483); +ok($C->_str($y), 321); + +ok($C->_str(scalar $C->_div($x, $y)), 123); +ok($C->_str($x), 123); +ok($C->_str($y), 321); + +$x = $C->_new("39483"); +my ($x1, $r1) = $C->_div($x, $y); +ok("$x1", "$x"); +$C->_inc($x1); +ok("$x1", "$x"); +ok($C->_str($r1), '0'); + +# check that sub modifies the right argument: + +$x = $C->_new("221"); +$y = $C->_new("444"); + +$x = $C->_sub($y, $x, 1); # 444 - 221 => 223 + +ok($C->_str($x), 223); +ok($C->_str($y), 444); + +$x = $C->_new("444"); +$y = $C->_new("221"); + +ok($C->_str($C->_sub($x, $y)), 223); # 444 - 221 => 223 + +ok($C->_str($x), 223); +ok($C->_str($y), 221); + +############################################################################### + +$x = $C->_new("39483"); # reset +$y = $C->_new("321"); # reset + +my $z = $C->_new("2"); +ok($C->_str($C->_add($x, $z)), 39485); +my ($re, $rr) = $C->_div($x, $y); + +ok($C->_str($re), 123); +ok($C->_str($rr), 2); + +############################################################################## +# is_zero, _is_one, _one, _zero + +ok($C->_is_zero($x)||0, 0); +ok($C->_is_one($x)||0, 0); + +ok($C->_str($C->_zero()), "0"); +ok($C->_str($C->_one()), "1"); + +############################################################################## +# _two() and _ten() + +ok($C->_str($C->_two()), "2"); +ok($C->_str($C->_ten()), "10"); +ok($C->_is_ten($C->_two()), 0); +ok($C->_is_two($C->_two()), 1); +ok($C->_is_ten($C->_ten()), 1); +ok($C->_is_two($C->_ten()), 0); + +ok($C->_is_one($C->_one()), 1); +ok($C->_is_one($C->_two()), 0); +ok($C->_is_one($C->_ten()), 0); + +ok($C->_is_one($C->_zero()) || 0, 0); + +ok($C->_is_zero($C->_zero()), 1); + +ok($C->_is_zero($C->_one()) || 0, 0); + +############################################################################### +# is_odd, is_even + +ok($C->_is_odd($C->_one()), 1); +ok($C->_is_odd($C->_zero())||0, 0); +ok($C->_is_even($C->_one()) || 0, 0); +ok($C->_is_even($C->_zero()), 1); + +sub _check_len { + my ($y, $m) = @_; + + my $len = length($y); + $x = $C->_new($y); + if ($m eq '_len') { + ok($C->$m($x), $len); + } else { + # equal or at most one bigger + print STDERR "# $len $y". $C->$m($x). "\n" unless + ok($len >= $C->$m($x), 1); + } +} + +# _len and _alen +for my $m (qw/_len _alen/) { + _check_len("1", $m); + _check_len("12", $m); + _check_len("123", $m); + _check_len("1234", $m); + _check_len("12345", $m); + _check_len("123456", $m); + _check_len("1234567", $m); + _check_len("12345678", $m); + _check_len("123456789", $m); + _check_len("1234567890", $m); + _check_len("7", $m); + _check_len("8", $m); + _check_len("9", $m); + _check_len("10", $m); + _check_len("11", $m); + _check_len("21", $m); + _check_len("321", $m); + _check_len("320", $m); + _check_len("4321", $m); + _check_len("54321", $m); + _check_len("654321", $m); + _check_len("7654321", $m); + _check_len("7654321", $m); + _check_len("87654321", $m); + _check_len("987654321", $m); + _check_len("9876543219876543210", $m); + _check_len("1234567890" x 10, $m); + _check_len("1234567890" x 100, $m); + + for (my $i = 1; $i < 9; $i++) { + my $a = "$i" . '0' x ($i-1); + _check_len($a, $m); + } +} + +############################################################################### +# _digit + +$x = $C->_new("123456789"); +ok($C->_digit($x, 0), 9); +ok($C->_digit($x, 1), 8); +ok($C->_digit($x, 2), 7); +ok($C->_digit($x, -1), 1); +ok($C->_digit($x, -2), 2); +ok($C->_digit($x, -3), 3); + +############################################################################### +# _copy + +foreach (qw/ 1 12 123 1234 12345 123456 1234567 12345678 123456789/) { + $x = $C->_new("$_"); + ok($C->_str($C->_copy($x)), "$_"); + ok($C->_str($x), "$_"); # did _copy destroy original x? +} + +############################################################################### +# _zeros + +$x = $C->_new("1256000000"); +ok($C->_zeros($x), 6); + +$x = $C->_new("152"); +ok($C->_zeros($x), 0); + +$x = $C->_new("123000"); +ok($C->_zeros($x), 3); + +$x = $C->_new("123001"); +ok($C->_zeros($x), 0); + +$x = $C->_new("1"); +ok($C->_zeros($x), 0); + +$x = $C->_new("8"); +ok($C->_zeros($x), 0); + +$x = $C->_new("10"); +ok($C->_zeros($x), 1); + +$x = $C->_new("11"); +ok($C->_zeros($x), 0); + +$x = $C->_new("0"); +ok($C->_zeros($x), 0); + +############################################################################### +# _lsft, _rsft + +$x = $C->_new("10"); +$y = $C->_new("3"); +ok($C->_str($C->_lsft($x, $y, 10)), 10000); +$x = $C->_new("20"); +$y = $C->_new("3"); +ok($C->_str($C->_lsft($x, $y, 10)), 20000); + +$x = $C->_new("128"); +$y = $C->_new("4"); +ok($C->_str($C->_lsft($x, $y, 2)), 128 << 4); + +$x = $C->_new("1000"); +$y = $C->_new("3"); +ok($C->_str($C->_rsft($x, $y, 10)), 1); +$x = $C->_new("20000"); +$y = $C->_new("3"); +ok($C->_str($C->_rsft($x, $y, 10)), 20); +$x = $C->_new("256"); +$y = $C->_new("4"); +ok($C->_str($C->_rsft($x, $y, 2)), 256 >> 4); + +$x = $C->_new("6411906467305339182857313397200584952398"); +$y = $C->_new("45"); +ok($C->_str($C->_rsft($x, $y, 10)), 0); + +############################################################################### +# _acmp + +$x = $C->_new("123456789"); +$y = $C->_new("987654321"); +ok($C->_acmp($x, $y), -1); +ok($C->_acmp($y, $x), 1); +ok($C->_acmp($x, $x), 0); +ok($C->_acmp($y, $y), 0); +$x = $C->_new("12"); +$y = $C->_new("12"); +ok($C->_acmp($x, $y), 0); +$x = $C->_new("21"); +ok($C->_acmp($x, $y), 1); +ok($C->_acmp($y, $x), -1); +$x = $C->_new("123456789"); +$y = $C->_new("1987654321"); +ok($C->_acmp($x, $y), -1); +ok($C->_acmp($y, $x), +1); + +$x = $C->_new("1234567890123456789"); +$y = $C->_new("987654321012345678"); +ok($C->_acmp($x, $y), 1); +ok($C->_acmp($y, $x), -1); +ok($C->_acmp($x, $x), 0); +ok($C->_acmp($y, $y), 0); + +$x = $C->_new("1234"); +$y = $C->_new("987654321012345678"); +ok($C->_acmp($x, $y), -1); +ok($C->_acmp($y, $x), 1); +ok($C->_acmp($x, $x), 0); +ok($C->_acmp($y, $y), 0); + +############################################################################### +# _modinv + +$x = $C->_new("8"); +$y = $C->_new("5033"); +my ($xmod, $sign) = $C->_modinv($x, $y); +ok($C->_str($xmod), '4404'); + # (4404 * 8) % 5033 = 1 +ok($sign, '+'); + +############################################################################### +# _div + +$x = $C->_new("3333"); +$y = $C->_new("1111"); +ok($C->_str(scalar $C->_div($x, $y)), 3); +$x = $C->_new("33333"); +$y = $C->_new("1111"); +($x, $y) = $C->_div($x, $y); +ok($C->_str($x), 30); +ok($C->_str($y), 3); +$x = $C->_new("123"); +$y = $C->_new("1111"); +($x, $y) = $C->_div($x, $y); +ok($C->_str($x), 0); +ok($C->_str($y), 123); + +############################################################################### +# _num + +foreach (qw/1 12 123 1234 12345 1234567 12345678 123456789 1234567890/) { + $x = $C->_new("$_"); + ok(ref($x)||'', 'Math::BigInt::LTM'); + ok($C->_str($x), "$_"); + $x = $C->_num($x); + ok(ref($x)||'', ''); + ok($x, $_); +} + +############################################################################### +# _sqrt + +$x = $C->_new("144"); +ok($C->_str($C->_sqrt($x)), '12'); +$x = $C->_new("144000000000000"); +ok($C->_str($C->_sqrt($x)), '12000000'); + +############################################################################### +# _root + +$x = $C->_new("81"); +my $n = $C->_new("3"); +ok($C->_str($C->_root($x, $n)), '4'); # 4*4*4 = 64, 5*5*5 = 125 + +$x = $C->_new("81"); +$n = $C->_new("4"); +ok($C->_str($C->_root($x, $n)), '3'); # 3*3*3*3 == 81 + +############################################################################### +# _pow (and _root) + +$x = $C->_new("0"); +$n = $C->_new("3"); +ok($C->_str($C->_pow($x, $n)), 0); # 0 ** y => 0 + +$x = $C->_new("3"); +$n = $C->_new("0"); +ok($C->_str($C->_pow($x, $n)), 1); # x ** 0 => 1 + +$x = $C->_new("1"); +$n = $C->_new("3"); +ok($C->_str($C->_pow($x, $n)), 1); # 1 ** y => 1 + +$x = $C->_new("5"); +$n = $C->_new("1"); +ok($C->_str($C->_pow($x, $n)), 5); # x ** 1 => x + +$x = $C->_new("81"); +$n = $C->_new("3"); + +ok($C->_str($C->_pow($x, $n)), 81 ** 3); # 81 ** 3 == 531441 + +ok($C->_str($C->_root($x, $n)), 81); + +$x = $C->_new("81"); +ok($C->_str($C->_pow($x, $n)), 81 ** 3); +ok($C->_str($C->_pow($x, $n)), '150094635296999121'); # 531441 ** 3 == + +ok($C->_str($C->_root($x, $n)), '531441'); +ok($C->_str($C->_root($x, $n)), '81'); + +$x = $C->_new("81"); +$n = $C->_new("14"); +ok($C->_str($C->_pow($x, $n)), '523347633027360537213511521'); +ok($C->_str($C->_root($x, $n)), '81'); + +$x = $C->_new("523347633027360537213511520"); +ok($C->_str($C->_root($x, $n)), '80'); + +$x = $C->_new("523347633027360537213511522"); +ok($C->_str($C->_root($x, $n)), '81'); + +my $res = [ qw/ 9 31 99 316 999 3162 9999/ ]; + +# 99 ** 2 = 9801, 999 ** 2 = 998001 etc +for my $i (2 .. 9) { + $x = '9' x $i; + $x = $C->_new($x); + $n = $C->_new("2"); + my $rc = '9' x ($i-1). '8' . '0' x ($i-1) . '1'; + print "# _pow(", '9' x $i, ", 2) \n" + unless ok($C->_str($C->_pow($x, $n)), $rc); + + if ($i <= 7) { + $x = '9' x $i; + $x = $C->_new($x); + $n = '9' x $i; + $n = $C->_new($n); + print "# _root(", '9' x $i, ", ", 9 x $i, ") \n" + unless ok($C->_str($C->_root($x, $n)), '1'); + + $x = '9' x $i; + $x = $C->_new($x); + $n = $C->_new("2"); + print "# _root(", '9' x $i, ", ", 9 x $i, ") \n" + unless ok($C->_str($C->_root($x, $n)), $res->[$i-2]); + } +} + +############################################################################## +# _fac + +$x = $C->_new("0"); ok($C->_str($C->_fac($x)), '1'); +$x = $C->_new("1"); ok($C->_str($C->_fac($x)), '1'); +$x = $C->_new("2"); ok($C->_str($C->_fac($x)), '2'); +$x = $C->_new("3"); ok($C->_str($C->_fac($x)), '6'); +$x = $C->_new("4"); ok($C->_str($C->_fac($x)), '24'); +$x = $C->_new("5"); ok($C->_str($C->_fac($x)), '120'); +$x = $C->_new("10"); ok($C->_str($C->_fac($x)), '3628800'); +$x = $C->_new("11"); ok($C->_str($C->_fac($x)), '39916800'); +$x = $C->_new("12"); ok($C->_str($C->_fac($x)), '479001600'); +$x = $C->_new("13"); ok($C->_str($C->_fac($x)), '6227020800'); + +# test that _fac modifes $x in place for small arguments + +$x = $C->_new("3"); $C->_fac($x); ok($C->_str($x), '6'); +$x = $C->_new("13"); $C->_fac($x); ok($C->_str($x), '6227020800'); + +############################################################################## +# _inc and _dec + +foreach (qw/1 11 121 1231 12341 1234561 12345671 123456781 1234567891/) { + $x = $C->_new("$_"); + $C->_inc($x); + print "# \$x = ", $C->_str($x), "\n" + unless ok($C->_str($x), substr($_, 0, length($_)-1) . '2'); + $C->_dec($x); + ok($C->_str($x), $_); +} + +foreach (qw/19 119 1219 12319 1234519 12345619 123456719 1234567819/) { + $x = $C->_new("$_"); + $C->_inc($x); + print "# \$x = ", $C->_str($x), "\n" + unless ok($C->_str($x), substr($_, 0, length($_)-2) . '20'); + $C->_dec($x); + ok($C->_str($x), $_); +} + +foreach (qw/999 9999 99999 9999999 99999999 999999999 9999999999 99999999999/) { + $x = $C->_new("$_"); + $C->_inc($x); + print "# \$x = ", $C->_str($x), "\n" + unless ok($C->_str($x), '1' . '0' x (length($_))); + $C->_dec($x); + ok($C->_str($x), $_); +} + +$x = $C->_new("1000"); +$C->_inc($x); +ok($C->_str($x), '1001'); +$C->_dec($x); +ok($C->_str($x), '1000'); + +############################################################################### +# _log_int (test handling of plain scalar as base, bug up to v1.17) + +$x = $C->_new("81"); + +my ($r, $exact) = $C->_log_int($x, $C->_new("3")); +ok($C->_str($r), '4'); +ok($C->_str($x) eq '81' || $C->_str($x) eq '4'); +ok($exact, 1); + +$x = $C->_new("81"); + +($r, $exact) = $C->_log_int($x, 3); +ok($C->_str($r), '4'); +ok($C->_str($x) eq '81' || $C->_str($x) eq '4'); +ok($exact, 1); + +############################################################################### +# _mod + +$x = $C->_new("1000"); +$y = $C->_new("3"); +ok($C->_str(scalar $C->_mod($x, $y)), 1); +$x = $C->_new("1000"); +$y = $C->_new("2"); +ok($C->_str(scalar $C->_mod($x, $y)), 0); + +############################################################################### +# _and, _or, _xor + +$x = $C->_new("5"); +$y = $C->_new("2"); +ok($C->_str(scalar $C->_xor($x, $y)), 7); +$x = $C->_new("5"); +$y = $C->_new("2"); +ok($C->_str(scalar $C->_or($x, $y)), 7); +$x = $C->_new("5"); +$y = $C->_new("3"); +ok($C->_str(scalar $C->_and($x, $y)), 1); + +############################################################################### +# _from_hex, _from_bin + +ok($C->_str($C->_from_hex("0xFf")), 255); +ok($C->_str($C->_from_bin("0b10101011")), 160+11); + +############################################################################### +# _as_hex, _as_bin + +ok($C->_str($C->_from_hex($C->_as_hex($C->_new("128")))), 128); +ok($C->_str($C->_from_bin($C->_as_bin($C->_new("128")))), 128); +ok($C->_str($C->_from_hex($C->_as_hex($C->_new("0")))), 0); +ok($C->_str($C->_from_bin($C->_as_bin($C->_new("0")))), 0); +ok($C->_as_hex($C->_new("0")), '0x0'); +ok($C->_as_bin($C->_new("0")), '0b0'); +ok($C->_as_hex($C->_new("12")), '0xc'); +ok($C->_as_bin($C->_new("12")), '0b1100'); + +############################################################################### +# _from_oct + +$x = $C->_from_oct("001"); ok($C->_str($x), '1'); +$x = $C->_from_oct("07"); ok($C->_str($x), '7'); +$x = $C->_from_oct("077"); ok($C->_str($x), '63'); +$x = $C->_from_oct("07654321"); ok($C->_str($x), '2054353'); + +############################################################################### +# _as_oct +$x = $C->_new("2054353"); ok($C->_as_oct($x), '07654321'); +$x = $C->_new("63"); ok($C->_as_oct($x), '077'); +$x = $C->_new("0"); ok($C->_as_oct($x), '00'); + +############################################################################### +# _1ex + +ok($C->_str($C->_1ex(0)), "1"); +ok($C->_str($C->_1ex(1)), "10"); +ok($C->_str($C->_1ex(2)), "100"); +ok($C->_str($C->_1ex(12)), "1000000000000"); +ok($C->_str($C->_1ex(16)), "10000000000000000"); + +############################################################################### +# _check + +$x = $C->_new("123456789"); +ok($C->_check($x), 0); +ok($C->_check(123), '123 is not a reference'); + +# done + +1; diff --git a/t/mbi_ltm_bigintpm.t b/t/mbi_ltm_bigintpm.t new file mode 100644 index 0000000..ebb7582 --- /dev/null +++ b/t/mbi_ltm_bigintpm.t @@ -0,0 +1,52 @@ +#!perl + +use strict; +use warnings; + +use Test::More; + +BEGIN { + plan skip_all => "requires Math::BigInt 1.999712+" unless eval { require Math::BigInt && eval($Math::BigInt::VERSION) >= 1.999712 }; + plan tests => 3722 # tests in require'd file + + 6; # tests in this file +} + +use Math::BigInt lib => 'LTM'; + +our ($CLASS, $CALC); +$CLASS = "Math::BigInt"; +$CALC = "Math::BigInt::LTM"; + +my $x; + +############################################################################# +# from_hex(), from_bin() and from_oct() tests + +$x = Math::BigInt->from_hex('0xcafe'); +is($x, "51966", + qq|Math::BigInt->from_hex("0xcafe")|); + +$x = Math::BigInt->from_hex('0xcafebabedead'); +is($x, "223195403574957", + qq|Math::BigInt->from_hex("0xcafebabedead")|); + +$x = Math::BigInt->from_bin('0b1001'); +is($x, "9", + qq|Math::BigInt->from_bin("0b1001")|); + +$x = Math::BigInt->from_bin('0b1001100110011001100110011001'); +is($x, "161061273", + qq|Math::BigInt->from_bin("0b1001100110011001100110011001");|); + +$x = Math::BigInt->from_oct('0775'); +is($x, "509", + qq|Math::BigInt->from_oct("0775");|); + +$x = Math::BigInt->from_oct('07777777777777711111111222222222'); +is($x, "9903520314281112085086151826", + qq|Math::BigInt->from_oct("07777777777777711111111222222222");|); + +############################################################################# +# all the other tests + +require './t/mbi_ltm/bigintpm.inc'; # all tests here for sharing diff --git a/t/mbi_ltm_biglog.t b/t/mbi_ltm_biglog.t new file mode 100644 index 0000000..f4ea0ab --- /dev/null +++ b/t/mbi_ltm_biglog.t @@ -0,0 +1,194 @@ +#!/usr/bin/perl -w + +# Test blog function (and bpow, since it uses blog), as well as bexp(). + +# It is too slow to be simple included in bigfltpm.inc, where it would get +# executed 3 times. One time would be under BareCalc, which shouldn't make any +# difference since there is no CALC->_log() function, and one time under a +# subclass, which *should* work. + +# But it is better to test the numerical functionality, instead of not testing +# it at all (which did lead to wrong answers for 0 < $x < 1 in blog() in +# versions up to v1.63, and for bsqrt($x) when $x << 1 for instance). + +use strict; +use Test::More; + +BEGIN { + plan skip_all => "requires Math::BigInt 1.9997+" unless eval { require Math::BigInt && eval($Math::BigInt::VERSION) >= 1.9997 }; + plan tests => 71; +} + +use Math::BigFloat only => 'LTM'; +use Math::BigInt; + +my $cl = "Math::BigInt"; + +is (Math::BigInt->config()->{lib}, 'Math::BigInt::LTM', 'LTM loaded'); + +############################################################################# +# test log($n) in BigInt (broken until 1.80) + +is ($cl->new(2)->blog(), '0', "blog(2)"); +is ($cl->new(288)->blog(), '5',"blog(288)"); +is ($cl->new(2000)->blog(), '7', "blog(2000)"); + +############################################################################# +# test exp($n) in BigInt + +is ($cl->new(1)->bexp(), '2', "bexp(1)"); +is ($cl->new(2)->bexp(), '7',"bexp(2)"); +is ($cl->new(3)->bexp(), '20', "bexp(3)"); + +############################################################################# +############################################################################# +# BigFloat tests + +############################################################################# +# test log(2, N) where N > 67 (broken until 1.82) + +$cl = "Math::BigFloat"; + +# These tests can take quite a while, but are nec. Maybe protect them with +# some alarm()? + +# this triggers the calculation and caching of ln(2): +is ($cl->new(5)->blog(undef,71), +'1.6094379124341003746007593332261876395256013542685177219126478914741790'); + +# if the cache was correct, we should get this result, fast: +is ($cl->new(2)->blog(undef,71), +'0.69314718055994530941723212145817656807550013436025525412068000949339362'); + +is ($cl->new(11)->blog(undef,71), +'2.3978952727983705440619435779651292998217068539374171752185677091305736'); + +is ($cl->new(21)->blog(undef,71), +'3.0445224377234229965005979803657054342845752874046106401940844835750742'); + +############################################################################# + +# These tests are now really fast, since they collapse to blog(10), basically +# Don't attempt to run them with older versions. You are warned. + +# $x < 0 => NaN +is ($cl->new(-2)->blog(), 'NaN'); +is ($cl->new(-1)->blog(), 'NaN'); +is ($cl->new(-10)->blog(), 'NaN'); +is ($cl->new(-2,2)->blog(), 'NaN'); + +my $ten = $cl->new(10)->blog(); + +# 10 is cached (up to 75 digits) +is ($cl->new(10)->blog(), '2.302585092994045684017991454684364207601'); + +# 0.1 is using the cached value for log(10), too + +is ($cl->new(0.1)->blog(), -$ten); +is ($cl->new(0.01)->blog(), -$ten * 2); +is ($cl->new(0.001)->blog(), -$ten * 3); +is ($cl->new(0.0001)->blog(), -$ten * 4); + +# also cached +is ($cl->new(2)->blog(), '0.6931471805599453094172321214581765680755'); +is ($cl->new(4)->blog(), $cl->new(2)->blog * 2); + +# These are still slow, so do them only to 10 digits + +is ($cl->new('0.2')->blog(undef,10), '-1.609437912'); +is ($cl->new('0.3')->blog(undef,10), '-1.203972804'); +is ($cl->new('0.4')->blog(undef,10), '-0.9162907319'); +is ($cl->new('0.5')->blog(undef,10), '-0.6931471806'); +is ($cl->new('0.6')->blog(undef,10), '-0.5108256238'); +is ($cl->new('0.7')->blog(undef,10), '-0.3566749439'); +is ($cl->new('0.8')->blog(undef,10), '-0.2231435513'); +is ($cl->new('0.9')->blog(undef,10), '-0.1053605157'); + +is ($cl->new('9')->blog(undef,10), '2.197224577'); + +is ($cl->new('10')->blog(10,10), '1.000000000'); +is ($cl->new('20')->blog(20,10), '1.000000000'); +is ($cl->new('100')->blog(100,10), '1.000000000'); + +is ($cl->new('100')->blog(10,10), '2.000000000'); # 10 ** 2 == 100 +is ($cl->new('400')->blog(20,10), '2.000000000'); # 20 ** 2 == 400 + +is ($cl->new('4')->blog(2,10), '2.000000000'); # 2 ** 2 == 4 +is ($cl->new('16')->blog(2,10), '4.000000000'); # 2 ** 4 == 16 + +is ($cl->new('1.2')->bpow('0.3',10), '1.056219968'); +is ($cl->new('10')->bpow('0.6',10), '3.981071706'); + +# blog should handle bigint input +is (Math::BigFloat::blog(Math::BigInt->new(100),10), 2, "blog(100)"); + +############################################################################# +# some integer results +is ($cl->new(2)->bpow(32)->blog(2), '32', "2 ** 32"); +is ($cl->new(3)->bpow(32)->blog(3), '32', "3 ** 32"); +is ($cl->new(2)->bpow(65)->blog(2), '65', "2 ** 65"); + +my $x = Math::BigInt->new( '777' ) ** 256; +my $base = Math::BigInt->new( '12345678901234' ); +is ($x->copy()->blog($base), 56, 'blog(777**256, 12345678901234)'); + +$x = Math::BigInt->new( '777' ) ** 777; +$base = Math::BigInt->new( '777' ); +is ($x->copy()->blog($base), 777, 'blog(777**777, 777)'); + +############################################################################# +# test for bug in bsqrt() not taking negative _e into account +test_bpow ('200','0.5',10, '14.14213562'); +test_bpow ('20','0.5',10, '4.472135955'); +test_bpow ('2','0.5',10, '1.414213562'); +test_bpow ('0.2','0.5',10, '0.4472135955'); +test_bpow ('0.02','0.5',10, '0.1414213562'); +test_bpow ('0.49','0.5',undef , '0.7'); +test_bpow ('0.49','0.5',10 , '0.7000000000'); +test_bpow ('0.002','0.5',10, '0.04472135955'); +test_bpow ('0.0002','0.5',10, '0.01414213562'); +test_bpow ('0.0049','0.5',undef,'0.07'); +test_bpow ('0.0049','0.5',10 , '0.07000000000'); +test_bpow ('0.000002','0.5',10, '0.001414213562'); +test_bpow ('0.021','0.5',10, '0.1449137675'); +test_bpow ('1.2','0.5',10, '1.095445115'); +test_bpow ('1.23','0.5',10, '1.109053651'); +test_bpow ('12.3','0.5',10, '3.507135583'); + +test_bpow ('9.9','0.5',10, '3.146426545'); +test_bpow ('9.86902225','0.5',10, '3.141500000'); +test_bpow ('9.86902225','0.5',undef, '3.1415'); + +test_bpow ('0.2','0.41',10, '0.5169187652'); + +############################################################################# +# test bexp() with cached results + +is ($cl->new(1)->bexp(), '2.718281828459045235360287471352662497757', 'bexp(1)'); +is ($cl->new(2)->bexp(40), $cl->new(1)->bexp(45)->bpow(2,40), 'bexp(2)'); + +is ($cl->new("12.5")->bexp(61), $cl->new(1)->bexp(65)->bpow(12.5,61), 'bexp(12.5)'); + +############################################################################# +# test bexp() with big values (non-cached) + +is ($cl->new(1)->bexp(100), + '2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427', + 'bexp(100)'); + +is ($cl->new("12.5")->bexp(91), $cl->new(1)->bexp(95)->bpow(12.5,91), + 'bexp(12.5) to 91 digits'); + +# all done +1; + +############################################################################# +sub test_bpow + { + my ($x,$y,$scale,$result) = @_; + + print "# Tried: $x->bpow($y,$scale);\n" + unless ok ($cl->new($x)->bpow($y,$scale),$result); + } + + diff --git a/t/mbi_ltm_bigroot.t b/t/mbi_ltm_bigroot.t new file mode 100644 index 0000000..2eac4b0 --- /dev/null +++ b/t/mbi_ltm_bigroot.t @@ -0,0 +1,50 @@ +#!/usr/bin/perl -w + +# Test broot function (and bsqrt() function, since it is used by broot()). + +# It is too slow to be simple included in bigfltpm.inc, where it would get +# executed 3 times. + +# But it is better to test the numerical functionality, instead of not testing +# it at all. + +use strict; +use Test::More; + +BEGIN { + plan skip_all => "requires Math::BigInt 1.997+" unless eval { require Math::BigInt && eval($Math::BigInt::VERSION) >= 1.997 }; + plan tests => 1 + 4 * 2; +} + +use Math::BigFloat only => 'LTM'; +use Math::BigInt; + +is (Math::BigInt->config()->{lib}, 'Math::BigInt::LTM', 'LTM loaded'); + +my $cl = "Math::BigFloat"; +my $c = "Math::BigInt"; + +# 2 ** 240 = +# 1766847064778384329583297500742918515827483896875618958121606201292619776 + +# takes way too long +#test_broot ('2','240', 8, undef, '1073741824'); +#test_broot ('2','240', 9, undef, '106528681.3099908308759836475139583940127'); +#test_broot ('2','120', 9, undef, '10321.27324073880096577298929482324664787'); +#test_broot ('2','120', 17, undef, '133.3268493632747279600707813049418888729'); + +test_broot ('2','120', 8, undef, '32768'); +test_broot ('2','60', 8, undef, '181.0193359837561662466161566988413540569'); +test_broot ('2','60', 9, undef, '101.5936673259647663841091609134277286651'); +test_broot ('2','60', 17, undef, '11.54672461623965153271017217302844672562'); + +sub test_broot + { + my ($x,$n,$y,$scale,$result) = @_; + + my $s = $scale || 'undef'; + is ($cl->new($x)->bpow($n)->broot($y,$scale),$result, "Try: $cl $x->bpow($n)->broot($y,$s) == $result"); + $result =~ s/\..*//; + is ($c->new($x)->bpow($n)->broot($y,$scale),$result, "Try: $c $x->bpow($n)->broot($y,$s) == $result"); + } + diff --git a/t/mbi_ltm_bugs.t b/t/mbi_ltm_bugs.t new file mode 100755 index 0000000..ebb7582 --- /dev/null +++ b/t/mbi_ltm_bugs.t @@ -0,0 +1,52 @@ +#!perl + +use strict; +use warnings; + +use Test::More; + +BEGIN { + plan skip_all => "requires Math::BigInt 1.999712+" unless eval { require Math::BigInt && eval($Math::BigInt::VERSION) >= 1.999712 }; + plan tests => 3722 # tests in require'd file + + 6; # tests in this file +} + +use Math::BigInt lib => 'LTM'; + +our ($CLASS, $CALC); +$CLASS = "Math::BigInt"; +$CALC = "Math::BigInt::LTM"; + +my $x; + +############################################################################# +# from_hex(), from_bin() and from_oct() tests + +$x = Math::BigInt->from_hex('0xcafe'); +is($x, "51966", + qq|Math::BigInt->from_hex("0xcafe")|); + +$x = Math::BigInt->from_hex('0xcafebabedead'); +is($x, "223195403574957", + qq|Math::BigInt->from_hex("0xcafebabedead")|); + +$x = Math::BigInt->from_bin('0b1001'); +is($x, "9", + qq|Math::BigInt->from_bin("0b1001")|); + +$x = Math::BigInt->from_bin('0b1001100110011001100110011001'); +is($x, "161061273", + qq|Math::BigInt->from_bin("0b1001100110011001100110011001");|); + +$x = Math::BigInt->from_oct('0775'); +is($x, "509", + qq|Math::BigInt->from_oct("0775");|); + +$x = Math::BigInt->from_oct('07777777777777711111111222222222'); +is($x, "9903520314281112085086151826", + qq|Math::BigInt->from_oct("07777777777777711111111222222222");|); + +############################################################################# +# all the other tests + +require './t/mbi_ltm/bigintpm.inc'; # all tests here for sharing diff --git a/t/mbi_ltm_mbi-from-big-scalar.t b/t/mbi_ltm_mbi-from-big-scalar.t new file mode 100644 index 0000000..d27d9d8 --- /dev/null +++ b/t/mbi_ltm_mbi-from-big-scalar.t @@ -0,0 +1,53 @@ +#!/usr/bin/env perl + +# See https://rt.cpan.org/Ticket/Display.html?id=103517 + +use strict; +use warnings; + +use Test::More; +use Config; + +my $use64; + +BEGIN { + plan skip_all => "requires Math::BigInt 1.999712+" unless eval { require Math::BigInt && eval($Math::BigInt::VERSION) >= 1.999712 }; + # Don't run these tests unless we have proper 64-bit support. + plan skip_all => "missing 64bit int support" if $Config{ivsize} < 8; + $use64 = ~0 > 4294967295; + my $broken64 = (18446744073709550592 == ~0); + if ($broken64) { + plan(skip_all => + "Your 64-bit system is broken. Upgrade from 5.6 for this test."); + } + plan tests => 4*2 + 2*1 + 1 + $use64; +} + +diag "use64=".($use64?1:0)." ivsize=".$Config{ivsize}." ivtype=".$Config{ivtype}." use64bitint=".$Config{use64bitint}."\n"; + +use Math::BigInt lib => "LTM"; + +my $maxs = ~0 >> 1; +for my $n ($maxs - 2, $maxs - 1, $maxs, $maxs + 1) { + is( Math::BigInt->new($n), $n, "new $n" ); + is( Math::BigInt->new(-$n), -$n, "new -$n" ); +} + +for my $n (~0 - 1, ~0) { + is( Math::BigInt->new($n), $n, "new $n" ); +} + +# bacmp makes a new variable. This will test if it is screwing up the sign. +is( Math::BigInt->new(10)->bacmp(~0), -1, "10 should be less than maxint" ); + +if ($use64) { + SKIP: { + skip "The following test may hang or cause an exception if incorrect." + . " Set AUTHOR_TESTING to a true value to run this test.", 1 + unless $ENV{AUTHOR_TESTING}; + + is( Math::BigInt->new("14")->bmodpow(9506577562092332135, + "29544731879021791655795710"), + "19946192910281559497582964", "big modpow" ); + } +} diff --git a/t/mbi_ltm_storable.t b/t/mbi_ltm_storable.t new file mode 100644 index 0000000..1356429 --- /dev/null +++ b/t/mbi_ltm_storable.t @@ -0,0 +1,19 @@ +use strict; +use warnings; +use Test::More; + +BEGIN { + plan skip_all => "requires Storable 2.0+" unless eval { require Storable && eval($Storable::VERSION) >= 2.0 }; + plan tests => 1; +} + +use Math::BigInt::LTM; + +use Storable qw(freeze thaw); + +my $num = Math::BigInt::LTM->_new(42); + +my $serialised = freeze $num; +my $cloned = thaw $serialised; + +ok(!Math::BigInt::LTM->_acmp($cloned, $num)); diff --git a/t/mode_cbc.t b/t/mode_cbc.t new file mode 100644 index 0000000..09a41db --- /dev/null +++ b/t/mode_cbc.t @@ -0,0 +1,98 @@ +use strict; +use warnings; +use Test::More tests => 314; +use Crypt::Mode::CBC; + +my @tests; + +# test vectors from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf +push @tests, + { padding=>'none', key=>'2b7e151628aed2a6abf7158809cf4f3c', iv=>'000102030405060708090a0b0c0d0e0f', pt=>'6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710', ct=>'7649abac8119b246cee98e9b12e9197d5086cb9b507219ee95db113a917678b273bed6b8e3c1743b7116e69e222295163ff1caa1681fac09120eca307586e1a7' }, + { padding=>'none', key=>'8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b', iv=>'000102030405060708090a0b0c0d0e0f', pt=>'6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710', ct=>'4f021db243bc633d7178183a9fa071e8b4d9ada9ad7dedf4e5e738763f69145a571b242012fb7ae07fa9baac3df102e008b0e27988598881d920a9e64f5615cd' }, + { padding=>'none', key=>'603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4', iv=>'000102030405060708090a0b0c0d0e0f', pt=>'6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710', ct=>'f58c4c04d6e5f1ba779eabfb5f7bfbd69cfc4e967edb808d679f777bc6702c7d39f23369a9d9bacfa530e26304231461b2eb05e2c39be9fcda6c19078c6a9d1b' }, +; + +# test vectors produced by Crypt::CBC +push @tests, + { mode=>'AES+Crypt::CBC', padding=>'standard', len=>45, key=>'4cdc909dc310796429e26bcaca1b21329f5060813b7d17bf1a65f293154b54a9', iv=>'9124d8cfafd3d732e597f463d35a8a43', pt=>'ad67301bcd23a5d7b4601f93db3e6b5db71243fa00244182d0a2df6f0384a09f117821b7b70a4bcdc0a73a70130851f704a7aca59b96a3e5b8dc89efa7ee7846a906a3eb591bf8b6b472ae07113ac3cccfb1bc84723ed1472c1f59705eae7b9fbd6df2b38d2eac2a6c726b9f92', ct=>'588c33d96d99477bc6305c829a1fb188ab165f60ccadac67daaefb8054cfe8093cbb6fba14b684c26cd10c66db87cf1aa8cd69c98180d1d7cb6edc9191332863653ea707cb9ec4da0c7d4381cac33faa938a53df3519d06859260be7ac582674cdedfa411f4cd0204c8b2132d4b100cc' }, + { mode=>'AES+Crypt::CBC', padding=>'standard', len=>46, key=>'0c1afd6567e265240aacef873eb78ff11ce0e53931ca7de49143d8a2b1c84df5', iv=>'df5f1521ed1ee7b47ae7e5ef0ac49abb', pt=>'13436402bb6c57b3f202e88cd4d21d828e85856415000e5ef01f9fe43bf100ee5b94ea29e3246200dcddbc5779dce5e219c078bbad8cd878727c0c27f179c100beefcc832f605c8e8f27251a8b51b2475d5170ff8100c95d4d875d386016535a13373f7e15d798e0c39c94193b24', ct=>'3eb5203a12d11b2fe629cd764a9963ad7f314d0efe75806c12e00f3bfe916c765a318be81337d1cb43f20c030f8af6e31991fb09477d06baa3492836f884470177584ad32241ac8fd66469fdd858ce1d04e90375689e70a4bc40be149b1df6cabc5943cff8e7cecdac6fe81fc0aac8f8' }, + { mode=>'AES+Crypt::CBC', padding=>'standard', len=>47, key=>'9dd6b591b1589ff6fb5bbd41a8da4b1449674155119285857d719d44281daa3d', iv=>'321d48c36326dcc951aa208542d2fdd7', pt=>'75e4309485e3df2006c411a316073973e8adf51bfd6287a7833f15e18f2f6b571c192a527bd6290722713eb77c9116a28b321cc5decd44a5a49a13750d43e99e4d360e647300cb7b9d31a82c39d8885e6d2b5521f1c7339b30d3947bddc7323a50891f4d37a7bc9cc6971037373722', ct=>'f1f7d95a90ece772a931e3c1f919da110246268291d10d5b2a3ff62596f0cd2a0c3dbdab41e210424f5a1d35b72a4df26a32d4c9ac80e808438f31e07a4f16555a82bade488a73afe239e6c557f100cf17632a8f767445ad6db8f7d2775f63f4b4e73fc5180b20334f941f8c49f7968a' }, + { mode=>'AES+Crypt::CBC', padding=>'standard', len=>48, key=>'d2ee6699d1c975c08c08644d0c87cae26da0cf62a32e722926dcef82d4076e93', iv=>'a6352c34af3450612cc9070e686fe37b', pt=>'20f8ebe4281ed99f7fbacf781430e6ac89c984acfca73073efc168109690e0027f3f9954c2aaaec8fada73d09a2715c9ea33224d9360ca8fc4b379a656fd9ac9be49196cb2984387caff89f48c40cd8393f6bc13e96b37f1ebcdae167c05b4ec1a46bd1ed31cf1f5ee89415dac1782a2', ct=>'17b300b588ef03a585c8130c87e1247d0c7900bd2f31f0a0eab4a542e370e9d6ba5ea803aa48bd67f2e23da3d6761b97ed32f313baa2e65c23b344605eb740a7d1e4cf26c320c2830e387e8562361eb0900868bf58b5071fd54c449ab15368b9940ac507761a0e3ee3ea37287de6e476adfe344d00c5fd4a8d008f4f4bc70b26' }, + { mode=>'AES+Crypt::CBC', padding=>'standard', len=>49, key=>'e48000f92e643c1821a307fb1673ecdaa834b423ad4e45bb922ab28d97213116', iv=>'85a3a0c660f7bc183383516143d6102e', pt=>'099b427090a4d806fe9a463872aced748ef4e1747be7063c7ae5b0738cc3247f170a09460236964540b533fc271fdf9bafb9cb0c3e408a59539ee8b882890bf9ff826e1c568ffdad503f0d5d7568fb4aae6de43c75b541fa7b08b32ba8fa18cc8ffd5a97206ea2ec5fc7f3db542f9c496e', ct=>'59ec204ea6a862236405a97d89b9bf1692c4694a5aea039fd08e3a6ed35bd5764a8cca5cffb3bf5913d0b5d4f362f4f171f72240a91878b3803ea41a14a3d0b80771eb446971f682069d7e5c5d950c20d14011bee512f786972f0fd71db631f7332cd863d1285ec994418db47b7204c7148710c6dde320f614c621c6ae819095' }, + { mode=>'AES+Crypt::CBC', padding=>'standard', len=>50, key=>'410662fb7ced9a775632da209b8c1d114de85ee83739850449650e69b082f261', iv=>'7e98386b58bc8a85af4b8b3c7c9ccf48', pt=>'77a4117d8ccd4798bd32c7079b64aa04f0ce964818c897e6501b2dc115155018a32584c17014f4b87b98983ff7ebc46a6a971c506d966e2ba190fed03a8f771e003bb940130650acfafc705185f4905e8c05a33a8f5114bbfc17c7817afa5bcb8395c395ab3c365bdcc7e7b80e69a0730029', ct=>'79ba74b32dbf1d84afaee3c577e9f28cb1e38ce0e39d8d9938e54d17acb2d3bdf811a776aa8e92aeee579657f2c3430d67afc2b3e15c26f6eff2a483df219b4f72367a75827986e001264729ce7e82c32df66dede60d3105f7debc0043539b797fbc63ed01879a2c2ab96861411fc4757908eee0754df56fccf4cabccc76538d' }, + { mode=>'AES+Crypt::CBC', padding=>'standard', len=>61, key=>'e6e52745bec4be4699cb1fb15797d4c6a211942a3405c1c9ddca549f3fe882c3', iv=>'4f86433e92beb35ef6d56f1d14928669', pt=>'cfb9ad9bc13efaadd46ad46ae09413e7e30707cee0f90e263b86469f48d691babf20a685988a58592b9cee19ba15db8a75fac948d77e834184108496aab2bcc3a3e55e2246a0f32568fb27782c54661d4872bd6300a379d09ac30911eee5ac55f476137dcb6c5a5b2d7e7268f7e8e62f1469ae5c65378a75a407cf9a8f', ct=>'0d817303f1b9d1bff93aa9cdb89abcccfff4bb630695a6275b330975bb0f58f8350cd791a7634b0c7973c3e2a142bb1d215c1e9e083424c0983b546d13fa4017ed7b726702353d54431b276190c6ee404b9a3032234b8303a2653588c4ef2f931db9f9c3e1895ad68bf60eab45a03f63d165754fc055c571c80a9bb6919e9a36' }, + { mode=>'AES+Crypt::CBC', padding=>'standard', len=>62, key=>'b9dffb9c4ba930ecd69e4c19530705c70bd95f5dee943d0b15f382dc11a6c2f7', iv=>'295907c65d22d55743047215e43ba578', pt=>'13de19bb521bbedb2d88588eae8898b3fad2f264173b13605afe9e932b606a9f6f46b2f6499338efe48b6723869524e9fd5bf5036601191210fc91f54ef064ed437df8be1c1d4441db3736ee61a67a107206f2407ed48a494103905eb1c3f3a7cc3146c21d98d1e0538943c88be8d5074d87afd97d5cdd3631d1783c08dc', ct=>'cf55d9e1eac7414684a2a1c591a6a7be855771fb293e19197c3a3692dffafdc524550501e04461f87b721d18e2a4f27bd74a13d0890cfc39655c176e74fa752e51a9d39e25baf65447200611ca6e6c482ae0d042692180d6ee91b900b845cf257c7252b357f23809e9b8b4cfc0fb004085b0b61edcb747eea9889c1081456c5d' }, + { mode=>'AES+Crypt::CBC', padding=>'standard', len=>63, key=>'cf2b183e93b2b715d8ef2424c09b24d1eb9cb3bfa6c4b5ef365526f4a08d7b9e', iv=>'e61ba23a2c70f999dee235fd30bdc3dd', pt=>'59a76d9394d5e16fe3ba53897295ca1fbc898119ff500f9fd3a8fe823116159384f8d60dc65a5a97aabecc497819d6aea306f4b246a76e62133ef98ca7829b450b247cc4f78ddc8d429474986fa03ab404b05b661410feac9bb39a4510a479fa3fe4f34f86c0812bcba493671e98f6a973d0eaa04fec13e98ac60bf07dc48f', ct=>'6ecc1fc3a67f17b9791946a3c3434bb441a9f30eba5efb1d3173eb71a5a0f98d3925addcac29d1ad69f7bf19f56d5b73e984ca4b7686d66674f1ce0b557cbfaec542dd9c4f3f7ca4dbf99a7e391bb6eca127661468dd71b72d030e51bef89f5326b71ce08760f3455f61bafb581a74ddb100778899ba97630cdc376a7d08c6d8' }, + { mode=>'AES+Crypt::CBC', padding=>'standard', len=>64, key=>'f5fa281cf55a77e3a45388e6d64c616a2b26f47af51cf2ae21eef483113f704e', iv=>'b22052aae87626bfc7b67af9c3b959d6', pt=>'5fdf2493e809ea6ec9179a2235dca09725259d58cf87fb2cf8765c1e7171b346aa3dc4ea5885c1a6a8377363ac283af15b6471c8b4d57d38501c587448608f8e69d06ac533f4da6eeb4db3a19dad66de07165c36e953261a3db7e95c35300afcc341253a7746262e3ee811e9eefc3dc72f0c6d629baff9d804ee1ebb0bf507fb', ct=>'abba44e77469c68db93419e041aa512a47aa03891e102182668591614bb81d083a6c6b9ec761aacb65e7a6456e2a602b10f86cac6c886ebe84ac5047ea8a9ed5f6134bdac936c3e3cb5a21275ac471f24c02a31be7f1088bc1d0d798310a180596f8d4632ee976bff4f80d227a31992830028b1112d9c46f3ac88e89992088bb9c7bab2d9c1e403ec98102007feffbee' }, + { mode=>'AES+Crypt::CBC', padding=>'standard', len=>65, key=>'c4c2d3a2aac2db867ff91cd363050da166af579f18f24cac74dcfe5f0b283b64', iv=>'d5be581e0bee9a6ad46d6a9d1a454f49', pt=>'1ba72c2c58b536c3d88b0f67c99b8ca4aea8956c5e78f4527521f2a9017e6a392b2d7a82c8086a646ea78d64a06477fcf8e38ce4d75cfc6e0c60b3b9d4d23bbccfc5137c86e5d80c01139fb43907a99152b6bf9392242cdd0840e838e39cd1c121260e8f2f5ce11d2dceb7d784eba1964c427b949069b6b412a8cc4b63fe0493d7', ct=>'a3026f2b0151760da3bf7ef194bad524fc74aa8785dd3f2b8ed51702e39590b97bbc9d68a1156c8ca73a8bb222f4d5e9f5e0319c1f67f774cdcf8afb5acd58629e193b251dd122578a09b5a83f5d6fe3e60348ef8da5c3300b98065bd264071cde25c4ae67dbb393a66b3e190c7d79b4a46a8efa1aa263816e56956c2e4c261c0f32c5828829fbdfcf3e81cc1813629f' }, + { mode=>'AES+Crypt::CBC', padding=>'standard', len=>66, key=>'6ed4b7d127dce8bb15d6d772e043e5f4297d0c936671572823db00346fe8c54f', iv=>'c148a482405a6adc4aa7bd55d4fb9c5b', pt=>'982cd450603380b0001449817ea73efed17581846178e308e8e732e4001a7843fbfdc9e1c1b3f136e01008225c67d3be503adf82795257754c0b1e02d8415da82b8cb47e537f9c6f9c21571c52eab3c7fcc91a94e9b4fca0b5f032d302ef8c592cc54647ff1f58ede5001b6a65f28a00029519b38801843cfe9c63f088ec575cecf2', ct=>'4731d8fc61ea27f54595314239b0c6ea9708dc8044950725e0814e47d4bcee32fc88b1734933688e3df66479f74d47000cb88d19d40c01415db4abe1c2008196c7cee60c173943d9360fcea6b05fae17ead1e879f4f8bc4e085c73732dc2c5f9aed46c6d3dc63354d1b7d08f4fff00eed533889e895a5897fef338185deee24ccd225713b4a3e4cb3db6e949dd83f0a0' }, + { mode=>'AES+Crypt::CBC', padding=>'oneandzeroes', len=>45, key=>'a31400af9c12b62e9f512585e2096ca5c4eb3f3d0ab3fab82c651b59d92259bb', iv=>'9e6e3e7eab26dffb2d1f0a94cd6b40be', pt=>'5da888bd7a8e29568c9a05f6f6935439b6effdea9e862f775116bfebdb4fbf489e0d82a79e82e0c0912bd5228c1adc84a51dc0f2ba83c4c68edf2709569eef8a11b3c99da949cccbe2a843cf9d20d1d1ba1df67c085c61518fb16c44aa9b05034b49bcbb9b010fe84dfa111ebf', ct=>'ed5fdc33568ffe9bce4a7cf15fb0f4a11e644c6b9a349b39968fffaf1dfa371bcdc53a7bf2f642ee629ebdcd9e37f4b07994b5184960c7600a54cc6f8fedb0b85292f0a72343bd3aa838f04ba9d6dcbb947fa21e94709b652da239b13a5a5cc828cbf186d35c717e41319d0fa57ba627' }, + { mode=>'AES+Crypt::CBC', padding=>'oneandzeroes', len=>46, key=>'cac6d61e5acf7d818db0d1344cdbcd34a9d5f699a769898e474e7475ef99ca80', iv=>'c65d55b06f6ca01b0a197159a901e2aa', pt=>'e52274e59b046d5bf01dca1ef6e3afeb289f7fe256c857367ad4c7382d219973cc00697cced4563e1569ee91f21c3703f7ea693df3d4f0814c6a2563294b1182cc26f80f7ea5dbe6b2e2e2780e8b7a205fb7030462e9daebcf0db58c96a6cbd7a2219a3823a712a52ff881b8e74c', ct=>'7611509b6df3dd00da0c84b320a3a2622318b533724170564ea83d3099d564ac995c4ad26900d7846b40c02d477b5a5c2171950aba4b082e7aaa2a51bc57c8fdd94350bb5975538113bda892074cadfcd1d824c585245790b0b281910ab3f0b19b05bf7752cfeedc10d55750c098c1d7' }, + { mode=>'AES+Crypt::CBC', padding=>'oneandzeroes', len=>47, key=>'4102b812a1ac0a8cc224c9f48372e6b5f51ef5240f9021042207c32e311c6dcb', iv=>'6294d27e3b6a1bdcc9f9e542a74dee06', pt=>'46c6c5ca20642b5c4a380acdd20dbc7f1c0bb60024fa6b6654cb43ed94f4ddfec2edeb30acd31db015cda268e872b0f4802cb779dadf027372b7c409ae58ddc2a93f5a520d958b3503bb6c53c2ec95e02b0bce79888d7bf45bab21857ac959b6f83aedf88e982ef2e8d842232e77b2', ct=>'4f0ba8ccc9a638aaee103a9eab8055166259a73f67615751a26be2d9d00674b29d8d22c7667eabe48c6176f946c198a78393e342ce69bd1fce05bbb3c0d5ddc8c8402a7e6e56dbca37d27c2fc28e97c0010d706ff4b6a76172b383f31bcd344e092e2c1a4feef23a3b719ae250af69fe' }, + { mode=>'AES+Crypt::CBC', padding=>'oneandzeroes', len=>48, key=>'18b9e2cd23bb350cb9e1c3260339d991d76640c85d492157c7d9b9fd2551fce6', iv=>'2952a3e126418b7b889ae54c7f93c214', pt=>'4190805d7ba4c03e19887e5e501bb6ffd7345d0fab61a8a7b3b62e3a58de51937bc3f4550b8b35d60ef65b08156618ba455c9f10872aefa1ee9b3a402b2da0523dc46859246cf233dc7f93316a2624b7cb8c7eae1cbeddb8db14238d0856b38d95e8f44bf225bdb0493808c145334b28', ct=>'94e533ad2771dd88c76d38cfc32497a72e603efbf73b8cd128296415da4e0376e551f2c583c9bf91c539204ae54a47898d041bd0f7cca9a6f7fda1890ea4cc9c68335db83dc54507d947af3e7c12d9bbc98d8d0576c506ae4a3ab35bd4605710b924068b24fb1e32ee826c2d9562d0d1a551050909b3598eb2bdb9811a1cbdaf' }, + { mode=>'AES+Crypt::CBC', padding=>'oneandzeroes', len=>49, key=>'6cb5798c1009611d7231c872d5f98195b4a232e626e636d746e714e336926d09', iv=>'21bd28feac672984d5eff2db1df1c55e', pt=>'e8d66e82828e539419a337c6430c9f3cb1692a1d2e8a2d98d9f14b31bbdf259539890be5d55209d7101fa11dc566960800517727a90cf97d5984364c12bec9f7a88b9375f7341681544fcb8fff9ccf791e6e1541035f8497d3a301e224ce649fa4aafe7ba21a49bc94ed376a745fccafe2', ct=>'62ea3d115bad96e4980c12edfb4e5da2d53c57e15d50bc2ebc9c24401e8a94ae0d3e90dd6fa08a83a405d9b5a8323ec8a169da63c0c600122122a180cdd52470583b0aa80c91d677e7a6e0b25e61cb2cb4020c384b2bab68b53c35d2cfe5305dba2bf61e1d273b9237dbed4400a40d90b90170c1180171f41f5d71a9e3b37910' }, + { mode=>'AES+Crypt::CBC', padding=>'oneandzeroes', len=>50, key=>'728757dea0973aa1f5a69c859f223c22d4ce91c3817011c252ea033aeea4da21', iv=>'a1ea0246ed15c43bfd4502ddb586ae89', pt=>'647dd99c0065d239e75737a794f079d912e6464dcacef0dbbad08211d123dc7f64e67f6bceb01e6f82c6c6415fbaf2f1065d1c2918c32422dee54a5c3aeea1ef54fe7ea3c51adfdce5f09d7a693988bd85f46f99631647655346df80d5f775db9e2db472124f3c2fde92ab73064fedc8c776', ct=>'294c695e58bf34e2ade1b8140eda57918cd4e1fc0158745498778cc0e2b88dd068285b994e1206952da749547dc6d0080cfc4c41e0b4e4c944d85c19115b1778abc384e0a565af8fd7999216d423eb6040a02322a82f9f40bbcc43167a6c5115c8629124e47c429980845dae04771d1c20475027cb54da48048b8f06b7cf2113' }, + { mode=>'AES+Crypt::CBC', padding=>'oneandzeroes', len=>61, key=>'5aeedd3c1d2ecc0fc0e951337d8a61abeae3e6a89e47b57b3bb10fabc4a6299d', iv=>'a6a6fde7cd96880499a1922e04222e71', pt=>'19cff45762e6bdfc55b0d3efdb22734bebd426c71f64bbf48448bf0faf762c498313ed15fed19036226a977805e8fe43f51ab81b1cce787a42b666d4bca64bfb59f225e68e6eb54c6e47c879bede3c2896cb2e6be4e990eabcc266e4e5561ac028299947a5a2cafda352abaab27e1c4ab6b40c25306acf3c43b3084a3c', ct=>'9d6d671e1f81aad8906559135c5a9af3c1e277675cb80f9cb0ca7ac033b041beeb2d86fafc7af7041900a619f4b821a5a0c7a87c6b9e0909f74d19b631b4754c642db425ddc1accb596fcdfc7d5f6774b1b867085649dbdc60783726568ec76cb21933ac5d374b29ed02d70e285b769fa0b8de701308795e4d01219f83c8a6f5' }, + { mode=>'AES+Crypt::CBC', padding=>'oneandzeroes', len=>62, key=>'2d17ff1612873c72f9f7a98766f287ae6721b369024fda2b8a666a6c7f0a0ed1', iv=>'fda61ecb9f3d0e097d901f83224f23a0', pt=>'bc1d4c335a2d466eea4b540d3eca5083649a375ec125881e6217fd317c5c98cb85f7116f43b37171dad7d3193dc3a6839e5136ac3fc10792e5f9202880976a5b04f8c14149129b5d97b7cad9daa1863d5ebd14f8a45669b3b4458e27aa8bc2efbe1b215685646ec6e4f52c678b469043cbbf8e299d68c4e3e521b469ddc0', ct=>'ebb5ada37eeb7aa60f2eb8f26dc589cf8d92e98cbd2ceef65f057c6dcb9cafd3a05b5ace7a483f8630b1039e62161774f3baa0d439bb3c1583e83bbc953e278f80230f4147cbfcabc7320b81d265115323708b649667fd39534fdb43ae081ea2f834c74eb44b8e6f72710bd84fcd8da48a596611268f278b8508f195fc40af3d' }, + { mode=>'AES+Crypt::CBC', padding=>'oneandzeroes', len=>63, key=>'059d905aedbed8a3e83ea4e78bb1f83cfb8abbf4d8b59cd377c2c8d21804e172', iv=>'515a7f90bbfc534db5a9d73c0f43b665', pt=>'9eab0ebda29a926352ecf3a845cbba7e1259a2dd6cc1d090849267134c802c966027bab6f4ca1f1156157bd5584a00496bd0d3802b1af1647b7759c021fcd08af956696320ed2a5f673a1c91862ea49c8bd48f94e78b79a575cb46483cd4b343c868b0ae136d84814343348be1ee3f851aa06afe52fbf296d30a49983e2c00', ct=>'ef8a589776965e0674c135245a4a2ac7a783b4faee906372616f0e63df396faeb932fa0c68aa023107c91bafbca02cac55233eb9df61a042fb745d52a835833e34ffc1cb4f7239d1b9f14988239fc1fa621db6dcbb604154a09c578e3f617193458b0568cf6dd1533bb5c38897f668dfd39989acbdec2c0d8cd61d27ba770b28' }, + { mode=>'AES+Crypt::CBC', padding=>'oneandzeroes', len=>64, key=>'89d796ce74233ee7928ab3530c130c847791a5a841daf9aabd569f435796a54a', iv=>'758178be5d320fd5bf0e7c6b99b71b64', pt=>'dbd5aef963e811f4abe1e7674b1454f0f27e583b33b8f5097c6d8073a82a2a03473e451016a3646a6f9e78f7a29b8429c15c9aa99b393350219eea0fa2af830ab83686fb85c46694b1a6c2296ebcfc4288b02aef5e57a4ad6eef67e0805580bd9592b7570d04b19180949804bf90408c5ef2d99ad8dec1c302a9180369855510', ct=>'50104d3952006fff50bff50108b7eee2ee6e95fb7f0d4bfd8285871eda133836bc929f3c91fbde7e9be69b566ead6b4ae3717040c2422442d6e33a0d226d1da8fecc2f4a82e10e87d426b5608136c09878b116a8a20b3064b6b2ca20e4ff4beba7f35a3e1bb9a6b46b3bad912f8fed6545b9be30f5540182dcf5246535b3f511d087e9a91862e36e26ec44b20097ac80' }, + { mode=>'AES+Crypt::CBC', padding=>'oneandzeroes', len=>65, key=>'65ce85da260bd2a0779ee905791ecdee4b6f310236b137488360945efdce39ee', iv=>'2c9235dde136a62b9a42b32485970f25', pt=>'4871a0e74c3a510a9488f1f3404e5e76c76620e5e54d31e2359bc757867a559aee04c1c57618fcf94647f0262539e463591c8c6ac69f8458aa94da87835ec94e60a4b8bfe33f5d39194dc59ac5cfab8caad66f82c6934894bc2d9bda6132c5d17aad599dad9b5385754928907870dc32d415d663b626178e0a8fee5159530ec6da', ct=>'4b311dc4a84f173747e730aae501e548e152f48151c49ebe2e2369799db22aed0bc6927527145c87afd359017c796a987434b1f005c2ed72a7a012c17d7b4f179897837e432fa3615350006001c61744ea860df63f9081d5c2e7e2c24f43f8908651dbc1fad594ef749e8ad2484cd92040a2c77157a835be6cbf0674bb78a12cddb6040ebedeeed148f072c978fb5be9' }, + { mode=>'AES+Crypt::CBC', padding=>'oneandzeroes', len=>66, key=>'259dcc1e8bd959a66a58b5795768e341579db530a823ebff38e46b51720fb598', iv=>'11bfb017d9ca4690b0fc7ee6199eb20c', pt=>'6cf1d98a58b5683e403ea6747a02b2b6b3697114a5d8234f63637cf7327c8df19eafc185710d53ff762de59babc66ae3d5697ca7dd38ea00bebb741434dd7d8dab52b9876c9c4cefdd36c6b0c716108273f7d3d23f7970990f09f9530276236489b64a0079347cb14eb82106fc2945a40553392f3d964b677870fe6aeeebf159eba6', ct=>'ff829a0e6e21de39a5a3733a7f6d4b52e8a72e97a7192afeaa29c63c12bc57b61f5ab04b3cde81d557ad57f5c1771b24ededea0f2a7a3819d9d463f5c195503c145283c762ba6adf876fae4efb8b22c24a036b6d27f4d65c6c9db5d584e504af2afc6e932b67f24e07fae51c6e14a981aec4fac5161a523e944529bdeba100a3b366d5c6a730a7e9382a7a824d31c463' }, + { mode=>'AES+Crypt::CBC', padding=>'none', len=>48, key=>'5e6a5e40f836575205cd7db38f7ca96624040450317770e8a3c0516802bf7135', iv=>'61ad18d56036a51d9748f291ec007df9', pt=>'975123a7b4d97d11e562b9c47bbdc55c19398512d2ba3890123024d7066e66f94f5c16241695785b1fc11f3191bcd7ac7b400ca6c633ae73dfb0f4e97669ff724366f147b3333182117e02dd5469732677bb29c5d9d15e9019b428663287948307706f88eb0392acdda2c0e36d6b3c15', ct=>'7a7e50b6650920a3447aefd5a0e54389499d919f3eacfacdc6593febccc15c5f5d9a1a1036d7ac0e3b03026aade4e88c2cca310725314add54df3dd2e68f6687ac54644075261bdb5e8dd474191714d7e90a5b71307e0011e98e2b73b8c3b53f9e698e851e4a7b527f0e3c3a3781c598' }, + { mode=>'AES+Crypt::CBC', padding=>'none', len=>64, key=>'d0f6307a64837231f7ef94a8100fab507e31eb180a4b0f514f4128f431b19d92', iv=>'53095c611e2172debd73a7780ab8fd6e', pt=>'da7a390b0b83b4c7f054a09d382876135997bb00d73f59bc36c1d1d7943d241c4fc91f670978e0144d1ffe1dac6d80989b35518642ffa1a854fdb4d6aedab71a97b64cedadafff46476d97830bbd9f8a9ef16381ee59f1e504e6284ff1b4328bc494e55acbf15f61c644611ac24acd770ed984318ec151fd9637b1cd0e67f570', ct=>'a653d2ef928cf109351a01953cd53795fb7baf9e22e6863c3df0a384ab1b13a53777f881a60e10d192a88e0db2066ad85accfa438de56b4c191cf2ec69bdf89744b7f0bd6b466912fcebbdeea53bd957c42396bf983f0633df91109e790b598099d6c1604aacb11e03135c30953ec9b23f2d14cdaac46ef56eedbdedff5596c7' }, +; + +for (@tests) { + my ($pt, $ct, $m); + $m = 0 if $_->{padding} eq 'none'; + $m = 1 if $_->{padding} eq 'standard'; + $m = 2 if $_->{padding} eq 'oneandzeroes'; + die "invalid padding" unless defined $m; + $ct = Crypt::Mode::CBC->new('AES', $m)->encrypt(pack("H*",$_->{pt}), pack("H*",$_->{key}), pack("H*",$_->{iv})); + $pt = Crypt::Mode::CBC->new('AES', $m)->decrypt(pack("H*",$_->{ct}), pack("H*",$_->{key}), pack("H*",$_->{iv})); + ok($ct, "cipher text"); + ok($pt, "plain text"); + is(unpack("H*",$ct), $_->{ct}, 'cipher text match'); + is(unpack("H*",$pt), $_->{pt}, 'plain text match'); +} + +{ + my @t = ( + { padding=>2, key=>'259dcc1e8bd959a66a58b5795768e341579db530a823ebff38e46b51720fb598', iv=>'11bfb017d9ca4690b0fc7ee6199eb20c', pt=>'6cf1d98a58b5683e403ea6747a02b2b6b3697114a5d8234f63637cf7327c8df19eafc185710d53ff762de59babc66ae3d5697ca7dd38ea00bebb741434dd7d8dab52b9876c9c4cefdd36c6b0c716108273f7d3d23f7970990f09f9530276236489b64a0079347cb14eb82106fc2945a40553392f3d964b677870fe6aeeebf159eba6', ct=>'ff829a0e6e21de39a5a3733a7f6d4b52e8a72e97a7192afeaa29c63c12bc57b61f5ab04b3cde81d557ad57f5c1771b24ededea0f2a7a3819d9d463f5c195503c145283c762ba6adf876fae4efb8b22c24a036b6d27f4d65c6c9db5d584e504af2afc6e932b67f24e07fae51c6e14a981aec4fac5161a523e944529bdeba100a3b366d5c6a730a7e9382a7a824d31c463' }, + { padding=>1, key=>'6ed4b7d127dce8bb15d6d772e043e5f4297d0c936671572823db00346fe8c54f', iv=>'c148a482405a6adc4aa7bd55d4fb9c5b', pt=>'982cd450603380b0001449817ea73efed17581846178e308e8e732e4001a7843fbfdc9e1c1b3f136e01008225c67d3be503adf82795257754c0b1e02d8415da82b8cb47e537f9c6f9c21571c52eab3c7fcc91a94e9b4fca0b5f032d302ef8c592cc54647ff1f58ede5001b6a65f28a00029519b38801843cfe9c63f088ec575cecf2', ct=>'4731d8fc61ea27f54595314239b0c6ea9708dc8044950725e0814e47d4bcee32fc88b1734933688e3df66479f74d47000cb88d19d40c01415db4abe1c2008196c7cee60c173943d9360fcea6b05fae17ead1e879f4f8bc4e085c73732dc2c5f9aed46c6d3dc63354d1b7d08f4fff00eed533889e895a5897fef338185deee24ccd225713b4a3e4cb3db6e949dd83f0a0' }, + { padding=>0, key=>'d0f6307a64837231f7ef94a8100fab507e31eb180a4b0f514f4128f431b19d92', iv=>'53095c611e2172debd73a7780ab8fd6e', pt=>'da7a390b0b83b4c7f054a09d382876135997bb00d73f59bc36c1d1d7943d241c4fc91f670978e0144d1ffe1dac6d80989b35518642ffa1a854fdb4d6aedab71a97b64cedadafff46476d97830bbd9f8a9ef16381ee59f1e504e6284ff1b4328bc494e55acbf15f61c644611ac24acd770ed984318ec151fd9637b1cd0e67f570', ct=>'a653d2ef928cf109351a01953cd53795fb7baf9e22e6863c3df0a384ab1b13a53777f881a60e10d192a88e0db2066ad85accfa438de56b4c191cf2ec69bdf89744b7f0bd6b466912fcebbdeea53bd957c42396bf983f0633df91109e790b598099d6c1604aacb11e03135c30953ec9b23f2d14cdaac46ef56eedbdedff5596c7' }, + ); + for (@t) { + my $pt = pack("H*", $_->{pt}); + my $ct = pack("H*", $_->{ct}); + my $m = Crypt::Mode::CBC->new('AES', $_->{padding}); + + for my $l (1..33) { + + { + $m->start_encrypt(pack("H*",$_->{key}), pack("H*",$_->{iv})); + my $i = 0; + my $ct = ''; + while ($i < length($pt)) { + $ct .= $m->add(substr($pt, $i, $l)); + $i += $l; + } + $ct .= $m->finish; + is(unpack("H*",$ct), $_->{ct}, "cipher text match [l=$l]"); + } + + { + $m->start_decrypt(pack("H*",$_->{key}), pack("H*",$_->{iv})); + my $i = 0; + my $pt = ''; + while ($i < length($ct)) { + $pt .= $m->add(substr($ct, $i, $l)); + $i += $l; + } + $pt .= $m->finish; + is(unpack("H*",$pt), $_->{pt}, "plain text match [l=$l]"); + } + + } + } +} diff --git a/t/mode_cfb.t b/t/mode_cfb.t new file mode 100644 index 0000000..78b17d4 --- /dev/null +++ b/t/mode_cfb.t @@ -0,0 +1,27 @@ +use strict; +use warnings; +use Test::More tests => 12; +use Crypt::Mode::CFB; + +my @tests = ( + { key=>'2b7e151628aed2a6abf7158809cf4f3c', iv=>'000102030405060708090a0b0c0d0e0f', + pt=>'6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710', + ct=>'3b3fd92eb72dad20333449f8e83cfb4ac8a64537a0b3a93fcde3cdad9f1ce58b26751f67a3cbb140b1808cf187a4f4dfc04b05357c5d1c0eeac4c66f9ff7f2e6' }, + { key=>'8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b', iv=>'000102030405060708090a0b0c0d0e0f', + pt=>'6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c', + ct=>'cdc80d6fddf18cab34c25909c99a417467ce7f7f81173621961a2b70171d3d7a2e1e8a1dd59b88b1c8e60fed1efac4c9c05f9f9ca9834fa042ae8fba584b' }, + { key=>'603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4', iv=>'000102030405060708090a0b0c0d0e0f', + pt=>'6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417b', + ct=>'dc7e84bfda79164b7ecd8486985d386039ffed143b28b1c832113c6331e5407bdf10132415e54b92a13ed0a8267ae2f975a385741ab9cef82031623d' }, +); + +my $m = Crypt::Mode::CFB->new('AES'); +for (@tests) { + my ($pt, $ct); + $ct = $m->encrypt(pack("H*",$_->{pt}), pack("H*",$_->{key}), pack("H*",$_->{iv})); + $pt = $m->decrypt(pack("H*",$_->{ct}), pack("H*",$_->{key}), pack("H*",$_->{iv})); + ok($ct, "cipher text"); + ok($pt, "plain text"); + is(unpack("H*",$ct), $_->{ct}, 'cipher text match'); + is(unpack("H*",$pt), $_->{pt}, 'plain text match'); +} diff --git a/t/mode_ctr.t b/t/mode_ctr.t new file mode 100644 index 0000000..623894a --- /dev/null +++ b/t/mode_ctr.t @@ -0,0 +1,49 @@ +use strict; +use warnings; +use Test::More tests => 8; + +use Crypt::Mode::CTR; + +my $pt_hex = '6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710'; +my $ct_hex = "3b3fd92eb72dad20333449f8e83cfb4a96ef86442deb1b77ed386671a3c3ecfab3006f3856f9a6699a37efae3e3d5c62b501d9aec0ea791c33b2c869c427fec1"; +my $key = pack("H*", '2b7e151628aed2a6abf7158809cf4f3c'); +my $iv = pack("H*", '000102030405060708090a0b0c0d0e0f'); +my $crt_mode = 0; + +sub do_test { + my %a = @_; + my $pt = pack("H*", $a{pt}); + my $key = pack("H*", $a{key}); + my $iv = pack("H*", $a{iv}); + my $ct_out = Crypt::Mode::CTR->new('AES', $a{mode}, $a{width})->encrypt($pt, $key, $iv); + is(unpack("H*", $ct_out), $a{ct}, "cipher text [m=$a{mode}, w=$a{width}]"); + my $pt_out = Crypt::Mode::CTR->new('AES', $a{mode}, $a{width})->decrypt($ct_out, $key, $iv); + is(unpack("H*", $pt_out), $a{pt}, "plain text [m=$a{mode}, w=$a{width}]"); +} + +do_test(%$_) for ( + { + pt => '6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710', + ct => '3b3fd92eb72dad20333449f8e83cfb4a96ef86442deb1b77ed386671a3c3ecfab3006f3856f9a6699a37efae3e3d5c62b501d9aec0ea791c33b2c869c427fec1', + key => '2b7e151628aed2a6abf7158809cf4f3c', iv => '000102030405060708090a0b0c0d0e0f', + mode => 0, width => 0, + }, + { + pt => '6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710', + ct => '3b3fd92eb72dad20333449f8e83cfb4a010c041999e03f36448624483e582d0ea62293cfa6df74535c354181168774df2d55a54706273c50d7b4f8a8cddc6ed7', + key => '2b7e151628aed2a6abf7158809cf4f3c', iv => '000102030405060708090a0b0c0d0e0f', + mode => 1, width => 0, + }, + { + pt => '6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710', + ct => '5303b2f11da8287d9ab277cc95ff75812de5f929eba6eee4e17b411b619880dc7356e1adbcf9061a7b62480b38419b3e0146ff417abed13f054b9de33a7d3837', + key => '2b7e151628aed2a6abf7158809cf4f3c', iv => '000102030405060708090a0b0c0d0e0f', + mode => 2, width => 0, + }, + { + pt => '6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710', + ct => 'c4e030aca9a30c3c330c35f50864b47538c705de1b803cde2779ef344922a861eb029d447a3443569f6478ca31ba0b28ee4c049b87186d1a43e8bf76a1320b79', + key => '2b7e151628aed2a6abf7158809cf4f3c', iv => '000102030405060708090a0b0c0d0e0f', + mode => 3, width => 0, + }, +); diff --git a/t/mode_ecb.t b/t/mode_ecb.t new file mode 100644 index 0000000..0f7dab1 --- /dev/null +++ b/t/mode_ecb.t @@ -0,0 +1,85 @@ +use strict; +use warnings; +use Test::More tests => 266; +use Crypt::Mode::ECB; + +my @tests; + +# test vectors from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf +push @tests, + { padding=>'none', key=>'2b7e151628aed2a6abf7158809cf4f3c', pt=>'6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710', ct=>'3ad77bb40d7a3660a89ecaf32466ef97f5d3d58503b9699de785895a96fdbaaf43b1cd7f598ece23881b00e3ed0306887b0c785e27e8ad3f8223207104725dd4' }, + { padding=>'none', key=>'8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b', pt=>'6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710', ct=>'bd334f1d6e45f25ff712a214571fa5cc974104846d0ad3ad7734ecb3ecee4eefef7afd2270e2e60adce0ba2face6444e9a4b41ba738d6c72fb16691603c18e0e' }, + { padding=>'none', key=>'603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4', pt=>'6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710', ct=>'f3eed1bdb5d2a03c064b5a7e3db181f8591ccb10d410ed26dc5ba74a31362870b6ed21b99ca6f4f9f153e7b1beafed1d23304b7a39f9f3ff067d8d8f9e24ecc7' }, +; + +# test vectors produced by Crypt::ECB +push @tests, + { mode=>'AES+Crypt::ECB', padding=>'standard', len=>45, key=>'9c1975bc3f89e58f790e8e1cdaeea5cc1147fa43c5da2f9ae681274bd406a663', pt=>'a99303fcd37a6c39acb2dd2f3955cbcdf2d4643cc5542019f549ca2b62a4b27a099f42e0a8fb90fc53f0f32c5402f89822215472d1a5c5e8e299090cfeb80151222922c91aa0a8e21ff07147ca62a4542cc36fb437ff2f56be51e6db4e763252960b4a02cfda2fb8a74a63c0fa', ct=>'b52d56dfbd230e87af5d6cd122b050ba4dacfa112e214359d04626efbf57ccde810246076261e0dd7be797bc9b07b20c3a737f72822498fecc68d73ff6c057a1313684058ff1110af0e59347953e1b337b6dbcb852f9210099ea4b54482ae4d9069193d5cb22c6cdfad968a27771b38b' }, + { mode=>'AES+Crypt::ECB', padding=>'standard', len=>46, key=>'11748a8de11e393c610eb582ee3534414f7187790435cdcbe1fd5f7c6db757be', pt=>'ff6da3d97b3907fcc171090bdcc97a43d98cde4bd76937eb672e3a4ce04b15de634d6c320bbe0b84304e52fbf004111f0d0671674196b3ea380f09295a04deb1f26b4d49bc239669bbed6b9316277516914ca4f30d570c156ea90f58565cbf26ead7c6d04eb411b83ef2445a914c', ct=>'91f00f683e3a381ebadb9553db928776fa972a06ca73a31e38ba6501d0f7b27c0013dcf3b25b3206ccd2083fcc815eaa3f843fa14ceca9e54a687b69d0e515dff1cf4b756744f242955b766c87473275ffa6c2191c89ad064c4b83e95ded84514613bc5d7763ffc0b0ec2281bf36d76c' }, + { mode=>'AES+Crypt::ECB', padding=>'standard', len=>47, key=>'d36ba22781e756dfe5e64bc9729e7d50bc00a24133ea90de1d77e666e9b39bb5', pt=>'a74a52d0a02d9e959127a1fa84790605828c6e1e8a9d71ff78320b1bc888affb3e19db2c5e62233ef6ab4adf89524efe369b12259925461b88d412d8276e5e80f327addee10c3e99778e0df730cf70509faef08e7c22b2142cc6201474465b47af54e99299290117eca9514a583ecf', ct=>'1e768190063599f2be4309a27c2d1b294714bb567f231ea9ad17fe31c183b3ab2d3db1b95a3e646aa88c35d98b3ce193640e2013e643b5da787087a2a115b1f61370e42943c90c384c64b128eeaa06c98b0c7b9e9a3c2b875100c5fb9703c5e94dc394c45ffc079d2ba75ad2b342100e' }, + { mode=>'AES+Crypt::ECB', padding=>'standard', len=>48, key=>'c81db73dd90c0edec5dc988ef9c23284ccf5030997c5b3ab971cd134fbfb7915', pt=>'aabc66bbf94ecaafd3368d2ad464522d86431ebdfb678d0e6bf7012614f24e760265918f5765f4ecca2fb74dc1b699d553d8dd3fc758df536e70d26729d1c06cc3c06bb4050f9b53df9b9f0977142646cbdd0a4b7efae5935505af6902b90831fa2bc01d5cede403c769815f5e926eea', ct=>'79e038414bbff323f8ace3b38eec6a49e9b011d83531a9655037f8c12a8d0cf2ed5fd8f293edcbfc1c1876773c9f4c36279dc3893229556af897a8948a6f0cf2007447925badf65f8cb18b30efc1ce9a58fe826b973466b316277ecd11deb804fa9fb8c4f46fcf225f4484af6ff7259ee5ea601127a1882030eb31d679214f5a' }, + { mode=>'AES+Crypt::ECB', padding=>'standard', len=>49, key=>'5e077065a0d1344fbf08106c0e1ceaca7b9455641291b41ccc68285770d72921', pt=>'b2ef1c2557039e56d1c01d68c8e0cc1ee632dbccb7fe2b344d3327b86844f7e428a36e55d2e7fcf53579056a067f868693ea0bae53173942ab12a1ef8b7155361648d48431b9529c5fc1d8400fcd38235037979aefd97f29b3fe949c75f457223113a2d1680061a3b89930401df2397200', ct=>'532f55915edca9782577b1828fcb9fb4c6de41b9f0ba65d2925aadf27949c8445da27c994dc8f13cf3e37af2b2b841058b6f49cf1d32a259773fa3aae38a3d97e954be3371ef46b204deb6a0f4148623d2b2dd70ce5218dbd7930b8d81e914b17b8ebb622201b87f06bae3de1def3b27e2773d188a4a2f8b4d2d857c09113d8a' }, + { mode=>'AES+Crypt::ECB', padding=>'standard', len=>50, key=>'1668a028d8da7cc4181886416ba735f22dab4df08722ba97c3eaff1eafde09a1', pt=>'a15c2358e9254c4f541d9873ce11353108901a4dba5beca1a856d42d06746dd55508eb7d8c66f506edb6ceed07f9bc5bc2d077a6d232d1ae97fec21bf3f5658c2026bb985a71bc5649aecdc76bfeadfba78ff75e60889e0dbe71c86cf6de2fd63225d7fde4452f8220c45985f9d8eaaeec01', ct=>'456c08bbc1afa46126fe81b95f4a3fbc1ab284ff5cf45c21bed20fc21a6086b91ec3e6a8b22798491953dc8632de38812ea8e6fcc914d0603409da7911420a2de7a514722177937384cc2c63800cf66eb0e61513b141c65ab08db8aec887e5599c0e02b6660a4084985e5bdcbf29e5b46c4cca64761fb4d02a9c913153d4cc6a' }, + { mode=>'AES+Crypt::ECB', padding=>'standard', len=>61, key=>'082350b5a25d440529c7aa42eff92407b21805b36b6c9123385d600011abce63', pt=>'a7382c0e4a60bf66b001bddebf0e91a7a07dfaab25b8bfb05144e1fa33859e76b9369495712c65fd238d4f9ffdc8b93ea754035fdb5b8d4ac00c4d648b5d4890ff9cf8e7c51d9d349647e0940d9e544b0580c82522c811e690b31217f63fea643a235b39924fe2f49426c0640fd1d17290b9e96cf16b4f8d02eedcc8f6', ct=>'0b4d53297e8cc94c25fc7bd2045433743f26ce8e5bddfdeb2b725165a83971599569f42abe5820cee5ac8b70a9abde3e872b94fc3734c1f326933344c64443dc56c191c18442a963fe722dde88996fa7328ecba06da7c01637e958da30d79ea528bd478d94f89529de6c5a15704464bd8be825315cbf15044041448eb27733b9' }, + { mode=>'AES+Crypt::ECB', padding=>'standard', len=>62, key=>'802612ccbea22d8557d99004907ed090ac369f44a3a6c5f4685d9e7d5d71ed32', pt=>'431a32eaeb7c7947bcb0f3cd97d75ba606befb12f10893122983a4a20ed37d3ef15067f8730c0562bc064590cf49132827f420ccf50853083ab403d6fac899c00bb3b34c3bde1900aaf887d053842ca4e08ba805e62f820631f98b594601b81eb0c892d6841f37267ac4c6ffd98fb42c2e52048ffdd51ca88b9b982821b9', ct=>'a5c525f9994b6c33f5ab57c9b0c98eff74699d3439009103b39b2fbae5f5d4f93c86df65066a8656873ef44fbf4e71c6381e7119254d42e6e903a1c5c7ade99a3ad92b9104b8fb000af967d10e79750a5edab1706192bfcdb750398439ba22880dedc3124d37a2b6655ab7aeebf769b7d2f8142d90f897baa928107fc6a17299' }, + { mode=>'AES+Crypt::ECB', padding=>'standard', len=>63, key=>'b673afee984c45eac1bce4387e9079fe82497dc597c9cfbe8e53fade93099640', pt=>'58643eb31a9951c4928ca5612f8893223a2cf03ab2db6cf9464230431edb9f87bf664e49eca86196e5708450929258f31cc0c13f95d5be45f943a41b827a5eb316407ce518943a67fd1f9b3fa1eec0c39dc142e19445372d552148c5b2190aca407f5f8d372f18a904c1beef4e54c3b6255bd458712448d6b88dcd3176c022', ct=>'3582f853543ea393d6ac2eaa30d765def81f21da8db46c301000c0a3a30bff4c380267b8705feb48d5f16d7937140cd878fcfae99801b2908f83f1a5e84fffbab86495f9c47791a8714567f671ac7fac63921b25da5ac30d18d859c1f33d404bd9960a116eabe71098a3372199aa1fa9866ae5cf9c83b76983a9be6503fb307a' }, + { mode=>'AES+Crypt::ECB', padding=>'standard', len=>64, key=>'f5f9efb5f4fe71186a91f3eb2944c4e54bf45614dff6e473fcfa9c0b885311dd', pt=>'ef06a0bcc0f1b26a41736052540c8badc53cd08c093e12a68bffc43bb5707a0d98c16ad988d811498add8fa0059a0f238badbec6cfad0184b560903ef635ec2de847af2e9a140e71095b75f420a560aa846ea5f3306380ac79af896f6c1695781488000ee3aff9e23424bdfe83deb52b1857bb54995fbda358d8ac9f6c9b2002', ct=>'285da6c06751a6811b4a6f56ad1c3a6ee3813d695bedd8151e0282357038109e15b0c2cd9c7008ab4513a1f48ee298b750b115f7bfa906b6c481ba5e0117611a8de0386de099bf6fad8e7e85412a3dd040fcaef75fb57e1ccb23c9f3da84fed22d4d6ce31fb73abad54396449d54519b9c95cbf34eb1cf5aed4c526531c5580bd62ff10c0dd5110bab7bc3e9b0ea00b3' }, + { mode=>'AES+Crypt::ECB', padding=>'standard', len=>65, key=>'d12852a3a07b7b83f55565df4fdf825a0db8ccda4a3f6598a9751d9924e9f7ce', pt=>'c58d1ab06aade14858687993232e7836ebd4fa71ca2c734efcb9a442ecff26d9ed96760b2bb5fd0de05e3cdd6292fead7c7b3fcd52867ab48bb12bb4f64c35c2efc545705abe4188251df968e1dba60fa5936eda59c36e2b10b945e9266db8484673496c4862ded7ac3bc68b8103e5433d48eb19fd756436993733e43bd5cb08e7', ct=>'87b71b3ce97e1a0cf52b088ad3605331b63e8159f093f17153e57b47a4021c99e069c529c2dbaa4c86522a86eb1b89aff03e5b6c2c06ceee46de322598c6f4d23471d36642be5d7635577c935e5a600fa473d5a283da969ec73ed5572d6cb4eaf97a47a460d9920cf805275c904380db321286bc1c5d552093ee7016daa095d6cb151076329a592688d60aab65d4d3bb' }, + { mode=>'AES+Crypt::ECB', padding=>'standard', len=>66, key=>'24667ee02db1e4b35984c6678dd5d3eb18ebfc3c8530c7b4cebe76aace87977a', pt=>'5ecef2891b3d9cc2dfbc44af183237cef460736313338399b1499e5aff94b08ced6a33f8765bfa3e6874b0d1bcc8f73588abcd95013db83cf1cd23aa7e6eabd71427ae460cdf46a2d3b79e9c98d69a4b124f17e292ac714e96ac544bb48707812ed7266e122560493ca13c1c78d9353f2e2a6a95163e1ddf5e09e8fd3fec0ddb4ded', ct=>'df1b5cb5c2b9d6aa58fea48567b0b7aa02a1b06627decdf7e9a5886dfbadfb937c185ea45140776ff1976fa549e40918efb97f387b4bdc73be38bb58be6ca4a1c592d69eb2830c8523a1c1fd2b16706c1fdf61916348ca5cec4274b800bd37c831f8d96bdd3951a45ceea3d1e2228beb8e723e163810e45c1c52d1941771c9d062a7da642a8c868a13925e3aa4b1c761' }, + { mode=>'AES+Crypt::ECB', padding=>'none', len=>48, key=>'661b5aff95cf8ab76e45b526bef583396b9eba163e10847afaac7ad36b3979cd', pt=>'9dd919c944cbdba69a3c5d5233148dc4042f36c18acb4b49704c9f87d8532168d1f75ef4bce56d729b67f55743deb3dd719498c1995dfc887465d5561985b33f8f5105ab39b6ac05f1aa27e2f0a19c72996ff4014778ec883f1a3a1d48174a24e8bcc84546c491b3da040b3fd001c4ec', ct=>'34e43d2c24ba6c2e5c32b817171b7dd780ba3bd4d774e7a51c20b992d4c29cb570e161d43aba819155242ecf960bd363e471d19772f37669e1ca552535744df3f6a6540b85a90a67fa2c3343dcd2f2f2c9b72578b823b09405a3d917b65ae1a29a0638df46aa0b8dfb62fd1a199a281e' }, + { mode=>'AES+Crypt::ECB', padding=>'none', len=>64, key=>'9d59c6f36300896c33d5f9adbea4831fa158e29fd2020cdcf93405671d591729', pt=>'e6daa0b28199d245fa3293f710a1a72eb92dadc63fad8a0c8b0f4cba85c350a2b133f0630dd13900c5a5067f1e5425b5272aa147e209cbd57af939a431865b9c1c928bab46d2c5b5d1e34041b9099bd09e32223181848da4a7c3ab6f1426d4f30bd51fa48e032d49285e3e1d2c7e9def030e57784c83135550cbb1fed7849d64', ct=>'97645d39a60497d80f542f61d81f3a065562852c375f95d3709d6b51bdbd0faf6a1112524c1625550d31047acfebc567ddf39d061ef57e85c65243bec96a69b5dc53674570380cef776d4c0744bd3f9c82d47b11ce81c77a6ee014503de4adbf9c78a32e70bb916378428f9a33f3f1837bbeb559fdb1675219f83fbefc4a361b' }, +; + +for (@tests) { + my ($pt, $ct, $m); + $m = 0 if $_->{padding} eq 'none'; + $m = 1 if $_->{padding} eq 'standard'; + $m = 2 if $_->{padding} eq 'oneandzeroes'; + die "invalid padding" unless defined $m; + $ct = Crypt::Mode::ECB->new('AES', $m)->encrypt(pack("H*",$_->{pt}), pack("H*",$_->{key})); + $pt = Crypt::Mode::ECB->new('AES', $m)->decrypt(pack("H*",$_->{ct}), pack("H*",$_->{key})); + ok($ct, "cipher text"); + ok($pt, "plain text"); + is(unpack("H*",$ct), $_->{ct}, 'cipher text match'); + is(unpack("H*",$pt), $_->{pt}, 'plain text match'); +} + +{ + my @t = ( + { padding=>1, key=>'f5f9efb5f4fe71186a91f3eb2944c4e54bf45614dff6e473fcfa9c0b885311dd', pt=>'ef06a0bcc0f1b26a41736052540c8badc53cd08c093e12a68bffc43bb5707a0d98c16ad988d811498add8fa0059a0f238badbec6cfad0184b560903ef635ec2de847af2e9a140e71095b75f420a560aa846ea5f3306380ac79af896f6c1695781488000ee3aff9e23424bdfe83deb52b1857bb54995fbda358d8ac9f6c9b2002', ct=>'285da6c06751a6811b4a6f56ad1c3a6ee3813d695bedd8151e0282357038109e15b0c2cd9c7008ab4513a1f48ee298b750b115f7bfa906b6c481ba5e0117611a8de0386de099bf6fad8e7e85412a3dd040fcaef75fb57e1ccb23c9f3da84fed22d4d6ce31fb73abad54396449d54519b9c95cbf34eb1cf5aed4c526531c5580bd62ff10c0dd5110bab7bc3e9b0ea00b3' }, + { padding=>1, key=>'d12852a3a07b7b83f55565df4fdf825a0db8ccda4a3f6598a9751d9924e9f7ce', pt=>'c58d1ab06aade14858687993232e7836ebd4fa71ca2c734efcb9a442ecff26d9ed96760b2bb5fd0de05e3cdd6292fead7c7b3fcd52867ab48bb12bb4f64c35c2efc545705abe4188251df968e1dba60fa5936eda59c36e2b10b945e9266db8484673496c4862ded7ac3bc68b8103e5433d48eb19fd756436993733e43bd5cb08e7', ct=>'87b71b3ce97e1a0cf52b088ad3605331b63e8159f093f17153e57b47a4021c99e069c529c2dbaa4c86522a86eb1b89aff03e5b6c2c06ceee46de322598c6f4d23471d36642be5d7635577c935e5a600fa473d5a283da969ec73ed5572d6cb4eaf97a47a460d9920cf805275c904380db321286bc1c5d552093ee7016daa095d6cb151076329a592688d60aab65d4d3bb' }, + { padding=>0, key=>'9d59c6f36300896c33d5f9adbea4831fa158e29fd2020cdcf93405671d591729', pt=>'e6daa0b28199d245fa3293f710a1a72eb92dadc63fad8a0c8b0f4cba85c350a2b133f0630dd13900c5a5067f1e5425b5272aa147e209cbd57af939a431865b9c1c928bab46d2c5b5d1e34041b9099bd09e32223181848da4a7c3ab6f1426d4f30bd51fa48e032d49285e3e1d2c7e9def030e57784c83135550cbb1fed7849d64', ct=>'97645d39a60497d80f542f61d81f3a065562852c375f95d3709d6b51bdbd0faf6a1112524c1625550d31047acfebc567ddf39d061ef57e85c65243bec96a69b5dc53674570380cef776d4c0744bd3f9c82d47b11ce81c77a6ee014503de4adbf9c78a32e70bb916378428f9a33f3f1837bbeb559fdb1675219f83fbefc4a361b' }, + ); + for (@t) { + my $pt = pack("H*", $_->{pt}); + my $ct = pack("H*", $_->{ct}); + my $m = Crypt::Mode::ECB->new('AES', $_->{padding}); + for my $l (1..33) { + + { + $m->start_encrypt(pack("H*",$_->{key})); + my $i = 0; + my $ct = ''; + while ($i < length($pt)) { + $ct .= $m->add(substr($pt, $i, $l)); + $i += $l; + } + $ct .= $m->finish; + is(unpack("H*",$ct), $_->{ct}, "cipher text match [l=$l]"); + } + + { + $m->start_decrypt(pack("H*",$_->{key})); + my $i = 0; + my $pt = ''; + while ($i < length($ct)) { + $pt .= $m->add(substr($ct, $i, $l)); + $i += $l; + } + $pt .= $m->finish; + is(unpack("H*",$pt), $_->{pt}, "plain text match [l=$l]"); + } + + } + } +} diff --git a/t/mode_ofb.t b/t/mode_ofb.t new file mode 100644 index 0000000..84266db --- /dev/null +++ b/t/mode_ofb.t @@ -0,0 +1,28 @@ +use strict; +use warnings; +use Test::More tests => 12; +use Crypt::Mode::OFB; + +my @tests = ( + { key=>'2b7e151628aed2a6abf7158809cf4f3c', iv=>'000102030405060708090a0b0c0d0e0f', + pt=>'6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710', + ct=>'3b3fd92eb72dad20333449f8e83cfb4a7789508d16918f03f53c52dac54ed8259740051e9c5fecf64344f7a82260edcc304c6528f659c77866a510d9c1d6ae5e' }, + { key=>'8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b', iv=>'000102030405060708090a0b0c0d0e0f', + pt=>'6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c', + ct=>'cdc80d6fddf18cab34c25909c99a4174fcc28b8d4c63837c09e81700c11004018d9a9aeac0f6596f559c6d4daf59a5f26d9f200857ca6c3e9cac524bd9ac' }, + { key=>'603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4', iv=>'000102030405060708090a0b0c0d0e0f', + pt=>'6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417b', + ct=>'dc7e84bfda79164b7ecd8486985d38604febdc6740d20b3ac88f6ad82a4fb08d71ab47a086e86eedf39d1c5bba97c4080126141d67f37be8538f5a8b' }, +); + +my $m = Crypt::Mode::OFB->new('AES'); + +for (@tests) { + my ($pt, $ct); + $ct = $m->encrypt(pack("H*",$_->{pt}), pack("H*",$_->{key}), pack("H*",$_->{iv})); + $pt = $m->decrypt(pack("H*",$_->{ct}), pack("H*",$_->{key}), pack("H*",$_->{iv})); + ok($ct, "cipher text"); + ok($pt, "plain text"); + is(unpack("H*",$ct), $_->{ct}, 'cipher text match'); + is(unpack("H*",$pt), $_->{pt}, 'plain text match'); +} diff --git a/t/pk_dh.t b/t/pk_dh.t new file mode 100644 index 0000000..ec0b82e --- /dev/null +++ b/t/pk_dh.t @@ -0,0 +1,209 @@ +use strict; +use warnings; +use Test::More tests => 74; + +use Crypt::PK::DH qw(dh_encrypt dh_decrypt dh_sign_message dh_verify_message dh_sign_hash dh_verify_hash dh_shared_secret); + +{ + my $k; + + $k = Crypt::PK::DH->new('t/data/cryptx_priv_dh1.bin'); + ok($k, 'load cryptx_priv_dh1.bin'); + ok($k->is_private, 'is_private cryptx_priv_dh1.bin'); + is($k->size, 256, 'size'); + is(uc($k->key2hash->{x}), 'FBC1062F73B9A17BB8473A2F5A074911FA7F20D28FBF5D7F4DAF58016CE03A391BA57CB80067EB2D59AD1AA66869F5F37A1B57D440428F67881085F7C1484FADC3A54E39703CE679068417269651DD3438EDBF7827A09419F88A326B76EF04D81145D87D7D2DCF1B24902202B971BBF2EEF956A1EA1A88770097B94C859AE4F06DDDEB9ED31084004815F97D4F6F74C791CF1EC1836013DF835B653E8704981D52FF2323F7AFE22915B82CBA7EBF0558ACA6A182A6F3D631B843B72137D4E5B07603A7517F6768B375FC6C38F7B767C63E5A3DD99CD9EA0992C236EB827EAD4E877430F260020E64CBA26DAA8DEEF5D216C11941C48F76FE2B097BB5D504FBCF', 'key2hash'); + + $k = Crypt::PK::DH->new('t/data/cryptx_priv_dh2.bin'); + ok($k, 'load cryptx_priv_dh2.bin'); + ok($k->is_private, 'is_private cryptx_priv_dh2.bin'); + + $k = Crypt::PK::DH->new('t/data/cryptx_pub_dh1.bin'); + ok($k, 'load cryptx_pub_dh1.bin'); + ok(!$k->is_private, 'is_private cryptx_pub_dh1.bin'); + + $k = Crypt::PK::DH->new('t/data/cryptx_pub_dh2.bin'); + ok($k, 'load cryptx_pub_dh2.bin'); + ok(!$k->is_private, 'is_private cryptx_pub_dh2.bin'); +} + +{ + my $k; + + $k = Crypt::PK::DH->new('t/data/cryptx_priv_dh_pg1.bin'); + ok($k, 'load cryptx_priv_dh_pg1.bin'); + ok($k->is_private, 'is_private cryptx_priv_dh_pg1.bin'); + is($k->size, 256, 'size'); + is(uc($k->key2hash->{x}), '29BB37065071D1C23AE0D8C555E24E5E546954B985260ECC6A1A21252FCFD2D633B0580F6A00B80ED75123EC37A3E784F888EE026C1034CD930CA58464EB6A59A090D1113855AFA48C9A79631E2534D7F33FAD4DC8FF48E88C865E517B67DAD4B40D64BD67CBFE52F56FBC6764D0629E5EFF63351AF19FF398375BDCE22FBDF3A044DAB2B6EAAA44D1A78F4FF74088175E6B5F184222F116F4C6188547F90B0ADCA3255EA7148CB57E5E852E79F438F995CFC3AC79A01D2C329C0750D55FDADCC6FAF6D6850892EEC073FD77CC7F98D8D317D402E2A89E4161001DAEF43DAC0F386E48870D457FB12CC5B70E6F5719609631CB8B439DB6D2F04CF8A774678F68', 'key2hash'); + + $k = Crypt::PK::DH->new('t/data/cryptx_priv_dh_pg2.bin'); + ok($k, 'load cryptx_priv_dh_pg2.bin'); + ok($k->is_private, 'is_private cryptx_priv_dh_pg2.bin'); + + $k = Crypt::PK::DH->new('t/data/cryptx_pub_dh_pg1.bin'); + ok($k, 'load cryptx_pub_dh_pg1.bin'); + ok(!$k->is_private, 'is_private cryptx_pub_dh_pg1.bin'); + + $k = Crypt::PK::DH->new('t/data/cryptx_pub_dh_pg2.bin'); + ok($k, 'load cryptx_pub_dh_pg2.bin'); + ok(!$k->is_private, 'is_private cryptx_pub_dh_pg2.bin'); +} + +{ + my $pr1 = Crypt::PK::DH->new; + $pr1->import_key('t/data/cryptx_priv_dh1.bin'); + my $pu1 = Crypt::PK::DH->new; + $pu1->import_key('t/data/cryptx_pub_dh1.bin'); + + my $ct = $pu1->encrypt("secret message"); + my $pt = $pr1->decrypt($ct); + ok(length $ct > 100, 'encrypt ' . length($ct)); + is($pt, "secret message", 'decrypt'); + + my $sig = $pr1->sign_message("message"); + ok(length $sig > 60, 'sign_message ' . length($sig)); + ok($pu1->verify_message($sig, "message"), 'verify_message'); + + my $hash = pack("H*","04624fae618e9ad0c5e479f62e1420c71fff34dd"); + $sig = $pr1->sign_hash($hash, 'SHA1'); + ok(length $sig > 60, 'sign_hash ' . length($sig)); + ok($pu1->verify_hash($sig, $hash, 'SHA1'), 'verify_hash'); + + my $pr2 = Crypt::PK::DH->new; + $pr2->import_key('t/data/cryptx_priv_dh2.bin'); + my $pu2 = Crypt::PK::DH->new; + $pu2->import_key('t/data/cryptx_pub_dh2.bin'); + + my $ss1 = $pr1->shared_secret($pu2); + my $ss2 = $pr2->shared_secret($pu1); + is(unpack("H*",$ss1), unpack("H*",$ss2), 'shared_secret'); +} + +{ + my $pr1 = Crypt::PK::DH->new; + $pr1->import_key('t/data/cryptx_priv_dh_pg1.bin'); + my $pu1 = Crypt::PK::DH->new; + $pu1->import_key('t/data/cryptx_pub_dh_pg1.bin'); + + my $ct = $pu1->encrypt("secret message"); + my $pt = $pr1->decrypt($ct); + ok(length $ct > 100, 'encrypt ' . length($ct)); + is($pt, "secret message", 'decrypt'); + + my $sig = $pr1->sign_message("message"); + ok(length $sig > 60, 'sign_message ' . length($sig)); + ok($pu1->verify_message($sig, "message"), 'verify_message'); + + my $hash = pack("H*","04624fae618e9ad0c5e479f62e1420c71fff34dd"); + $sig = $pr1->sign_hash($hash, 'SHA1'); + ok(length $sig > 60, 'sign_hash ' . length($sig)); + ok($pu1->verify_hash($sig, $hash, 'SHA1'), 'verify_hash'); + + my $pr2 = Crypt::PK::DH->new; + $pr2->import_key('t/data/cryptx_priv_dh_pg2.bin'); + my $pu2 = Crypt::PK::DH->new; + $pu2->import_key('t/data/cryptx_pub_dh_pg2.bin'); + + my $ss1 = $pr1->shared_secret($pu2); + my $ss2 = $pr2->shared_secret($pu1); + is(unpack("H*",$ss1), unpack("H*",$ss2), 'shared_secret'); +} + +{ + my $pr1 = Crypt::PK::DH->new; + $pr1->import_key_raw(pack('H*','5F7EF8D4F7D80C2D88ADADDFE57F4F4DC578259E3B5F42D82838D5905FF6D2BECDC489452D3F5807EF4E2361821089DDC9B27198D79E9C22EE249318688FE250CCC69E49C5F985777405A76264C5EF0D83AEA1C368B1E1A48DC0E04D6E0C884F0C95A3949B29A05437A6179E7AADCC4D095A55C03046296C02AA9991EFD17745615726D52B8B8A12DAC7218265DBB4B760176C27E644AD2EC15B238980326BE1B27D5AC28EA2B2DC5F24FD6A315CA2193A23370B130B541D54C470AD91BE20ECD697B01C2DAEE00E0027A9EBD2D87404E20ADE1DE3B92798928B837AC5EFB305C168823D362A1162C7A709A70E6619F01AF113E316376B3561F88AC2B6F647B2'),'private','ike2048'); + my $pu1 = Crypt::PK::DH->new; + $pu1->import_key_raw(pack('H*','4B9ECB56202EDBC6578072A4519EBE625DE8972877462240F62393C59A6C04AA159E56505156E7DF645FF6EC588E0778A96B78B26A0793D90A4B5C5EC4C61EA69D21C630843ACC2BFD3864CD9DA9600BA8F1B7D8542B01F7251AA3AC257C7AC65A1D2BCF51A8E3E67D9544599B0956710E2B052CDA9B565CDD121CC123364B480E9E7E2237D3D6B5B1E200C7BF858C54CCD3175736DB28336210A16F8F0ACEC08847EF7905FAB7E97E626CFD13CBDF167441FEEB72CB6E7407DFC59F03249F79312A94DA89B1D61196B41E90C08D2C801FD7BEA02A47A1CDA1581F57BA700C1BCDDE6338718E19079055194CAF176D85464957D405B04CC3DD9756C211E11BF2'),'public','ike2048'); + ok($pr1, 'import_key_raw private1'); + ok($pu1, 'import_key_raw public1'); + ok($pr1->is_private, 'is_private private1'); + ok(!$pu1->is_private, 'is_private public1'); + is(uc(unpack('H*',$pr1->export_key_raw('private'))),'5F7EF8D4F7D80C2D88ADADDFE57F4F4DC578259E3B5F42D82838D5905FF6D2BECDC489452D3F5807EF4E2361821089DDC9B27198D79E9C22EE249318688FE250CCC69E49C5F985777405A76264C5EF0D83AEA1C368B1E1A48DC0E04D6E0C884F0C95A3949B29A05437A6179E7AADCC4D095A55C03046296C02AA9991EFD17745615726D52B8B8A12DAC7218265DBB4B760176C27E644AD2EC15B238980326BE1B27D5AC28EA2B2DC5F24FD6A315CA2193A23370B130B541D54C470AD91BE20ECD697B01C2DAEE00E0027A9EBD2D87404E20ADE1DE3B92798928B837AC5EFB305C168823D362A1162C7A709A70E6619F01AF113E316376B3561F88AC2B6F647B2'); + is(uc(unpack('H*',$pr1->export_key_raw('public'))),'4B9ECB56202EDBC6578072A4519EBE625DE8972877462240F62393C59A6C04AA159E56505156E7DF645FF6EC588E0778A96B78B26A0793D90A4B5C5EC4C61EA69D21C630843ACC2BFD3864CD9DA9600BA8F1B7D8542B01F7251AA3AC257C7AC65A1D2BCF51A8E3E67D9544599B0956710E2B052CDA9B565CDD121CC123364B480E9E7E2237D3D6B5B1E200C7BF858C54CCD3175736DB28336210A16F8F0ACEC08847EF7905FAB7E97E626CFD13CBDF167441FEEB72CB6E7407DFC59F03249F79312A94DA89B1D61196B41E90C08D2C801FD7BEA02A47A1CDA1581F57BA700C1BCDDE6338718E19079055194CAF176D85464957D405B04CC3DD9756C211E11BF2'); + is(uc(unpack('H*',$pu1->export_key_raw('public'))),'4B9ECB56202EDBC6578072A4519EBE625DE8972877462240F62393C59A6C04AA159E56505156E7DF645FF6EC588E0778A96B78B26A0793D90A4B5C5EC4C61EA69D21C630843ACC2BFD3864CD9DA9600BA8F1B7D8542B01F7251AA3AC257C7AC65A1D2BCF51A8E3E67D9544599B0956710E2B052CDA9B565CDD121CC123364B480E9E7E2237D3D6B5B1E200C7BF858C54CCD3175736DB28336210A16F8F0ACEC08847EF7905FAB7E97E626CFD13CBDF167441FEEB72CB6E7407DFC59F03249F79312A94DA89B1D61196B41E90C08D2C801FD7BEA02A47A1CDA1581F57BA700C1BCDDE6338718E19079055194CAF176D85464957D405B04CC3DD9756C211E11BF2'); + + my $ct = $pu1->encrypt("secret message"); + my $pt = $pr1->decrypt($ct); + ok(length $ct > 100, 'encrypt ' . length($ct)); + is($pt, "secret message", 'decrypt'); + + my $sig = $pr1->sign_message("message"); + ok(length $sig > 60, 'sign_message ' . length($sig)); + ok($pu1->verify_message($sig, "message"), 'verify_message'); + + my $hash = pack("H*","04624fae618e9ad0c5e479f62e1420c71fff34dd"); + $sig = $pr1->sign_hash($hash, 'SHA1'); + ok(length $sig > 60, 'sign_hash ' . length($sig)); + ok($pu1->verify_hash($sig, $hash, 'SHA1'), 'verify_hash'); + + my $pr2 = Crypt::PK::DH->new; + $pr2->import_key_raw(pack('H*','473156C909EBB0A6F61F707CDDD7E6401BFDE22BC57B8D3CCC30C4CD3FF7678CCD9B022167AA774786F367FE5B5924A3C1E09AA71264F94E7ABA87FFA888913BB9592613F8AD87FBE82E99064B00CE3294CFD410BCFB4C88A46F5F8532633458C317DF40F395C2F08A822D84BF4291A1A63DE1F6D0F460DB81C685ADD0F26262307823227C17B4671BCF74A6337738BB4596337644656A060F1BB109640878D23F56E493719D6EF60FEA7AC85123CFB6E476392789AC1FE4F4CA371DB2863192ADE424F3EFDEE52D4CB445B99B10566A4B6F6DC813C265DC0052D710AEAA0969392BD478A46AB9C7A0E2FA27964A759938904FCEFAC4CE061C9927764AAB57DC'),'private','ike2048'); + my $pu2 = Crypt::PK::DH->new; + $pu2->import_key_raw(pack('H*','774A01FF19C1603040DFBB5C8A44F11CE8719F757C2AF6B2921EDDDEF27F77D5F2DAF9539BCBCB30F80D76E054C489C9E6533051767E6220539C871F23D3B6F80D84037A6FBAB3AE6AF8F214A60A816D6F0F6C3F31801DCD6EA771F41A2A5618BC333D650F46F22FEA81A94F4E00CD05B83F8FE257A2607E62519D9BF8B8C96D0587FB2BCEC8D18DDCF66EBBB8A56623953531EE27C68C8C37E6413FD2C98339F491A0472E5D4DFADC7BF30E89A2CE2081EE3CF9F9B0FFCD902A3021CAC14A4AD7E00F6202C8A9AB93BF96E33838FB9178DC8A8F995ABD81F28F5A137A78E813ABD185498A3A50CB3021CF58BE9D0200C19928AA097D306ABAD9874E0F217482'),'public','ike2048'); + + my $ss1 = $pr1->shared_secret($pu2); + my $ss2 = $pr2->shared_secret($pu1); + is(unpack("H*",$ss1), unpack("H*",$ss2), 'shared_secret'); +} + +{ + my $k = Crypt::PK::DH->new; + $k->generate_key(256); + ok($k, 'generate_key'); + ok($k->is_private, 'is_private'); + ok($k->export_key('private'), 'export_key_pem pri'); + ok($k->export_key('public'), 'export_key_pem pub'); +} + +{ + my $k = Crypt::PK::DH->new; + $k->generate_key({g => 2, p => 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF'}); + ok($k, 'generate_key'); + ok($k->is_private, 'is_private'); + ok($k->export_key('private'), 'export_key_pem pri gp'); + ok($k->export_key('public'), 'export_key_pem pub gp'); +} + +{ + my $k = Crypt::PK::DH->new; + $k->generate_key('ike2048'); + ok($k, 'generate_key'); + ok($k->is_private, 'is_private'); + ok($k->export_key('private'), 'export_key_pem pri ike2048'); + ok($k->export_key('public'), 'export_key_pem pub ike2048'); +} + +{ + my $ct = dh_encrypt('t/data/cryptx_pub_dh1.bin', 'test string'); + ok($ct, 'dh_encrypt'); + my $pt = dh_decrypt('t/data/cryptx_priv_dh1.bin', $ct); + ok($pt, 'dh_decrypt'); + my $sig = dh_sign_message('t/data/cryptx_priv_dh1.bin', 'test string'); + ok($sig, 'dh_sign_message'); + ok(dh_verify_message('t/data/cryptx_pub_dh1.bin', $sig, 'test string'), 'dh_verify_message'); + my $hash = pack("H*","04624fae618e9ad0c5e479f62e1420c71fff34dd"); + $sig = dh_sign_hash('t/data/cryptx_priv_dh1.bin', $hash, 'SHA1'); + ok($sig, 'dh_sign_hash'); + ok(dh_verify_hash('t/data/cryptx_pub_dh1.bin', $sig, $hash, 'SHA1'), 'dh_verify_hash'); + + my $ss1 = dh_shared_secret('t/data/cryptx_priv_dh1.bin', 't/data/cryptx_pub_dh2.bin'); + my $ss2 = dh_shared_secret('t/data/cryptx_priv_dh2.bin', 't/data/cryptx_pub_dh1.bin'); + is(unpack("H*",$ss1), unpack("H*",$ss2), 'shared_secret'); +} + +{ + my $ct = dh_encrypt('t/data/cryptx_pub_dh_pg1.bin', 'test string'); + ok($ct, 'dh_encrypt'); + my $pt = dh_decrypt('t/data/cryptx_priv_dh_pg1.bin', $ct); + ok($pt, 'dh_decrypt'); + my $sig = dh_sign_message('t/data/cryptx_priv_dh_pg1.bin', 'test string'); + ok($sig, 'dh_sign_message'); + ok(dh_verify_message('t/data/cryptx_pub_dh_pg1.bin', $sig, 'test string'), 'dh_verify_message'); + my $hash = pack("H*","04624fae618e9ad0c5e479f62e1420c71fff34dd"); + $sig = dh_sign_hash('t/data/cryptx_priv_dh_pg1.bin', $hash, 'SHA1'); + ok($sig, 'dh_sign_hash'); + ok(dh_verify_hash('t/data/cryptx_pub_dh_pg1.bin', $sig, $hash, 'SHA1'), 'dh_verify_hash'); + + my $ss1 = dh_shared_secret('t/data/cryptx_priv_dh_pg1.bin', 't/data/cryptx_pub_dh_pg2.bin'); + my $ss2 = dh_shared_secret('t/data/cryptx_priv_dh_pg2.bin', 't/data/cryptx_pub_dh_pg1.bin'); + is(unpack("H*",$ss1), unpack("H*",$ss2), 'shared_secret'); +} diff --git a/t/pk_dsa.t b/t/pk_dsa.t new file mode 100644 index 0000000..80335f6 --- /dev/null +++ b/t/pk_dsa.t @@ -0,0 +1,114 @@ +use strict; +use warnings; +use Test::More tests => 44; + +use Crypt::PK::DSA qw(dsa_encrypt dsa_decrypt dsa_sign_message dsa_verify_message dsa_sign_hash dsa_verify_hash); + +{ + my $k; + + $k = Crypt::PK::DSA->new('t/data/cryptx_priv_dsa1.der'); + ok($k, 'load cryptx_priv_dsa1.der'); + ok($k->is_private, 'is_private cryptx_priv_dsa1.der'); + is($k->size, 256, 'size'); + is(uc($k->key2hash->{x}), '6C801901AC74E2DC714D75A9F6969483CF0239D142AB7E3F329ED8D49E07', 'key2hash'); + + $k = Crypt::PK::DSA->new('t/data/cryptx_priv_dsa2.der'); + ok($k, 'load cryptx_priv_dsa2.der'); + ok($k->is_private, 'is_private cryptx_priv_dsa2.der'); + + $k = Crypt::PK::DSA->new('t/data/cryptx_pub_dsa1.der'); + ok($k, 'load cryptx_pub_dsa1.der'); + ok(!$k->is_private, 'is_private cryptx_pub_dsa1.der'); + + $k = Crypt::PK::DSA->new('t/data/cryptx_pub_dsa2.der'); + ok($k, 'load cryptx_pub_dsa2.der'); + ok(!$k->is_private, 'is_private cryptx_pub_dsa2.der'); + + $k = Crypt::PK::DSA->new('t/data/openssl_dsa1.der'); + ok($k, 'load openssl_dsa1.der'); + ok($k->is_private, 'is_private openssl_dsa1.der'); + + $k = Crypt::PK::DSA->new('t/data/openssl_dsa2.der'); + ok($k, 'load openssl_dsa2.der'); + ok($k->is_private, 'is_private openssl_dsa2.der'); + + $k = Crypt::PK::DSA->new('t/data/cryptx_priv_dsa1.pem'); + ok($k, 'load cryptx_priv_dsa1.pem'); + ok($k->is_private, 'is_private cryptx_priv_dsa1.pem'); + + $k = Crypt::PK::DSA->new('t/data/cryptx_priv_dsa2.pem'); + ok($k, 'load cryptx_priv_dsa2.pem'); + ok($k->is_private, 'is_private cryptx_priv_dsa2.pem'); + + $k = Crypt::PK::DSA->new('t/data/cryptx_pub_dsa1.pem'); + ok($k, 'load cryptx_pub_dsa1.pem'); + ok(!$k->is_private, 'is_private cryptx_pub_dsa1.pem'); + + $k = Crypt::PK::DSA->new('t/data/cryptx_pub_dsa2.pem'); + ok($k, 'load cryptx_pub_dsa2.pem'); + ok(!$k->is_private, 'is_private cryptx_pub_dsa2.pem'); + + $k = Crypt::PK::DSA->new('t/data/openssl_dsa1.pem'); + ok($k, 'load openssl_dsa1.pem'); + ok($k->is_private, 'is_private openssl_dsa1.pem'); + + $k = Crypt::PK::DSA->new('t/data/openssl_dsa2.pem'); + ok($k, 'load openssl_dsa2.pem'); + ok($k->is_private, 'is_private openssl_dsa2.pem'); +} + +{ + my $pr1 = Crypt::PK::DSA->new; + $pr1->import_key('t/data/cryptx_priv_dsa1.der'); + my $pu1 = Crypt::PK::DSA->new; + $pu1->import_key('t/data/cryptx_pub_dsa1.der'); + + my $ct = $pu1->encrypt("secret message"); + my $pt = $pr1->decrypt($ct); + ok(length $ct > 200, 'encrypt ' . length($ct)); + is($pt, "secret message", 'decrypt'); + #XXX-FIXME somwhere here a crash happens on solaris - http://ppm4.activestate.com/sun4-solaris/5.14/1400/M/MI/MIK/CryptX-0.017.d/log-20130924T103600.txt + my $sig = $pr1->sign_message("message"); + ok(length $sig > 60, 'sign_message ' . length($sig)); + ok($pu1->verify_message($sig, "message"), 'verify_message'); + + my $hash = pack("H*","04624fae618e9ad0c5e479f62e1420c71fff34dd"); + $sig = $pr1->sign_hash($hash, 'SHA1'); + ok(length $sig > 60, 'sign_hash ' . length($sig)); + ok($pu1->verify_hash($sig, $hash, 'SHA1'), 'verify_hash'); + + my $pr2 = Crypt::PK::DSA->new; + $pr2->import_key('t/data/cryptx_priv_dsa2.der'); + my $pu2 = Crypt::PK::DSA->new; + $pu2->import_key('t/data/cryptx_pub_dsa2.der'); + + #my $ss1 = $pr1->shared_secret($pu2); + #my $ss2 = $pr2->shared_secret($pu1); + #is(unpack("H*",$ss1), unpack("H*",$ss2), 'shared_secret'); +} + +{ + my $k = Crypt::PK::DSA->new; + $k->generate_key(20, 128); + ok($k, 'generate_key'); + ok($k->is_private, 'is_private'); + ok($k->export_key_pem('private'), 'export_key_pem pri'); + ok($k->export_key_pem('public'), 'export_key_pem pub'); + ok($k->export_key_der('private'), 'export_key_der pri'); + ok($k->export_key_der('public'), 'export_key_der pub'); +} + +{ + my $ct = dsa_encrypt('t/data/cryptx_pub_dsa1.der', 'test string'); + ok($ct, 'dsa_encrypt'); + my $pt = dsa_decrypt('t/data/cryptx_priv_dsa1.der', $ct); + ok($pt, 'dsa_decrypt'); + my $sig = dsa_sign_message('t/data/cryptx_priv_dsa1.der', 'test string'); + ok($sig, 'dsa_sign_message'); + ok(dsa_verify_message('t/data/cryptx_pub_dsa1.der', $sig, 'test string'), 'dsa_verify_message'); + my $hash = pack("H*","04624fae618e9ad0c5e479f62e1420c71fff34dd"); + $sig = dsa_sign_hash('t/data/cryptx_priv_dsa1.der', $hash, 'SHA1'); + ok($sig, 'dsa_sign_hash'); + ok(dsa_verify_hash('t/data/cryptx_pub_dsa1.der', $sig, $hash, 'SHA1'), 'dsa_verify_hash'); +} diff --git a/t/pk_dsa_test_vectors_openssl.t b/t/pk_dsa_test_vectors_openssl.t new file mode 100644 index 0000000..65037d5 --- /dev/null +++ b/t/pk_dsa_test_vectors_openssl.t @@ -0,0 +1,42 @@ +use strict; +use warnings; + +use Test::More tests => 90; +use Crypt::PK::DSA; + +my $data = [ + {SIZE=>512,PRI_FILE=>'key_512-1.pri.pem',PUB_FILE=>'key_512-1.pub.pem',PRI=>'53faaa79adc02e31ce2865e09393d321978b0b84',PUB=>'2b7cd87cef58954dab4368d51cb96d063317e018def42fd4bb0703a3c7c7cc31b81683197e49bb0c9076f0f6bf2d210380c54f5a1f166c0b0f25b933d4f6fcfd',DSA_SHA1=>'302c02141b9ee2d783233c759384d029875e6cc8b69038d9021475e1ddede6d839c6dca249b0415eaf426a793f21',DSA_SHA256=>'302c02140363f4b1dfaf90d8d6acaf158b205ca0d3948bc702143155b536047e44b7554355fe926f7409c29d2d07',PRI_DER=>'3081f7020100024100dd47e95c66ccd30418c25aff403bdd09ef907699f7168fb34893e2722d76ab62ac31503a1d32e6ec6f8dc209ad35c90a055520d87b0496c27c22c4a75e90994f0215009043e406a88f6cc9af5d620512424fc501c418e102405057ac1eaab6313f35c23aad24f11f85c4adf5d2d81cfac94cae2a0fe9641825a8eeedda170d596b0f9ac857b59d3fd803f4eff9eb16cde387b8b48ca969778702402b7cd87cef58954dab4368d51cb96d063317e018def42fd4bb0703a3c7c7cc31b81683197e49bb0c9076f0f6bf2d210380c54f5a1f166c0b0f25b933d4f6fcfd021453faaa79adc02e31ce2865e09393d321978b0b84',PUB_DER=>'3081f03081a806072a8648ce38040130819c024100dd47e95c66ccd30418c25aff403bdd09ef907699f7168fb34893e2722d76ab62ac31503a1d32e6ec6f8dc209ad35c90a055520d87b0496c27c22c4a75e90994f0215009043e406a88f6cc9af5d620512424fc501c418e102405057ac1eaab6313f35c23aad24f11f85c4adf5d2d81cfac94cae2a0fe9641825a8eeedda170d596b0f9ac857b59d3fd803f4eff9eb16cde387b8b48ca969778703430002402b7cd87cef58954dab4368d51cb96d063317e018def42fd4bb0703a3c7c7cc31b81683197e49bb0c9076f0f6bf2d210380c54f5a1f166c0b0f25b933d4f6fcfd'}, + {SIZE=>1024,PRI_FILE=>'key_1024-1.pri.pem',PUB_FILE=>'key_1024-1.pub.pem',PRI=>'1c59ff18088e085ff6ad546f902536b7d92d4664',PUB=>'4e2f8de47faa96295eec8c12f4e69bdadcc911cb013c23ba84621abe72a6497c1ee64524ca19c4adb64e438ba72f2d0b879e362fce0208ee67136da3bf7acb2f64fb9695062c4d7d67f4f848d60ce25e03415b041c3218e22ad145a2f4e203dbdbd0ddcf92ee131d3201c179538eff896438dd7cf98c54f20218516a0192ca80',DSA_SHA1=>'302c02142596d20c3c1922aa08794d13180d5b1ef9ccf76102141df0e2d0241d50da26c812fc464afd2aff2f9be3',DSA_SHA256=>'302c02141bbb545956785ab5b34bb4606ed82ef2bde6f2c0021425dd6c191efb0c709c7266f4fb8819154b5924ab',PRI_DER=>'308201bb020100028181009de4a90812fd9998704cac7d43c789c3fa13aed3e3ad426ba063c06e722b52f217c7dc4717fc03798220d84e880ad9200b45b0ca1add4b423242bbaee134d8a91467a79423ca499857897606dffb5f53565490a8040038431959eebc9d04a319136eff5c5e353eaf8740c25286ef0dee9ea8b602ea7e948702f9087ace8249b5021500876df298aebc94a3a4ac0831743cd7be00873627028181009d5eea2e5644112c0eb3ca36d8b3578755914d076d2ced54246f67a1ecb149524c4c183143854d7b75e7b5111227c95412fd312ac22ac5c28dba33ca4aae3cb35a0f8d4a131a2aa2317ecae04e5fbea9dbee056a7dc8794f4be31c2496ac15cec6eaff1df6a6859c82476a6c172ade0112ed6ac8cbb282db0e381a87e62bb3c20281804e2f8de47faa96295eec8c12f4e69bdadcc911cb013c23ba84621abe72a6497c1ee64524ca19c4adb64e438ba72f2d0b879e362fce0208ee67136da3bf7acb2f64fb9695062c4d7d67f4f848d60ce25e03415b041c3218e22ad145a2f4e203dbdbd0ddcf92ee131d3201c179538eff896438dd7cf98c54f20218516a0192ca8002141c59ff18088e085ff6ad546f902536b7d92d4664',PUB_DER=>'308201b73082012c06072a8648ce3804013082011f028181009de4a90812fd9998704cac7d43c789c3fa13aed3e3ad426ba063c06e722b52f217c7dc4717fc03798220d84e880ad9200b45b0ca1add4b423242bbaee134d8a91467a79423ca499857897606dffb5f53565490a8040038431959eebc9d04a319136eff5c5e353eaf8740c25286ef0dee9ea8b602ea7e948702f9087ace8249b5021500876df298aebc94a3a4ac0831743cd7be00873627028181009d5eea2e5644112c0eb3ca36d8b3578755914d076d2ced54246f67a1ecb149524c4c183143854d7b75e7b5111227c95412fd312ac22ac5c28dba33ca4aae3cb35a0f8d4a131a2aa2317ecae04e5fbea9dbee056a7dc8794f4be31c2496ac15cec6eaff1df6a6859c82476a6c172ade0112ed6ac8cbb282db0e381a87e62bb3c2038184000281804e2f8de47faa96295eec8c12f4e69bdadcc911cb013c23ba84621abe72a6497c1ee64524ca19c4adb64e438ba72f2d0b879e362fce0208ee67136da3bf7acb2f64fb9695062c4d7d67f4f848d60ce25e03415b041c3218e22ad145a2f4e203dbdbd0ddcf92ee131d3201c179538eff896438dd7cf98c54f20218516a0192ca80'}, + {SIZE=>1536,PRI_FILE=>'key_1536-1.pri.pem',PUB_FILE=>'key_1536-1.pub.pem',PRI=>'630c5e35d645b884c0de84055feceed4d5cd55a1',PUB=>'67b3a9dcdbdfe145df560b5b3226827489cda4987b7103bd4b4857b4826ea1e39fb6bc56ff6eec5775963baf2ce673268e5b3b8519e6d2e1d6a7355c4be977086f288a0dc68c5823426580287bb347505c2eed5ed6b0c377b261a3941a97e2e0da0feb0cb7e7ba65c7e2e3d1704a1ce977c543c2f8c1c5e4634049ecbab3271f15d0d59a7305b6ae312677a32836ae4e2b1e4f37372df0760c152472104953955501f8e37a70e6e8ca8cd7e90bd4a79c070a79dbe20eb48cd17704c2b803e3ca',DSA_SHA1=>'302c0214534053ef9a874980e394edf7158c5a3f0effc2f4021406e384a6bb00df3dbed75ad1cfe044efd4227c72',DSA_SHA256=>'302c02141ecbfc3e5bddc6f06e25925622b9770e5c9eaf74021446f42b32a5ee8647f77419b3e114733946d442fa',PRI_DER=>'3082027b0201000281c100a4ca1614ae22c8e03cc012db3f07b5d08f82fe0b51f895d57359fb928c04a2654ca8a184776341fea9d3e18b74d562bc506d477eb9b35fa5eecda63a11fd62f95872b1dff55858b41273ae2cde311e0b7e945128b5f796a71136fbb02fab0fb17008ae2b91818ac6c5d8f5729f8d843efc042f686da1bd530dd15a88bd253024a66f94710b1444dc190a439ab8888169ea847751d767290ff00991c022a46cd10a7fef1c7263ac6793a1a2c1a26932aee4cf138e7690d7117e5eb4a2d92ff27d02150087bd7144a9eb4b7a915fa3aaf3ce33827545deff0281c100860ab0c50678098f84b43f3b64a25fe9a4c4f5830b08986ba0853b80196eb4e8bdafc262b00c26bb54175e229dd0fec2ec4be42c0511ef4959b1ea7efd2f9fd196b3e41345798fc733ddeded1e390f0cde596b31f3ac4e541c942112d6da33ce1657f238f8ae44eb88562471951af02f25e97162465ddb25113b5d3557d55cdea1fccd7a047e07dad60e1ed4131a166dd502e4c022af28e489bbcef8245ff8cefa26395b24c111a3e0616072dafb3f9c6c6d17d4404c6fd33a1827f3a99b548f0281c067b3a9dcdbdfe145df560b5b3226827489cda4987b7103bd4b4857b4826ea1e39fb6bc56ff6eec5775963baf2ce673268e5b3b8519e6d2e1d6a7355c4be977086f288a0dc68c5823426580287bb347505c2eed5ed6b0c377b261a3941a97e2e0da0feb0cb7e7ba65c7e2e3d1704a1ce977c543c2f8c1c5e4634049ecbab3271f15d0d59a7305b6ae312677a32836ae4e2b1e4f37372df0760c152472104953955501f8e37a70e6e8ca8cd7e90bd4a79c070a79dbe20eb48cd17704c2b803e3ca0214630c5e35d645b884c0de84055feceed4d5cd55a1',PUB_DER=>'30820277308201ac06072a8648ce3804013082019f0281c100a4ca1614ae22c8e03cc012db3f07b5d08f82fe0b51f895d57359fb928c04a2654ca8a184776341fea9d3e18b74d562bc506d477eb9b35fa5eecda63a11fd62f95872b1dff55858b41273ae2cde311e0b7e945128b5f796a71136fbb02fab0fb17008ae2b91818ac6c5d8f5729f8d843efc042f686da1bd530dd15a88bd253024a66f94710b1444dc190a439ab8888169ea847751d767290ff00991c022a46cd10a7fef1c7263ac6793a1a2c1a26932aee4cf138e7690d7117e5eb4a2d92ff27d02150087bd7144a9eb4b7a915fa3aaf3ce33827545deff0281c100860ab0c50678098f84b43f3b64a25fe9a4c4f5830b08986ba0853b80196eb4e8bdafc262b00c26bb54175e229dd0fec2ec4be42c0511ef4959b1ea7efd2f9fd196b3e41345798fc733ddeded1e390f0cde596b31f3ac4e541c942112d6da33ce1657f238f8ae44eb88562471951af02f25e97162465ddb25113b5d3557d55cdea1fccd7a047e07dad60e1ed4131a166dd502e4c022af28e489bbcef8245ff8cefa26395b24c111a3e0616072dafb3f9c6c6d17d4404c6fd33a1827f3a99b548f0381c4000281c067b3a9dcdbdfe145df560b5b3226827489cda4987b7103bd4b4857b4826ea1e39fb6bc56ff6eec5775963baf2ce673268e5b3b8519e6d2e1d6a7355c4be977086f288a0dc68c5823426580287bb347505c2eed5ed6b0c377b261a3941a97e2e0da0feb0cb7e7ba65c7e2e3d1704a1ce977c543c2f8c1c5e4634049ecbab3271f15d0d59a7305b6ae312677a32836ae4e2b1e4f37372df0760c152472104953955501f8e37a70e6e8ca8cd7e90bd4a79c070a79dbe20eb48cd17704c2b803e3ca'}, + {SIZE=>2048,PRI_FILE=>'key_2048-1.pri.pem',PUB_FILE=>'key_2048-1.pub.pem',PRI=>'5ca7ce7397dd512ab599883efc620734fcd0742eeb6adb07a663508cb74adf4e',PUB=>'49f560fa511efc8614fda1be58146bc92e5799788bebd7d317fb97bbbe2df363d2188b29344a33300e76da04f3bfe5ca048413991b3491f9acdd06f8347fed58a28a2f7d95a431190fa4a0fa56221562204dd97fb2db1304e936dce96d85f768e9a7bef22bfc4f81cf535a625b7b8b643a89e9416a0c2c27806e4fa20000ff617d124a168f35f9ab47855429c5c5d95582a798826a333273f024b0e2bea5d2c56535bdbb47e5312844ce71512f941b4c14db30a3a3d0face56e90dae0d02b2f5136b27dbb85fe9da160a9f76e69cbf0a5732bc1bc0ead82632250d046bdd986bfd177c58f39bc38a3ed79387ff0912cfd09198d15abfc9743c493cc62300e034',DSA_SHA1=>'304402206933c92131ae35fc927a3048cc034d201d32dfb416da1bd64908c80360db70240220530dae54a59c2e01f6c20a463fcf6943698810694ce1f8b7133a77af07cfb95e',DSA_SHA256=>'304502204b6316c274f294cbb520f80bbc4d87dc7afcaa87d8a05a677341e12fd89ee7c902210083e1b36acc4b31fb6d306a56684c81fa2b671c82b0a2564612abe14c7ced1bd2',PRI_DER=>'308203550201000282010100bae9f4e5dd259b1060ea6ff3b82c3b97e1f02b0c425b20e5d4c5d047a94d1f82509cff932ffba7c5e9b52da023903c325ae61061084dc3151ee3706523c7de8f9fea845a33415f7b53990be646a8b628d5ccbfc89b0fc7013b42ad5297281f3c0e04475544ce23f75429a5c5590d7547349ab1bae2e1167366ecccdbfe845890131692601ab0ebe62ea26dc4c01f62c501bcb34ff91d4023938a09e23d783c06092850a7dcec9a87fbb86ff497336129f67cab5c28e467f2ea39043f14233da6ef42a98d8e4c3f125b124577dbd6dd6a41293c80b542e40e309cfff667c981b678474d87fc386e6bff62f267b1e2a51a6e80788c7d598d48006e64756656465f022100b264d85ef485a50705816616ae53043812eb180375c6a1d68924ba9e741c8aaf02820100127400355ca7e838353e051904a3ab2fd02a6efc82605d435cdacfb588c30fabdc0d65ba66d7004ec30f557812bc112269f2cdcfa2354860851d991aa2155a2f06a1c5d96c738c113571f77849c5e31baf01ca9b8d95485a3665e329887d33524cec864375ee9f262464a062943b6fb9cddddfc6fc8b14639dcf52be4d3761318c9aa3a7260e3c3914a4b4561caa20a68df5acc856ea5a134d658f071364e58e79229a829c3d7d9fe499daa11fad49ec7a441d24f71e4d20517a4d5eb4bdf21348317b6bdd7b85e9871a02c32ee3b1af0231638ee4da86d04912123d90c8aed6310fff61f6aa060423a7f6abf2f05613cda96d1eadb343d43ff9bdacaab56eba0282010049f560fa511efc8614fda1be58146bc92e5799788bebd7d317fb97bbbe2df363d2188b29344a33300e76da04f3bfe5ca048413991b3491f9acdd06f8347fed58a28a2f7d95a431190fa4a0fa56221562204dd97fb2db1304e936dce96d85f768e9a7bef22bfc4f81cf535a625b7b8b643a89e9416a0c2c27806e4fa20000ff617d124a168f35f9ab47855429c5c5d95582a798826a333273f024b0e2bea5d2c56535bdbb47e5312844ce71512f941b4c14db30a3a3d0face56e90dae0d02b2f5136b27dbb85fe9da160a9f76e69cbf0a5732bc1bc0ead82632250d046bdd986bfd177c58f39bc38a3ed79387ff0912cfd09198d15abfc9743c493cc62300e03402205ca7ce7397dd512ab599883efc620734fcd0742eeb6adb07a663508cb74adf4e',PUB_DER=>'308203463082023906072a8648ce3804013082022c0282010100bae9f4e5dd259b1060ea6ff3b82c3b97e1f02b0c425b20e5d4c5d047a94d1f82509cff932ffba7c5e9b52da023903c325ae61061084dc3151ee3706523c7de8f9fea845a33415f7b53990be646a8b628d5ccbfc89b0fc7013b42ad5297281f3c0e04475544ce23f75429a5c5590d7547349ab1bae2e1167366ecccdbfe845890131692601ab0ebe62ea26dc4c01f62c501bcb34ff91d4023938a09e23d783c06092850a7dcec9a87fbb86ff497336129f67cab5c28e467f2ea39043f14233da6ef42a98d8e4c3f125b124577dbd6dd6a41293c80b542e40e309cfff667c981b678474d87fc386e6bff62f267b1e2a51a6e80788c7d598d48006e64756656465f022100b264d85ef485a50705816616ae53043812eb180375c6a1d68924ba9e741c8aaf02820100127400355ca7e838353e051904a3ab2fd02a6efc82605d435cdacfb588c30fabdc0d65ba66d7004ec30f557812bc112269f2cdcfa2354860851d991aa2155a2f06a1c5d96c738c113571f77849c5e31baf01ca9b8d95485a3665e329887d33524cec864375ee9f262464a062943b6fb9cddddfc6fc8b14639dcf52be4d3761318c9aa3a7260e3c3914a4b4561caa20a68df5acc856ea5a134d658f071364e58e79229a829c3d7d9fe499daa11fad49ec7a441d24f71e4d20517a4d5eb4bdf21348317b6bdd7b85e9871a02c32ee3b1af0231638ee4da86d04912123d90c8aed6310fff61f6aa060423a7f6abf2f05613cda96d1eadb343d43ff9bdacaab56eba03820105000282010049f560fa511efc8614fda1be58146bc92e5799788bebd7d317fb97bbbe2df363d2188b29344a33300e76da04f3bfe5ca048413991b3491f9acdd06f8347fed58a28a2f7d95a431190fa4a0fa56221562204dd97fb2db1304e936dce96d85f768e9a7bef22bfc4f81cf535a625b7b8b643a89e9416a0c2c27806e4fa20000ff617d124a168f35f9ab47855429c5c5d95582a798826a333273f024b0e2bea5d2c56535bdbb47e5312844ce71512f941b4c14db30a3a3d0face56e90dae0d02b2f5136b27dbb85fe9da160a9f76e69cbf0a5732bc1bc0ead82632250d046bdd986bfd177c58f39bc38a3ed79387ff0912cfd09198d15abfc9743c493cc62300e034'}, + {SIZE=>3072,PRI_FILE=>'key_3072-1.pri.pem',PUB_FILE=>'key_3072-1.pub.pem',PRI=>'43062c67f9f5a90a268040fdad17d1990bf88731849baa38997dce9b145285a7',PUB=>'0384463ae72b8cf36be819c9e27d1303cbcaf779976c21492876133dafb6ece83c2402f9a7260dba4b5df25512da0a332b84079c438b9a5ea42142941d8a7170a2385d79cb904748292892ccce0c24e643658e326a1a191edddcb97fc23764d1e5fb937116b0798cc10c915e16b6694b651965969723d460693fd0e1d87882ddea7bf22a4f3c66b26ee24aff8da7b54fa37369e0a240b253c805f80f975ebbc3323e3dfbe683670dd9d4c518205756692a2fb986e101a21d4dc2b29fe2561ce48a014a33db0bfd5da99dd60d5dc111b5657266320a9295be0fef3fc483a49b8826b9f2c433a2452e5898a95d93e0cd5fd00734cab519c0131db95eb9be9d564ff3b03fe1160ea619220b3dfb21e5746798ed68aca608bc261e1832d4af45ddf62e08e1934272f8a8b063e7cb74b100b9c89cf5b6c2837abb825f8595fdb648a8f5a90a270c403c01137852b2579583c5ba7632ef2d8636c4a08856a0584252892edb6b142585aa5f370d45ccb11aece796f5b18202a309a4d3f1c124683c2209',DSA_SHA1=>'304502210080df69ae68f75c230b58f1ca262c1d164eea62b128206122799c7b08b3635a7a022026603ee5655ac7ae2c351ed73f3a952420c5625404082761e2e1fc6ca698b0e8',DSA_SHA256=>'304402203ea77e1adde22694d030e1b068166241b7c3912653c1db106afb2165c94e57cc02203cf8ab667ec48a64b8a2be2219d1252853435706d2916d08b362204e57183705',PRI_DER=>'308204d50201000282018100feb941727d8c2ab11c0dc6f712b9c7a7887a4ff691a3eb0378ea2ea223cdce8f7b6f8904465a5c25a0ba1894f82a141b2c98703a2e9fba5f70e64d88a68658e7456c398b25c5a87177fc8bff41f25ea7528f67548a7e61ff7125e7439ff5f4cb4f37a1347a0901b0fa68cad66960386fed67e82a1b0a1657209758d218e97fc44552557806d2efac2858c61332a744bf00f2cf9552828ade2ad0177b79559ade4d25b551701fab8d876068ad50598ebd9bb5e90d12cd5be1468b1a52e99ee7abad1c00f731b3369bbbef6075678ccb073709893a10315e44d21a8707dd0b6337fa36bbb127bc635abaf4358cfc997adc46d435f4a381daf5682470742e45e50877a02f5ff101b74a043a41086464ea7fd38f8e48beb29ddd421d051e232437d44f6552a1bf9546b8fa5f6a61af84df2fa2f825bb3a6dc851bbc813d44d2830074a05479bfa7743c3c9c756427fb4f6a05970b21f0c923e09a297949964707fc8af4c92ff3a86f734e872132dd4fa6bea942c16396f27c224a6d72f023e2b9a0f022100860af3885a0d2a1f8b804a2f9808e396c023767a1eeb1afa98c0afe45456af91028201806c67ad7e0e74bfe7cc0a8ef15de9a05aa181ec7b764670deba67845903615c82e92e9048678e354698ec0603b114cd53f219b3ad8067b2fd3e95d5f66804768c3aaa278189be38c0461395fbf39bfaada63e23145916328dd0d244e4143a0c37cd8f16dfcbc7d65af513e62a01ead870469798938181495847c0ff61e3b119c48aa6822cc574e995ef40e10118fc35f145ccbf36c8fe8d54d05d6b46dacdb14c43d064a12ca66887f8b2cd85e8df03d83a1e9db69a9fecf5d5fd44608e8705b6c6e553c4ef075c078b2eca1dcf6949433da60c3fd92023764141bc11f8a0fd75b046c85d11da12c271fa6c186e94c31b0919dbfc7b2e8007c2169895d3882807762a6e70e00c5d6a714a09a58f40d6a2b3d70985a2d8a362c21b286ee503253872933634fd51493be04b9204b4f9f9d2401c6cb1aa53ee5699f171ef4e53e8cde8dde4d5fff8dc76156f37c5a733ee523d8ee8cfb1bf5bd552ee32b56c62e18263843a6ba53983eb06c1996fe33fff33fd87fc88774ba60f423bf5c2ef3d6ae5028201800384463ae72b8cf36be819c9e27d1303cbcaf779976c21492876133dafb6ece83c2402f9a7260dba4b5df25512da0a332b84079c438b9a5ea42142941d8a7170a2385d79cb904748292892ccce0c24e643658e326a1a191edddcb97fc23764d1e5fb937116b0798cc10c915e16b6694b651965969723d460693fd0e1d87882ddea7bf22a4f3c66b26ee24aff8da7b54fa37369e0a240b253c805f80f975ebbc3323e3dfbe683670dd9d4c518205756692a2fb986e101a21d4dc2b29fe2561ce48a014a33db0bfd5da99dd60d5dc111b5657266320a9295be0fef3fc483a49b8826b9f2c433a2452e5898a95d93e0cd5fd00734cab519c0131db95eb9be9d564ff3b03fe1160ea619220b3dfb21e5746798ed68aca608bc261e1832d4af45ddf62e08e1934272f8a8b063e7cb74b100b9c89cf5b6c2837abb825f8595fdb648a8f5a90a270c403c01137852b2579583c5ba7632ef2d8636c4a08856a0584252892edb6b142585aa5f370d45ccb11aece796f5b18202a309a4d3f1c124683c2209022043062c67f9f5a90a268040fdad17d1990bf88731849baa38997dce9b145285a7',PUB_DER=>'308204c63082033906072a8648ce3804013082032c0282018100feb941727d8c2ab11c0dc6f712b9c7a7887a4ff691a3eb0378ea2ea223cdce8f7b6f8904465a5c25a0ba1894f82a141b2c98703a2e9fba5f70e64d88a68658e7456c398b25c5a87177fc8bff41f25ea7528f67548a7e61ff7125e7439ff5f4cb4f37a1347a0901b0fa68cad66960386fed67e82a1b0a1657209758d218e97fc44552557806d2efac2858c61332a744bf00f2cf9552828ade2ad0177b79559ade4d25b551701fab8d876068ad50598ebd9bb5e90d12cd5be1468b1a52e99ee7abad1c00f731b3369bbbef6075678ccb073709893a10315e44d21a8707dd0b6337fa36bbb127bc635abaf4358cfc997adc46d435f4a381daf5682470742e45e50877a02f5ff101b74a043a41086464ea7fd38f8e48beb29ddd421d051e232437d44f6552a1bf9546b8fa5f6a61af84df2fa2f825bb3a6dc851bbc813d44d2830074a05479bfa7743c3c9c756427fb4f6a05970b21f0c923e09a297949964707fc8af4c92ff3a86f734e872132dd4fa6bea942c16396f27c224a6d72f023e2b9a0f022100860af3885a0d2a1f8b804a2f9808e396c023767a1eeb1afa98c0afe45456af91028201806c67ad7e0e74bfe7cc0a8ef15de9a05aa181ec7b764670deba67845903615c82e92e9048678e354698ec0603b114cd53f219b3ad8067b2fd3e95d5f66804768c3aaa278189be38c0461395fbf39bfaada63e23145916328dd0d244e4143a0c37cd8f16dfcbc7d65af513e62a01ead870469798938181495847c0ff61e3b119c48aa6822cc574e995ef40e10118fc35f145ccbf36c8fe8d54d05d6b46dacdb14c43d064a12ca66887f8b2cd85e8df03d83a1e9db69a9fecf5d5fd44608e8705b6c6e553c4ef075c078b2eca1dcf6949433da60c3fd92023764141bc11f8a0fd75b046c85d11da12c271fa6c186e94c31b0919dbfc7b2e8007c2169895d3882807762a6e70e00c5d6a714a09a58f40d6a2b3d70985a2d8a362c21b286ee503253872933634fd51493be04b9204b4f9f9d2401c6cb1aa53ee5699f171ef4e53e8cde8dde4d5fff8dc76156f37c5a733ee523d8ee8cfb1bf5bd552ee32b56c62e18263843a6ba53983eb06c1996fe33fff33fd87fc88774ba60f423bf5c2ef3d6ae50382018500028201800384463ae72b8cf36be819c9e27d1303cbcaf779976c21492876133dafb6ece83c2402f9a7260dba4b5df25512da0a332b84079c438b9a5ea42142941d8a7170a2385d79cb904748292892ccce0c24e643658e326a1a191edddcb97fc23764d1e5fb937116b0798cc10c915e16b6694b651965969723d460693fd0e1d87882ddea7bf22a4f3c66b26ee24aff8da7b54fa37369e0a240b253c805f80f975ebbc3323e3dfbe683670dd9d4c518205756692a2fb986e101a21d4dc2b29fe2561ce48a014a33db0bfd5da99dd60d5dc111b5657266320a9295be0fef3fc483a49b8826b9f2c433a2452e5898a95d93e0cd5fd00734cab519c0131db95eb9be9d564ff3b03fe1160ea619220b3dfb21e5746798ed68aca608bc261e1832d4af45ddf62e08e1934272f8a8b063e7cb74b100b9c89cf5b6c2837abb825f8595fdb648a8f5a90a270c403c01137852b2579583c5ba7632ef2d8636c4a08856a0584252892edb6b142585aa5f370d45ccb11aece796f5b18202a309a4d3f1c124683c2209'}, + {SIZE=>4096,PRI_FILE=>'key_4096-1.pri.pem',PUB_FILE=>'key_4096-1.pub.pem',PRI=>'00b14ee1226c4aeb4d7a9ff494214918c0489d479c4d0a0107928400abe41035e5',PUB=>'2a6218a818996260e331afc85e2696b02e3b6e14c25c2b7a3a742c9600c67d371be48ce4aabb814294bd7977ea3a5cec0398330c5501784dc45df1e2fa2487a02e9c4c5ba1b7c04d172db32ee6955cc5b3ea368fd044dd068d677f28d650a281f8a3bdf67efa1b1e47b885784d7281d5a5a096b39f23f52e5482b6e2c51806c69614f2f02c441542f62f0fbb8da887998bd181cc6db9d570bb8d5a14e8e6033414bf30170bdc33569685678321a4537e52fac8fe1a45c8f940c2eda85b03a257673a4f589b0956bac61bb01afd44242d10763060169eb09459d39eb9da034a8897473c5db16e3adb56216e5b81b454fe6bc622ddf3eabe3851ecf1fb9bdd2b7cf0c43184192cc9564db5e472b8d52c0b1cb7b7be3cde77424524d9f99bee280590def04b6856fdf2d5765fdb64429bd02c0083caa2d0c57a12b16d659196e6b195f02104ab02e9083c7e5158d4440bcb7a263476c10b8a389677f94274840a0436a492651f12e959bb1338757f111e80db13c6cbff4bdfc2ecd0ef0c80c16fb4bbbb6eb2a72a1a000160a65c5e79c766b09d60bbaed6e2f4a63e50d63a949a101c2d31010d212a7481e7fbdff57c5bc1dea8230882262ce661ba10c7081993657935419621a2aecae0476d487f1e09ee241bfb12e723edc95c395a4d692ab2bb6ff5bbaa5b61334600066b1e1e1e6577757089f110f4742667df74367293278b',DSA_SHA1=>'304502203085c025a9f5fc220ec42c3d3b7c14925f7fa94ee90926ad6fb00bebad056c7102210096b0e77cbc0ccfe16d3781566a9efc8c95ffc68e042a8fbc97725935bac43588',DSA_SHA256=>'304502203e0ae9a870323e30469fd854775dd1509802801eff9620b2115b7ac84bc5ea6702210085725f39bf186a24bf98d8b03aa07a90f7dca1a092a4015d428012a92cf1ed4c',PRI_DER=>'308206560201000282020100f28559890368a4d099f36f59a9e75ac562f5d0092662332924b10987f354dc97a8aa0cd77db048d52a8bee696d781d97e6df71e02b8aa35a25d891d62d7fb34ced5ee522069b6282fa9fb7b48450f24df6585b35cacd5eb2a311a1e239d4acfed79009b287f6e4265b8b369e3aba8c901ce3c421aa46d6e526f61fefd899edfcea94f416ddad7e48fd87b4b820be28e7f8a34d86e73d984eaa9c939d2e5e7ef4549ec9506f080ae18a633657e0caab2005a174a7161232158c9f76def948def72be4120da4dff7fe535c8968c3b35eba307d5c9f0142c8343469fcbafadbd4d2274ad50266bdb783e367a8703967e53836bbd0028e09c7dd37f5d5a670ab7e0af487de28a968cf8712f2aab20637d8e0a2f05f1c2075775170d4a56124090f159c9776cfda62ce66e582834023d4ba08f7de63456cfc94cd5e0b7e7d230638aa768f32d7f89262454810c0e40e303bff463e12b7691866fb004a336edf4d4c6be131c6b4690f0e4b328289bfebe98cfdf1babf8b17607d7b0ba236bb1abd56ec1698319141d8c6c4ca154a2d7d9a323a5b6005c3a9639adee5b756d42156f8ff405decb098072454af97496d017e4a2de551ad286f5f6c89925a32e042f2fab1be11e25be5848fed6986f309d55671687403d23272fb96e2017277e39b917bd34254e4275049d5a75a00e94f01077b51de470c4867b239ec739fabdf8b0bd65d022100ef8decba0475990b9cdb3d28ea579028e587cc78c4304903e98f2358692bcad9028202000c794a5b82ddf4e62bccb6e939cbf48627c8d4fb45b05d3ee175249c5feea6f6c9bc6a080e5fdd3ba86da51b7529bb7c07da35e39859f44f13fc62d8878936d0738dd00cb322edf5e6ee5503777257ab18060cccabb15a532f9ac291d508e27b939812c9b288a06aaaa3911141fd1756094dc8e843d60eed4ee974c4b8e06bea58dab388dfc7b36d088b8b9d2a6070d3bd49f20befa0734ebfaf7312c73ffad54f69609bd3e94da4296760818afc409f3f955631284f5c416a415d150bb149728fdc75443e16677c62a0193f9ece50cdf55c5877f62164d5e95d8e8da9502927036743fb292e2c5260b7561e09f26702ca4f8d1aacc68fb4f73dee9a3febded8f217725a9a18347776778c69046b55910ca984e4ce7acfec24e3435c7e966b41415b8d3c9865535a5cc149f8518a9ec6fd7ad9c8ef8074347c16a51642b2a2326be4cffcfa7611dde0633131f0f9471702d23d2271657d3e59e334c082a1205e1387b063c84d9459af72290ec0afaaf1fef3852811faf8981f5ab803aa24ec600448b65ef2bdca0d014209fa3e7db677fd1964bba279abd9785e7604ab91810002c31fac482843313019924c850c007abb6b9fe1bbdb8b90b419b636c0f90fe02f020a6a60de8e20fe5c9bfa4efe8e6a5c3bdc3adbc2a49ed1f2203ce76d5f08bf91b354104c57bd2be1cc210e6b357e247622a2ae72c710d3910bd5f64639d4028202002a6218a818996260e331afc85e2696b02e3b6e14c25c2b7a3a742c9600c67d371be48ce4aabb814294bd7977ea3a5cec0398330c5501784dc45df1e2fa2487a02e9c4c5ba1b7c04d172db32ee6955cc5b3ea368fd044dd068d677f28d650a281f8a3bdf67efa1b1e47b885784d7281d5a5a096b39f23f52e5482b6e2c51806c69614f2f02c441542f62f0fbb8da887998bd181cc6db9d570bb8d5a14e8e6033414bf30170bdc33569685678321a4537e52fac8fe1a45c8f940c2eda85b03a257673a4f589b0956bac61bb01afd44242d10763060169eb09459d39eb9da034a8897473c5db16e3adb56216e5b81b454fe6bc622ddf3eabe3851ecf1fb9bdd2b7cf0c43184192cc9564db5e472b8d52c0b1cb7b7be3cde77424524d9f99bee280590def04b6856fdf2d5765fdb64429bd02c0083caa2d0c57a12b16d659196e6b195f02104ab02e9083c7e5158d4440bcb7a263476c10b8a389677f94274840a0436a492651f12e959bb1338757f111e80db13c6cbff4bdfc2ecd0ef0c80c16fb4bbbb6eb2a72a1a000160a65c5e79c766b09d60bbaed6e2f4a63e50d63a949a101c2d31010d212a7481e7fbdff57c5bc1dea8230882262ce661ba10c7081993657935419621a2aecae0476d487f1e09ee241bfb12e723edc95c395a4d692ab2bb6ff5bbaa5b61334600066b1e1e1e6577757089f110f4742667df74367293278b022100b14ee1226c4aeb4d7a9ff494214918c0489d479c4d0a0107928400abe41035e5',PUB_DER=>'308206463082043906072a8648ce3804013082042c0282020100f28559890368a4d099f36f59a9e75ac562f5d0092662332924b10987f354dc97a8aa0cd77db048d52a8bee696d781d97e6df71e02b8aa35a25d891d62d7fb34ced5ee522069b6282fa9fb7b48450f24df6585b35cacd5eb2a311a1e239d4acfed79009b287f6e4265b8b369e3aba8c901ce3c421aa46d6e526f61fefd899edfcea94f416ddad7e48fd87b4b820be28e7f8a34d86e73d984eaa9c939d2e5e7ef4549ec9506f080ae18a633657e0caab2005a174a7161232158c9f76def948def72be4120da4dff7fe535c8968c3b35eba307d5c9f0142c8343469fcbafadbd4d2274ad50266bdb783e367a8703967e53836bbd0028e09c7dd37f5d5a670ab7e0af487de28a968cf8712f2aab20637d8e0a2f05f1c2075775170d4a56124090f159c9776cfda62ce66e582834023d4ba08f7de63456cfc94cd5e0b7e7d230638aa768f32d7f89262454810c0e40e303bff463e12b7691866fb004a336edf4d4c6be131c6b4690f0e4b328289bfebe98cfdf1babf8b17607d7b0ba236bb1abd56ec1698319141d8c6c4ca154a2d7d9a323a5b6005c3a9639adee5b756d42156f8ff405decb098072454af97496d017e4a2de551ad286f5f6c89925a32e042f2fab1be11e25be5848fed6986f309d55671687403d23272fb96e2017277e39b917bd34254e4275049d5a75a00e94f01077b51de470c4867b239ec739fabdf8b0bd65d022100ef8decba0475990b9cdb3d28ea579028e587cc78c4304903e98f2358692bcad9028202000c794a5b82ddf4e62bccb6e939cbf48627c8d4fb45b05d3ee175249c5feea6f6c9bc6a080e5fdd3ba86da51b7529bb7c07da35e39859f44f13fc62d8878936d0738dd00cb322edf5e6ee5503777257ab18060cccabb15a532f9ac291d508e27b939812c9b288a06aaaa3911141fd1756094dc8e843d60eed4ee974c4b8e06bea58dab388dfc7b36d088b8b9d2a6070d3bd49f20befa0734ebfaf7312c73ffad54f69609bd3e94da4296760818afc409f3f955631284f5c416a415d150bb149728fdc75443e16677c62a0193f9ece50cdf55c5877f62164d5e95d8e8da9502927036743fb292e2c5260b7561e09f26702ca4f8d1aacc68fb4f73dee9a3febded8f217725a9a18347776778c69046b55910ca984e4ce7acfec24e3435c7e966b41415b8d3c9865535a5cc149f8518a9ec6fd7ad9c8ef8074347c16a51642b2a2326be4cffcfa7611dde0633131f0f9471702d23d2271657d3e59e334c082a1205e1387b063c84d9459af72290ec0afaaf1fef3852811faf8981f5ab803aa24ec600448b65ef2bdca0d014209fa3e7db677fd1964bba279abd9785e7604ab91810002c31fac482843313019924c850c007abb6b9fe1bbdb8b90b419b636c0f90fe02f020a6a60de8e20fe5c9bfa4efe8e6a5c3bdc3adbc2a49ed1f2203ce76d5f08bf91b354104c57bd2be1cc210e6b357e247622a2ae72c710d3910bd5f64639d40382020500028202002a6218a818996260e331afc85e2696b02e3b6e14c25c2b7a3a742c9600c67d371be48ce4aabb814294bd7977ea3a5cec0398330c5501784dc45df1e2fa2487a02e9c4c5ba1b7c04d172db32ee6955cc5b3ea368fd044dd068d677f28d650a281f8a3bdf67efa1b1e47b885784d7281d5a5a096b39f23f52e5482b6e2c51806c69614f2f02c441542f62f0fbb8da887998bd181cc6db9d570bb8d5a14e8e6033414bf30170bdc33569685678321a4537e52fac8fe1a45c8f940c2eda85b03a257673a4f589b0956bac61bb01afd44242d10763060169eb09459d39eb9da034a8897473c5db16e3adb56216e5b81b454fe6bc622ddf3eabe3851ecf1fb9bdd2b7cf0c43184192cc9564db5e472b8d52c0b1cb7b7be3cde77424524d9f99bee280590def04b6856fdf2d5765fdb64429bd02c0083caa2d0c57a12b16d659196e6b195f02104ab02e9083c7e5158d4440bcb7a263476c10b8a389677f94274840a0436a492651f12e959bb1338757f111e80db13c6cbff4bdfc2ecd0ef0c80c16fb4bbbb6eb2a72a1a000160a65c5e79c766b09d60bbaed6e2f4a63e50d63a949a101c2d31010d212a7481e7fbdff57c5bc1dea8230882262ce661ba10c7081993657935419621a2aecae0476d487f1e09ee241bfb12e723edc95c395a4d692ab2bb6ff5bbaa5b61334600066b1e1e1e6577757089f110f4742667df74367293278b'}, + {SIZE=>512,PRI_FILE=>'key_512-2.pri.pem',PUB_FILE=>'key_512-2.pub.pem',PRI=>'3a56c667cd9c95dec92aeafc3987274da82a57cf',PUB=>'6d00de86363f590dbaaeb289617d5b099e0bae1e483aa464411519831106a09571f13b51353f897b18865c8f6f2d3c95d9071db89333f0ec968e8f793a5069f5',DSA_SHA1=>'302c0214141fd4af5c16d4610eb37b52d54a306d3ebd37c3021463b294e41521763d0c9ec19b96e92b4dd15d0ded',DSA_SHA256=>'302c02140aaf646c5f39a84b6bc698ac8a22700cd4c8b6280214471cc080922947385772a00c9ce379b1e27b38c5',PRI_DER=>'3081f8020100024100ec6b341b598e6a69ab7aa592b071dd86345198bd5ef70a1b08285d364691439f8b0eb1516d9d8ad140c8e8aed9923eaaef1f70e16d7ad8e730812536249db869021500d4efc32035cfac6994ba06600ae587c452c4649102410093bf6ce6f9743760a2436eaae725811ca3bfec69c974413ae185860f277b58182065ee72a83a91d6d2fd66c5d0a4e8f8cec977b29a9bcfe66c080f441a3e5dfa02406d00de86363f590dbaaeb289617d5b099e0bae1e483aa464411519831106a09571f13b51353f897b18865c8f6f2d3c95d9071db89333f0ec968e8f793a5069f502143a56c667cd9c95dec92aeafc3987274da82a57cf',PUB_DER=>'3081f13081a906072a8648ce38040130819d024100ec6b341b598e6a69ab7aa592b071dd86345198bd5ef70a1b08285d364691439f8b0eb1516d9d8ad140c8e8aed9923eaaef1f70e16d7ad8e730812536249db869021500d4efc32035cfac6994ba06600ae587c452c4649102410093bf6ce6f9743760a2436eaae725811ca3bfec69c974413ae185860f277b58182065ee72a83a91d6d2fd66c5d0a4e8f8cec977b29a9bcfe66c080f441a3e5dfa03430002406d00de86363f590dbaaeb289617d5b099e0bae1e483aa464411519831106a09571f13b51353f897b18865c8f6f2d3c95d9071db89333f0ec968e8f793a5069f5'}, + {SIZE=>1024,PRI_FILE=>'key_1024-2.pri.pem',PUB_FILE=>'key_1024-2.pub.pem',PRI=>'3e07cddee79c1312d6812e42b824fe41c800a0d1',PUB=>'11f4a38220a7ee8f0e842fe058776e655aa8490e52399d6f190e83289a3c8044e1def4f84e12ca1bce210ca33101c20e28d82db43dfe198c94158a66de392e94410e3b536d67fe1e428b2ae75d1626dcfda48b1d2469b18deade9e7b4d3ae46d20b2d89f17245bdf1a7e33ea4fc2b8fdd88ac07a3a268e0170bb2a4150060a11',DSA_SHA1=>'302d0215008ffd4c5d43bdc2d7ed52459158d686181494940b02142d40e961290fbed9a4686c276c3a18e9e4238120',DSA_SHA256=>'302d0215008f82e99fd73dc62a889ae881a14e5b644d350470021409049520599783e9659e207ebc794c8040ca06f2',PRI_DER=>'308201ba02010002818100a44cca1539a619f46a0bfddc566aad42c081ad64f17e3080a02c40f833a0eb1eabc6deeb9ad2f3efe2fb82f8714ae1d4105a29fd1db950f50a5dd6cf93e98139f5afab6cff916c66d5192e27e1bfe169927c820615796ba8542875e52b7830430462af4fc1f90d324faa12e57ee817343330bffa6a1fddb351b78592d4e801670215009c1446d67299bef01c9fa08f7fa03f96306fb4890281804b3876507dfd6f3e1fcaeaf346f59062c6f5cfc147305d5ed83525f8e51bebd29377c96b36d5d373ec90f343243e6c40770dbb35083061b0244c5fb53c25bb6aa6724a2458336520380895d8631260c5441d51b396ce1ebe9a3aeecc342fc62d50ceab15c742cf6b290b1ff4d5f7de7ec6e3ec5aff2da5d9d2b1851d3810ef0302818011f4a38220a7ee8f0e842fe058776e655aa8490e52399d6f190e83289a3c8044e1def4f84e12ca1bce210ca33101c20e28d82db43dfe198c94158a66de392e94410e3b536d67fe1e428b2ae75d1626dcfda48b1d2469b18deade9e7b4d3ae46d20b2d89f17245bdf1a7e33ea4fc2b8fdd88ac07a3a268e0170bb2a4150060a1102143e07cddee79c1312d6812e42b824fe41c800a0d1',PUB_DER=>'308201b63082012b06072a8648ce3804013082011e02818100a44cca1539a619f46a0bfddc566aad42c081ad64f17e3080a02c40f833a0eb1eabc6deeb9ad2f3efe2fb82f8714ae1d4105a29fd1db950f50a5dd6cf93e98139f5afab6cff916c66d5192e27e1bfe169927c820615796ba8542875e52b7830430462af4fc1f90d324faa12e57ee817343330bffa6a1fddb351b78592d4e801670215009c1446d67299bef01c9fa08f7fa03f96306fb4890281804b3876507dfd6f3e1fcaeaf346f59062c6f5cfc147305d5ed83525f8e51bebd29377c96b36d5d373ec90f343243e6c40770dbb35083061b0244c5fb53c25bb6aa6724a2458336520380895d8631260c5441d51b396ce1ebe9a3aeecc342fc62d50ceab15c742cf6b290b1ff4d5f7de7ec6e3ec5aff2da5d9d2b1851d3810ef030381840002818011f4a38220a7ee8f0e842fe058776e655aa8490e52399d6f190e83289a3c8044e1def4f84e12ca1bce210ca33101c20e28d82db43dfe198c94158a66de392e94410e3b536d67fe1e428b2ae75d1626dcfda48b1d2469b18deade9e7b4d3ae46d20b2d89f17245bdf1a7e33ea4fc2b8fdd88ac07a3a268e0170bb2a4150060a11'}, + {SIZE=>1536,PRI_FILE=>'key_1536-2.pri.pem',PUB_FILE=>'key_1536-2.pub.pem',PRI=>'09d7c38692f017316b0ee0ea0ed40805c5c1afbb',PUB=>'009e39f3add36d29c6cdb19daaf75ef21c16594df511789489116f2b7f9b6e1f36a638bbcc7cd4993778d04892775bcabede3a24a907edefe0411a62f63b1f150e38b2f2a66932e37fffa5e3f83ecdc1b1107ea93f71199f2cd4f3db105ec39e01aa49877a54af76644fdbd3e2f87725cd94f34c991ba6dd1b0710c675b13dad03752b3f5caed2129873286687cc9f67c3b0c8143df89965173a0961ae173bd6a0ee16bee1b86ea7c6a634f5d9fcb46959e8524f6f2e8652046b1c32ddbcc12a6d',DSA_SHA1=>'302d021500a16ed40a1ee247e2af1d638bc0e49f8a0a0ff2ab02146761128987b8965fd52ea563f5a521af928c5438',DSA_SHA256=>'302d021500a21a000884f97aced098f6ac793824e16e1d0c7f02145d44972b36d27dfba5ef643789ff1551425ce037',PRI_DER=>'3082027c0201000281c100fba98712cd16a01b0fede62bf7785b259b7c3994b3caf492fdc4b9a596550b02e2771cf5b15a12994c59212772d83f512820391d76d4dafae6dce317fda9c3b4ffe493737e86d27c9f1ab8c7295bd16f8b69155ef43cd4196430d747a350b2dce22c8d531a60d53414c95b83fd6e4a0d14baeffc3c67b2f5eff8b4d2a8591eddea82849afc5553f44a4527cb78a03aca62deaf6996209e6e46df32eb2c910e8446e9c9d421585ae62410b082a669b2a950784b37d1e542361eab0e00dc7b3c11021500a4ff288631f6560028464eeba69f3922a661761b0281c1008df52bdcf90e37df6d8e6d52db5ebba47f9605ac345919ec8b985afe7d614b2bad9371aa7c1109b5b86bb90f79c72ff7f767f3306ccad681cb372a514de86d356a960f8798ad9d91b62e87d00a962dcef16be237ff413aadd7be1601a50df3344a99b5579e2c557a6f0d6dcc54b79d3f10e6e0a7faf8e2de861f076d4030375532451835bc0c056239bf4c904ab9567ae3c0c93b028c8c0db506945ecf3737be47d5bbcd81d8881249ab57cd7c573f7bec538b999b4590c5d4eefbd64bd6a8d10281c1009e39f3add36d29c6cdb19daaf75ef21c16594df511789489116f2b7f9b6e1f36a638bbcc7cd4993778d04892775bcabede3a24a907edefe0411a62f63b1f150e38b2f2a66932e37fffa5e3f83ecdc1b1107ea93f71199f2cd4f3db105ec39e01aa49877a54af76644fdbd3e2f87725cd94f34c991ba6dd1b0710c675b13dad03752b3f5caed2129873286687cc9f67c3b0c8143df89965173a0961ae173bd6a0ee16bee1b86ea7c6a634f5d9fcb46959e8524f6f2e8652046b1c32ddbcc12a6d021409d7c38692f017316b0ee0ea0ed40805c5c1afbb',PUB_DER=>'30820278308201ac06072a8648ce3804013082019f0281c100fba98712cd16a01b0fede62bf7785b259b7c3994b3caf492fdc4b9a596550b02e2771cf5b15a12994c59212772d83f512820391d76d4dafae6dce317fda9c3b4ffe493737e86d27c9f1ab8c7295bd16f8b69155ef43cd4196430d747a350b2dce22c8d531a60d53414c95b83fd6e4a0d14baeffc3c67b2f5eff8b4d2a8591eddea82849afc5553f44a4527cb78a03aca62deaf6996209e6e46df32eb2c910e8446e9c9d421585ae62410b082a669b2a950784b37d1e542361eab0e00dc7b3c11021500a4ff288631f6560028464eeba69f3922a661761b0281c1008df52bdcf90e37df6d8e6d52db5ebba47f9605ac345919ec8b985afe7d614b2bad9371aa7c1109b5b86bb90f79c72ff7f767f3306ccad681cb372a514de86d356a960f8798ad9d91b62e87d00a962dcef16be237ff413aadd7be1601a50df3344a99b5579e2c557a6f0d6dcc54b79d3f10e6e0a7faf8e2de861f076d4030375532451835bc0c056239bf4c904ab9567ae3c0c93b028c8c0db506945ecf3737be47d5bbcd81d8881249ab57cd7c573f7bec538b999b4590c5d4eefbd64bd6a8d10381c5000281c1009e39f3add36d29c6cdb19daaf75ef21c16594df511789489116f2b7f9b6e1f36a638bbcc7cd4993778d04892775bcabede3a24a907edefe0411a62f63b1f150e38b2f2a66932e37fffa5e3f83ecdc1b1107ea93f71199f2cd4f3db105ec39e01aa49877a54af76644fdbd3e2f87725cd94f34c991ba6dd1b0710c675b13dad03752b3f5caed2129873286687cc9f67c3b0c8143df89965173a0961ae173bd6a0ee16bee1b86ea7c6a634f5d9fcb46959e8524f6f2e8652046b1c32ddbcc12a6d'}, + {SIZE=>2048,PRI_FILE=>'key_2048-2.pri.pem',PUB_FILE=>'key_2048-2.pub.pem',PRI=>'1c590fa44b9e739c76249737db6174cd9769fe79d03fc03ba516b8ef74ad586a',PUB=>'00cb10c09a261164c1aaad42837226eecc283064a3d25e402bd6585a3f32386e8625d082ba587417a54f3d4f78e0f439cb7dd7a0533c6b7be576313080efd2ade6877df67e0f3ac2199970601fcdebd6f764151e98d3ac2e3a29c98787b1b43562681388c607da5bc54e7607fa393bcba944d7a92eb9b590d01080e24c235f2c9d4b96a0ace845a1447816e54910dd52bfa92e6a0cf26453d7a93158cc6f41afdabf9642ca0f7507cba2d7149f194aa0e89a765fff0af4e1da6a62e37e61b6b7fc8a6f5fc4034da9f4929c128a8753cc05d02b2ea98b73e7523e461b888736e82738e67af73db59e3d834d4cc7b61989883b90f9cfdc4c9e421681498bef22ce32',DSA_SHA1=>'304502210080cbd2427d64f09496a3955467112d83cd03de839a21a54eb1a4fe17464d08bb0220507dde54e2a736a3cb6695b037a7f861b0cec2879b88b2d04d84a5df1b4a283f',DSA_SHA256=>'3044022072e70831aa0d612f0ee132e382665d2329c9f33f97735a3a1e798d03dbb3acc60220089021568f94ce8bb2a8f723cf108a98f8a2ec9d23d896dc5931ad2b3de09e7b',PRI_DER=>'308203570201000282010100ee7508d90986f6fb4dc0477fb20012661bf17040120df3349812e4081306ca8dba7036e7db55163259f52c5daaa55d86b8b04950386eeefb37e7abadcf8424685c04c207a47bc73e85cd72a0d5dfd32db9150ca5bc5c310ab990d24ce778b99ee424449e202b253ba83b038fcf184236910115c98fafabfd51a835d28a34c3ccc4c40a7bcc0eb1aeb06084c23a156e36d55b5cd208b032f741e7225aad202f556d5175e649417ffdb86a05ced41c3728387708d5048b90687e09516ce1b934f94d8226e9791ce62827cfaced6e53a9befd1aa08baa3888996d7f076442f07a33b83ae9a8e3f0bc7abe41eb4505f32d711fca1a19cee56d733d8b1f25a7734c49022100a6220ae5da12fbfb2cb7d8b1e07c7d12e55c11db8316594b575b6bdc215931f9028201010081ae4099eec0b8a4bb8e4b4a54f445fad55d49e7561130f51e1c2eda1f1bfde83f482d15ef890587b106eed4aaf102eb57141be1824f124c0f1a4c8e34aa74de6597d411b3fb49cbdb5b163886f5b8954cb80404065575873feef35b676d70922d43cb471ab0e199bd1da380e39d9b80ffd52e72cdeef88333d8f83d6aca2f2e6332363fc002c63df5e1af6ef215ea78a44b26627fa09c3dfdd74704eddfdeac13fc34ba96355f3d48483b970e52371606ac345ddf911ce35018364d5dcb3d8f0b6845c8ca049d168d8245836a627cfaf03c0751c9faa4fd3870f596a190efca507a546fead9d63a792d8b04beda3f543a5ab19890033174484fb3081d8c8f100282010100cb10c09a261164c1aaad42837226eecc283064a3d25e402bd6585a3f32386e8625d082ba587417a54f3d4f78e0f439cb7dd7a0533c6b7be576313080efd2ade6877df67e0f3ac2199970601fcdebd6f764151e98d3ac2e3a29c98787b1b43562681388c607da5bc54e7607fa393bcba944d7a92eb9b590d01080e24c235f2c9d4b96a0ace845a1447816e54910dd52bfa92e6a0cf26453d7a93158cc6f41afdabf9642ca0f7507cba2d7149f194aa0e89a765fff0af4e1da6a62e37e61b6b7fc8a6f5fc4034da9f4929c128a8753cc05d02b2ea98b73e7523e461b888736e82738e67af73db59e3d834d4cc7b61989883b90f9cfdc4c9e421681498bef22ce3202201c590fa44b9e739c76249737db6174cd9769fe79d03fc03ba516b8ef74ad586a',PUB_DER=>'308203483082023a06072a8648ce3804013082022d0282010100ee7508d90986f6fb4dc0477fb20012661bf17040120df3349812e4081306ca8dba7036e7db55163259f52c5daaa55d86b8b04950386eeefb37e7abadcf8424685c04c207a47bc73e85cd72a0d5dfd32db9150ca5bc5c310ab990d24ce778b99ee424449e202b253ba83b038fcf184236910115c98fafabfd51a835d28a34c3ccc4c40a7bcc0eb1aeb06084c23a156e36d55b5cd208b032f741e7225aad202f556d5175e649417ffdb86a05ced41c3728387708d5048b90687e09516ce1b934f94d8226e9791ce62827cfaced6e53a9befd1aa08baa3888996d7f076442f07a33b83ae9a8e3f0bc7abe41eb4505f32d711fca1a19cee56d733d8b1f25a7734c49022100a6220ae5da12fbfb2cb7d8b1e07c7d12e55c11db8316594b575b6bdc215931f9028201010081ae4099eec0b8a4bb8e4b4a54f445fad55d49e7561130f51e1c2eda1f1bfde83f482d15ef890587b106eed4aaf102eb57141be1824f124c0f1a4c8e34aa74de6597d411b3fb49cbdb5b163886f5b8954cb80404065575873feef35b676d70922d43cb471ab0e199bd1da380e39d9b80ffd52e72cdeef88333d8f83d6aca2f2e6332363fc002c63df5e1af6ef215ea78a44b26627fa09c3dfdd74704eddfdeac13fc34ba96355f3d48483b970e52371606ac345ddf911ce35018364d5dcb3d8f0b6845c8ca049d168d8245836a627cfaf03c0751c9faa4fd3870f596a190efca507a546fead9d63a792d8b04beda3f543a5ab19890033174484fb3081d8c8f1003820106000282010100cb10c09a261164c1aaad42837226eecc283064a3d25e402bd6585a3f32386e8625d082ba587417a54f3d4f78e0f439cb7dd7a0533c6b7be576313080efd2ade6877df67e0f3ac2199970601fcdebd6f764151e98d3ac2e3a29c98787b1b43562681388c607da5bc54e7607fa393bcba944d7a92eb9b590d01080e24c235f2c9d4b96a0ace845a1447816e54910dd52bfa92e6a0cf26453d7a93158cc6f41afdabf9642ca0f7507cba2d7149f194aa0e89a765fff0af4e1da6a62e37e61b6b7fc8a6f5fc4034da9f4929c128a8753cc05d02b2ea98b73e7523e461b888736e82738e67af73db59e3d834d4cc7b61989883b90f9cfdc4c9e421681498bef22ce32'}, + {SIZE=>3072,PRI_FILE=>'key_3072-2.pri.pem',PUB_FILE=>'key_3072-2.pub.pem',PRI=>'00c2db365bb0b2788a9d1667d78d9103e43ae3d1417c3b475dbf5a1dd72c847dde',PUB=>'0b5601ed1907996bae158b1702daaae656884f08470597e74fa894fff8f5af2ee6c576c182b58abdf7b3e24833890e4e80ca6df45a26d8e504bbcb9c4ed0977dd04ac31cb3fd1834fd488527ccc8710de82b3421ebc367c9b18ebf43b4e218973d5fd63e01448e0633a7be225cc2974306fd908067920500a275a2ff37183c14c7951c72a7186c4a8b755bea148d29ffabc9895a2c7b798f80c39038ece615051ccb077eef7ac1a08a38c4dcf7cd1132202e7672848d2317b021d3779778f4d8d5a05308ba8d36f262cd661ea53a421f22bd94b521e2e9cb7e7a2831421cbe5cff7bee38ec95b1fc1a3bb09aab2395be4e5ebba2e8fe8122dde881d284ec5677f8ffdb33224c763d9fc88651df6defc321626e1c28309d80eb978392e41daf5575e9455c74db761f03367c3faf234d28d1cec619f43aaa88d5c4705f221ab9387740d30fe600399971a26c59d1a85dc075bf4515b8e41abd925c68dd49d19282119297308cf3883bc99a61c1a7bb85c28c5f3f5d863045eac5ce1b00e33a2afa',DSA_SHA1=>'3046022100cfce16904b96e5590b17bec1f739bc7aed862e9aa08d94e3d4bd465fcde977db022100dfccf04c741c4ea5e98030f1936f0928d1550f1b5ed3fe92324fc9b3715193ce',DSA_SHA256=>'3044022069f3380c6dbe99b2bc350d5d982ba2ada5605f260d15b9fa468eff1f13a6e490022030ee9d88348dc113ee3fa819e158593081fd1df15d6a803479ff68acd8509128',PRI_DER=>'308204d60201000282018100b237ef71b02ce1e42a2b3d0f5e64ee2e3c1424b1aba696d83f9ee26d0ff58fc9b506eaca7d9d1ffbab6c0aa750f87afe7661a00bb2abbc28c8f44d9d782bc955262dc4200159cf3ddf9ef7b31ce3606838af4edbfd4395f14177788059e34830b9598facf541d82306626ff5b3f6a846534e60d5d7cbdc97917c720771b1e4a9498d9a37ee997e6bac19612f7320db729f6b8c47899d6c0a80083cfaa1a534d81e0fd019d6bf145ee448e26b1597baa7140207d73924f1be96d77adc029a980019b22fa3b2a9d9c6421e0017c7c40e4b236808ad341b91403f75a1a8e57a96bd0e477458bedf13239da92176fe7b7beabe25f9edaa52c50871cb25d44faad5a0e8835bcaaf727bc9a49e77712a4006f6ac7159d954d5f5ebd4927b868e74f9409671d8b702f3e4adccd075bd3cc801de48bf3143f7e8c189f05bb7b4ef8a331ed8d806815903dd5b3e01b31928377b12ee7ee198fbd65e9c06faed56ebb170c1452c4097eb31f71c6dce49a06c9c9d74fda29ee65e74514736c78401372cabd7022100ed52f447dd0081a130d018d365c4267ec6bad820b5adf15133fd400a941d9929028201804815c0ad70253b9f0dc57a1970b7fa902f52ae06314587823043661de3f2a066a360de3a500138fbb4cfc499853550b9604d23f05b3537efc65dbf7f7149ab7e84646fad8e181fa8efcd559bcb66c29d65f71165d2564a0def5c53af84e878f1d0193f74d27c2229b6ccda82f696db41716688776c33aa9926031ef801f2519fb195d1f35236bf28e424fecf10bdc68681e30e6866810d9db7e8da5b3798a75243c9f50c18ec7bf57f266005b2e346f0038c104e7da5e8d64e8b80a41d7efba79f632493eeb06a830ee451016241a2e55820caa55c00bdd77728d6490d9b2ed2649e8ea3c92d28f8349aeef2e4fb11d76d5604dd7ce23f7fbb63adf6bbef219f6846660221f9cae8587dfba7ef1dd06a174f23ca5d2df23b4e35100d706d8af09b93c1cde387f5f814a1014cc1c0bf9662dd3eca365a6376d79058e6f5c73a04bb0064519d6b89de953ffc15044ecb7b7f16483c80084ea24dc0c1b3ae3b35d9f15519610534b18b9a66abb139bab1f1924b9d20e0d7dae504cef39cd71237f1028201800b5601ed1907996bae158b1702daaae656884f08470597e74fa894fff8f5af2ee6c576c182b58abdf7b3e24833890e4e80ca6df45a26d8e504bbcb9c4ed0977dd04ac31cb3fd1834fd488527ccc8710de82b3421ebc367c9b18ebf43b4e218973d5fd63e01448e0633a7be225cc2974306fd908067920500a275a2ff37183c14c7951c72a7186c4a8b755bea148d29ffabc9895a2c7b798f80c39038ece615051ccb077eef7ac1a08a38c4dcf7cd1132202e7672848d2317b021d3779778f4d8d5a05308ba8d36f262cd661ea53a421f22bd94b521e2e9cb7e7a2831421cbe5cff7bee38ec95b1fc1a3bb09aab2395be4e5ebba2e8fe8122dde881d284ec5677f8ffdb33224c763d9fc88651df6defc321626e1c28309d80eb978392e41daf5575e9455c74db761f03367c3faf234d28d1cec619f43aaa88d5c4705f221ab9387740d30fe600399971a26c59d1a85dc075bf4515b8e41abd925c68dd49d19282119297308cf3883bc99a61c1a7bb85c28c5f3f5d863045eac5ce1b00e33a2afa022100c2db365bb0b2788a9d1667d78d9103e43ae3d1417c3b475dbf5a1dd72c847dde',PUB_DER=>'308204c63082033906072a8648ce3804013082032c0282018100b237ef71b02ce1e42a2b3d0f5e64ee2e3c1424b1aba696d83f9ee26d0ff58fc9b506eaca7d9d1ffbab6c0aa750f87afe7661a00bb2abbc28c8f44d9d782bc955262dc4200159cf3ddf9ef7b31ce3606838af4edbfd4395f14177788059e34830b9598facf541d82306626ff5b3f6a846534e60d5d7cbdc97917c720771b1e4a9498d9a37ee997e6bac19612f7320db729f6b8c47899d6c0a80083cfaa1a534d81e0fd019d6bf145ee448e26b1597baa7140207d73924f1be96d77adc029a980019b22fa3b2a9d9c6421e0017c7c40e4b236808ad341b91403f75a1a8e57a96bd0e477458bedf13239da92176fe7b7beabe25f9edaa52c50871cb25d44faad5a0e8835bcaaf727bc9a49e77712a4006f6ac7159d954d5f5ebd4927b868e74f9409671d8b702f3e4adccd075bd3cc801de48bf3143f7e8c189f05bb7b4ef8a331ed8d806815903dd5b3e01b31928377b12ee7ee198fbd65e9c06faed56ebb170c1452c4097eb31f71c6dce49a06c9c9d74fda29ee65e74514736c78401372cabd7022100ed52f447dd0081a130d018d365c4267ec6bad820b5adf15133fd400a941d9929028201804815c0ad70253b9f0dc57a1970b7fa902f52ae06314587823043661de3f2a066a360de3a500138fbb4cfc499853550b9604d23f05b3537efc65dbf7f7149ab7e84646fad8e181fa8efcd559bcb66c29d65f71165d2564a0def5c53af84e878f1d0193f74d27c2229b6ccda82f696db41716688776c33aa9926031ef801f2519fb195d1f35236bf28e424fecf10bdc68681e30e6866810d9db7e8da5b3798a75243c9f50c18ec7bf57f266005b2e346f0038c104e7da5e8d64e8b80a41d7efba79f632493eeb06a830ee451016241a2e55820caa55c00bdd77728d6490d9b2ed2649e8ea3c92d28f8349aeef2e4fb11d76d5604dd7ce23f7fbb63adf6bbef219f6846660221f9cae8587dfba7ef1dd06a174f23ca5d2df23b4e35100d706d8af09b93c1cde387f5f814a1014cc1c0bf9662dd3eca365a6376d79058e6f5c73a04bb0064519d6b89de953ffc15044ecb7b7f16483c80084ea24dc0c1b3ae3b35d9f15519610534b18b9a66abb139bab1f1924b9d20e0d7dae504cef39cd71237f10382018500028201800b5601ed1907996bae158b1702daaae656884f08470597e74fa894fff8f5af2ee6c576c182b58abdf7b3e24833890e4e80ca6df45a26d8e504bbcb9c4ed0977dd04ac31cb3fd1834fd488527ccc8710de82b3421ebc367c9b18ebf43b4e218973d5fd63e01448e0633a7be225cc2974306fd908067920500a275a2ff37183c14c7951c72a7186c4a8b755bea148d29ffabc9895a2c7b798f80c39038ece615051ccb077eef7ac1a08a38c4dcf7cd1132202e7672848d2317b021d3779778f4d8d5a05308ba8d36f262cd661ea53a421f22bd94b521e2e9cb7e7a2831421cbe5cff7bee38ec95b1fc1a3bb09aab2395be4e5ebba2e8fe8122dde881d284ec5677f8ffdb33224c763d9fc88651df6defc321626e1c28309d80eb978392e41daf5575e9455c74db761f03367c3faf234d28d1cec619f43aaa88d5c4705f221ab9387740d30fe600399971a26c59d1a85dc075bf4515b8e41abd925c68dd49d19282119297308cf3883bc99a61c1a7bb85c28c5f3f5d863045eac5ce1b00e33a2afa'}, + {SIZE=>4096,PRI_FILE=>'key_4096-2.pri.pem',PUB_FILE=>'key_4096-2.pub.pem',PRI=>'38d41fa4f9f1b5c0f500db4333315efaa712e71cde8d789c6752166d48961287',PUB=>'0b368f4ad35f6e0b56d933d65446716d93869555a8ea5b2d8c3739ff84b6c5e330f340b667d6614249544f60896d6a8826b2cdba78c294a8a89680dc3b21885739578b1c81bc7832aadc9ca88a892cfa0b1a7fad0c4c45f2e021b1667403063855e022d1c689fb1c18239e0c8c615ca7c73d55ebd83050fc7378dfe6e4f4f30bff7b96c5def16d27fcccf40c27acae8dc2c2816b5eabbc85ad760b988ec24c33f3e2bb9757324c72b86d9baeb1899ca05a39faab9791d880927a1c6c6ec2ca695b5bc5666c94f681f958770018801323d597003153967b4c9ef3b44c65d367c86df422f9414b206db83e4264ab1e07a2be26f16cf890ae17a7335700223d46942f560834b9b368c8182f53a94aee019160544211e221caefd9697b98952543e596ffb35c1b781d181c6a1ee46c7e046b9a7281b463a7598eb04fda97e50f50f0fc191cbc0f0099432283870afce578fdfe0571f5aee8d26e0665985106ac779ae14134a0701d8864be3a7b75512cb202e2b607e90747df8177dd527d91055f6ff655ccd42fcd1b9acb71112a57c4485c23863fce3fac5dd9669cadeec0388083a087d10265ef3b215f3f0bdb7e8b6365a48583f1db8e957c39388e1655355d55890399c09c79a3d4b210c376522b95c364a804736b38ade020968febdf79fd4caa32b8ad1a3b6b4ecc57253738f3fd91fc4f6b76dfec5a3e7016b91bc0c366e2',DSA_SHA1=>'3044022026c960994107c0fa57498d136e915430577342513bfbc13b2c366ee83e0963fd0220290cf102aece997ab5811b0b19fcfecf8f8d131cf66efa23bdfe77e77eff7863',DSA_SHA256=>'304402203d265b947a4ece7bc09fac28b44e4957f07f6797ab7fab37d0618badc7d6cdae022041a9b074d9a0f8f10c79bd585192d85a2cb3670f39d8e661ee171474a2878f89',PRI_DER=>'30820655020100028202010090b1ddb54da806089760fafeb78ddbe711f28029e7759b9617f8f08708a28b9e3ece970e1faeaac05f6df297f417f45a7037f19fcab47d2d9ba6eae1d46a5f84ecb01511b796ac40dd26b794262410042e18c023806986fb8a1fe796e254f0b19f4c948c09f5980e9ed6789c9fed5e262eeefef61661c45479b0580fd81a380ddf18f6e7839f362515bdbcb67abda613bf9308f7667d6828b02b30bd33bbf32455bc7e5c112c80a7acb0e4917eb05f6e59f794887b909a061ac92dc579d9913ce454e51d856c07632a4a37af749d834b3b994a15193187eca0a20a325c42ef46386e0b01b17102f38ef0ab8e4cca6e52b158c5448957123df4b95f9d11a965a099dd986dd065f482432c023dd2c47231d300e03bc385e1721ff20b7b73c93f9c9e8f0125eb5f8e562eb8bfc187f69a942e1cc395ec531afd04e5b4867a7fcdc31bde4cfce070510d1c6b6dc27d3603c3eebcd7a0853b1b473838629c9b2356c1b340920a94ada02c59e49eae8ecdfbe6826a9b357dee648ab2723ea0bf9f2fa73c1ef86b2dbb2ade24d9d9ba1e9302a8e01a9fedf4b7fadba98fcc825397c49d341933df3b20a4f6baea78ee298df10e3482f1742d86bbd35e3426ae674a1d8059fa0d6ff1761f7df80fa628c17944ddd7e04798e64c2dcf689320bc3827b034c5b9a5e0de71a9a176a354671c2f178b89e294a04253b4b45cc4dd93c14fdb2702210081ec0285d408ba6cd1510844c6688e043ca153c251f8b013e81387e2dce34567028202000c517a3ce47e34e7fe8e40d1868e5c5b20f7c5d34f5c50abf776c4a229331aa66006d55824be2941ec88d664536641884e1a50ae02c789b323d7148073df13dded991591d84f29b38c37da71a4930160c1ce6bd3c0d2501f461db4e0e750b543631a7809e991a932527ee7de40b2709ad777e36f443d208de3898d2694af863494a1d13524d4d68bf23d40d2856c3f5b496053f6a7f0ed649a6165ab8ff6a3d6e733e0a7e55972e32d53afd0f8d62e4596ea0e95be45ac7939003f02d31904389cef190ea07456b2198e27c1fc1be7f1d40a9d57d5826f81e1430fbf7f73036e6069cb06438632add8c594619ccb28018b4e25a28940fc99e85aa909864bcbd6ac77d1021e2ecd7900c313179b9ec0b3fc0a619800389995e3be5f89d0bbb55e6e7b963aeee3bff45dbf76d8cb1be3b7ccc511b1a056df14b71927fbb64df02773a160c2dfb534f62b56f4fee6dd864ae46b366d96aee8fd714d4f8e87c27f53293475344b0117430c6033b41a19ac48d1472691f5123540477e23383848c308211a6c7d87885ec4db1edc424da2102006f4506f3e077c118a3f080ec0bdd03151bef1a2d860f9a6df2cf7b9ea7a6597f6bcd21bf8960e6a36ef032ed49ef11e5bdaf2b4b8b30178dae663f7f2dffb1d3e25ee4d039c2302164255353ce52535901fc9b9a054c1fb8fd0b9a2d8bc661ed0603f2e00f3d3532051082bb251c157028202000b368f4ad35f6e0b56d933d65446716d93869555a8ea5b2d8c3739ff84b6c5e330f340b667d6614249544f60896d6a8826b2cdba78c294a8a89680dc3b21885739578b1c81bc7832aadc9ca88a892cfa0b1a7fad0c4c45f2e021b1667403063855e022d1c689fb1c18239e0c8c615ca7c73d55ebd83050fc7378dfe6e4f4f30bff7b96c5def16d27fcccf40c27acae8dc2c2816b5eabbc85ad760b988ec24c33f3e2bb9757324c72b86d9baeb1899ca05a39faab9791d880927a1c6c6ec2ca695b5bc5666c94f681f958770018801323d597003153967b4c9ef3b44c65d367c86df422f9414b206db83e4264ab1e07a2be26f16cf890ae17a7335700223d46942f560834b9b368c8182f53a94aee019160544211e221caefd9697b98952543e596ffb35c1b781d181c6a1ee46c7e046b9a7281b463a7598eb04fda97e50f50f0fc191cbc0f0099432283870afce578fdfe0571f5aee8d26e0665985106ac779ae14134a0701d8864be3a7b75512cb202e2b607e90747df8177dd527d91055f6ff655ccd42fcd1b9acb71112a57c4485c23863fce3fac5dd9669cadeec0388083a087d10265ef3b215f3f0bdb7e8b6365a48583f1db8e957c39388e1655355d55890399c09c79a3d4b210c376522b95c364a804736b38ade020968febdf79fd4caa32b8ad1a3b6b4ecc57253738f3fd91fc4f6b76dfec5a3e7016b91bc0c366e2022038d41fa4f9f1b5c0f500db4333315efaa712e71cde8d789c6752166d48961287',PUB_DER=>'308206463082043906072a8648ce3804013082042c028202010090b1ddb54da806089760fafeb78ddbe711f28029e7759b9617f8f08708a28b9e3ece970e1faeaac05f6df297f417f45a7037f19fcab47d2d9ba6eae1d46a5f84ecb01511b796ac40dd26b794262410042e18c023806986fb8a1fe796e254f0b19f4c948c09f5980e9ed6789c9fed5e262eeefef61661c45479b0580fd81a380ddf18f6e7839f362515bdbcb67abda613bf9308f7667d6828b02b30bd33bbf32455bc7e5c112c80a7acb0e4917eb05f6e59f794887b909a061ac92dc579d9913ce454e51d856c07632a4a37af749d834b3b994a15193187eca0a20a325c42ef46386e0b01b17102f38ef0ab8e4cca6e52b158c5448957123df4b95f9d11a965a099dd986dd065f482432c023dd2c47231d300e03bc385e1721ff20b7b73c93f9c9e8f0125eb5f8e562eb8bfc187f69a942e1cc395ec531afd04e5b4867a7fcdc31bde4cfce070510d1c6b6dc27d3603c3eebcd7a0853b1b473838629c9b2356c1b340920a94ada02c59e49eae8ecdfbe6826a9b357dee648ab2723ea0bf9f2fa73c1ef86b2dbb2ade24d9d9ba1e9302a8e01a9fedf4b7fadba98fcc825397c49d341933df3b20a4f6baea78ee298df10e3482f1742d86bbd35e3426ae674a1d8059fa0d6ff1761f7df80fa628c17944ddd7e04798e64c2dcf689320bc3827b034c5b9a5e0de71a9a176a354671c2f178b89e294a04253b4b45cc4dd93c14fdb2702210081ec0285d408ba6cd1510844c6688e043ca153c251f8b013e81387e2dce34567028202000c517a3ce47e34e7fe8e40d1868e5c5b20f7c5d34f5c50abf776c4a229331aa66006d55824be2941ec88d664536641884e1a50ae02c789b323d7148073df13dded991591d84f29b38c37da71a4930160c1ce6bd3c0d2501f461db4e0e750b543631a7809e991a932527ee7de40b2709ad777e36f443d208de3898d2694af863494a1d13524d4d68bf23d40d2856c3f5b496053f6a7f0ed649a6165ab8ff6a3d6e733e0a7e55972e32d53afd0f8d62e4596ea0e95be45ac7939003f02d31904389cef190ea07456b2198e27c1fc1be7f1d40a9d57d5826f81e1430fbf7f73036e6069cb06438632add8c594619ccb28018b4e25a28940fc99e85aa909864bcbd6ac77d1021e2ecd7900c313179b9ec0b3fc0a619800389995e3be5f89d0bbb55e6e7b963aeee3bff45dbf76d8cb1be3b7ccc511b1a056df14b71927fbb64df02773a160c2dfb534f62b56f4fee6dd864ae46b366d96aee8fd714d4f8e87c27f53293475344b0117430c6033b41a19ac48d1472691f5123540477e23383848c308211a6c7d87885ec4db1edc424da2102006f4506f3e077c118a3f080ec0bdd03151bef1a2d860f9a6df2cf7b9ea7a6597f6bcd21bf8960e6a36ef032ed49ef11e5bdaf2b4b8b30178dae663f7f2dffb1d3e25ee4d039c2302164255353ce52535901fc9b9a054c1fb8fd0b9a2d8bc661ed0603f2e00f3d3532051082bb251c1570382020500028202000b368f4ad35f6e0b56d933d65446716d93869555a8ea5b2d8c3739ff84b6c5e330f340b667d6614249544f60896d6a8826b2cdba78c294a8a89680dc3b21885739578b1c81bc7832aadc9ca88a892cfa0b1a7fad0c4c45f2e021b1667403063855e022d1c689fb1c18239e0c8c615ca7c73d55ebd83050fc7378dfe6e4f4f30bff7b96c5def16d27fcccf40c27acae8dc2c2816b5eabbc85ad760b988ec24c33f3e2bb9757324c72b86d9baeb1899ca05a39faab9791d880927a1c6c6ec2ca695b5bc5666c94f681f958770018801323d597003153967b4c9ef3b44c65d367c86df422f9414b206db83e4264ab1e07a2be26f16cf890ae17a7335700223d46942f560834b9b368c8182f53a94aee019160544211e221caefd9697b98952543e596ffb35c1b781d181c6a1ee46c7e046b9a7281b463a7598eb04fda97e50f50f0fc191cbc0f0099432283870afce578fdfe0571f5aee8d26e0665985106ac779ae14134a0701d8864be3a7b75512cb202e2b607e90747df8177dd527d91055f6ff655ccd42fcd1b9acb71112a57c4485c23863fce3fac5dd9669cadeec0388083a087d10265ef3b215f3f0bdb7e8b6365a48583f1db8e957c39388e1655355d55890399c09c79a3d4b210c376522b95c364a804736b38ade020968febdf79fd4caa32b8ad1a3b6b4ecc57253738f3fd91fc4f6b76dfec5a3e7016b91bc0c366e2'}, + {SIZE=>512,PRI_FILE=>'key_512-3.pri.pem',PUB_FILE=>'key_512-3.pub.pem',PRI=>'44ad88412b165ab43a59205dee392b71a7166462',PUB=>'7354177bb79b818530f0afc8f1a8379273b3f6c22febce156e9ac187c97d99ed94e0465e96d688cd9e0896cd7fd2e755a9bd81206c5fcf28a28dde23d773270b',DSA_SHA1=>'302e021500a1a36ecd213faf706340004f766e8473d7d84a24021500b0431f94dbf71cb29424525ffcf3f46552ffd392',DSA_SHA256=>'302d02143a67062aa24c257431c3ac8ad1cd33a453ff545c0215008dfc43a31aade0136548451a4a2ca4d54f3b8715',PRI_DER=>'3081f70201000241009b328b2ee18d24b0c9f030c68038cab21d547a422f2bcced33b28b89c01f8ecc36f00d5a30d0cede004806ed3e1b1ec5231724d85756f8afabac16914c595a65021500b1e2ea9e46f4bf1f8bd158a0463e4c6fe50b1d8d024027f89024380018f5c3e2adc5d85763d82e4c54a9cacb6a1c25f7c12b29eeb0eddc7593e112a07576ad6dd4c4b78cf624d5df25a6a4cd69c7132e7a693990519302407354177bb79b818530f0afc8f1a8379273b3f6c22febce156e9ac187c97d99ed94e0465e96d688cd9e0896cd7fd2e755a9bd81206c5fcf28a28dde23d773270b021444ad88412b165ab43a59205dee392b71a7166462',PUB_DER=>'3081f03081a806072a8648ce38040130819c0241009b328b2ee18d24b0c9f030c68038cab21d547a422f2bcced33b28b89c01f8ecc36f00d5a30d0cede004806ed3e1b1ec5231724d85756f8afabac16914c595a65021500b1e2ea9e46f4bf1f8bd158a0463e4c6fe50b1d8d024027f89024380018f5c3e2adc5d85763d82e4c54a9cacb6a1c25f7c12b29eeb0eddc7593e112a07576ad6dd4c4b78cf624d5df25a6a4cd69c7132e7a693990519303430002407354177bb79b818530f0afc8f1a8379273b3f6c22febce156e9ac187c97d99ed94e0465e96d688cd9e0896cd7fd2e755a9bd81206c5fcf28a28dde23d773270b'}, + {SIZE=>1024,PRI_FILE=>'key_1024-3.pri.pem',PUB_FILE=>'key_1024-3.pub.pem',PRI=>'4589befc1e879af92d5aa5ebfb816d5cacb77297',PUB=>'0082af54957f228f659e65c974db10e4f7811f9f7a13b8e9b1dc7331284ad54f588f2b891745a36c9a5eb1e5bba4f28c4e357c494fad8f4b446421e5d823904816ce6233694c7114be15a0002ab92956b7787b1986dd6bb578b83933ab878593202ff74e94196e7fceb13fa55f5a1c4588d6c6b3c2941edda4fcd7ca66f7e2585a',DSA_SHA1=>'302c02140f83819f9e2acb17223aa75427240311a775e13402146d17093744308954cfe894790ed903a8811852b9',DSA_SHA256=>'302c0214236c3dece1c1cfda8fd6a581052aeea7a6a328e002140d790d58d2d8cc85383618eba360e414999c48e2',PRI_DER=>'308201bb0201000281810088d428e174d87c18265d9da55b384d1228c1fa6bf036401e8a41022bb32e5fbcb5ad3a75ef3ab7d90ece0b1ffbe611ed89beb2d59e2c40d570e8af8a6821936b29725074885a3a6ace615dce8fbceef93a3d3f671fd2ac4742ec0a18fc9369d003c127c603eb3b4d5d45cc9bbfdcd556e6a8418db55c453dc08f56e158e9aa03021500d452d5c4fd4bc831e0dc8c5d2d36ceda165fba9502818031bef6d3315713597c8f8e0306f9872e66ace4c54c30a76afbbfcacc2e2c4a719d947ed2b2f180ffb241ff62d7e5e000556e56ca5aa1e9e59b9a375d4b6779558787f9f931801b94cbe3a663dd9554077f597e719f276686b921a5477997d97b6953cdc8e05ad73ffeb9ebe7cff684a29021fe77d3ea432a5bb417fd422cad6a0281810082af54957f228f659e65c974db10e4f7811f9f7a13b8e9b1dc7331284ad54f588f2b891745a36c9a5eb1e5bba4f28c4e357c494fad8f4b446421e5d823904816ce6233694c7114be15a0002ab92956b7787b1986dd6bb578b83933ab878593202ff74e94196e7fceb13fa55f5a1c4588d6c6b3c2941edda4fcd7ca66f7e2585a02144589befc1e879af92d5aa5ebfb816d5cacb77297',PUB_DER=>'308201b73082012b06072a8648ce3804013082011e0281810088d428e174d87c18265d9da55b384d1228c1fa6bf036401e8a41022bb32e5fbcb5ad3a75ef3ab7d90ece0b1ffbe611ed89beb2d59e2c40d570e8af8a6821936b29725074885a3a6ace615dce8fbceef93a3d3f671fd2ac4742ec0a18fc9369d003c127c603eb3b4d5d45cc9bbfdcd556e6a8418db55c453dc08f56e158e9aa03021500d452d5c4fd4bc831e0dc8c5d2d36ceda165fba9502818031bef6d3315713597c8f8e0306f9872e66ace4c54c30a76afbbfcacc2e2c4a719d947ed2b2f180ffb241ff62d7e5e000556e56ca5aa1e9e59b9a375d4b6779558787f9f931801b94cbe3a663dd9554077f597e719f276686b921a5477997d97b6953cdc8e05ad73ffeb9ebe7cff684a29021fe77d3ea432a5bb417fd422cad6a038185000281810082af54957f228f659e65c974db10e4f7811f9f7a13b8e9b1dc7331284ad54f588f2b891745a36c9a5eb1e5bba4f28c4e357c494fad8f4b446421e5d823904816ce6233694c7114be15a0002ab92956b7787b1986dd6bb578b83933ab878593202ff74e94196e7fceb13fa55f5a1c4588d6c6b3c2941edda4fcd7ca66f7e2585a'}, + {SIZE=>1536,PRI_FILE=>'key_1536-3.pri.pem',PUB_FILE=>'key_1536-3.pub.pem',PRI=>'00f71141cf80f653272aaa38288b45424bf5145f3d',PUB=>'53f6a23eef20ee0032caa4a4ceea6eca6a4448246be18b935ddbb4982d737dd5bc216cf50b4343beca56d913175b8c984d7aa381fe55e60ff5cd5cdd12e7e1f16f29a25bc1911a2a14911dbf31c4004246e6930ed5b884ecc73332a9120c27aaa731a3249163ad91764a3883a3ea477744c9c5349abcf6291ef5ba5102aee912b475e4186eb400594474ecb6c53f996b17e2e9d1238fa2b9d44a6df4e536cff96cde614d5e146446303beba02b520ddf6fe42414391f73daacc5365e4b881d16',DSA_SHA1=>'302d0215008d3cddc5e8d7e19ced7d7859f8ec38e3a0c352be02143657b7417c64cf715eac4a1666c9e964e0ae5ac8',DSA_SHA256=>'302d02147d8330a66f4415e548a72c9bc95a172d1ce423ff021500df28aa0a60965fa6f096b95c216d419c219f8435',PRI_DER=>'3082027c0201000281c100b8dce58c5b30fa449a4d8a8c97bd8bd8279f47a15b0f4cc5ef9b566c19d3259ee57292f5d8a84fa11df9c9a3ea3183ad2cc62b7261da4815acf620387c265235c89c0ef4e7de13ce081b47dab3046a68a6858b183028567dae91fbbca6ce263af5bdc106018cf47686aea352df286af5c48d14c4fe528731c5684c5efb79e99bffd87e7c6ee52e4bb5ea536dfb85ea33a241f99adb30c5489f9c4b5b6f4a0231f74cae0986f70a0ef259e9ca18937abe8ce387c51644e0bb58950037098cc8bf021500facd6fa6fab1a552398b3fdd07fb704354ad305f0281c100b665a4de3c066541735a9a5c60707512e2e37af0ef3f36c7d73c7f419b98d1956aadac1551fb9196a1ed1f6318a0d100ec3f2e6b9dba345a9362db38b07d2e5f42ca91d4dc0168fd61a09c60c95596f7b1eda3a238db6931aced78116f4ec0cf901afd18d7143ee442a1037c3ee0efe80f120eb8bfdebf3b5c9f0e0d71f68a00393f5ce5b774cb1e44cfec7a794e34e6d7907a6c233d41a375779812f4c8283b24d8d18cfd13fbd717076004ed5cf59f2b5884e2310c069df1c5e75081a7202a0281c053f6a23eef20ee0032caa4a4ceea6eca6a4448246be18b935ddbb4982d737dd5bc216cf50b4343beca56d913175b8c984d7aa381fe55e60ff5cd5cdd12e7e1f16f29a25bc1911a2a14911dbf31c4004246e6930ed5b884ecc73332a9120c27aaa731a3249163ad91764a3883a3ea477744c9c5349abcf6291ef5ba5102aee912b475e4186eb400594474ecb6c53f996b17e2e9d1238fa2b9d44a6df4e536cff96cde614d5e146446303beba02b520ddf6fe42414391f73daacc5365e4b881d16021500f71141cf80f653272aaa38288b45424bf5145f3d',PUB_DER=>'30820277308201ac06072a8648ce3804013082019f0281c100b8dce58c5b30fa449a4d8a8c97bd8bd8279f47a15b0f4cc5ef9b566c19d3259ee57292f5d8a84fa11df9c9a3ea3183ad2cc62b7261da4815acf620387c265235c89c0ef4e7de13ce081b47dab3046a68a6858b183028567dae91fbbca6ce263af5bdc106018cf47686aea352df286af5c48d14c4fe528731c5684c5efb79e99bffd87e7c6ee52e4bb5ea536dfb85ea33a241f99adb30c5489f9c4b5b6f4a0231f74cae0986f70a0ef259e9ca18937abe8ce387c51644e0bb58950037098cc8bf021500facd6fa6fab1a552398b3fdd07fb704354ad305f0281c100b665a4de3c066541735a9a5c60707512e2e37af0ef3f36c7d73c7f419b98d1956aadac1551fb9196a1ed1f6318a0d100ec3f2e6b9dba345a9362db38b07d2e5f42ca91d4dc0168fd61a09c60c95596f7b1eda3a238db6931aced78116f4ec0cf901afd18d7143ee442a1037c3ee0efe80f120eb8bfdebf3b5c9f0e0d71f68a00393f5ce5b774cb1e44cfec7a794e34e6d7907a6c233d41a375779812f4c8283b24d8d18cfd13fbd717076004ed5cf59f2b5884e2310c069df1c5e75081a7202a0381c4000281c053f6a23eef20ee0032caa4a4ceea6eca6a4448246be18b935ddbb4982d737dd5bc216cf50b4343beca56d913175b8c984d7aa381fe55e60ff5cd5cdd12e7e1f16f29a25bc1911a2a14911dbf31c4004246e6930ed5b884ecc73332a9120c27aaa731a3249163ad91764a3883a3ea477744c9c5349abcf6291ef5ba5102aee912b475e4186eb400594474ecb6c53f996b17e2e9d1238fa2b9d44a6df4e536cff96cde614d5e146446303beba02b520ddf6fe42414391f73daacc5365e4b881d16'}, + {SIZE=>2048,PRI_FILE=>'key_2048-3.pri.pem',PUB_FILE=>'key_2048-3.pub.pem',PRI=>'193475eb231fd607055354f80d9ff3e57ec231e8dbbff55f95482fd519b74fe0',PUB=>'661321784a1ea8dc4790d824e1f816f29245e01801336a3c171019815c7a948e4c39304b4f242a8353a4f7c1b51d1a1318145769f5cdf4ede0728f383b896d4ece262706e4612711427f96651c1440f1b7ef669a9811771c777e851cc6f81fb205ea8e8e1585a0dadca1b6f5e276590716616345d8a3fba6fb3a3b7c34ed16a3214fd9d51936c39348c64af6ba30dee50e5a10c8e19a53ec88217ac3f6b8ab237fcfcf25d08a202bfff256cf68cf5d0e6d9b03296c15a3be0598d349234128ce76ac6e207702bdbfe99b545a900880400130249fbbd67ea2135ebc15150eb1814da820d81a01185b7dce2c4f6bae3a20f0a9cefa03b0cb660934022c07070ac3',DSA_SHA1=>'304502200b25566c0237e7dca7ac792b10a314ee0360337c3a5a089ba0e2e84fcae3786802210088af5f3c1fb63a286d47985b19499f727bbea199af01d36684db1d003689e4de',DSA_SHA256=>'304402201e4355145e0efe9d86a9c2c2a104e2ccc3fbe7af3f6282f3b011e0f2a3f6a056022057e94dda0220995348167aa23f80d7a91138a7b076d47416b6994b8b63cf8bae',PRI_DER=>'308203560201000282010100f25d3273dcd60ae415dfcaffa157a2781adf86a6227fcd411be3d09becde1ea2ed6ad1e3de90f41f441af965f21c739af4aa0f89d881f13e995e075d1279124deb25adcbbd43a0281e2272807fd402f74a9e07a151c1b6f95ed80a5e5fab67afb6b0d2b799d1c12e3e154a4caf48322352eb218c085fa91309f4b94b4a448651adbb7cfc6511883881ae241143b456f28844fdbfd22294dec457c9d9915c823dc68d336211832786500b775900816cdc9abdd8e97bdc3838d2f88cb172511770cc59ee067d9c8cac1776c7818a4b6d432eefdeed2429d2662f6e7885d79bfa17df116648634f4a133e95c6250cf7c9e3cbd8f74d49ad804f5c0ca1377f9efa590221009cc0f23bd00116a00b0fa28ee420c58a34d4809fa661f0755b3ea2ed51e55b0d0282010100c8c793880b0c8fbdfc0ecc7320e7fee017c5796382d00575875d4a9df8c313310054e33b46f2f3ec20cb78bc2ac5de6c86416f7359cb10e5a20b9822db9e323e416a43669fdc6bcf6ad57aadeceffb101c7a4683c3b77ab5a7e13126f1332880a70536669d35783d0c2d58b27234aeee67940e96cc8b3cb228d4e2c1dd347b324d8ac5a80ec208db47cd121e260cac787c0f7500e220a2db1f0f940d5fac2a7756b050f45bf8726610f7ab61bfb9353d3c6cf00df77110f32d038bc58597275e3942e303befdbf37b440c4f5c419551d8943f852a3f641bc454b22e5ecf6687aefb258971aa4b414c14298bab8948859985c57ce1a52ed1d21e4bb1255773dce02820100661321784a1ea8dc4790d824e1f816f29245e01801336a3c171019815c7a948e4c39304b4f242a8353a4f7c1b51d1a1318145769f5cdf4ede0728f383b896d4ece262706e4612711427f96651c1440f1b7ef669a9811771c777e851cc6f81fb205ea8e8e1585a0dadca1b6f5e276590716616345d8a3fba6fb3a3b7c34ed16a3214fd9d51936c39348c64af6ba30dee50e5a10c8e19a53ec88217ac3f6b8ab237fcfcf25d08a202bfff256cf68cf5d0e6d9b03296c15a3be0598d349234128ce76ac6e207702bdbfe99b545a900880400130249fbbd67ea2135ebc15150eb1814da820d81a01185b7dce2c4f6bae3a20f0a9cefa03b0cb660934022c07070ac30220193475eb231fd607055354f80d9ff3e57ec231e8dbbff55f95482fd519b74fe0',PUB_DER=>'308203473082023a06072a8648ce3804013082022d0282010100f25d3273dcd60ae415dfcaffa157a2781adf86a6227fcd411be3d09becde1ea2ed6ad1e3de90f41f441af965f21c739af4aa0f89d881f13e995e075d1279124deb25adcbbd43a0281e2272807fd402f74a9e07a151c1b6f95ed80a5e5fab67afb6b0d2b799d1c12e3e154a4caf48322352eb218c085fa91309f4b94b4a448651adbb7cfc6511883881ae241143b456f28844fdbfd22294dec457c9d9915c823dc68d336211832786500b775900816cdc9abdd8e97bdc3838d2f88cb172511770cc59ee067d9c8cac1776c7818a4b6d432eefdeed2429d2662f6e7885d79bfa17df116648634f4a133e95c6250cf7c9e3cbd8f74d49ad804f5c0ca1377f9efa590221009cc0f23bd00116a00b0fa28ee420c58a34d4809fa661f0755b3ea2ed51e55b0d0282010100c8c793880b0c8fbdfc0ecc7320e7fee017c5796382d00575875d4a9df8c313310054e33b46f2f3ec20cb78bc2ac5de6c86416f7359cb10e5a20b9822db9e323e416a43669fdc6bcf6ad57aadeceffb101c7a4683c3b77ab5a7e13126f1332880a70536669d35783d0c2d58b27234aeee67940e96cc8b3cb228d4e2c1dd347b324d8ac5a80ec208db47cd121e260cac787c0f7500e220a2db1f0f940d5fac2a7756b050f45bf8726610f7ab61bfb9353d3c6cf00df77110f32d038bc58597275e3942e303befdbf37b440c4f5c419551d8943f852a3f641bc454b22e5ecf6687aefb258971aa4b414c14298bab8948859985c57ce1a52ed1d21e4bb1255773dce038201050002820100661321784a1ea8dc4790d824e1f816f29245e01801336a3c171019815c7a948e4c39304b4f242a8353a4f7c1b51d1a1318145769f5cdf4ede0728f383b896d4ece262706e4612711427f96651c1440f1b7ef669a9811771c777e851cc6f81fb205ea8e8e1585a0dadca1b6f5e276590716616345d8a3fba6fb3a3b7c34ed16a3214fd9d51936c39348c64af6ba30dee50e5a10c8e19a53ec88217ac3f6b8ab237fcfcf25d08a202bfff256cf68cf5d0e6d9b03296c15a3be0598d349234128ce76ac6e207702bdbfe99b545a900880400130249fbbd67ea2135ebc15150eb1814da820d81a01185b7dce2c4f6bae3a20f0a9cefa03b0cb660934022c07070ac3'}, + {SIZE=>3072,PRI_FILE=>'key_3072-3.pri.pem',PUB_FILE=>'key_3072-3.pub.pem',PRI=>'00b7f3580347bd0036d803d6ec8b91390cde0486e1bc78e79585b91c3da0a1f654',PUB=>'2eec741d2835ff4dffa7b41c533105346c21bf6140bdbc25aec290166b1c87f1bec4c9a3b6c41f3ca5e1a170b1656485fdc98a00bc294fb8e2b95f03f1b0b104768d69de74146dd0921545babc51e7f85c35276602c319dea058b3973614866af220d5bc7aed3353ac79a506b7b5b7e3f8e957ebb2c5d1bd5bcda844df0ea275d80eb28c40f501cca3cf1d64173e244daca9e3fb53925dee37ac0eda6ae08141003f48c5580688a40d5b2b11e2fa81ad4888514a2eaf59cd23f3bb5bab4f595aec5a8639001788280272af77caa3eb16c4544708b2540d89f52cf544138bd3ac1e44c50ef9f99169a090a4ee36f61964189a03eecba84bfeec150cbd99d2b410fc2e465d9c0131d373510e48503a9a71f808f96515ab908dd942ca71f745ce7d3f50da9a202490939ca4037ff67ca3542914b0becea148979b1a78bac983863a39ac04f4ca73a24573c4d8bee1031008e7b4497304cf660d5ee300d767f7ade2945005a0fb75c9817e8351fa57cf7aab3db012702cfbe90fcd1aac50faab11df',DSA_SHA1=>'304502210093daa231cb0aaaa606e081f9dc0f877ab6e7b0bd96ef7b80885f871b72805cd402202d4f30e5f05d41138719abdb1897053c9588743f218b78044c63b4fd2f4080b3',DSA_SHA256=>'304402201cbaf998e6da4d73c94eda876a0683a72f7b808cef4b74191f40ec04810e8f16022061a8182ebddb911be3b6ac9e45576fecc3ea115285562907743ce0220e34bef9',PRI_DER=>'308204d6020100028201810080ac23af0ddcf39c3e8755c8fc9ae0ca0d698af17474bcac63e591f71397dd38ce912a9ef9f429ac3b5bf49c29e3723e45f47202c8ae050ec978ebece60436748e3cda32cfd3b072fd2719dc38dd8ffa200aa1b221a5f2478947056e20a0aba6f2475be6e71213bda62b284a0a07a20524c8edcd494933a89da43a576ed98476f46ff0f03838fedf4a902ea4abcc6f0c98749b6e7c678922b5a19042c011102b853c90fb490a268830cbbd9a74e24d0328d63f0c2851b768560b010cac03ea9b79abdbd1c0c80306d6a7eea7763b713e27e1ac45f483f7a14d64308a9fa09521609263cac314492f50487bf6c3a63f53b4a98bf8053c63cbb65dce373e70637aca6f63afabdd9dbb3106609052c4d8946cc3c2f08abf8171b18d5de415d001b69e63a07a69ef8a85fa69ac6acce63728c93a435c22e6342ab6f9438aee6dfd9f39c482751a1d1200d17903b05785eb15c35af02866275b0f42277a46c7a9205765ef756bdb9db084c2ceb2bb0380ed86dd15a121929b6cbba611908231d086ad022100b956a289913fd513bf3d085e8837f60e6490be78eff0d98d93f4d08c5e74001d0282018029004ac99e2e5aba6d99ba74da246fbbaae7ba1540cb5d35dfdcd93dcf5bb0742bd8db503ae91bb0b3d8c6847e40c86e85f7770c62691ae204e52d73d824c3510a56f0c221125cd9281522be35e4b52c5c8bc8b4eb72669841e5d4171bd92db8771c546975078070fc6c18b49823df98cb2d2584ae483a73161b1eb9768d1948e3ce2bf8da0eb922278ca17453eb67157c92a0e143cd8b817323229a98ad818418a1ad994ec0cb1a726d2118b494efb763c866f49337c22b34dd0fa4fbb73c9d4f88ab28541ce78a52255cd7c95fc3d7fc228d79a99e83d54ea4168275aa3a72fbd950891c3d42c048b9ba03c553b5d0aed83637569f59686aa57488e4746ad89c90fea0e377959075abafaefd7ccff5bd1212e547dbcd70026b9cb04012d8c97d62ba8dc1b9c3ef7eb6ff0b9e25efc3eb593ce2e604b7b662e12390f3044591d80812d309382367d21ab77ead78ce7d1606dbe22e5a3ec722bb2a6d67e5d0f0d44c00b1e80cee0583f61df7bdb9b9ebf8225a5041b633dfaf11198d7c983f60028201802eec741d2835ff4dffa7b41c533105346c21bf6140bdbc25aec290166b1c87f1bec4c9a3b6c41f3ca5e1a170b1656485fdc98a00bc294fb8e2b95f03f1b0b104768d69de74146dd0921545babc51e7f85c35276602c319dea058b3973614866af220d5bc7aed3353ac79a506b7b5b7e3f8e957ebb2c5d1bd5bcda844df0ea275d80eb28c40f501cca3cf1d64173e244daca9e3fb53925dee37ac0eda6ae08141003f48c5580688a40d5b2b11e2fa81ad4888514a2eaf59cd23f3bb5bab4f595aec5a8639001788280272af77caa3eb16c4544708b2540d89f52cf544138bd3ac1e44c50ef9f99169a090a4ee36f61964189a03eecba84bfeec150cbd99d2b410fc2e465d9c0131d373510e48503a9a71f808f96515ab908dd942ca71f745ce7d3f50da9a202490939ca4037ff67ca3542914b0becea148979b1a78bac983863a39ac04f4ca73a24573c4d8bee1031008e7b4497304cf660d5ee300d767f7ade2945005a0fb75c9817e8351fa57cf7aab3db012702cfbe90fcd1aac50faab11df022100b7f3580347bd0036d803d6ec8b91390cde0486e1bc78e79585b91c3da0a1f654',PUB_DER=>'308204c63082033906072a8648ce3804013082032c028201810080ac23af0ddcf39c3e8755c8fc9ae0ca0d698af17474bcac63e591f71397dd38ce912a9ef9f429ac3b5bf49c29e3723e45f47202c8ae050ec978ebece60436748e3cda32cfd3b072fd2719dc38dd8ffa200aa1b221a5f2478947056e20a0aba6f2475be6e71213bda62b284a0a07a20524c8edcd494933a89da43a576ed98476f46ff0f03838fedf4a902ea4abcc6f0c98749b6e7c678922b5a19042c011102b853c90fb490a268830cbbd9a74e24d0328d63f0c2851b768560b010cac03ea9b79abdbd1c0c80306d6a7eea7763b713e27e1ac45f483f7a14d64308a9fa09521609263cac314492f50487bf6c3a63f53b4a98bf8053c63cbb65dce373e70637aca6f63afabdd9dbb3106609052c4d8946cc3c2f08abf8171b18d5de415d001b69e63a07a69ef8a85fa69ac6acce63728c93a435c22e6342ab6f9438aee6dfd9f39c482751a1d1200d17903b05785eb15c35af02866275b0f42277a46c7a9205765ef756bdb9db084c2ceb2bb0380ed86dd15a121929b6cbba611908231d086ad022100b956a289913fd513bf3d085e8837f60e6490be78eff0d98d93f4d08c5e74001d0282018029004ac99e2e5aba6d99ba74da246fbbaae7ba1540cb5d35dfdcd93dcf5bb0742bd8db503ae91bb0b3d8c6847e40c86e85f7770c62691ae204e52d73d824c3510a56f0c221125cd9281522be35e4b52c5c8bc8b4eb72669841e5d4171bd92db8771c546975078070fc6c18b49823df98cb2d2584ae483a73161b1eb9768d1948e3ce2bf8da0eb922278ca17453eb67157c92a0e143cd8b817323229a98ad818418a1ad994ec0cb1a726d2118b494efb763c866f49337c22b34dd0fa4fbb73c9d4f88ab28541ce78a52255cd7c95fc3d7fc228d79a99e83d54ea4168275aa3a72fbd950891c3d42c048b9ba03c553b5d0aed83637569f59686aa57488e4746ad89c90fea0e377959075abafaefd7ccff5bd1212e547dbcd70026b9cb04012d8c97d62ba8dc1b9c3ef7eb6ff0b9e25efc3eb593ce2e604b7b662e12390f3044591d80812d309382367d21ab77ead78ce7d1606dbe22e5a3ec722bb2a6d67e5d0f0d44c00b1e80cee0583f61df7bdb9b9ebf8225a5041b633dfaf11198d7c983f600382018500028201802eec741d2835ff4dffa7b41c533105346c21bf6140bdbc25aec290166b1c87f1bec4c9a3b6c41f3ca5e1a170b1656485fdc98a00bc294fb8e2b95f03f1b0b104768d69de74146dd0921545babc51e7f85c35276602c319dea058b3973614866af220d5bc7aed3353ac79a506b7b5b7e3f8e957ebb2c5d1bd5bcda844df0ea275d80eb28c40f501cca3cf1d64173e244daca9e3fb53925dee37ac0eda6ae08141003f48c5580688a40d5b2b11e2fa81ad4888514a2eaf59cd23f3bb5bab4f595aec5a8639001788280272af77caa3eb16c4544708b2540d89f52cf544138bd3ac1e44c50ef9f99169a090a4ee36f61964189a03eecba84bfeec150cbd99d2b410fc2e465d9c0131d373510e48503a9a71f808f96515ab908dd942ca71f745ce7d3f50da9a202490939ca4037ff67ca3542914b0becea148979b1a78bac983863a39ac04f4ca73a24573c4d8bee1031008e7b4497304cf660d5ee300d767f7ade2945005a0fb75c9817e8351fa57cf7aab3db012702cfbe90fcd1aac50faab11df'}, + {SIZE=>4096,PRI_FILE=>'key_4096-3.pri.pem',PUB_FILE=>'key_4096-3.pub.pem',PRI=>'14ab4fb361bd3ea6bbf83488224966d224f6fe247fd1f7ae6ef40f098c3f4e15',PUB=>'59ee50c1c33bffc11b087f29ef0e2295ad0ce5534ba81d4edd93c6069f213695a594b6df516fd3cf29312cb11e01ada478df2371b980f6468e745925ffc623395445410b7d83ac4549e378edc757b7ab59c2ac38369b4180f207cd5f3674a968fc02e1ac243bab7af78356580474616342521ca2c1c81615418045f0239cf55f52b4c193514abd1fba7e02bd7d7db219206bc565c11f615efe768c28fff6930a961f88fa4984e775644522ea42b3fd698c79b7e6b06bb0d5f53a9ead504e80d299684485e926d37d8d111913e78e532e3816706b466a6888dfd136ce041c5d8f60b52f4bd0df145850c50640562a013a23f52d1fc4b35a0dffc55b628f7a651f621a11e4fc5176bb901791def06f003884bd3e2826b3532b72be884f52cce7a85f3b6c01093dfd8421a9a986310051e1d4a940ade05a0c40d794940921208ebe0a243fefcbcc6356cd28617218c403e0c972f8c3cc3ac0e41693a58651a01d0ac03e126cddd362aa2e73039c8d53f78b1e06e5abf67b91a5b2f1c4d2d2c593c1a397e4a5d4b486e53cd17354c1ad3a712030e23cebd6614c3e3c38c4ae31759fd8ea276ac95f19f0f644f7fde56c7c221a9911f1189e996476e5cd3d3d000d7c50e5289286e08a1afccd6e3dfea5e30ad76ef2482d16ac9321b8524e839c2522c217003dc247ff69a6eec5d8a0e87fe498b449beedc5cd44aff00e97f5a185a9',DSA_SHA1=>'304402201a99853cdf35cef247bc4d029dde5172c18f65e7ea9b69904319017d6e9bf0b5022069e8e1bba98f9ea859016ba4cbea0115ef452f9bce4f47d7216ef542bea71b3a',DSA_SHA256=>'30440220560704814ace4a241dcff64c95f89c71ad3cb2b23d5f15ce4bac5d5826afdb0802204f7deb328ba25f3b1d76f957bde23c28c08a68fe84070c4c05ea58996f42e399',PRI_DER=>'30820655020100028202010099043ca2b994c89a2999c839a41c2a79d12b626a0c8cbf73c6c65af93b28ac9ec69bab58d65bfb02f2da42f6743f63ee68e224517c04c4d0fb4286f981e84612ea19ddcd4217d0996c78c346c67e0930a882bd135761bf43f6e9fd9cb27c341cbbec64aa7b2d3193089f2e2975656555b0b274fb3348262bb52cd3e97cc0840b9f4caab0b0bd6a47b9f1ac73cb7e5a3c0c773f463605a16ef2dff07e429060d7fb9dda0839890a2d5dac70ac5d8a2ba4084e635541b9dd774db993d638ed70e405437d9bfb8a4d763dbc6d19364103bc2f2dad3e491091fb47998c754e2b098c7dfe00bab9c1d7e207744364fd2c91fc9694082598a688623f5fb4cfbccf0e9f97f700304bb6e955f5ac8a09c85b82b28a50b95ccf90728e8e13aaa82b3d08905f244bd9df07d2f0f98ff52dcd033587377b722975020fc33d725990cf40f35df744aa89efed8d94d9edc5deb807d0cbdd2652ccd2e358c0c4e5dac7235cd5d630b7a4cbb61cc8620985cd7ee67c4e3a7b8439cccb9f8bb06cee107f241219227b0f679f9dd6844e21ff7c1b52bbe3420838ccbb7d6a2bc3a73325d775ec5b4b277b9ea08f665502a90126152f8a9da01f2019dae3238d05d62615825eb8bb5a6476e12d8b5fabefa5b0f95ff57267f814fcdaf2d12fff188fc016d6e0aa0a6259c3e6532db32ace8a18e14451cadd9495099b3157afb249f6a593f5de1fcb910221008492598d9db34282ddd651a5a141ad2f2f3b928306c7b18f2245e3bb47baceb7028202000d820b8709730584eae360da462883ee99b7ca79aa9a8d13bd99ff040205a47d2db840748bb845fe20d538baa75b63ff35a57fe91c7eab39f3136a7e095404dacebe3606398df71a2e4a7ce9cc76db2a345e908048dfd58b91d296678e865862fadc8d0055d84bc2eddc422119fa6796c74408e76bb228adf4d18829771e0bb185480d64366aec6520a3c1398963e436e6176e8ea2ba75ed81251d39bbdff79b421f4b1976db9bbc71fdfb9bec22433c922c27f921b13c017b946549830318462cd80fc2c3383108d77a2add324b1cc180d57e99ea265d99aac0a00cafdccbbf9c1e259d45e410e04e14d4d434f526d03edec2ebc93a5d25a8bdf68771e94e8d3ac53dd9687c7c68edb90477cd8c06b7a159ac117518a24a28cc21da768761c0542f2898eb2cbe17e550a390f84d78dbd032acd9841e9ac4bbe9c1a64b9f7ca51ebb2ba855b6935c0dc109c064270de846e739ac63595db70914d3d747b43a51cf17056021721ef41e9fa813247ae0eb37e9227eb338fd1a194ba1392ef794de6aebb4e73bae2d7d6e10fffc7c24a19f3851b7962c40f86e36635816acaee929edb919444f5c7be739201a88cc0500885ed1736e5c723dbb97bc2e8ae66414498d416e809aa006fd2c91f3dbc0d103c79f34165fa4984ce18902d205a70ba9b46f65dde7b73bdb55830c9f1349f89a1ee47429593f4546b04483b1e0381d5daf0282020059ee50c1c33bffc11b087f29ef0e2295ad0ce5534ba81d4edd93c6069f213695a594b6df516fd3cf29312cb11e01ada478df2371b980f6468e745925ffc623395445410b7d83ac4549e378edc757b7ab59c2ac38369b4180f207cd5f3674a968fc02e1ac243bab7af78356580474616342521ca2c1c81615418045f0239cf55f52b4c193514abd1fba7e02bd7d7db219206bc565c11f615efe768c28fff6930a961f88fa4984e775644522ea42b3fd698c79b7e6b06bb0d5f53a9ead504e80d299684485e926d37d8d111913e78e532e3816706b466a6888dfd136ce041c5d8f60b52f4bd0df145850c50640562a013a23f52d1fc4b35a0dffc55b628f7a651f621a11e4fc5176bb901791def06f003884bd3e2826b3532b72be884f52cce7a85f3b6c01093dfd8421a9a986310051e1d4a940ade05a0c40d794940921208ebe0a243fefcbcc6356cd28617218c403e0c972f8c3cc3ac0e41693a58651a01d0ac03e126cddd362aa2e73039c8d53f78b1e06e5abf67b91a5b2f1c4d2d2c593c1a397e4a5d4b486e53cd17354c1ad3a712030e23cebd6614c3e3c38c4ae31759fd8ea276ac95f19f0f644f7fde56c7c221a9911f1189e996476e5cd3d3d000d7c50e5289286e08a1afccd6e3dfea5e30ad76ef2482d16ac9321b8524e839c2522c217003dc247ff69a6eec5d8a0e87fe498b449beedc5cd44aff00e97f5a185a9022014ab4fb361bd3ea6bbf83488224966d224f6fe247fd1f7ae6ef40f098c3f4e15',PUB_DER=>'308206463082043906072a8648ce3804013082042c028202010099043ca2b994c89a2999c839a41c2a79d12b626a0c8cbf73c6c65af93b28ac9ec69bab58d65bfb02f2da42f6743f63ee68e224517c04c4d0fb4286f981e84612ea19ddcd4217d0996c78c346c67e0930a882bd135761bf43f6e9fd9cb27c341cbbec64aa7b2d3193089f2e2975656555b0b274fb3348262bb52cd3e97cc0840b9f4caab0b0bd6a47b9f1ac73cb7e5a3c0c773f463605a16ef2dff07e429060d7fb9dda0839890a2d5dac70ac5d8a2ba4084e635541b9dd774db993d638ed70e405437d9bfb8a4d763dbc6d19364103bc2f2dad3e491091fb47998c754e2b098c7dfe00bab9c1d7e207744364fd2c91fc9694082598a688623f5fb4cfbccf0e9f97f700304bb6e955f5ac8a09c85b82b28a50b95ccf90728e8e13aaa82b3d08905f244bd9df07d2f0f98ff52dcd033587377b722975020fc33d725990cf40f35df744aa89efed8d94d9edc5deb807d0cbdd2652ccd2e358c0c4e5dac7235cd5d630b7a4cbb61cc8620985cd7ee67c4e3a7b8439cccb9f8bb06cee107f241219227b0f679f9dd6844e21ff7c1b52bbe3420838ccbb7d6a2bc3a73325d775ec5b4b277b9ea08f665502a90126152f8a9da01f2019dae3238d05d62615825eb8bb5a6476e12d8b5fabefa5b0f95ff57267f814fcdaf2d12fff188fc016d6e0aa0a6259c3e6532db32ace8a18e14451cadd9495099b3157afb249f6a593f5de1fcb910221008492598d9db34282ddd651a5a141ad2f2f3b928306c7b18f2245e3bb47baceb7028202000d820b8709730584eae360da462883ee99b7ca79aa9a8d13bd99ff040205a47d2db840748bb845fe20d538baa75b63ff35a57fe91c7eab39f3136a7e095404dacebe3606398df71a2e4a7ce9cc76db2a345e908048dfd58b91d296678e865862fadc8d0055d84bc2eddc422119fa6796c74408e76bb228adf4d18829771e0bb185480d64366aec6520a3c1398963e436e6176e8ea2ba75ed81251d39bbdff79b421f4b1976db9bbc71fdfb9bec22433c922c27f921b13c017b946549830318462cd80fc2c3383108d77a2add324b1cc180d57e99ea265d99aac0a00cafdccbbf9c1e259d45e410e04e14d4d434f526d03edec2ebc93a5d25a8bdf68771e94e8d3ac53dd9687c7c68edb90477cd8c06b7a159ac117518a24a28cc21da768761c0542f2898eb2cbe17e550a390f84d78dbd032acd9841e9ac4bbe9c1a64b9f7ca51ebb2ba855b6935c0dc109c064270de846e739ac63595db70914d3d747b43a51cf17056021721ef41e9fa813247ae0eb37e9227eb338fd1a194ba1392ef794de6aebb4e73bae2d7d6e10fffc7c24a19f3851b7962c40f86e36635816acaee929edb919444f5c7be739201a88cc0500885ed1736e5c723dbb97bc2e8ae66414498d416e809aa006fd2c91f3dbc0d103c79f34165fa4984ce18902d205a70ba9b46f65dde7b73bdb55830c9f1349f89a1ee47429593f4546b04483b1e0381d5daf03820205000282020059ee50c1c33bffc11b087f29ef0e2295ad0ce5534ba81d4edd93c6069f213695a594b6df516fd3cf29312cb11e01ada478df2371b980f6468e745925ffc623395445410b7d83ac4549e378edc757b7ab59c2ac38369b4180f207cd5f3674a968fc02e1ac243bab7af78356580474616342521ca2c1c81615418045f0239cf55f52b4c193514abd1fba7e02bd7d7db219206bc565c11f615efe768c28fff6930a961f88fa4984e775644522ea42b3fd698c79b7e6b06bb0d5f53a9ead504e80d299684485e926d37d8d111913e78e532e3816706b466a6888dfd136ce041c5d8f60b52f4bd0df145850c50640562a013a23f52d1fc4b35a0dffc55b628f7a651f621a11e4fc5176bb901791def06f003884bd3e2826b3532b72be884f52cce7a85f3b6c01093dfd8421a9a986310051e1d4a940ade05a0c40d794940921208ebe0a243fefcbcc6356cd28617218c403e0c972f8c3cc3ac0e41693a58651a01d0ac03e126cddd362aa2e73039c8d53f78b1e06e5abf67b91a5b2f1c4d2d2c593c1a397e4a5d4b486e53cd17354c1ad3a712030e23cebd6614c3e3c38c4ae31759fd8ea276ac95f19f0f644f7fde56c7c221a9911f1189e996476e5cd3d3d000d7c50e5289286e08a1afccd6e3dfea5e30ad76ef2482d16ac9321b8524e839c2522c217003dc247ff69a6eec5d8a0e87fe498b449beedc5cd44aff00e97f5a185a9'}, +]; + +#diag("samples_count=". @$data); + +for my $h (@$data) { + my $dsa_pri = Crypt::PK::DSA->new->import_key(\pack("H*",$h->{PRI_DER})); + my $dsa_pub = Crypt::PK::DSA->new->import_key(\pack("H*",$h->{PUB_DER})); + my $dsa_pri_h = $dsa_pri->key2hash; + my $dsa_pub_h = $dsa_pub->key2hash; + $h->{PRI} =~ s/^(00)+//; + $h->{PUB} =~ s/^(00)+//; + is($dsa_pri_h->{x}, uc $h->{PRI}, "$h->{PRI_FILE}/PRI"); + is($dsa_pri_h->{y}, uc $h->{PUB}, "$h->{PRI_FILE}/PUB"); + is($dsa_pub_h->{y}, uc $h->{PUB}, "$h->{PUB_FILE}/PUB"); + ok( $dsa_pub->verify_message(pack("H*", $h->{DSA_SHA1}), 'test-data', 'SHA1'), "$h->{PRI_FILE}/DSA_SHA1"); + ok( $dsa_pub->verify_message(pack("H*", $h->{DSA_SHA256}), 'test-data', 'SHA256'), "$h->{PRI_FILE}/DSA_SHA256"); +} diff --git a/t/pk_ecc.t b/t/pk_ecc.t new file mode 100644 index 0000000..27fd0b8 --- /dev/null +++ b/t/pk_ecc.t @@ -0,0 +1,206 @@ +use strict; +use warnings; +use Test::More tests => 121; + +use Crypt::PK::ECC qw(ecc_encrypt ecc_decrypt ecc_sign_message ecc_verify_message ecc_sign_hash ecc_verify_hash ecc_shared_secret); + +sub read_file { + my ($file) = @_; + return unless $file; + if (open(my $fh, "<", $file)) { + local $/; + binmode($fh); + my $content = <$fh>; + close($fh); + return $content; + } +} + +{ + my ($k, $k2); + + $k = Crypt::PK::ECC->new('t/data/cryptx_priv_ecc1.der'); + ok($k, 'load cryptx_priv_ecc1.der'); + ok($k->is_private, 'is_private cryptx_priv_ecc1.der'); + is($k->size, 32, 'size'); + is(uc($k->key2hash->{pub_x}), 'C068B754877A4AB328A569BAC6D464A81B17E527D2D652572ABB11BDA3572D50', 'key2hash'); + is(uc($k->curve2hash->{prime}), 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F', 'curve2hash'); + + $k2 = Crypt::PK::ECC->new; + $k2->import_key(\$k->export_key_pem('private')); + is($k->export_key_der('private'), $k2->export_key_der('private'), 'import_key priv pem'); + + $k2 = Crypt::PK::ECC->new; + $k2->import_key(\$k->export_key_pem('public')); + is($k->export_key_der('public'), $k2->export_key_der('public'), 'import_key pub pem'); + + $k2 = Crypt::PK::ECC->new; + $k2->import_key($k->key2hash); + is($k->export_key_der('private'), $k2->export_key_der('private'), 'import_key hash'); + + $k = Crypt::PK::ECC->new('t/data/cryptx_priv_ecc2.der'); + ok($k, 'load cryptx_priv_ecc2.der'); + ok($k->is_private, 'is_private cryptx_priv_ecc2.der'); + + $k = Crypt::PK::ECC->new('t/data/cryptx_pub_ecc1.der'); + ok($k, 'load cryptx_pub_ecc1.der'); + ok(!$k->is_private, 'is_private cryptx_pub_ecc1.der'); + + $k = Crypt::PK::ECC->new('t/data/cryptx_pub_ecc2.der'); + ok($k, 'load cryptx_pub_ecc2.der'); + ok(!$k->is_private, 'is_private cryptx_pub_ecc2.der'); + + ### XXX-TODO regenerate keys + $k = Crypt::PK::ECC->new('t/data/cryptx_priv_ecc1.pem'); + ok($k, 'load cryptx_priv_ecc1.pem'); + ok($k->is_private, 'is_private cryptx_priv_ecc1.pem'); + + $k = Crypt::PK::ECC->new('t/data/cryptx_priv_ecc2.pem'); + ok($k, 'load cryptx_priv_ecc2.pem'); + ok($k->is_private, 'is_private cryptx_priv_ecc2.pem'); + + $k = Crypt::PK::ECC->new('t/data/cryptx_pub_ecc1.pem'); + ok($k, 'load cryptx_pub_ecc1.pem'); + ok(!$k->is_private, 'is_private cryptx_pub_ecc1.pem'); + + $k = Crypt::PK::ECC->new('t/data/cryptx_pub_ecc2.pem'); + ok($k, 'load cryptx_pub_ecc2.pem'); + ok(!$k->is_private, 'is_private cryptx_pub_ecc2.pem'); + $k = Crypt::PK::ECC->new('t/data/cryptx_pub_ecc2.pem'); + + for (qw( cryptx_pub_ecc1.der cryptx_pub_ecc1.pem cryptx_pub_ecc2.der cryptx_pub_ecc2.pem )) { + $k = Crypt::PK::ECC->new("t/data/$_"); + is($k->export_key_der('public'), read_file("t/data/$_"), 'export_key_der public') if (substr($_, -3) eq "der"); + is($k->export_key_pem('public'), read_file("t/data/$_"), 'export_key_pem public') if (substr($_, -3) eq "pem"); + } + + for (qw( cryptx_priv_ecc1.der cryptx_priv_ecc1.pem cryptx_priv_ecc2.der cryptx_priv_ecc2.pem )) { + $k = Crypt::PK::ECC->new("t/data/$_"); + is($k->export_key_der('private'), read_file("t/data/$_"), 'export_key_der private') if (substr($_, -3) eq "der"); + is($k->export_key_pem('private'), read_file("t/data/$_"), 'export_key_pem private') if (substr($_, -3) eq "pem"); + } + + for (qw( openssl_ec1.pub.pem openssl_ec1.pub.der openssl_ec1.pubc.der openssl_ec1.pubc.pem + cryptx_pub_ecc1_OLD.der cryptx_pub_ecc1_OLD.pem cryptx_pub_ecc2_OLD.der cryptx_pub_ecc2_OLD.pem )) { + $k = Crypt::PK::ECC->new("t/data/$_"); + ok($k, "load $_"); + ok(!$k->is_private, "is_private $_"); + } + for (qw( openssl_ec1.pri.der openssl_ec1.pri.pem openssl_ec1.pric.der openssl_ec1.pric.pem openssl_ec1.key.pem + cryptx_priv_ecc1_OLD.der cryptx_priv_ecc1_OLD.pem cryptx_priv_ecc2_OLD.der cryptx_priv_ecc2_OLD.pem )) { + $k = Crypt::PK::ECC->new("t/data/$_"); + ok($k, "load $_"); + ok($k->is_private, "is_private $_"); + } +} + +{ + my $pr1 = Crypt::PK::ECC->new; + $pr1->import_key('t/data/cryptx_priv_ecc1.der'); + my $pu1 = Crypt::PK::ECC->new; + $pu1->import_key('t/data/cryptx_pub_ecc1.der'); + + my $ct = $pu1->encrypt("secret message"); + my $pt = $pr1->decrypt($ct); + ok(length $ct > 30, 'encrypt ' . length($ct)); + is($pt, "secret message", 'decrypt'); + + my $sig = $pr1->sign_message("message"); + ok(length $sig > 60, 'sign_message ' . length($sig)); + ok($pu1->verify_message($sig, "message"), 'verify_message'); + + my $sig_rfc7518 = $pr1->sign_message_rfc7518("message"); + ok(length $sig_rfc7518 > 60, 'sign_message_rfc7518 ' . length($sig_rfc7518)); + ok($pu1->verify_message_rfc7518($sig_rfc7518, "message"), 'verify_message_rfc7518'); + + my $hash = pack("H*","04624fae618e9ad0c5e479f62e1420c71fff34dd"); + $sig = $pr1->sign_hash($hash, 'SHA1'); + ok(length $sig > 60, 'sign_hash ' . length($sig)); + ok($pu1->verify_hash($sig, $hash, 'SHA1'), 'verify_hash'); + + my $pr2 = Crypt::PK::ECC->new; + $pr2->import_key('t/data/cryptx_priv_ecc2.der'); + my $pu2 = Crypt::PK::ECC->new; + $pu2->import_key('t/data/cryptx_pub_ecc2.der'); + + my $ss1 = $pr1->shared_secret($pu2); + my $ss2 = $pr2->shared_secret($pu1); + is(unpack("H*",$ss1), unpack("H*",$ss2), 'shared_secret'); +} + +{ + my $k = Crypt::PK::ECC->new; + $k->generate_key('secp224r1'); + ok($k, 'generate_key'); + ok($k->is_private, 'is_private'); + #ok($k->export_key_pem('private'), 'export_key_pem pri'); + #ok($k->export_key_pem('public'), 'export_key_pem pub'); + ok($k->export_key_der('private'), 'export_key_der pri'); + ok($k->export_key_der('public'), 'export_key_der pub'); + ok($k->export_key_der('private_short'), 'export_key_der pri_short'); + ok($k->export_key_der('public_short'), 'export_key_der pub_short'); +} + +{ + my $ct = ecc_encrypt('t/data/cryptx_pub_ecc1.der', 'test string'); + ok($ct, 'ecc_encrypt'); + my $pt = ecc_decrypt('t/data/cryptx_priv_ecc1.der', $ct); + ok($pt, 'ecc_decrypt'); + my $sig = ecc_sign_message('t/data/cryptx_priv_ecc1.der', 'test string'); + ok($sig, 'ecc_sign_message'); + ok(ecc_verify_message('t/data/cryptx_pub_ecc1.der', $sig, 'test string'), 'ecc_verify_message'); + my $hash = pack("H*","04624fae618e9ad0c5e479f62e1420c71fff34dd"); + $sig = ecc_sign_hash('t/data/cryptx_priv_ecc1.der', $hash, 'SHA1'); + ok($sig, 'ecc_sign_hash'); + ok(ecc_verify_hash('t/data/cryptx_pub_ecc1.der', $sig, $hash, 'SHA1'), 'ecc_verify_hash'); + + my $ss1 = ecc_shared_secret('t/data/cryptx_priv_ecc1.der', 't/data/cryptx_pub_ecc2.der'); + my $ss2 = ecc_shared_secret('t/data/cryptx_priv_ecc2.der', 't/data/cryptx_pub_ecc1.der'); + is(unpack("H*",$ss1), unpack("H*",$ss2), 'shared_secret'); +} + +for my $priv (qw/openssl_ec-short.pem openssl_ec-short.der/) { + my $f = "t/data/$priv"; + my $k = Crypt::PK::ECC->new($f); + ok($k, "load $priv"); + ok($k->is_private, "is_private $priv"); + is($k->size, 32, "size $priv"); + is(uc($k->key2hash->{pub_x}), 'A01532A3C0900053DE60FBEFEFCCA58793301598D308B41E6F4E364E388C2711', "key2hash $priv"); + is(uc($k->curve2hash->{prime}), 'FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF', "curve2hash $priv"); + is($k->key2hash->{curve_name}, "secp256r1", "EC curve_name is lowercase"); + is($k->export_key_der('private_short'), read_file($f), 'export_key_der private_oid') if (substr($priv, -3) eq "der"); + is($k->export_key_pem('private_short'), read_file($f), 'export_key_pem private_oid') if (substr($priv, -3) eq "pem"); +} + +for my $pub (qw/openssl_ec-short.pub.pem openssl_ec-short.pub.der/) { + my $f = "t/data/$pub"; + my $k = Crypt::PK::ECC->new($f); + ok($k, "load $pub"); + ok(!$k->is_private, "is_private $pub"); + is($k->size, 32, "$pub size"); + is(uc($k->key2hash->{pub_x}), 'A01532A3C0900053DE60FBEFEFCCA58793301598D308B41E6F4E364E388C2711', "key2hash $pub"); + is($k->key2hash->{curve_name}, "secp256r1", "EC curve_name is lowercase"); + is($k->export_key_der('public_short'), read_file($f), 'export_key_der public_short') if (substr($pub, -3) eq "der"); + is($k->export_key_pem('public_short'), read_file($f), 'export_key_pem public_short') if (substr($pub, -3) eq "pem"); +} + +{ + my $k = Crypt::PK::ECC->new; + eval { $k->export_key_pem('public'); }; + ok($@, 'key not generated'); + + # known curves lookup + my $params = $Crypt::PK::ECC::curve{secp384r1}; + $k = Crypt::PK::ECC->new; + ok($k->generate_key($params), "generate_key hash params"); + is($k->key2hash->{curve_name}, 'secp384r1', "key2hash curve_name"); + is($k->key2hash->{curve_oid}, $params->{oid}, "key2hash curve_oid"); + ok($k->export_key_der('private_short'), "export_key_der auto oid"); + + $k = Crypt::PK::ECC->new; + ok($k->generate_key({ %$params, A => '0' }), "generate_key invalid auto oid"); + is($k->key2hash->{curve_name}, 'custom', "key2hash custom curve_name"); + ok(!exists($k->key2hash->{curve_oid}), "key2hash curve_oid doesn't exist"); + eval { $k->export_key_der('private_short'); }; + ok($@, "export_key_der invalid auto oid"); +} diff --git a/t/pk_ecc_test_vectors_openssl.t b/t/pk_ecc_test_vectors_openssl.t new file mode 100644 index 0000000..9569c52 --- /dev/null +++ b/t/pk_ecc_test_vectors_openssl.t @@ -0,0 +1,90 @@ +use strict; +use warnings; + +use Test::More tests => 660; +use Crypt::PK::ECC; + +my $data = [ + {CURVE=>'secp112r1',PRI_FILE=>'key_secp112r1-1.pri.pem',PUB_FILE=>'key_secp112r1-1.pub.pem',PRI=>'9c8c2a0cd14052e0a802e965ea77',PUB=>'0411f09ba3f913b142b38585d19fc48c928f2b6026bc15b98157f2fb9d',PUBC=>'0311f09ba3f913b142b38585d19fc4',ECDSA_SHA1=>'3020020e194733eb7aea5031db4cf273e84e020e12bef575d5a9a78391f421d7c607',ECDSA_SHA256=>'3021020f00a81637ea3744d65335e2870aefd6020e514a4b4c7d7b25b257276ab476f9'}, + {CURVE=>'secp112r2',PRI_FILE=>'key_secp112r2-1.pri.pem',PUB_FILE=>'key_secp112r2-1.pub.pem',PRI=>'2dad629912f1ef7acd7ff55a6072',PUB=>'047d8cb70beab422d22880c79fe117d0392c404dc974831c5f26c506a3',PUBC=>'037d8cb70beab422d22880c79fe117',ECDSA_SHA1=>'3020020e115b7759e0bc13dbbb77db756850020e09d74cc8e9d70f7def749bc59759',ECDSA_SHA256=>'3020020e10eb5ca8badd470e4794c1a108db020e02de4d6532d666f6f08b64e89b30'}, + {CURVE=>'secp128r1',PRI_FILE=>'key_secp128r1-1.pri.pem',PUB_FILE=>'key_secp128r1-1.pub.pem',PRI=>'5c5e30ef79639baa2ddd0e41637384ae',PUB=>'04dedf05d521119c98a0b91f081401ac7c3e359793e5ff70f2ee31324d263e9f61',PUBC=>'03dedf05d521119c98a0b91f081401ac7c',ECDSA_SHA1=>'3026021100d366e9dac9a3bc43576b38962c9afba9021100acffead8c8440c5b4c288a2869919b2f',ECDSA_SHA256=>'30250210674badb9584429bacf8ad1ff6819f4c1021100c2621e5cb97206474177d50b3d1c0145'}, + {CURVE=>'secp128r2',PRI_FILE=>'key_secp128r2-1.pri.pem',PUB_FILE=>'key_secp128r2-1.pub.pem',PRI=>'31739a3d53459d7df41e3134d8c3cf1b',PUB=>'042b294c16752327dd9be5311d70561fd1f0c75e6b6cb69fcc152670777eec89ab',PUBC=>'032b294c16752327dd9be5311d70561fd1',ECDSA_SHA1=>'302402102697263886c57d8de361afec554f29e7021011d091dab40603a4e7d8dffbcdc1ed0f',ECDSA_SHA256=>'302402101e3dd1147131625b9ad5bbf114d1bc0d02103d82b9a394054844e9d353565c50ff99'}, + {CURVE=>'secp160k1',PRI_FILE=>'key_secp160k1-1.pri.pem',PUB_FILE=>'key_secp160k1-1.pub.pem',PRI=>'14b70aec3aa250e66c5eedbf4363a27b4b27231f',PUB=>'048d448a89c0290d646b4e0a4592c0eafe51bfae0174462140df8839784b02683088f3eae3dbd77ccb',PUBC=>'038d448a89c0290d646b4e0a4592c0eafe51bfae01',ECDSA_SHA1=>'302e021500ed2e2adac4a5145a6408211c1d47d98ffd6c5b89021500a6ebc3897cf5163bd3f842b50d7facb307fc0f3d',ECDSA_SHA256=>'302d021500bd3ed4ceca917b49ac2faec87a91378a81e6172c02146017099013c0adb4bceb08b8e6cbcfdbb494b6b6'}, + {CURVE=>'secp160r1',PRI_FILE=>'key_secp160r1-1.pri.pem',PUB_FILE=>'key_secp160r1-1.pub.pem',PRI=>'4f3ff1d85f36dda2930ce4fd6e50fbe66830042d',PUB=>'04a497c25340df2b80aef1e26ed45ea179dd5f6f52d017a07f00b5a40ac2c76bb2aaec555d4bc08a1f',PUBC=>'03a497c25340df2b80aef1e26ed45ea179dd5f6f52',ECDSA_SHA1=>'302c021453e1ba4695646e93ac5db45933d59c4a2b64d3f902142a383226907d5952af829765645d5ae34a15ab5f',ECDSA_SHA256=>'302d021500a559a68611e26d4acfe0eaa59e9e4956ad080b9902147730150c0a79f7500f23953bdc84577111d9f4bf'}, + {CURVE=>'secp160r2',PRI_FILE=>'key_secp160r2-1.pri.pem',PUB_FILE=>'key_secp160r2-1.pub.pem',PRI=>'999e25723cd7baf003b110e1d3e719396b0486e3',PUB=>'04fed95dd2b94579147d09c7cf1fff0a2156fad1b48e6dd96ca660ef55097589f4d75dbcae1553c9a1',PUBC=>'03fed95dd2b94579147d09c7cf1fff0a2156fad1b4',ECDSA_SHA1=>'302d021500f58ff53a28bd1e41bed2b214aeb2672852276f4c02141d088051ad977dcaa44a68994ff35ac447cc4848',ECDSA_SHA256=>'302c021478385546c27950308485c44a5ed2b3cabfd4d65602144fe588beecb3f1a42a3eefa1d74b9382fa066f96'}, + {CURVE=>'secp192k1',PRI_FILE=>'key_secp192k1-1.pri.pem',PUB_FILE=>'key_secp192k1-1.pub.pem',PRI=>'a98043d5c9cff228846613d2557d83747249666420f66a28',PUB=>'04581e261bb2fce5f6c5306cf5b5952a548c72e591baf73d8621569c4311490499db5b6e2969bd5965aad628f99c996183',PUBC=>'03581e261bb2fce5f6c5306cf5b5952a548c72e591baf73d86',ECDSA_SHA1=>'3035021900d36a2d3a3702f954b4364aad125bf710f5f772cc2d06da200218389da6af997dfedb713858e4d415aedfc0235d59453a3a5e',ECDSA_SHA256=>'3036021900f3a48ae6f34dc434e7605ddd2edc3363116a076bafbbefc0021900f08e144406402eed1297d309e40caa7107f8ec2e0e7e8b75'}, + {CURVE=>'secp224k1',PRI_FILE=>'key_secp224k1-1.pri.pem',PUB_FILE=>'key_secp224k1-1.pub.pem',PRI=>'230e41b86eec5b958d5f2959bc4b392aa27fa3f7e3fdf9915db47da7',PUB=>'046adc2b376d687aabb7b05bb00bbe03822f32711512e054510ee89be429eb839d41fa5ad6a6f70f274850d477e1049e08c9e6098d2d1208a7',PUBC=>'036adc2b376d687aabb7b05bb00bbe03822f32711512e054510ee89be4',ECDSA_SHA1=>'303d021c1f58bfc8684e3f333433cd0fa3c66892c06727ddd8b1a4913f2b152d021d00d518957f96b59789f8ecf3e3b963d2aa3466152571775e93462c10ea',ECDSA_SHA256=>'303c021c74a28d855453e3a8c93cf520e367e12659d254d64c2248fb3060d02a021c03340c2b4d88018ad203f01f6f6ff072d22a653d7379b139ca5b86c3'}, + {CURVE=>'secp224r1',PRI_FILE=>'key_secp224r1-1.pri.pem',PUB_FILE=>'key_secp224r1-1.pub.pem',PRI=>'fe892ab148f432be15645766bc969487197bc84dd92e4e2ef00c1a86',PUB=>'0467ebe5a5aef2c7cf7752970ccca9c6bb29f5420dff40d003dbf3e5d57f910b1174d0b9507107c55c4e9b386b0358a07b24c49ee219b3a52f',PUBC=>'0367ebe5a5aef2c7cf7752970ccca9c6bb29f5420dff40d003dbf3e5d5',ECDSA_SHA1=>'303e021d00bb0d2991ed5c73c0b61685a6e81b578c31a3d72bb4ede6d8d0534d74021d00f24f418c3105ee6299dd6de2f3f866c9e71213c5a144c40440fdb3c9',ECDSA_SHA256=>'303e021d008467a633a2682253bd99285e40040cf7b0c7f528f1418aeade8318fe021d00dbd009aba53c06fc09293caf1a4ac0dc6dc38dc2c126c2ef306f67e7'}, + {CURVE=>'secp256k1',PRI_FILE=>'key_secp256k1-1.pri.pem',PUB_FILE=>'key_secp256k1-1.pub.pem',PRI=>'4b03aa0b55fb2911a54a708d900a95ada33fd76306f03268fa388b63d0aefb43',PUB=>'0422af1a552f83cccce76d197c55d3c7d8ad8cb68dc3042c227984211b0a78aa7f153768dc1fd47239ba4fccb73e3c2d1285560eb809a2a84a12371c2915d59af9',PUBC=>'0322af1a552f83cccce76d197c55d3c7d8ad8cb68dc3042c227984211b0a78aa7f',ECDSA_SHA1=>'3045022100de6548db95f7c10e6dfd3241dbef8f0b5fb350932c0a2f209f4aab95aaddf08e022006caa0150bd1c1355574e3164c2a1287e8e77d7bd1b272f4d286f40f281004e3',ECDSA_SHA256=>'3044022060595de7d992adb52f68e1b6a5aa4fed88d8e31f73a4aafce3345997b7d72f560220408e8d7f9d5f7111cab83853a5f5e3667bd20c0a707d53f02c5b36052b750549'}, + {CURVE=>'secp384r1',PRI_FILE=>'key_secp384r1-1.pri.pem',PUB_FILE=>'key_secp384r1-1.pub.pem',PRI=>'2705f8a76c216172157b6187a466852a8127e7670188448444452ae2e3404155fcfdcdfbd014753ae9e5156b1b57db69',PUB=>'04cd738a8ebc08734a0fcfaf68b9123075a05d0c4b2a387da1c8ca378402abac23a87fd5c4fdffab91127bc61fbc8d69f57ca9e3aafed7698ce75b9116235e749d7b6f29c91d2123112289426dbe174f42022924ed9752e94d5037ceddd007473c',PUBC=>'02cd738a8ebc08734a0fcfaf68b9123075a05d0c4b2a387da1c8ca378402abac23a87fd5c4fdffab91127bc61fbc8d69f5',ECDSA_SHA1=>'306602310092acb263c179af269bdea79361a1a6b71ac53a5496fb3a04955493882725b5210c9c2f59ba315f53e61c254986b1f844023100d9872b751d26660ae5dc43161b6f6527b254cf1fc2e59a07ed76b39d7698f06d40abcec14848dab97362cbf475184268',ECDSA_SHA256=>'30650231009eb92d03cf786e936c0dbe0d710d2b55e92415b4133ee9272acb1af4529b53bfa573f5c6683b9a89072c34c2a7fc98650230062d798914ee0fba4bebe73f6efdf694299aafac7680744187f3f9bfcbcfd56790b9cbcf7b0fb8a9968bebf2ac6970a7'}, + {CURVE=>'secp521r1',PRI_FILE=>'key_secp521r1-1.pri.pem',PUB_FILE=>'key_secp521r1-1.pub.pem',PRI=>'013cc69064c1be4f387df1cbb9481e6182ef91c2db8b099ade5ac1241e634d8bd419f5766131b00bbc0c8b136cdbc01658cdbfefbf08ddb78030fdfe3b877c61ca0f',PUB=>'04006d71a3ba5519119aa9352a156ce8a55fe5f9c2a8380697132619802581e597cf7c05a363d0a0fdee4e4a2296350090cef05f6ee6fb3ad1d8d300108ddcd7d13410014599a7509db9ca78804c8ee96a36101020649ae13b3890f35a72a05229c4247fbfea322cdb939617aee52fe491f911ac11dca100e105d6b7b9043384b33100077b',PUBC=>'03006d71a3ba5519119aa9352a156ce8a55fe5f9c2a8380697132619802581e597cf7c05a363d0a0fdee4e4a2296350090cef05f6ee6fb3ad1d8d300108ddcd7d13410',ECDSA_SHA1=>'308187024133ac3eb5173908318f71aab17f39f3a9a608e9b8117b7896f76a875e671fbfc386f2de6b288f4314b41f1d97a1fcd43e380226d0908af28dfd7b0cad33ba689d20024201aa82692b8ab235faf3f0a801d25dd226d1e4ca06913415d9194ac457e5a6ed114725caa490fdba9d8b9e05513978dc29f5c6b59fe26e3019e9b3fe09d66b7d7517',ECDSA_SHA256=>'308188024201216ee0ed86caad32a443c592e64bd573f71f42d89cd41bdab291554331af9cf62f3619913fa1e3954d565f2bfbe8020f4ede97ea67f3915bf9984013cfbb83a159024200a59d3ffa95564849ec9b1382aef9165f9dbc473bc6ef41cdaaa5c2beda03e863ec298e84c16a25fc034d3975e0b91c2f882478ab0d4892ee70d4390d923852ddee'}, + {CURVE=>'prime192v1',PRI_FILE=>'key_prime192v1-1.pri.pem',PUB_FILE=>'key_prime192v1-1.pub.pem',PRI=>'bcadb48540afbf1f994030949e8bf180e58f4f82f23e337f',PUB=>'04dc06d31d9ccc7e0d453727f870c2ef8ff751c04a1c225d729d16255ae82522536cdd979cec71c7af8ddbdbe8073bd18f',PUBC=>'03dc06d31d9ccc7e0d453727f870c2ef8ff751c04a1c225d72',ECDSA_SHA1=>'3035021862ab2dbb184e1bab8e4286fc53cd0e7d556e11dccd7f4f28021900dcfe136e14be8993c87aadf4b21225a0c1664bc71fad1916',ECDSA_SHA256=>'3034021873d9d19eb128b21bab27292f83f1c7a1afccbae9ddfc2c1d0218296f9823316f98449293c3fdde89f328fd49d4a5e92d9c25'}, + {CURVE=>'prime192v2',PRI_FILE=>'key_prime192v2-1.pri.pem',PUB_FILE=>'key_prime192v2-1.pub.pem',PRI=>'e76be718c514a9bc3a293b1a5058a16ec61023e596118aad',PUB=>'047450c16d9975711cf80dc60743427321e3d218be9e59b1d546bbc49500904c8e19740611ff85670c163646e19c81943b',PUBC=>'037450c16d9975711cf80dc60743427321e3d218be9e59b1d5',ECDSA_SHA1=>'3035021818d6f73595b8e384a7149dc85296c8666f8d2474b8dbc436021900e9e2781a2c78747ef03c7ee91eee5017dd88b0a088a4cdd1',ECDSA_SHA256=>'3036021900a868c241a3b265b1a5f14a1159e65b2d7674d614a1261fb2021900f25c9af9b2a30188f5899e8af96a28d9fbc1d4424566f734'}, + {CURVE=>'prime192v3',PRI_FILE=>'key_prime192v3-1.pri.pem',PUB_FILE=>'key_prime192v3-1.pub.pem',PRI=>'648e23d8d716b1df186359698827d52cc708c17f0a8b2a43',PUB=>'0428986b5a7a2b25f8f6ed245e1ceb5c7ab9809f666678a31f50f7ea09b7ddea56af39317425ba1ec600f06d2497dad527',PUBC=>'0328986b5a7a2b25f8f6ed245e1ceb5c7ab9809f666678a31f',ECDSA_SHA1=>'3036021900caf7c9f8015999e1b8c412f5740f12eb5f43a1c1f69f56550219009de8beb76045131000a8049abbea025cc6c2e8767c0adfca',ECDSA_SHA256=>'30340218364fd7612789f6ef38a431d7a68a16fe3b4ea5d6f231fe9e0218360da0b99234285196a18d707e8721b641239ac41195716e'}, + {CURVE=>'prime239v1',PRI_FILE=>'key_prime239v1-1.pri.pem',PUB_FILE=>'key_prime239v1-1.pub.pem',PRI=>'3a8dc3010097c31c7badfb2bf9d609ec697f1811f2d744ad0557984fe8b9',PUB=>'046d4c619ce0f8550c1c480740f9e441ccaddc67a3a3b4d5585e11c8882d2e36df87f6b2f964c4def52105234eac2e3ff9753c4f8e6da5e331a68a2409',PUBC=>'036d4c619ce0f8550c1c480740f9e441ccaddc67a3a3b4d5585e11c8882d2e',ECDSA_SHA1=>'3040021e323f05efea814b067583c06ae373c7285293ccfabb4ce2e57ec14d66a677021e1f1defc99fecc9d684f3a388dee309311af73a1ec3f156bb6e3584f5def4',ECDSA_SHA256=>'3040021e6b9d25707ffdc1f80fda1e698a72cb2229591a4031bcb88719ab9321a65e021e2f72ac85bb20053173dc35338bf3a18aac47b3fd7a152154e2d77d3b945a'}, + {CURVE=>'prime239v2',PRI_FILE=>'key_prime239v2-1.pri.pem',PUB_FILE=>'key_prime239v2-1.pub.pem',PRI=>'56d2b5b6929413702756f0eab763ed439dac7ff458298d9b2e4017fc9909',PUB=>'040c545af1fa000b4ae404e915efa2ae4e66f5f00c493f00f06d1449038657760786628e9d1b0be3d184caa45c53c9b2e9c940709409ef531e01d6f8a4',PUBC=>'020c545af1fa000b4ae404e915efa2ae4e66f5f00c493f00f06d1449038657',ECDSA_SHA1=>'3040021e63d489be144e5bf005179b4c72e82d9a5fcb91dddab247ee2829685cf075021e0c2bf212b80c86bd7e5d3224694ee968519e8bab17b18615b5dc41cd02d1',ECDSA_SHA256=>'3040021e58400e9b4b36380d8b053c7ea7a301dddf5fa5ce4fbdc3d8122ef7c3ebc6021e2f009f726bd9809e7ef9f9a3d89571c044143e19e5c1214d27a409ed346c'}, + {CURVE=>'prime239v3',PRI_FILE=>'key_prime239v3-1.pri.pem',PUB_FILE=>'key_prime239v3-1.pub.pem',PRI=>'33810cfd9a7332f57c4a3c10269df7ef04313e101da1de843ebf10c5db45',PUB=>'0445ea95ec167f4f059915bc6edf8801315ad057ff4121729345ce1b5c60e208960be1c5ceeb08d7ad23cdc5dbe4d2a890df710ec845d0966a36dcdec6',PUBC=>'0245ea95ec167f4f059915bc6edf8801315ad057ff4121729345ce1b5c60e2',ECDSA_SHA1=>'3040021e12b35c822cbf04bd254f8e65437514987427ef1be09c092ebaac80020af2021e2507686d483701f43859c8e8d15523d85d5717b7b144a16b930feadf2e19',ECDSA_SHA256=>'3040021e29db586a8c429a3a13c914b6e424ed3261c19d05736d4bf131825de73dcd021e655362728f9d039c62f07a09e5817b48e59794fa5be03ecec3567cba3905'}, + {CURVE=>'prime256v1',PRI_FILE=>'key_prime256v1-1.pri.pem',PUB_FILE=>'key_prime256v1-1.pub.pem',PRI=>'be1a6a95799d80c63e671c1c7df3c55ab17398acb4a1e86048a902d2a0177359',PUB=>'04c513e40a8a1acbb660e56aceb0c814a9e73750059c2ffc355c0117143d02e9557672ae5fe192f5ab270eab920daeba57b1281da53bfcba91070c894082d745d3',PUBC=>'03c513e40a8a1acbb660e56aceb0c814a9e73750059c2ffc355c0117143d02e955',ECDSA_SHA1=>'3046022100b5d61020541bdc9fb4f45edcc51d7d3e1398b394ada7ed94b227733b552442ce022100d76b73bd24d71b75cf4ecd11f9840c901d9e30b5a4a56bae7040a541d5c31082',ECDSA_SHA256=>'3043022037b324cba8f288a9c6befa49065dce22a6e60c28b04d7ed4cdca986033509b78021f44225fe81e5a4f6ac78b2b56c7187b8b31837ad30add379c780b125e3ff533'}, + {CURVE=>'secp112r1',PRI_FILE=>'key_secp112r1-2.pri.pem',PUB_FILE=>'key_secp112r1-2.pub.pem',PRI=>'8e5fbe3aebddc8a13f4d438cd170',PUB=>'045bfd38feda320a73e8bfcd804d3351272055e00eb139c6d5635c784e',PUBC=>'025bfd38feda320a73e8bfcd804d33',ECDSA_SHA1=>'3020020e62608296f33ecbe6ab204c5363dc020e289acb64e5f41fc11dea1295dfe3',ECDSA_SHA256=>'3022020f00902b45f5c263486633ac52e6f651020f00b8aa90c885a11ca76843db7d8937'}, + {CURVE=>'secp112r2',PRI_FILE=>'key_secp112r2-2.pri.pem',PUB_FILE=>'key_secp112r2-2.pub.pem',PRI=>'094a8840454dd75a9633026622ca',PUB=>'04147cfe973288ff633c7a57228fc179d08a91ba4703304f63b1a16d51',PUBC=>'03147cfe973288ff633c7a57228fc1',ECDSA_SHA1=>'3020020e135c91a6b875e35fab2ff1916f45020e05d85149bd8a5fc007091cc31ea9',ECDSA_SHA256=>'3020020e0f4f6ff485ffbc027c84d4793597020e037e1dfec72c665384c77ca8ebb9'}, + {CURVE=>'secp128r1',PRI_FILE=>'key_secp128r1-2.pri.pem',PUB_FILE=>'key_secp128r1-2.pub.pem',PRI=>'d8108a2ba9817e63aa251a1c7e6b5f08',PUB=>'04c1bce4bd65cdb84c67a15f5a46445a68ae5d2dd02477ce42c2a0da5a80b94be9',PUBC=>'03c1bce4bd65cdb84c67a15f5a46445a68',ECDSA_SHA1=>'302502102693e1ee12b6575e6bcaa80ed3ef8d98021100bcbb082a9be6040e32c79cc64a50d5e8',ECDSA_SHA256=>'302502103c1a1e95c3ef7c8a8fac8c111f5e293b021100dba18950be1f5bed4a554cc0dfdf79c8'}, + {CURVE=>'secp128r2',PRI_FILE=>'key_secp128r2-2.pri.pem',PUB_FILE=>'key_secp128r2-2.pub.pem',PRI=>'3ff23cebb55a74409042e2a9eb750d57',PUB=>'04cb2d66b60721e0f0d97b7c98af40247e54ec27097f08468a820eb9849aec2d3b',PUBC=>'03cb2d66b60721e0f0d97b7c98af40247e',ECDSA_SHA1=>'30240210296e7edd2551b28086d0870778d9690402101b3fdb29f6619c1545b97dcb4d861d61',ECDSA_SHA256=>'302402101cbf75997ef81010142794150cc19c5b021037504f952172552593ab384c8e1f36f6'}, + {CURVE=>'secp160k1',PRI_FILE=>'key_secp160k1-2.pri.pem',PUB_FILE=>'key_secp160k1-2.pub.pem',PRI=>'f337ddafec2746fe7dc9da27447eb341df179d6a',PUB=>'045678d69216c722bc84753a0216a71316fcac81b3e2f074eb9269dcd09351ade008faea4c66e62d92',PUBC=>'025678d69216c722bc84753a0216a71316fcac81b3',ECDSA_SHA1=>'302e021500968ed51e956e8c7099d43188da98ac2cd7859520021500c91dece0f7e8dd3c5f303c9a7d3d17f025963a3a',ECDSA_SHA256=>'302d0214094116423bb12bb3b9ffa3f4abaf8de7f47055a102150094b9baf8434c6cb49a6125a634b0a9e8f2cfeabb'}, + {CURVE=>'secp160r1',PRI_FILE=>'key_secp160r1-2.pri.pem',PUB_FILE=>'key_secp160r1-2.pub.pem',PRI=>'3d6ebb5fde1043333948b72ed440726160bbb13c',PUB=>'04a7b54fb28c8275d9667adbe63e4dfe84b387e9eea16d67505274d51ac808d4b436c93e9aeb02956d',PUBC=>'03a7b54fb28c8275d9667adbe63e4dfe84b387e9ee',ECDSA_SHA1=>'302c02145d57a2bbcf49841f80562285aad853d171a71c5f0214530e8338ba0754531f9c1a46df5c8a555beed5e4',ECDSA_SHA256=>'302e021500a6972031ba74c43385072d42b090730982b69129021500a11478df762c506c3832f42b26815d9f88e4dda4'}, + {CURVE=>'secp160r2',PRI_FILE=>'key_secp160r2-2.pri.pem',PUB_FILE=>'key_secp160r2-2.pub.pem',PRI=>'6e21d1f56b4aa5a4acc70cf872668cb2f3e67d8c',PUB=>'04c39963ee5bc371c9c1fdbbae426517ddcbb42e362891dd49d52582a6e56b3572e87717fd1f80d4f5',PUBC=>'03c39963ee5bc371c9c1fdbbae426517ddcbb42e36',ECDSA_SHA1=>'302e0215009fcad076515550c9c0cdf7e22889d955279c3bca021500892a8436a33a99d5e36dcb38bb2a659ba92a2ee6',ECDSA_SHA256=>'302d021500fedf83d3d70c02c9e2f7fcf72b99c7855ecb8dfc02143ffe07b330c2a8a36a62156bf1a940b342f514cf'}, + {CURVE=>'secp192k1',PRI_FILE=>'key_secp192k1-2.pri.pem',PUB_FILE=>'key_secp192k1-2.pub.pem',PRI=>'bb4412db119fab036e42eb8028ce4552188e5fd12cab1bc5',PUB=>'04f3ecb98a3c0c5715a5425a08e99b092caf166a457da770d2d56111a007faf45c6ec5f38849b94f5011b90151ada2df78',PUBC=>'02f3ecb98a3c0c5715a5425a08e99b092caf166a457da770d2',ECDSA_SHA1=>'303502182a806106c98d2e3131f4eedd35fae93421b4ea3362e56511021900c501bdedae0c3e2fc1bfc74727b17a1d8e8234ce5e8c0551',ECDSA_SHA256=>'3034021823f499904af5aa3cacf41b559202a89510bf4238399af7d1021854a24fe0050e810d4b12313e341c74d0c67b85997ab81abd'}, + {CURVE=>'secp224k1',PRI_FILE=>'key_secp224k1-2.pri.pem',PUB_FILE=>'key_secp224k1-2.pub.pem',PRI=>'504e3418a6f2bec9b61b82818cfae14360e9c523224b010976494ae4',PUB=>'04a2c7ad145b9323d9cbbdb0989d1294338ae89808f805666ef09913282c47712e7a8ff702bfbfafc624d07e84d34d52ab4f5a025224bf7e53',PUBC=>'03a2c7ad145b9323d9cbbdb0989d1294338ae89808f805666ef0991328',ECDSA_SHA1=>'303d021d00a5c69f06a247cd5155e62244f9cb0b01645ed1872b86e977433ccb35021c1c7b36e14f36764906d64d78305cd131bce4ca4f576fbd55120bfcd5',ECDSA_SHA256=>'303d021d00eb13832d8736ba2305d8d52621ea3be465d56286f8d93f54d8b07388021c1a34e39ceb48e7caaf4b4554127ac5ca56361d5cb22e139c34f70f4a'}, + {CURVE=>'secp224r1',PRI_FILE=>'key_secp224r1-2.pri.pem',PUB_FILE=>'key_secp224r1-2.pub.pem',PRI=>'5f037dbc728b0c912f33f79748ad9e13c531aabfb1a6f36c52871de3',PUB=>'04ed81d7d9b0185ad27a09c231e97253983af2435019cb5d20bf838e9ea78f4153eba00627a93dcbf26d16b765e43899f22416a0e9fb210fe0',PUBC=>'02ed81d7d9b0185ad27a09c231e97253983af2435019cb5d20bf838e9e',ECDSA_SHA1=>'303d021d00da725b75f0798ab2b35c981f539bf32e0be4b630094b0f602d246b3e021c419900df5a076f7eedfbb4fb6db996f9284ec3cfae2b563eeff24900',ECDSA_SHA256=>'303d021d00f1b6b3505010b9f9f285dd5304a593e217114644ffe789b71e16542d021c7f33a2703e633885738844c164189eefcb6fdfc41244efcd600cf425'}, + {CURVE=>'secp256k1',PRI_FILE=>'key_secp256k1-2.pri.pem',PUB_FILE=>'key_secp256k1-2.pub.pem',PRI=>'91d44bd72c399f23f1423c750eec025e007d1d9fbb372a4a0cf5813a35a1ba42',PUB=>'04d5f31fd4a14bf567d93b1f9b1e17b1c10ab53127dfdcede6eaf4915f0f0f675e7f26378ad406fd4f9499c1453c655262733c26c0e7df31b6f414734e04c72c02',PUBC=>'02d5f31fd4a14bf567d93b1f9b1e17b1c10ab53127dfdcede6eaf4915f0f0f675e',ECDSA_SHA1=>'3046022100abd606d9332a56e50e7312c7f62575267966fb5d61feea9564c136222282eddf022100b415ee5c718bbec1db767e24f47427fe6d4fa778637fbc2af053ecf64e78a6d9',ECDSA_SHA256=>'30440220495590030cb410f2b15f25fb6508866b94c32fba01a08527d119468db80d0c9202204074b2f994b345742e55c52f5edc5543e97e975fad73934dae9fb5f42ba0a91a'}, + {CURVE=>'secp384r1',PRI_FILE=>'key_secp384r1-2.pri.pem',PUB_FILE=>'key_secp384r1-2.pub.pem',PRI=>'56973b2fca72e7edf50efda16a3ed1191b9b04a8701849965afbef82639b3fc533af184e35097efc2947f34075963652',PUB=>'04e7175772defa198cf0fbbdf2fe4658551678d6b982c2a5e9a5c07652f5534dd5be12fbbfab701fbde3fc140d3f666f2b39f9a93f136c8c8b6857a70126e97cc893d6831c2f7a4356b2dd896fb9864d436989b4618191b14b4579a8961c3801fd',PUBC=>'03e7175772defa198cf0fbbdf2fe4658551678d6b982c2a5e9a5c07652f5534dd5be12fbbfab701fbde3fc140d3f666f2b',ECDSA_SHA1=>'3064023017f1d5e1987978315138ec211f10a93a9272d9ccdf5b40d25576e7256964af43f40b47d02b7f88a573241e46f88275af02305ce504f4c18601dda24f0b4fbc68d1f4ee28b09524882c37babea5c6091164642dcba21b8f7cb0f6f7ed63ebbea641f4',ECDSA_SHA256=>'3065023100f3571b35f8d5a37ff773bd48f1f366c5680b9331765078fa642f4a0e07fa6e60b7581b7175372092a914d7bbd4ff825a02305d42ac2c0e596900685d2d7a900d626cbd26128f8b8d225d2c2222214f9b2d98dcf12439f87bf647aeeaf1d991fc8269'}, + {CURVE=>'secp521r1',PRI_FILE=>'key_secp521r1-2.pri.pem',PUB_FILE=>'key_secp521r1-2.pub.pem',PRI=>'0175ba2b79d6fd589da82df79c5d05fafd80e25ba28e0735d3563ea5eb2cba0be36799ea4b5db067cecd8129456d552d556049d404afbb3f1a07fdb7e77b22716c47',PUB=>'0401f0761f84de1a2a48986fff480f0186ae2c2283b429c2c9c89e124138bd580a9414a4438036d80d40156a14ecec290cd4321075dfb7a130c85e8a5f1a9f025245730152eea2a0bf7ce57a1374f6f5b3be85d42619654bd341c3b54834ece5f09e28e4b4f200059c8d305fb5bac6353d4abc4ce8b599d64c457154cc2d382ce958fa8f5e',PUBC=>'0201f0761f84de1a2a48986fff480f0186ae2c2283b429c2c9c89e124138bd580a9414a4438036d80d40156a14ecec290cd4321075dfb7a130c85e8a5f1a9f02524573',ECDSA_SHA1=>'30818702416065101e06016a4b6a9c33939a60a135029d75bbe63632dd211de90e612c8b6c70eb82fb3e3ff93a3f7bf99833f3d2ce1a09386219031524475998105e076804db024200875bafb63e370157cc05f01a5aeeb20e123c7f030ef603119341bd85d1faf10993bc96e3c23f10c284834acc38b288a72b886539774b71aa231697eadf761d0206',ECDSA_SHA256=>'3081880242019a8a0d0f32c72209e918ab6c64049a397127f40957321c051ed2865d9f103d271dc1a3489887fb4f7b6089d91cc2797b05c45795a92876d9639ee7c8a9ae6006db0242016f9fd8f5d799a6085b42aa8c7ff131afdbc12d017b5563384f9c83bffefcba72c38a151cadb337d9ea35bbbba9082ae0e3eebec6570eaed7d25268a12e607f6033'}, + {CURVE=>'prime192v1',PRI_FILE=>'key_prime192v1-2.pri.pem',PUB_FILE=>'key_prime192v1-2.pub.pem',PRI=>'71ac6f0ae6aa7fe4c12073291e4a26242f7877732ea7ae42',PUB=>'04be75fe89acac6396e72fd9488f036a0f45574f0d5a528a9e1f3485f4477d328f082331fc529f26918510cacac28b6980',PUBC=>'02be75fe89acac6396e72fd9488f036a0f45574f0d5a528a9e',ECDSA_SHA1=>'3034021866a002530fb1feaf300e06a45d7c034e8fffc21b77594893021801c8b0a27cb0e901d151cae47c0c99df9560118a2565a814',ECDSA_SHA256=>'3035021900eac516c8c76282a6adaf7013e4984b04a6e4bea8b3fdba2f02180d76b408f2dd457015b923a7580c10655f855e9b36dc61f4'}, + {CURVE=>'prime192v2',PRI_FILE=>'key_prime192v2-2.pri.pem',PUB_FILE=>'key_prime192v2-2.pub.pem',PRI=>'bc6532fb8adc6fa22da85e99d49024769c7c0c56869e238f',PUB=>'04acc0985af3bf8e31f0af0b3838ef7a0c626657c9b5ca3e436aa8dec02391bb465099ab50bc89f193d5759f8b4f242685',PUBC=>'03acc0985af3bf8e31f0af0b3838ef7a0c626657c9b5ca3e43',ECDSA_SHA1=>'3036021900809a8999cabd8cd4112524fff6fbb6daf8f459e91fbfd693021900f5608819d4cba9d5e574e65265d61a19649bea696838c148',ECDSA_SHA256=>'303502190084a289c87df7219ae5c0bd5a3cb6a622eeda328468ed76a3021816c5701f707db1c263670d670bbba401ca278aa93c3e536b'}, + {CURVE=>'prime192v3',PRI_FILE=>'key_prime192v3-2.pri.pem',PUB_FILE=>'key_prime192v3-2.pub.pem',PRI=>'8494aebbe0d99d40240ddb354e3b7a52ade08cc692e3fd06',PUB=>'040ad7d2cff956a360c9cd80486f6cc6da080eb6bba14f637cc21db492d38007fc894f685edaf2d6d8361a376e0b359c74',PUBC=>'020ad7d2cff956a360c9cd80486f6cc6da080eb6bba14f637c',ECDSA_SHA1=>'3036021900bc3384edd8302ac6c3535fcdce339952aa37e2dad1b2ae78021900d5b0a106b65c384185147f5a13b172426dc30d3f84e7e4af',ECDSA_SHA256=>'30360219008e507ad0476d149bad832f1b06301e90ae881838a83fd392021900b9986def1c09c5a35bb0f922658891dd13719ae0844c3105'}, + {CURVE=>'prime239v1',PRI_FILE=>'key_prime239v1-2.pri.pem',PUB_FILE=>'key_prime239v1-2.pub.pem',PRI=>'5193b61d599160d1272ecfe4f7a5ad010dbe3b77a15c56bedcc1232bc7bc',PUB=>'0473003b786b391df8bfee506d3c8ef06ba6abe797dfbd83d56c1c77fa4fa35bcb925515f3b443d85993fc40f71e82ce6a528b2083637e1cc43a0e541b',PUBC=>'0373003b786b391df8bfee506d3c8ef06ba6abe797dfbd83d56c1c77fa4fa3',ECDSA_SHA1=>'3040021e34a760575935aad189d1fd58d0b84740f25cb91e829a605e02d3d78da526021e6669d3b4d56edff4d95310bc59ec443e306aba3443efbe6356153f3d2d3a',ECDSA_SHA256=>'3040021e42392d20a54b930870df319b4ff2b401d73d028e1a0aff73eee6f9bb1f04021e6a688a6eee784c86cb7a80a74e2ac7936c54f203bc5b7e38a3e8339ce02e'}, + {CURVE=>'prime239v2',PRI_FILE=>'key_prime239v2-2.pri.pem',PUB_FILE=>'key_prime239v2-2.pub.pem',PRI=>'420d695063758fd46b007badcefa22031d1544c81e6179ba211cab1f4870',PUB=>'04706eaf62b820e6982b6b77604d58640c14f2e6d9d500a25c5af132bde7342ea7caa1edc98513c48fffe799615ecc5ca27316b748a7cf1d61a36093d5',PUBC=>'03706eaf62b820e6982b6b77604d58640c14f2e6d9d500a25c5af132bde734',ECDSA_SHA1=>'3040021e3dc9786d2909e492b79e0829dec995094bce0fa72aa2f5792ed1e49c94f6021e033ec9cd8d9b53d6365e54fad6ff92c029636f4f1d05d8309c5908940cdf',ECDSA_SHA256=>'3040021e371a500289437979ac9e9ba3544589bbdddfca5cc4f11d8b9d2220b81929021e710f645cee7d7939d5bd35dfef8fcfc8f46e4bfc2ca7875e1fae52a258e7'}, + {CURVE=>'prime239v3',PRI_FILE=>'key_prime239v3-2.pri.pem',PUB_FILE=>'key_prime239v3-2.pub.pem',PRI=>'659e95f77dade42c7d9110ea4e4515bb8f02d8f5e3626aacf6d105121747',PUB=>'0429bc5929ae9da6f71a4f3616f90a4f4ef0268db5f11699d35da37218f1a32cf63dc7c17e2e2bc5d14298e168b745bdc142eeb5fcb94c47f646fcfbb7',PUBC=>'0329bc5929ae9da6f71a4f3616f90a4f4ef0268db5f11699d35da37218f1a3',ECDSA_SHA1=>'3040021e291cb5e727a422ae3594d8a39795355107dd3100935e7084589666179085021e7a5ee8a8e84cee4f818f4893b87003f02f5f1f7bd8d8db7d382ee24255d7',ECDSA_SHA256=>'3040021e478e0c7becb16f197b8491c16cd01a26a5623ea2b29a7f1b13ab240fdcd0021e60996413db68c035ff740476ef5eef859243a6daae5e94485dc486efdc0a'}, + {CURVE=>'prime256v1',PRI_FILE=>'key_prime256v1-2.pri.pem',PUB_FILE=>'key_prime256v1-2.pub.pem',PRI=>'40c961ba75e7e7bb72cf3a70164bd91697e99ab0436668031e17ec9306f4a418',PUB=>'04c4e24a83f54c2dd5b3c826b9bdcf1771d2e0ad164a4e91b6658f746cf8949a5938d8e727e08f54b8403acc4c5882fda0b1001692215a098e35df5aa22d4dccb4',PUBC=>'02c4e24a83f54c2dd5b3c826b9bdcf1771d2e0ad164a4e91b6658f746cf8949a59',ECDSA_SHA1=>'3045022063b6370e207f3611b2f4a2f56b7f31cf9aa0049b91d347bbfa48da1a07c600060221008784387f01b1cfa7951caa20bca1fa81e49b812661a8512513615a44dabd2772',ECDSA_SHA256=>'3046022100d21eb03d217c9545c82eb0cece3d5c9b0a5540f8350e5b200bec17509bacad86022100de403a528f8c4fcd2b6bcc6ec5131ffa830ae75827d1b7b828fc44fee7fefdf9'}, + {CURVE=>'secp112r1',PRI_FILE=>'key_secp112r1-3.pri.pem',PUB_FILE=>'key_secp112r1-3.pub.pem',PRI=>'99dac1a9d673f1495db2b80ee5f6',PUB=>'041d02fae808bccb57ca565c312cae0abaadaadf6a46d12ccaf7d12c95',PUBC=>'031d02fae808bccb57ca565c312cae',ECDSA_SHA1=>'3020020e1d29a37d02f2a35edd287f9bf894020e7b646f073a8f260095427ed24456',ECDSA_SHA256=>'3020020e603f37bb2c02c86716537630572a020e2af1fbd9760dcdbde41374307638'}, + {CURVE=>'secp112r2',PRI_FILE=>'key_secp112r2-3.pri.pem',PUB_FILE=>'key_secp112r2-3.pub.pem',PRI=>'013e4250b66bef1fe4bebfb2ae4d',PUB=>'04246c25c0a706d4b66062b75522e53922c012d5fc6b6c1b4a5e303e13',PUBC=>'03246c25c0a706d4b66062b75522e5',ECDSA_SHA1=>'3020020e16185a3bdbb6f1b0580ce4a9ffab020e182b89aaea76c1a7ac67a170174d',ECDSA_SHA256=>'3020020e26232f75db40434bfc8750402edb020e2cb40a523f9b157238696f11e49f'}, + {CURVE=>'secp128r1',PRI_FILE=>'key_secp128r1-3.pri.pem',PUB_FILE=>'key_secp128r1-3.pub.pem',PRI=>'16de36667a6aed4dfd0b6c589333862a',PUB=>'0415f6582df158fd71655e4b30d79a34a63635d644d8fc95efb53df1f9ef26ceba',PUBC=>'0215f6582df158fd71655e4b30d79a34a6',ECDSA_SHA1=>'30260211008da8921c9f3622e1b0e0b1c9b62348d7021100e1bc3b9a759fe65d52edcaa1faf35d08',ECDSA_SHA256=>'302402101a84782f46201fb5f8f48929670d173802104e4eea5f3010a169dbac27bbe86d6b1d'}, + {CURVE=>'secp128r2',PRI_FILE=>'key_secp128r2-3.pri.pem',PUB_FILE=>'key_secp128r2-3.pub.pem',PRI=>'0e8511b4ca37715cce554c75d93a0717',PUB=>'048127262ecb6d260ad2b531700e53873cd3e36bad4a35ae9a8cf0f46fa7153257',PUBC=>'038127262ecb6d260ad2b531700e53873c',ECDSA_SHA1=>'3024021000eb393148856af9d9c8a85dbc1c2b960210279019c29f1b9affebab711b73fbbed7',ECDSA_SHA256=>'3024021030f8c03c69cd3681152bfcb47baedd3602100146958b926d985bbe0f2f326f8b2c40'}, + {CURVE=>'secp160k1',PRI_FILE=>'key_secp160k1-3.pri.pem',PUB_FILE=>'key_secp160k1-3.pub.pem',PRI=>'de18c665d4ead6391e6d865a1f437ad41a63fe99',PUB=>'04a9cb746bbcd7fcf9df839e516816d11867322a0a3f589dcc639e3e37575c20e19f1d78e1734451b7',PUBC=>'03a9cb746bbcd7fcf9df839e516816d11867322a0a',ECDSA_SHA1=>'302e021500897668859cb3a0afc961c6622b8362bd1db9cd45021500ac8ecb94e4c2fc0b36064c75aecdceda4be95243',ECDSA_SHA256=>'302e021500e26e12f798ff67d292986f42c1700f867dfaed46021500ebaac751bf8953ea7b18bf7765b8d40320d78409'}, + {CURVE=>'secp160r1',PRI_FILE=>'key_secp160r1-3.pri.pem',PUB_FILE=>'key_secp160r1-3.pub.pem',PRI=>'4c3c347ce986c9c9af2d978a4f520d309f53a32c',PUB=>'044ef02c65cc01e27355e82839dd939c1d907569ff9b24bcb72962f24a5434989a8a494cdc982e272c',PUBC=>'024ef02c65cc01e27355e82839dd939c1d907569ff',ECDSA_SHA1=>'302e021500d83981a07ee6bfaafab87746d8ada8774bfce737021500d88aa07b13f7c8ca9110f83217da200cdf84e40a',ECDSA_SHA256=>'302e02150095e2b46af8171a27b5005096be62d86f09212240021500b6899293eca3af7ac8f2651ee9b294fdbb4915c7'}, + {CURVE=>'secp160r2',PRI_FILE=>'key_secp160r2-3.pri.pem',PUB_FILE=>'key_secp160r2-3.pub.pem',PRI=>'c7b1c191ccee2c0e1d691719350e7c6761c02e4f',PUB=>'04c6810cc1ed89788e9581fa85edfff774ddee38d9f01a87c51b748750f7a9b15ee83e620cdc4c3f46',PUBC=>'02c6810cc1ed89788e9581fa85edfff774ddee38d9',ECDSA_SHA1=>'302e021500b349b13cc377b37ca63a91fb2fe0219dd9e4b886021500a10e071c02762443ab4e8b2315a8acf456c9b911',ECDSA_SHA256=>'302d0214374915221f383798358bee6fde43a6a7cf431438021500ba3b6f5e9af136addb05d8acd0134462151a72d5'}, + {CURVE=>'secp192k1',PRI_FILE=>'key_secp192k1-3.pri.pem',PUB_FILE=>'key_secp192k1-3.pub.pem',PRI=>'1476eb7512b0f85d3e4824da18912335f5abc74e50ca3deb',PUB=>'04b20094e3df79dfcdef5ea044e9ee85457910379d939683a6c372ca525b543270c712d10260a58f21ad583383e9887568',PUBC=>'02b20094e3df79dfcdef5ea044e9ee85457910379d939683a6',ECDSA_SHA1=>'3035021900c5c2ae75f2106d5f4dfccf2f76a41f6f0bd587ebe8344e5d021852d7aa70f1f6cc73f50e9459252b68707995c90005844c9f',ECDSA_SHA256=>'303402181d7a041cdaa6ad34ba834fd7b53c6e260a1c6ccfe2638f7402183d7ef9e11953bf1fbdc7bb5cf7fd2701d28a64402f5925b5'}, + {CURVE=>'secp224k1',PRI_FILE=>'key_secp224k1-3.pri.pem',PUB_FILE=>'key_secp224k1-3.pub.pem',PRI=>'1709f944da01983d28b96777782e5a78e40e08c54212b19840f84006',PUB=>'04b56fdf57979beb9267a57e2ff9f5752dbf77c41c9ee12b8aa1e769802866f41bbfb4159b19659c42a95e40ff1c667eee4ab250b66cfe775d',PUBC=>'03b56fdf57979beb9267a57e2ff9f5752dbf77c41c9ee12b8aa1e76980',ECDSA_SHA1=>'303d021d0093e0b6edf75e3c2109caa6fa2dd79f2099081238c01cb0ad0ec09f2d021c404ea31d975290d58f03906293630913fea5a0a0839030f30828db75',ECDSA_SHA256=>'303c021c2118c6c3e8926ce2d1239e111da1a2979d14176c8ab144367121dd48021c376d49e2f4a212d274963c44bc72bea6249fb733f3445fb913bc85f5'}, + {CURVE=>'secp224r1',PRI_FILE=>'key_secp224r1-3.pri.pem',PUB_FILE=>'key_secp224r1-3.pub.pem',PRI=>'53dfaeffd502ac4d6c7942a2f7ff2367a016b20b1b350635f8c820eb',PUB=>'04b1fb44ffa8e4f655c060074e380900675b84cace46fd1fcada9b3d9b44cef8598e4caa8861bd10d81052606a3fe4a2cbfd1344287952837b',PUBC=>'03b1fb44ffa8e4f655c060074e380900675b84cace46fd1fcada9b3d9b',ECDSA_SHA1=>'303d021c2cbf83ae5138d0a4ea7aa0284a7195aefec5e12e2e3fe2dcd72926da021d00cd74475d258fe3070ba43a7b4e8653d1daaa18252a56a563d0c8062a',ECDSA_SHA256=>'303c021c094487a847116fdc95d77b981dfa8eb4363dbb33c42c1e9ce145b932021c5dcd1325cfa137f0d1b9076b49b2c29a91fbb3d9ca5fa32a8d3a350c'}, + {CURVE=>'secp256k1',PRI_FILE=>'key_secp256k1-3.pri.pem',PUB_FILE=>'key_secp256k1-3.pub.pem',PRI=>'20a12fab9d4a13fb06e1146ef6c715f6b663037336a5d59c2027b613d016eaeb',PUB=>'04275b2c4783e4ee1c22d0862b804ce97aa7c74631ad8f599fa94884ab366e44bc8f7bec169298abf6af998195cf47965e6c7426baac71653941b02942f50a4dc9',PUBC=>'03275b2c4783e4ee1c22d0862b804ce97aa7c74631ad8f599fa94884ab366e44bc',ECDSA_SHA1=>'3045022100a366fdf8d18bd322966a38834b5594080f19558af75e2216c637f048903e81f302201435b36c9ec5a864435af3c492216162357157a3b18a7c5811e4183b6263d662',ECDSA_SHA256=>'3046022100d0abdee98a71dd2a931266ce68b8937bfc6dbc74bde97919fbeeddc201e0fbf1022100e1db50da1e9e5c4adcb3fe1271d4dd32f3946659ea9a2d93eae6ac18eb02c26a'}, + {CURVE=>'secp384r1',PRI_FILE=>'key_secp384r1-3.pri.pem',PUB_FILE=>'key_secp384r1-3.pub.pem',PRI=>'1730392b33dac04f9f5e689308ea7c17cfe764a5f2208f598ba897c82317e469db16fe42457a68139b3e56c0a30fb983',PUB=>'0408353a2bb4dba518ad6a2c2cec3dfa9a17fc3440628cb03635749100bc46accd0ee6477ef0b018cae45f660f2134298e8a1b68fb2b8a9f9be8e6bfd09175923f4cd1efc459a7a6f233f5bae751333c4b318a32cd8834a9654bd72975a2fc82a7',PUBC=>'0308353a2bb4dba518ad6a2c2cec3dfa9a17fc3440628cb03635749100bc46accd0ee6477ef0b018cae45f660f2134298e',ECDSA_SHA1=>'3066023100d5a1649ebb113acc2f640316fb6798ff1d4532dd5fbd8744d821bcea8e15223e7d15b3fa2dcbe89e776f2f477a681791023100d0a60af9620eaa62a68830e0b717442e9c12e677da652705326da9c0e9766d1b654d94a2c3c11bdd98fa620764b3e143',ECDSA_SHA256=>'306502303b7a750e8b7e9007d4bd6f4a25a75cdf706cd75c6acb8c7543b06a72ba56ec5df629e51141c173459edb9c7e96212e71023100e5a98ee967460796fcf90c27009f485dd2dc066eb31bfe99ed0a2647a56a1206cdd28c7c9911896a74466b98363c668a'}, + {CURVE=>'secp521r1',PRI_FILE=>'key_secp521r1-3.pri.pem',PUB_FILE=>'key_secp521r1-3.pub.pem',PRI=>'01f2baec33a3d20b041c4ee883d457306e03f4e54b1285e0180e97d246461826a56dc49f8c6261e44c5e37de393fc467f505ec254d5380e6d82ace0335af5b4f8d15',PUB=>'0400b7f08eee478a92ba8e682286add2ca686409213662795632703c0ee39964af94188d133b793b4a9e6e354e6755f24d9d77018d77bb20238732147c9459b75eb50b000f099e980ee1cbb8ca4e1029b12a57083c300e8bb7240a23e0e8e5914010eb4c65b032e499570c59ee6d506501dfab6a4e3a957950437cba1495314af2c2863d98',PUBC=>'0200b7f08eee478a92ba8e682286add2ca686409213662795632703c0ee39964af94188d133b793b4a9e6e354e6755f24d9d77018d77bb20238732147c9459b75eb50b',ECDSA_SHA1=>'30818702412b146ccf45b99f845473b001765e875f69fa17cecdbe4f50189f75cce4d4910f24932e31cc5784fd56b817e6763afe78f3c793cb5796f121c044ab6dfc1ed01a8a024201cedad9d70fcbbb3c7c0677dc9a16b4b0bc8522fd3eac63cb7dd94452e375f66e56ff32a94c036e388367b5935482c50d4660e27b08d16f99b004855e4690929ce2',ECDSA_SHA256=>'308188024201c4f42125a4b3a51fba577722541d618139b01052d7ac866f411e22ff710cd3df0e3df9dbf89f70775911e6067024dc4b300dfa1146b0f13418946fd2e90d3646ff0242017275db4bad078310dd163a60c48cc805bb43b022be881b58d0a66d46762e380eee32735cd7fe1f0caed6eb57ed1af12cf5bff8f8bc66bb4a47313dd0e9bab2895f'}, + {CURVE=>'prime192v1',PRI_FILE=>'key_prime192v1-3.pri.pem',PUB_FILE=>'key_prime192v1-3.pub.pem',PRI=>'eb566f88950fd765e3d1f757e7293bd040b5a038812fc7bb',PUB=>'0404aef826969cfb139810d6bfe286917ec14e378730ea0707912480112d723d1eb50f129edb9367fda59fdd4867a0e0d8',PUBC=>'0204aef826969cfb139810d6bfe286917ec14e378730ea0707',ECDSA_SHA1=>'3036021900d88f65003cc149dbd2b7b30a86ad378f0298621a981b8b2f021900e618e0cae3b3d79886ba6a12deeb7fcb81dc74bbea7c3838',ECDSA_SHA256=>'3035021900fea28b7e0140628e06ed3946cbcc4cde7af87b3452e15b62021846ef2b4e550b954ac08798e5707770c78b8c4b71800ba486'}, + {CURVE=>'prime192v2',PRI_FILE=>'key_prime192v2-3.pri.pem',PUB_FILE=>'key_prime192v2-3.pub.pem',PRI=>'ec2af2777a78eacff5e4057925c8f4c3f1f4134492ce6e97',PUB=>'0423abfde9a835f43a1bbbb8ee413a24070b358af447b958997b8f2000089556a0128dd5252c5fb6ffb9532059f559846e',PUBC=>'0223abfde9a835f43a1bbbb8ee413a24070b358af447b95899',ECDSA_SHA1=>'303502184c83e052e376a1aa8ad731b197a51cb064b8cc426508653c0219008dfafacf06139e4982b7bedfd106c19ff320409809c17f23',ECDSA_SHA256=>'3035021814308b29608456cf4531f9cc107f077f5140f1e96865b0ff021900b372c4d61e8d24ccf76ed94dd8830aefdfaf0135cb582e37'}, + {CURVE=>'prime192v3',PRI_FILE=>'key_prime192v3-3.pri.pem',PUB_FILE=>'key_prime192v3-3.pub.pem',PRI=>'f721088da7d09e79a0f44e6bd6e92c27c68c6bf97242d3f5',PUB=>'04d93470443f8713e656a4509468c3706ef40b6a2ef86043fb181e6ca5eaffc54f7874b86b9ffad5f5b1a8f2703c121096',PUBC=>'02d93470443f8713e656a4509468c3706ef40b6a2ef86043fb',ECDSA_SHA1=>'3036021900c9cbf98af8853554b6c5012943d2f08c77b759bff7c719ee021900bc9534db2e4f40b8ffc7284a1f0c5bc0fa35bee52b56c699',ECDSA_SHA256=>'3034021810b340e088be8c6f50be9697e054780438f7e95f62f5302b021818cb8f834fdf26d23ead0f612171b5e0a66393633f647c46'}, + {CURVE=>'prime239v1',PRI_FILE=>'key_prime239v1-3.pri.pem',PUB_FILE=>'key_prime239v1-3.pub.pem',PRI=>'7b4521bca9b02ef8b57d9e2d6193a732d138b39d8abc741e96e146b01e3c',PUB=>'042c30f53413f4ea8a794724d02f1824ed9412a2b7cb02792f7e6ef06a93b130d45b9b4cde3e4b178921e0aa0c310e550a39f4d67800932466583f3690',PUBC=>'022c30f53413f4ea8a794724d02f1824ed9412a2b7cb02792f7e6ef06a93b1',ECDSA_SHA1=>'3040021e4165b85d1f2709847a739c3009adca605b7957eee86002461c92c8895b01021e7bcc9b21701e6b290b7032cba2ba87c8e0565c965db2190e9baa1152c372',ECDSA_SHA256=>'3040021e601b96746a533f378fafc2c12ee980a04857c6e56c36fcadb290ba0d0370021e312662f498a75da7506da87567a68e169d79f335cf743ce90516da562aff'}, + {CURVE=>'prime239v2',PRI_FILE=>'key_prime239v2-3.pri.pem',PUB_FILE=>'key_prime239v2-3.pub.pem',PRI=>'1da296ea5305b60c16824671f792118e585b65d564ed627371f3031765bc',PUB=>'04333d12e0faf83df27d7af2767f3196bfa2c7b758c8f7e394298b5d892aac7832609b6fb037ac1059cd471e3bece6784a39263a13979af094c00baf37',PUBC=>'03333d12e0faf83df27d7af2767f3196bfa2c7b758c8f7e394298b5d892aac',ECDSA_SHA1=>'3040021e6ba7fb1fe0ced3a2e221800817906de9e95035bf6970745792a3e46badcc021e5c4f8bc42973ad07509813c020d076972992a8294bd3b084a779e2a18cff',ECDSA_SHA256=>'3040021e6610ea72b2f451e5f801d6c81ecc416ccc0c6614adae2c51f5cf8d01d332021e2694f4086968d8552cbf9508a248967ece6a2e75e1a91caea584bd460656'}, + {CURVE=>'prime239v3',PRI_FILE=>'key_prime239v3-3.pri.pem',PUB_FILE=>'key_prime239v3-3.pub.pem',PRI=>'2c33bab3e10be173c9a98c8bda253f929569c4c53b8c26ebdea5202fbc3f',PUB=>'040bc536b07d27c9c138875e9d03f3cc1ce4d4bcd9a5fcfc0dcb6e9b539b9e126747a584397c8c9e29fc7c60205be6d018e16cc6a0ee4e9e014d87aa3a',PUBC=>'020bc536b07d27c9c138875e9d03f3cc1ce4d4bcd9a5fcfc0dcb6e9b539b9e',ECDSA_SHA1=>'3040021e04e94698eb31a90baaa8f9b578ec307f8d1f83edc85fd90c14652b520408021e3fbcf91f4dfa164ece8765bdbc70f72ced1e0c6aa919483fdefe3e75cbfe',ECDSA_SHA256=>'3040021e4c1e0fa1474a4bdfe5ad4ebdaf76e8eccb4d3288997ccda97cb8ac5e1771021e2a821fd377761401de5302f4dc99bc25705273967bf78e46068450a07328'}, + {CURVE=>'prime256v1',PRI_FILE=>'key_prime256v1-3.pri.pem',PUB_FILE=>'key_prime256v1-3.pub.pem',PRI=>'e6e3680400f2d4ee67577cec2819bf920fcfdf69fce549e5b603778b5b8f2894',PUB=>'0407ff8b133730ccdc19eb24bddd7931459488829e458e77ad5d5620f90ba61224ad599d9d436ec8fbcbc883e8342e14847f97fb37ff71e898d800574ab6a9e03f',PUBC=>'0307ff8b133730ccdc19eb24bddd7931459488829e458e77ad5d5620f90ba61224',ECDSA_SHA1=>'3045022100def3eba30349fe165c36da726f22579ad3ccfb853f6edf26ef8707b7e09332c40220076bcf2b5855b8485a460a5b96f211c7ea538b18fe3a4c54711bb53f9dfe18a4',ECDSA_SHA256=>'3045022100b4197fb9426cebae0204d63f250b1ba82d96a246369e56eef9196bcfd2f4b006022057131c64a5bd9c32f0c7cecaa1562f68f04c8390cdee81bd59d62551b87f9142'}, +]; + +#diag("samples_count=". @$data); + +for my $h (@$data) { + ok( length($h->{PUB}) == 2 * length($h->{PRI})+2, "$h->{PRI_FILE}/length test PUB"); + ok( length($h->{PUBC}) == length($h->{PRI})+2, "$h->{PRI_FILE}/length test PUBC"); +} + +for my $h (@$data) { + my $ec_pri = Crypt::PK::ECC->new->import_key_raw(pack("H*",$h->{PRI}), $h->{CURVE}); + my $ec_pub = Crypt::PK::ECC->new->import_key_raw(pack("H*",$h->{PUB}), $h->{CURVE}); + my $ec_pubc = Crypt::PK::ECC->new->import_key_raw(pack("H*",$h->{PUBC}), $h->{CURVE}); + is( unpack("H*", $ec_pub ->export_key_raw('public_compressed')), $h->{PUBC}, "$h->{PRI_FILE}/ec_pub public compressed"); + is( unpack("H*", $ec_pub ->export_key_raw('public')) , $h->{PUB}, "$h->{PRI_FILE}/ec_pub public uncompressed"); + is( unpack("H*", $ec_pubc->export_key_raw('public_compressed')), $h->{PUBC}, "$h->{PRI_FILE}/ec_pubc public compressed"); + is( unpack("H*", $ec_pubc->export_key_raw('public')) , $h->{PUB}, "$h->{PRI_FILE}/ec_pubc public uncompressed"); + is( unpack("H*", $ec_pri ->export_key_raw('public_compressed')), $h->{PUBC}, "$h->{PRI_FILE}/ec_pri public compressed"); + is( unpack("H*", $ec_pri ->export_key_raw('public')) , $h->{PUB}, "$h->{PRI_FILE}/ec_pri public uncompressed"); + is( unpack("H*", $ec_pri ->export_key_raw('private')) , $h->{PRI}, "$h->{PRI_FILE}/ec_pri private"); + ok( $ec_pub->verify_message(pack("H*", $h->{ECDSA_SHA1}), 'test-data', 'SHA1'), "$h->{PRI_FILE}/ECDSA_SHA1"); + ok( $ec_pub->verify_message(pack("H*", $h->{ECDSA_SHA256}), 'test-data', 'SHA256'), "$h->{PRI_FILE}/ECDSA_SHA256"); +} diff --git a/t/pk_enc_pem.t b/t/pk_enc_pem.t new file mode 100644 index 0000000..1ba9c17 --- /dev/null +++ b/t/pk_enc_pem.t @@ -0,0 +1,22 @@ +use strict; +use warnings; +use Test::More tests => 27; + +use Crypt::PK::RSA; +use Crypt::PK::DSA; +use Crypt::PK::ECC; + +for my $f (qw/rsa-aes128.pem rsa-aes192.pem rsa-aes256.pem rsa-des.pem rsa-des3.pem rsa-seed.pem rsa-camellia128.pem rsa-camellia192.pem rsa-camellia256.pem/) { + my $pk = Crypt::PK::RSA->new("t/data/$f", 'secret'); + is($pk->is_private, 1, $f); +} + +for my $f (qw/dsa-aes128.pem dsa-aes192.pem dsa-aes256.pem dsa-des.pem dsa-des3.pem dsa-seed.pem dsa-camellia128.pem dsa-camellia192.pem dsa-camellia256.pem/) { + my $pk = Crypt::PK::DSA->new("t/data/$f", 'secret'); + is($pk->is_private, 1, $f); +} + +for my $f (qw/ec-aes128.pem ec-aes192.pem ec-aes256.pem ec-camellia128.pem ec-camellia192.pem ec-camellia256.pem ec-des.pem ec-des3.pem ec-seed.pem/) { + my $pk = Crypt::PK::ECC->new("t/data/$f", 'secret'); + is($pk->is_private, 1, $f); +} diff --git a/t/pk_rsa.t b/t/pk_rsa.t new file mode 100644 index 0000000..8105bee --- /dev/null +++ b/t/pk_rsa.t @@ -0,0 +1,106 @@ +use strict; +use warnings; +use Test::More tests => 45; + +use Crypt::PK::RSA qw(rsa_encrypt rsa_decrypt rsa_sign_message rsa_verify_message rsa_sign_hash rsa_verify_hash); + +{ + my $k; + + $k = Crypt::PK::RSA->new('t/data/cryptx_priv_rsa1.der'); + ok($k, 'load cryptx_priv_rsa1.der'); + ok($k->is_private, 'is_private cryptx_priv_rsa1.der'); + is($k->size, 256, 'size'); + is(uc($k->key2hash->{q}), 'FC07E46B163CAB6A83B8E467D169534B2077DCDEECAE8FCFC0C3AD2EBA2C4B02D2372369990C62A923D22E10719CED191E231C4832FB4896ECDC2E1F39688D226C7B46E35F93CBD83B1F56A30B6660E0BEE43E719C9F533EFB8A0618EC2D164CC0AE64F20AFB888C14EAFF8C8E889FF1227A31152B3E23432B40A11C6541BBE3', 'key2hash'); + + $k = Crypt::PK::RSA->new('t/data/cryptx_priv_rsa2.der'); + ok($k, 'load cryptx_priv_rsa2.der'); + ok($k->is_private, 'is_private cryptx_priv_rsa2.der'); + + $k = Crypt::PK::RSA->new('t/data/cryptx_pub_rsa1.der'); + ok($k, 'load cryptx_pub_rsa1.der'); + ok(!$k->is_private, 'is_private cryptx_pub_rsa1.der'); + + $k = Crypt::PK::RSA->new('t/data/cryptx_pub_rsa2.der'); + ok($k, 'load cryptx_pub_rsa2.der'); + ok(!$k->is_private, 'is_private cryptx_pub_rsa2.der'); + + $k = Crypt::PK::RSA->new('t/data/openssl_rsa1.der'); + ok($k, 'load openssl_rsa1.der'); + ok($k->is_private, 'is_private openssl_rsa1.der'); + + $k = Crypt::PK::RSA->new('t/data/openssl_rsa2.der'); + ok($k, 'load openssl_rsa2.der'); + ok($k->is_private, 'is_private openssl_rsa2.der'); + + $k = Crypt::PK::RSA->new('t/data/cryptx_priv_rsa1.pem'); + ok($k, 'load cryptx_priv_rsa1.pem'); + ok($k->is_private, 'is_private cryptx_priv_rsa1.pem'); + + $k = Crypt::PK::RSA->new('t/data/cryptx_priv_rsa2.pem'); + ok($k, 'load cryptx_priv_rsa2.pem'); + ok($k->is_private, 'is_private cryptx_priv_rsa2.pem'); + + $k = Crypt::PK::RSA->new('t/data/cryptx_pub_rsa1.pem'); + ok($k, 'load cryptx_pub_rsa1.pem'); + ok(!$k->is_private, 'is_private cryptx_pub_rsa1.pem'); + + $k = Crypt::PK::RSA->new('t/data/cryptx_pub_rsa2.pem'); + ok($k, 'load cryptx_pub_rsa2.pem'); + ok(!$k->is_private, 'is_private cryptx_pub_rsa2.pem'); + + $k = Crypt::PK::RSA->new('t/data/openssl_rsa1.pem'); + ok($k, 'load openssl_rsa1.pem'); + ok($k->is_private, 'is_private openssl_rsa1.pem'); + + $k = Crypt::PK::RSA->new('t/data/openssl_rsa2.pem'); + ok($k, 'load openssl_rsa2.pem'); + ok($k->is_private, 'is_private openssl_rsa2.pem'); +} + +{ + my $pr1 = Crypt::PK::RSA->new; + $pr1->import_key('t/data/cryptx_priv_rsa1.der'); + my $pu1 = Crypt::PK::RSA->new; + $pu1->import_key('t/data/cryptx_pub_rsa1.der'); + + my $ct = $pu1->encrypt("secret message"); + my $pt = $pr1->decrypt($ct); + ok(length $ct > 200, 'encrypt ' . length($ct)); + is($pt, "secret message", 'decrypt'); + + my $sig = $pr1->sign_message("message"); + ok(length $sig > 60, 'sign_message ' . length($sig)); + ok($pu1->verify_message($sig, "message"), 'verify_message'); + + my $hash = pack("H*","04624fae618e9ad0c5e479f62e1420c71fff34dd"); + $sig = $pr1->sign_hash($hash, 'SHA1'); + ok(length $sig > 60, 'sign_hash ' . length($sig)); + ok($pu1->verify_hash($sig, $hash, 'SHA1'), 'verify_hash'); +} +#XXX-FIXME somwhere here a crash happens on solaris - http://ppm4.activestate.com/sun4-solaris/5.14/1400/M/MI/MIK/CryptX-0.017.d/log-20130924T103600.txt +{ + my $k = Crypt::PK::RSA->new; + $k->generate_key(256, 65537); + ok($k, 'generate_key'); + ok($k->is_private, 'is_private'); + ok($k->export_key_pem('private'), 'export_key_pem pri'); + ok($k->export_key_pem('public'), 'export_key_pem pub'); + ok($k->export_key_pem('public_x509'), 'export_key_pem pub_x509'); + ok($k->export_key_der('private'), 'export_key_der pri'); + ok($k->export_key_der('public'), 'export_key_der pub'); +} + +{ + my $ct = rsa_encrypt('t/data/cryptx_pub_rsa1.der', 'test string', 'none'); + ok($ct, 'rsa_encrypt'); + my $pt = rsa_decrypt('t/data/cryptx_priv_rsa1.der', $ct, 'none'); + ok($pt, 'rsa_decrypt'); + my $sig = rsa_sign_message('t/data/cryptx_priv_rsa1.der', 'test string'); + ok($sig, 'rsa_sign_message'); + ok(rsa_verify_message('t/data/cryptx_pub_rsa1.der', $sig, 'test string'), 'rsa_verify_message'); + my $hash = pack("H*","04624fae618e9ad0c5e479f62e1420c71fff34dd"); + $sig = rsa_sign_hash('t/data/cryptx_priv_rsa1.der', $hash, 'SHA1'); + ok($sig, 'rsa_sign_hash'); + ok(rsa_verify_hash('t/data/cryptx_pub_rsa1.der', $sig, $hash, 'SHA1'), 'rsa_verify_hash'); +} diff --git a/t/pk_rsa_test_vectors_openssl.t b/t/pk_rsa_test_vectors_openssl.t new file mode 100644 index 0000000..30b2729 --- /dev/null +++ b/t/pk_rsa_test_vectors_openssl.t @@ -0,0 +1,65 @@ +use strict; +use warnings; + +use Test::More tests => 246; +use Crypt::PK::RSA; +use Crypt::Misc qw(decode_b64); + +my $data = [ #test vectors generated by: OpenSSL 1.0.1e 11 Feb 2013 + {ID=>'key-512-1',SIZE=>512,PRI=>'632B6C7F984EA022C2B3D507A3A0886678F8794B151E16EA696883B0305B2A984EB6CBE3CC56025852CCE742A51655A8CADE5BE73EBE75CEEF70CAA72F82A801',PUB=>'C5920D48C0DB954D7834FA7C74DB7C91714C97EF2DA4B35DA302D75A0E08AD3B7C05296533C71DF5045F66DDD2E1F9A0D487CDAFE4137214F7764D2BE25D0D29',SIGSHA1=>'v/ZzE0JT8xakMsHhh2qVcEm1r/odXZAfSr+JK/B2trzq3UrzUwYfWgM7NtO2L6kU0wyNCVTy+gMpGECfaAEiqA==',SIGSHA256=>'pjOjBMaGXx7XZ+uNgfszCD1yy9WeLwgdM/1eP987j+s6hGaIjHKOm2PAxXZ6cEqYi1QQsMybe3F9UhL2b5ws9A==',SIGSHA512=>'',ENC=>'mQw7zaZdwthCgpBdV/BxdzMp9yUMOSFHogB7DvwCYztRlqlc8bXnJUsa6yasLARaN2rbb3dyIN+apNW+wZkvrg==',PRIDER=>'MIIBOgIBAAJBAMWSDUjA25VNeDT6fHTbfJFxTJfvLaSzXaMC11oOCK07fAUpZTPHHfUEX2bd0uH5oNSHza/kE3IU93ZNK+JdDSkCAwEAAQJAYytsf5hOoCLCs9UHo6CIZnj4eUsVHhbqaWiDsDBbKphOtsvjzFYCWFLM50KlFlWoyt5b5z6+dc7vcMqnL4KoAQIhAPLj363QXovzYxztngqfImgsXOSBwgTpmnKylb6oSbfVAiEA0Dv50hhAHRneuo0M4nat47wIvc5MmJVS4ecf1N4bngUCIEbwgRLd6c9MPaVkTSVjBwSP+G2Q7F7M75wSRqQRuL4lAiEAqDzcsQ6gtiJRnh0ZnNpP0Z/43AkSP3DdfuByClTMsVUCIH3TYvzcDPJO1K9KTLNXGOSAhkh3QE3wJBLZCI7jm3LY',PUBDER=>'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMWSDUjA25VNeDT6fHTbfJFxTJfvLaSzXaMC11oOCK07fAUpZTPHHfUEX2bd0uH5oNSHza/kE3IU93ZNK+JdDSkCAwEAAQ=='}, + {ID=>'key-1024-1',SIZE=>1024,PRI=>'56293EFF57BC5C6A708CB55AE74403F6B21ACACC2642E50E020D2D3429BF815A53DC13858DD1F2E79FD5377EF1DA04740FEA5D3F1C862252F1A88F750ACCA71C5B6C60C43FD4AC2A102D7F48968E38EBB792CE643FF511E7892853532E7A98DF9DD9773627CC29EFE17C8B41AAEA31BC57078B5BE466CA0D64390E997727D631',PUB=>'ABCF9F5B2BA9FA2A11B8BA608756387234B2A10A96033C27BFC789BD3907AC53BA5227DCBDADC865B7991D6DCAA2C7FB0C8742C3D59AF3100FAB034CADCE51DCFDA813E4064D476A683ED8BB4E6C7CBC3A0485DD6A852AD087FAA99567436E165E73210068B7544BD6DC3D66A61A3D1C9953D28CFC0E2CE4EFFD6C01645B766B',SIGSHA1=>'nJVnjobpUG6jIjIXTLgM6Oo4SXegZD3MYMC/ejjypCn0aDVoCpCatouypILdBiWm3QoBlcwAZoDfwV2xPhRi9Y4Uy4Fwn2h2ItkJSaoV1j16jVnR/GHl8qXS1lX3Euj1AWScYy0uXP5ddSNjxjjPwWPHh/R8hjHg/+JSi1v/XRw=',SIGSHA256=>'fIziZBxGd1VR+b7DdjqlpBUn7dlShTkmCSBtx31Ryl3Ku/UCFKU02NURE5l5nH3AE366LU7FX8H55VsoTdxySNGHW1vzAe+BqgTzYnTYZTlgBAJxtdgBaLF2JewOZB3iX90TKeCcLclUlcNtcFNpf2r7/qdxdNQwzsuy80gOAls=',SIGSHA512=>'BTIfuv37aZkHPWVhj3RQRQREun0iUdj5FEJppjVtBfFIe3ZCAYnEO8XA0vaNbIyKHTzz66tCHAON/x1lsoGDZztzKnalUJVGkdsXu8NaBdH0Wrxo6tiaKkOSoHOrFrtiWC998HB/POZCOIXJq9PgamCp4sQ1u/pQu+6vG3+SfDk=',ENC=>'LIefk1+idC96eS6yPAMAzuO6nH3FyCutvBCfoGIh0BSmpYvfyLHsdg5hog9Zgva9vs/LXJHOGzQ4c82O05SEG7+IiwL78l/jmIUXUusCGo0BRDn2J2oPl5ZpF+ku5W2w+wFy70AnVzB97kUjsM104ZugbO+9W4PYoLVLMWh+R2I=',PRIDER=>'MIICXQIBAAKBgQCrz59bK6n6KhG4umCHVjhyNLKhCpYDPCe/x4m9OQesU7pSJ9y9rchlt5kdbcqix/sMh0LD1ZrzEA+rA0ytzlHc/agT5AZNR2poPti7Tmx8vDoEhd1qhSrQh/qplWdDbhZecyEAaLdUS9bcPWamGj0cmVPSjPwOLOTv/WwBZFt2awIDAQABAoGAVik+/1e8XGpwjLVa50QD9rIayswmQuUOAg0tNCm/gVpT3BOFjdHy55/VN37x2gR0D+pdPxyGIlLxqI91CsynHFtsYMQ/1KwqEC1/SJaOOOu3ks5kP/UR54koU1Muepjfndl3NifMKe/hfItBquoxvFcHi1vkZsoNZDkOmXcn1jECQQDhVP7yFj7RFGmwWzGgobh9K2YQlvkbTJzL4WAR7TtcwrNhpNxKNooI3ryG5XqejZDEY7VKA5jiLoPtHYR6S3x1AkEAwzHaAc62JfYPUoiFGZ6XHbslUhdE1VwuEk+O/0OmJZe5hEIlR5iwfpudsJFKy/zDpK1LpJYzKHBNMwpAHRpLXwJBANbc0W3OQH/l0xHTI3NkQiM46s4O5+JcH3dZpN3zNJOzJJGLPnOVpfHnUiXfVBk0LELYQNoeq/2hFTNY3iYvLLECQExxf5FppQgk30dRU97+ruvj2O/XUQvF9/0Pz07E7ZKXYv4a8YKil6xdwVne7M4KhYw+mfsxH4Pcxz8P6p/7Jj0CQQCrDRP2Rhqre0Oq3fyRd44uIaN+hWArLFBwB8VDoTnbymG0qPuvfROAHroRLmXmF9PFeGrKcPGjej2G1C+AuSdm',PUBDER=>'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrz59bK6n6KhG4umCHVjhyNLKhCpYDPCe/x4m9OQesU7pSJ9y9rchlt5kdbcqix/sMh0LD1ZrzEA+rA0ytzlHc/agT5AZNR2poPti7Tmx8vDoEhd1qhSrQh/qplWdDbhZecyEAaLdUS9bcPWamGj0cmVPSjPwOLOTv/WwBZFt2awIDAQAB'}, + {ID=>'key-1536-1',SIZE=>1536,PRI=>'B97EC809C3728D720E2C5674E2FBCA68C904C0C981C0A3B95C0138A0B91FB295DC168BF7EC002795BC8F24CBF82314FCE8FD7D69BF0FA022AEE48DC3163A4195E3197ABF65FEAC42069914B57D153591E1D08C7D5F4CAFA2B6922280BEEA31CD505E34970AB1B785F64A0BBD7F92534D0C6E1356C86A358F2BA9CEF16BF27D4AC7DF712337ADC46B3186584F551E5933CE4A85A140A5382E7A7D2797DF8E1EA862338D47E7AF3DC86994CF2E17D2CCA6784294AFFB8D9CC6B34C655987A53255',PUB=>'DA464976929528C9868B7CB656CFD969269119A9CA8D91931714DDC2BCB937BD40D5C11140191843A467DE2F310B63FEFABF82462744F04B9920ADE448851CDA47ACA0EF75F33DCB205049AF15399EA2301E251EE450D67326CB1F64AECECC560C43E3C3EC683D716B4C6814AD8FE26E6442B1A462C23CB0F41CC2B159C940837687C8A3C3818B5E9D5E2E4DDEE6507B17F06AEE9257C6A8EF33E8E7C06C5D52DE858110BE260FF5CCBE1BEAE7FEE1BF576045819676732BC3991D7F8CC13E15',SIGSHA1=>'NUrmQizMnT/GScFhWdIMq0zJ0mmhfFj8pF5Ux8K/Awf/nFViJSuTb7yDHp3k7QmGgo6UmWZNCNrTy2jZo6F9XAwNo+IVsnPXVtoCVLMRxNYYpOV8H0Ph8xaym0jmowj+TivyGx7k/6UoJMer1lTow1nZ/d7rroDrrKTnRoK8cBTfXaq9xiGztXTd0+kXkLSai64JQ8i2H66dDY6P713fPhWZxD3w9uTJ5pPlhBVX76ccz/4o5UPKXQUHDKvhG6lO',SIGSHA256=>'KnD9d6valiHNzj1zX4yYU7W9IffPdScpAKbKhUDv0D/y+EkH0jUJJ/F7dV0JBxGshf1Kmi5B7BnXbND9/fHPDIFPlgJ1rxFeIntG9+m7c2xg8Dh0S1rh6slMAJgj8dKaw/mRwBVwmMi1luBrW17r1LKlDUDYfNnjKTeXzbwny8Je5COlDfDP/Lk3NtX5DuY9Et+3+MQCRn95CedNokteW3jO9q7a+1UcQ9F7EYPiISyDje2Eh5rbc+eNHjZ3iBJq',SIGSHA512=>'c+lX10eLEZx0bregmdnBuY5usXmWrGQ2HNd++2mkyXK3UqGmJSdmpfxoHmK7rFaQaCf/QOlhSzYPx5MG7GS9sxxbJsYTBa0S78RslfBNQVUYiS9BZNae6kLCDyKPfoAOIvZdqg35SQFasDqdS2cv4s/2TrP1ziAriEP/Uv6MIPIODZq0qdVswyWIJIOOmG5CN4eoi70y2VLtcN1+PgcYpJG+dmgFE6EVItGqUss1XoMuhx4xn8xhbYLISsR0fylK',ENC=>'so1DFioxlbOOm7e0A4HOcznRjGS/dgji5ThBJMMVmvzCMv2lBaKy6kfemk+NhjG9dUIRuf9aPY+sASHJwGfBI72puf6H0VkFFzYPzIkTndW57fVJItTIuh8yre74fPadi6hcW2JBWoDCU7EO6hJynM1Zlol/Qt2gXiy5LrDp0QGV6tkl5z/Vho+I/PnPA8bbTs8/Iw+WKgtgnakK9gE2u2TjU8MpHM2SyShnRAMVW/qUeblQcrNORMGD1bY6tXk9',PRIDER=>'MIIDfwIBAAKBwQDaRkl2kpUoyYaLfLZWz9lpJpEZqcqNkZMXFN3CvLk3vUDVwRFAGRhDpGfeLzELY/76v4JGJ0TwS5kgreRIhRzaR6yg73XzPcsgUEmvFTmeojAeJR7kUNZzJssfZK7OzFYMQ+PD7Gg9cWtMaBStj+JuZEKxpGLCPLD0HMKxWclAg3aHyKPDgYtenV4uTd7mUHsX8GruklfGqO8z6OfAbF1S3oWBEL4mD/XMvhvq5/7hv1dgRYGWdnMrw5kdf4zBPhUCAwEAAQKBwQC5fsgJw3KNcg4sVnTi+8poyQTAyYHAo7lcATiguR+yldwWi/fsACeVvI8ky/gjFPzo/X1pvw+gIq7kjcMWOkGV4xl6v2X+rEIGmRS1fRU1keHQjH1fTK+itpIigL7qMc1QXjSXCrG3hfZKC71/klNNDG4TVshqNY8rqc7xa/J9SsffcSM3rcRrMYZYT1UeWTPOSoWhQKU4Lnp9J5ffjh6oYjONR+evPchplM8uF9LMpnhClK/7jZzGs0xlWYelMlUCYQD4ouyy0yEpXK7jQ8keFTo5/dWD4KS+hw+PdxpcDDXPxJ8WF8SaP7c0vlmXesf6pbpZszaIZoLnIUi6LePpmQ1QWQUXpC3Wwpfybz+hySxzEGPl0oN3Jqi2ESXMh77oJpsCYQDgvStQS1Db1Ln71ncg/9XmqCHhbV3cclYjivtC9FcytK2UGGr1da0pqiIV3iDWLCbddO2POJDwMFi6X/MiiwJa2jSdKhN27kbN7vAhBoMFjUcesw46KoRBrIjME0zXIQ8CYQD31QaUtShv3yef9thIeSZB2cdzHX95Poz/Ftwadj1JLRbZ4bUhf3MxSq9o84TUTU9zy9QGoA/JLP8ePVHZbaq8tQ8DYq4iTHNCvysxK6J3yxWYZn6OTOWMHYmM1p4vLxMCYQCWX5z6tdpdrSHgkyjUyLoMAtXgqzgRh+OBFr52l109DU3TeN8gbGO4LCFwdleMVrCOn21Q1m2MeRz1X7wkkdS6i6SGwJ+ThW2U31qHDn9emKBMt0w+uTITa2mA+y0ACRsCYQCFvIhdbvkrzk2BVa4sdL6u0zbcIWPdtujqV6eruK5es8p/98kBz2o0XQLbwtZoIe1yjgx9BrPXMRNq8fUx71XJ4Vx6WcxzvvHIGpTrJt7ylPm6TrowwMoMQ+C8bqo8V+4=',PUBDER=>'MIHfMA0GCSqGSIb3DQEBAQUAA4HNADCByQKBwQDaRkl2kpUoyYaLfLZWz9lpJpEZqcqNkZMXFN3CvLk3vUDVwRFAGRhDpGfeLzELY/76v4JGJ0TwS5kgreRIhRzaR6yg73XzPcsgUEmvFTmeojAeJR7kUNZzJssfZK7OzFYMQ+PD7Gg9cWtMaBStj+JuZEKxpGLCPLD0HMKxWclAg3aHyKPDgYtenV4uTd7mUHsX8GruklfGqO8z6OfAbF1S3oWBEL4mD/XMvhvq5/7hv1dgRYGWdnMrw5kdf4zBPhUCAwEAAQ=='}, + {ID=>'key-2048-1',SIZE=>2048,PRI=>'035BAC35A8E3E44462A1F4BF6A61EF45E899456BB9F0ECBB24100AA500875E424EC269B877131B80D1DAFECFC2D740FA108790C9BBD0840B9839E7A32D1985D74E069EE3F9B13BED01CAF208D354DEBB4C71C5517B4642400CDE9DAB8B1E312D3C72FFAF4DC60D4A62F935A23DA8AF0C768410C02727E1830F5BDC50276AECA6FB67BC24AE0D96F3A38503959EB0A2E2F1C326829573697CD27DF9AB4603A7CE5A0579E4EF87F4FEC3D6378171EDB9D4A75C00B70D376B38C14DBE5B06781746ED0DC80220BFE4649EFC47C24F796EEADD723FD590D0E9696A945E5B4DD4944DF1DF57A40273E1821C2FBBAEC6B1D14F9899953E7D97DA6B0A2F6FF319806541',PUB=>'E76B4A62D1D9027F4CCFA5EBD885F6CE2A4FAF82EC863CDACBD381391D7100B8667C7EC17E229CA62FDDB9232B9CE38D31298A71C2B116E93120890A289113DFA94CF746F436460DEC112E821E113EC44981F47E2400691142AB59AEEAA9AB52009A034FCDC1D59602954B7E99262574FB07121833B19380198D3C925DF7F1722BEFBBAA4CDF0C5A44001B0A0FCC47790E55D1F8A08E5D12362A2B3E94224D47DA3886B76FB30A5505BA2B0E50906D7DEE236132D3D30B2357CD02B860C7E87F915B44F25ABB07FDF842F52EC5524ACA10F1B3E0A027D563636AFE3B5B9DF1ED996E3E2D44295EB0EDCE7FF9227DD92FDEC6A8592DB20F76AFCA9D2BAFA87C9B',SIGSHA1=>'t7hzGMLSKGA3Qnp6b5GdCayymGTJQST8Q9q16VF+8nUrSk3D9LeyWkw1WKdXUMpklS831aUPRW8p5ri6Iy5ZvRr1ukjDR4v4cSnn3aVfrP19z+gazVnWGnJlP6cgfu84yxvn0CjLu+8+cqN2Ky7mLrfMQCGTPc+JNnv80DG4mHEr3PqHpZl8zCgBuD3ysejFbdIVbAoo2hnSRmwKjvMXWbACAU78bRqkaMxdEv6aGPfJvtR9BzeHvM+NT9duELHBxKt2hc0XUYgGo6FhnA2ikGpKnw8vTXqTHap8qORfahPy4uhQ4+BVeIAUyt7eGMQpc/qPcFB+uY+3Ul/zrKN7zw==',SIGSHA256=>'xdwP2TFfCitIB8eol5XNbuc+eeWLXumVSAIooBktCQjb3EdzK0WOyd6GJHk8DLT48itK75nJhOh1IYFMlsUoNAKItzSnvSXt2bJVmavA8+MnkIXn9uZXmPAD6vXadocHtZFex7wq0t2xcObnyVI5i9FsW84icOJzwPm4jTELVrmkecZ+mQcFmgTxE7S7iT8a/FUqDa2vIfaD7PVpC5HctmWmMDVwpbBTmwZDwBbrzQm5MS3PbVhhpHDmwH/nBRgWCeCnL+jcZAxV+sWy209I3ZKiO0OuvSlhyl5sF9kk1B0A9Oiyje7xvPqwV6yybf9cWibihdIOBi7gSlHRTX2oiw==',SIGSHA512=>'mAJ6B3krtvDorBPLwTdCjiZgrtzkuqqM0VGWASX1a9BzwQ2WgfaJupbTNru8CSuu7Bef9gR1Gtv+6a5MrjrgE9EaTjF1yJfWr5+azsjyCGcJGtZlhj0GbsMqLUdHagkDpNhAVtnYG+Kug/Qgn4WgMj7Jyiqy0aqEcntbbsT4KtNzFdQyO9CIQss9QCSZYGJ0cKdFr46i0sIe4bIpzzAHG58Q1Ipwq3wtxtwKIoIZlSpAwSsLvm570civoQ3+cJdLOvLpJqLz90kgR3GNioh0XH1KsvXfaWrEJnEXQApoYc/Xeaw7+F6SBZmGwUHC3+EjNDyqg27084ef4rr+Qkh/BQ==',ENC=>'NeTQwFritWcP2UbW8bnMLfIezi2vcjQuMkv/TvRfDS8GvIoYkSDNT6aa2Husiy461c4xmpXlnRMGIYppf6cPOO1P3tXm+3Wvb/6tt2aMi1g5kAOct6Tg348uxpy3H0dXaIhXRyC8YRVaDcV/tVYR4AvZONDD1Xj89jtEopfPySCfpKUTw8WL9hblvCCSaiEDDsB6xVeqjPLsH0NaKFMm7FnriBXwE7OoIl1GXh3XAWz+GrFjXThO0rai5rcIpRrB1uO9r7H1EQI6Bg2fZ0XqbFs+XwtJXQ5MxVMuFFmGEnEaDjUKhmH3tvSu9tY2WIHs25JkeIHjdLaijjqfthPwdA==',PRIDER=>'MIIEpAIBAAKCAQEA52tKYtHZAn9Mz6Xr2IX2zipPr4Lshjzay9OBOR1xALhmfH7BfiKcpi/duSMrnOONMSmKccKxFukxIIkKKJET36lM90b0NkYN7BEugh4RPsRJgfR+JABpEUKrWa7qqatSAJoDT83B1ZYClUt+mSYldPsHEhgzsZOAGY08kl338XIr77uqTN8MWkQAGwoPzEd5DlXR+KCOXRI2Kis+lCJNR9o4hrdvswpVBborDlCQbX3uI2Ey09MLI1fNArhgx+h/kVtE8lq7B/34QvUuxVJKyhDxs+CgJ9VjY2r+O1ud8e2Zbj4tRClesO3Of/kifdkv3saoWS2yD3avyp0rr6h8mwIDAQABAoIBAANbrDWo4+REYqH0v2ph70XomUVrufDsuyQQCqUAh15CTsJpuHcTG4DR2v7PwtdA+hCHkMm70IQLmDnnoy0ZhddOBp7j+bE77QHK8gjTVN67THHFUXtGQkAM3p2rix4xLTxy/69Nxg1KYvk1oj2orwx2hBDAJyfhgw9b3FAnauym+2e8JK4NlvOjhQOVnrCi4vHDJoKVc2l80n35q0YDp85aBXnk74f0/sPWN4Fx7bnUp1wAtw03azjBTb5bBngXRu0NyAIgv+RknvxHwk95burdcj/VkNDpaWqUXltN1JRN8d9XpAJz4YIcL7uuxrHRT5iZlT59l9prCi9v8xmAZUECgYEA/3gLqu2XOb+MmeytV4DDUlLXGykHmEvqDm6sWiojEdWF3dGUTxSAiwNWd7SjNmR3dbfUQvOodYnfFAyny3wLViBrMdN9ymBHnPblxBmu3W5YF5JUC7MOp9Zh+Ae8ZUaDjjU/Dno7UDvcLx1YGHSjAsYorb2FQkHBPrtYfq8MqeECgYEA5+ZyPcWAFQhrT89vwi+iadr2+AbKwzTlZscHCRvzb6rn6r9BbnG2AtqN3wzXTKP6CVZDs91ZCU309EZYgRNm+5b48PU0Jv5A40PIutOMK91fuCM2zWVfAYrwi4n7UNxEClZ4KUMYVHL/XB92rLx9q17T2+aJYyYIMJg/9HxNjfsCgYEA9OK4HINf4SVyu+IaT7TIhtOOCyULeLvcgzUn1c5qi5/okLdjuWJnzdnHOzxW777inF85A2zZ4MHmqytudSpVG5w75SlcfXBJdXdezNnpu60YmI/WLNjZhZ2Fj+Kqf1JWrSzxYwlcbg7Tg/5XAipcUD5vpAv1/4tUmLOxos5eD0ECgYAvJmbB8n8ZR63x+z5A4EiId1HRmiftyrp9zCe9DWbQpJIk46AdIZedOuyvlj/MQGbdMSHw1yd8QdJ1PDxQei5tJwQUkfZ5myZ8TtLoUYzlekw090v0NRE9Eg/Yf0SO60oWRACIezDeMseC5o7NjkGK72vqARScCSaPItWWExP9swKBgQDiwDNbc8hYyMdCtUquETEHULXi4UNaJEGAbd6c2rKmJF4Spc1jul38RGQvuJ6AkYXF18ICYgkod414TNr6Gdj/OU6kJ4EK8hOaSm3xBTWNu8ScG527Tiado9B2YIhHj2CKmPzNcMuChUFPFWy4ju5hurT7vU4gyWOOqdSth0d2sA==',PUBDER=>'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA52tKYtHZAn9Mz6Xr2IX2zipPr4Lshjzay9OBOR1xALhmfH7BfiKcpi/duSMrnOONMSmKccKxFukxIIkKKJET36lM90b0NkYN7BEugh4RPsRJgfR+JABpEUKrWa7qqatSAJoDT83B1ZYClUt+mSYldPsHEhgzsZOAGY08kl338XIr77uqTN8MWkQAGwoPzEd5DlXR+KCOXRI2Kis+lCJNR9o4hrdvswpVBborDlCQbX3uI2Ey09MLI1fNArhgx+h/kVtE8lq7B/34QvUuxVJKyhDxs+CgJ9VjY2r+O1ud8e2Zbj4tRClesO3Of/kifdkv3saoWS2yD3avyp0rr6h8mwIDAQAB'}, + {ID=>'key-3072-1',SIZE=>3072,PRI=>'466B5E488E856F7999E3967AAF101A0E42F5BC5316758D3441CABBA36AEDF240BF7C17DF094B589439DFA688AB3B925D18CDBB18565A70EB85A5DB409DE3496081D14E883B6E96EB012916A2A2F42E67AF6884751384D09790E1C2D7CDE5AE24B16616D66517A71AB641838F5477D8B0D042DD35BA6E7A871A99303B2F0148E7D2C6CF0EAAFC144424A33874235E64F3231D2CC72E0E7C66F0F0525DCC001ACA7F4B3FDF3A93876CCC147E60B89BBB7AFE6E6138519109E1B2A0717D9A478EEC2182E93135A80DFB15AB3FA7DA6312B2AF2884F099E0190A3BE57B70DD604F82C581A36557AC062C5850DA0CC7C4EC32E576D04EF5B52FB1CC1557CA6C889BC6DA3F09F64BA12C856C891C850940BFA6CBF397830D6A3A23FBD5C0A16ECC270E341C3F2682CAC83A1AF059DB8336C68FE589E014D82F66705A247D31B07D3B19FDD46F6AF6CADD9B2BC99A044D7580CD1EDA0E8FFAEBE1FF49954CD17FA49DCF9E7A4BBCC9F3CF7E02A6686B7F42EA2CBC91557E265C2ACB52794129C68FA469',PUB=>'C1303847E4A1735F0E8DFE75B3C0717D1F73BD02CE2A694630F65C29437928DE50EAA2BA323DE544E644DDEA43D61860390A6784FE42F7F92052FF022A8ADA5F840DD95FAF50CB1C6E55D5B5F7C758DE46268E38B047E2BA3316780F5A83B3F0B13BBED9BB49BD903391A46D9B1BCCB2A0D8DE8F9D74AD88BD8D426F1384EF11CBD7156A87CDD70B821952CC246B6149A1C3CB8982460BD3178920CDBBEDF0E008CE57BFE67B6879DC12546481E2B3E96E40A871F6FDD195CEBFEDCDE8EDFFB98F3670F03063D37385C703EA7B3A708480237E39072561CA43B62541CCF52C03E964AF3E4D47CE894A0CB5390241689257700F9C7E7E6ECE66C7187217A762668E0606C2D8C59920BDC33AC8B72D59C77BA2AA325CA6598E70F9BED4EE07238FB67A34B7D64A6AD917F073A13C0724DFDFBD97881C0C646F018A3D1D8BBCFCB0B133FC4EECB15953DCCD62CD79817134C1D2212DE38736ED10C79BAB9AED2858EADA6705D6D1BD87A0D4976B75FAC33EEDCFBA2DB166D30BA8E8641D2BA8E19F',SIGSHA1=>'Y0wFAn1lm1ULtbLwJkWenpKDeyoawgxBL/KkBteZugp67v2+zAQJ1HnO2GGum0vG23pj6BU0evECZMddiH26robWkli2WtTIZFUnfemCSyVcMrjsp9R7xP7uvX36UuZOX3iPgFyRPen8vypQTDcD0HWva04ohcPq/LgD8Wsiy5NF/ksOxyCuLnn3G68jsgyIH1q4V3FOng4MDyw7O4YQF2VqjaOrskmjqooZU4G4JyrW04Lm+8h1kWyJOzuHzizxjMl08kV8zXxRMbKU3rk5zVDk6bf+12Ek5Op7CMaZ4Ca894nYSxm+5JLvzBJAdbpbV1Q0LI/rIYciSrXS2FipamTPzUw1uNuHWDii2aJ/OC8+ONzPgEnPTUDYofwplBXJxhyU1Vinzo4DJDFwEoPUMyNMCvxulyPM3QwXHj0/mzaOBGoBx7YyIJ17VOe0VXvG+WdYuHoq+p/cm9uU7XEsS1KSM6XNfBxCO1gmceJfHh0Y5ELDZzMTUvEjk5ozoMxm',SIGSHA256=>'BRcb9ZwKXtN+TkUnEDD+MEEJjY4iLS6eP5CLXbye0m59xOLlssKRswrm7Y020ySAHgpD4YxCLM7lkrNSmkVj/FFjo2M/ztUcz9nfp5FUPut9nhB3HToUJZX38eDaCTZAyYh5v3lL2UGpleiRAD59lEcSqnz1DrDUUyQXFRtDzGxNbmsz8wpAJAkLjfCtW872ZsiRFoB2WZk9GwHBuTyCIIe1Nbx9yF4qqLVU7hIwTsHfQcRkhcrRLlRz6z1+4i0CR9NyYZ/Hi9SZUGENg7z/eo+AQWP20G4ASlb7jlMfMAi723fKi0NK+NWYdqkVaLUyrBZcCU9qnztGbw+qv0botWrFemqY5ou6lVm1BNTTnhgBMseFFgN0SgG92t4rt/ZQY1JRGAEe7Mbiu8nqrSdF5hofF12EG7UADoxSFrfVpsN+wXcWswP3J9uMMSGPWKsIL+SThVx/RZAigs4YNFuDAKjW5hGlWmhn47uMm1W730S+CfEhataLdx+oIMMdwtmE',SIGSHA512=>'JE2fRi/inFlPZkc1dOQ/B4sE4S+wUKaTZhGW7QZ3LSC9mWk066l+1a9tXYPoIaHprHU+MRbbmlUZrJNs2Rc8BcG6XUjEoxayroturrqMkxpkb9/gKp2A3NBf27nW2bo0MPd9okyQhZ5FosY0VHX1oRJMUBWmvTScIsw9GbQN/8+xNmSaHiioHWFzbnITdW8S0aCwXZnCtoc+A7awMNV5gfNFP1jKk8NfYNfWH4S5pXulX33fQM2sDYN71Yfl511Wtn+YUfudUNnfGLAG2ExWsrkKlOoKF+8zyqTbUmGS7XqTtz/5zsoiWkwOcBvoSptWBkFklcyKk3sursTWPSATyXLBwa3R03DrAnlhgzaz6KlrXtVlC2Ww6TIosMawbEyMGk8/lPDaqlA4p20PREZcSGorOw+D0V+tXjIil7RZz8+V8s6TvTtSHh2JPpoZMH/azeFrad4iqMQ6MkiE8/ej0oM14VX5mIKn/98M2UfXBT3tVLhTgLnVPJyJlaWauwtF',ENC=>'vFJ5b7Bxh/Zpi59tSghhJyoYH0yO5IiKwDhNeGVDWPw/567mRYF4Jv3xhEnO16gUQQeuDGnmkoh6yuKPxIHrRsGbYtaV6PBp+4v6b/HnI+UPf55Agvv/5U4Tw/+SPFM8ax11diMTcNlTIm7WZ2gStm7EnLZQXFdW5L7mIqrF8Wxl2Xy6XYNRtRU4c7PiBpSM2D1GeXUwcjNTh1dwZB3fbTjwhgL6rc499mFy+ysbt3TI1JqyGpLG3mfRy/yjSS+KBv70nV5LuShctBy21MbEOjl62CcmrzptFCYfxZsobb/liMgO/o/NstcwczbnY96wmYhP32+7JD6AFUPT5ScNPMT+3AmIpXPE+IJ9ps062Ygq6ONeuJn4tGifwQq4euBn9aJBqTio+qMcYbt1TS1JwtjqtWNqHX1GgPzAZCtwSfXrAgWRfOxFO/OAQAq41wb3qneevY85JKqCPSKAu/tZUBPm9WQh8GkES46gNGoZ2bjh/9bjufT+gOpae0K8zsTW',PRIDER=>'MIIG4wIBAAKCAYEAwTA4R+Shc18Ojf51s8BxfR9zvQLOKmlGMPZcKUN5KN5Q6qK6Mj3lROZE3epD1hhgOQpnhP5C9/kgUv8CKoraX4QN2V+vUMscblXVtffHWN5GJo44sEfiujMWeA9ag7PwsTu+2btJvZAzkaRtmxvMsqDY3o+ddK2IvY1CbxOE7xHL1xVqh83XC4IZUswka2FJocPLiYJGC9MXiSDNu+3w4AjOV7/me2h53BJUZIHis+luQKhx9v3Rlc6/7c3o7f+5jzZw8DBj03OFxwPqezpwhIAjfjkHJWHKQ7YlQcz1LAPpZK8+TUfOiUoMtTkCQWiSV3APnH5+bs5mxxhyF6diZo4GBsLYxZkgvcM6yLctWcd7oqoyXKZZjnD5vtTuByOPtno0t9ZKatkX8HOhPAck39+9l4gcDGRvAYo9HYu8/LCxM/xO7LFZU9zNYs15gXE0wdIhLeOHNu0Qx5urmu0oWOraZwXW0b2HoNSXa3X6wz7tz7otsWbTC6joZB0rqOGfAgMBAAECggGARmteSI6Fb3mZ45Z6rxAaDkL1vFMWdY00Qcq7o2rt8kC/fBffCUtYlDnfpoirO5JdGM27GFZacOuFpdtAneNJYIHRTog7bpbrASkWoqL0LmevaIR1E4TQl5DhwtfN5a4ksWYW1mUXpxq2QYOPVHfYsNBC3TW6bnqHGpkwOy8BSOfSxs8OqvwURCSjOHQjXmTzIx0sxy4OfGbw8FJdzAAayn9LP986k4dszBR+YLibu3r+bmE4UZEJ4bKgcX2aR47sIYLpMTWoDfsVqz+n2mMSsq8ohPCZ4BkKO+V7cN1gT4LFgaNlV6wGLFhQ2gzHxOwy5XbQTvW1L7HMFVfKbIibxto/CfZLoSyFbIkchQlAv6bL85eDDWo6I/vVwKFuzCcONBw/JoLKyDoa8FnbgzbGj+WJ4BTYL2ZwWiR9MbB9Oxn91G9q9srdmyvJmgRNdYDNHtoOj/rr4f9JlUzRf6Sdz556S7zJ889+AqZoa39C6iy8kVV+Jlwqy1J5QSnGj6RpAoHBAOkEAp/dNjbMY50CK0060h2DWbSNWDfTSu2huSqhBTotar4IHt8PT8sSKqK2Odu2jjyXL//Q/GA+jTQqMBIHEW/7uvR6UhplhP25YHQqYiNtkQrFkknTSNQdwZ6cvdqDND5IpDzGj06T519pTNo1heI0dEViauAAgM9raemFd9M/BvkMJyVhFc3IdoGSk0c7gnHS3xuSGCFdlktQDPQL8ElFmfHBssrZJGcpU74ObN1BE8O+86PJW5DhJBOC/ucndQKBwQDUPoLjPD4bq7wGLdJRg0yC79oAGNn9LoptoFnkAOujUbWyJERhHxwpFgSIItph2/uUD8D0j7chS0d057k3EhDSVDRfSVsG+UjGFmEpCKd/AxvEFPLV9As/5HWJG6Kz/tEqANA+r9QGhH0bkjv7ARXsUYTdRLD3mHQOgxfZdwxx/ZDp9rAhLoDc8OR8dKeak/ii16V/D6t+EvMcoJdDcVC0txhgh4RZQ1XW1CgggA7SGGYK+S99EjqmKCG4rY1/lkMCgcARLwOGiIiz99SswnkxA9J07LfT0cycqU9QQOnn0+IPzUOe6fhk2Ls4rYlJYIjZxBevLjMS+XVzH4nIPAg5fB30FStPVinx2mS5VU9gobOFC1Jz6egE27j2M4+Qw9xYXe6fXToHZVkyIUQhzCEnwmSyLs4YQ86/4Cmfojs4Rmh0wqQf/55vaj5yY4MhwQ5tZV0UScm8PcTbyQwJV8jswmig7qoQowktXmAJ34lWbbfnhSIRAGb1QCcpgwDnE3T61PUCgcBGNH87BvxMTtwc9x8wk0vFq+ziR1Yj5zcm1/mj76ICHc8KI/DyZ0X7WSsalNzDre5jpWpf+wHKY4o5Y0TisHkb+XpxYmRXxDGMRG7TEefFnZOboopItzbZZYpzVc7V1x381NQNSD/MABsZ+Z8ZgdxslPJr9oLLA4SwIDDNYBGfyw4aNd1AvI8nhg8uE7A082k1BDvb8aT6SO5ds8kVJ/BYNpA7rdfbZuiH7Rlw1qsQV725N3+70UHRIEk3O0EoyN0CgcEA0prEF6kjCMQJBF7FzhF1i/HMRYw2ab6miuo+JLPFNu73aQyOIjqyjaRz8ZtjSEAl44D8reFgBfmshiSLV2YMfLICJLv7EcAg8efITt5jSus47Son8tB6IpuSwjgcJZJcB61pXbiJnZpC13vlXkpv1GL9OchjipCWjAKyxTLQ9aVmp857ZUXH9Z4LF3NdVcJgKHX7MEbKZD4Z19yu6KZgCaSQJ88WuqdOH7NORlv2D0snusm1VVqAXUO6IB8/RS/Y',PUBDER=>'MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAwTA4R+Shc18Ojf51s8BxfR9zvQLOKmlGMPZcKUN5KN5Q6qK6Mj3lROZE3epD1hhgOQpnhP5C9/kgUv8CKoraX4QN2V+vUMscblXVtffHWN5GJo44sEfiujMWeA9ag7PwsTu+2btJvZAzkaRtmxvMsqDY3o+ddK2IvY1CbxOE7xHL1xVqh83XC4IZUswka2FJocPLiYJGC9MXiSDNu+3w4AjOV7/me2h53BJUZIHis+luQKhx9v3Rlc6/7c3o7f+5jzZw8DBj03OFxwPqezpwhIAjfjkHJWHKQ7YlQcz1LAPpZK8+TUfOiUoMtTkCQWiSV3APnH5+bs5mxxhyF6diZo4GBsLYxZkgvcM6yLctWcd7oqoyXKZZjnD5vtTuByOPtno0t9ZKatkX8HOhPAck39+9l4gcDGRvAYo9HYu8/LCxM/xO7LFZU9zNYs15gXE0wdIhLeOHNu0Qx5urmu0oWOraZwXW0b2HoNSXa3X6wz7tz7otsWbTC6joZB0rqOGfAgMBAAE='}, + {ID=>'key-4096-1',SIZE=>4096,PRI=>'0EEC3B4C4E7B954BE456C4D61D9F5B161991EDAA62ED6D101F903DC834F3FF6702C6AE015BD67B8EC423B69DD2DEA2CC57CAD50ED37AD756BE2235704F5FD5954687C00F85DB70A77FDE4966C82AAB569A8E646925AA2E3FE0C5370016D98EFEE0D6355B0E63D7FBD37F353D8CEC11193FE96D5F1CB35182DBFD2BBEE8C820382AFAF0D72912F1B8CDA6CCD3FC04E02304CAF8A007C9997F8819F020EFE3AB536534900905D0CD3CA3E0ED84241377D390390BCCC4CA25E1A18B8B6C2665183C388D08D05F60A7AB91481E4E8CA48C22BAEC25534FA2B2AA380F49CCE1B389688D5E2C7FB747EEEBDFADFBA9D1CE9BABD96EC07056DCCF72D4569649DC442BD7B31B964A612F5C64926D1834A428DF1613738CFA552411B06FDB5515C4D0491CB95CA60558E37F0C6F7FFB9B1712F9557DFEF310C78A5E1838514A138A0B25BB3EB52E833F4D38CF69991BC06C3F64AC6C077213C3D7BEFD8F8A3483466FA340FCA5CE0523C155583A62CB80AE41227D072F6B6BE575C342681C35222A9C6186ED047316193ADAFDEBF9BA0960399B4A8DC67B76AF0CA428DB00586F9DCED8C59A4FE6C103575B98CFE86E2ED172F2BA03E177DAA606228B02C08291C03DEFBB7EBC80479D996BF2761C35FFAE68FFE6207E4E7C33017B25E9A63DCCB40BFD9A4757ADA2B4A648BB29E2E7F2248B83BFB94B2B738626C4C7EAA0C89289C8A061',PUB=>'D2F4DB95A2573C457257888D7FBFFBE237A9D087361AF26417E00BF3C820EE465C33498E20AE763D634FE3CFEE22541952C8D3B1D6910D8FA7423D8B3308012A6A4CC9D820697F9C30E9C2E00F199841B4BC21FD76CBDE19204F0FF9B257597B055C72ED6E99A4899460C9437CE2F496411628ABF5882F2AEEFE706EB0A6994E96CFD697300C14F83C0EB70ADEB1D12AE6EDF7549EAE90F5B4FB5FCCC1BECC0AA1AE90527D8F850CA6D9DD617EFC04CE4E011B0C2E5332CA4B6290E165E4FA1BDFD221DF5200D4B8443C0E81282679E2CAB4B18EBDD8CF74FEFA94A96332C0D54D7563F1305A762901A610C6A7024A59F58A985B67E08AB15ADC243FC1294F844C37E10A5411AE8A2556778D93F3458F625B9642FA758DC7C44FFA1B412DB8CB19CF7803CF751DE47B4E7445F2A1386C4826AADAF6B34789995059D62B11B3303FD0928E80542BCB567CA88F838C22E77E1103D684E40F4E413A09BA85BACE459476B493DBF0879F626460FF6C465D9F192F3747C8BB96AE30980EB6F118FC2F106BD5666F85944097202C003DEC82F4D198EB3236134FE0D7F063EAF94F2F539585F4313318E5C340167E44C7A76FFAA0ED5BB737D6F86AD29E883E3134996DA5798452279685CD58288C52143150C802811FF6647889122E95A10D4E90976D8888C59C23BB88B18EB1225A2D09E61B13E7BF736B26A22EA794EB9FC4A1142F',SIGSHA1=>'W8K38ZGrWFFlBB6Btk/hIuDwaUKGGgNuHxClV+mJuElAErXPyCfav/ypw5jzjMgZn2X/6pAepJEN4PmEP4Jv3V/p0TmtGp5edgY9krTk5TbRxKSN1lMYV5qGO5W4wRDUTfKDdh40BALPBIPTR/MPR6CZpKAN0tIIzERb1qkMcPUUw3R5JpgE7SXqf576TD0YfGCShy8QQ5Mj6QtZMSCp3uYsc71Xt2qXXwWeRpKyMvyE3XtAUgJIFJuGTOqknsQx/l99cHtwEC+S57YiNBxuzkjSJqCDKytfdVJzgfk4CCd8Io12KaNNQ1wS8UafLsbg5TWm/inpQa+pPKhJdPdSQyxrhbcXJtPGv0jaZq/6KTm9AN245IrJ2sCPLRII2m8ryB2BcSdIb0bSAtHsLdUvr2NIPUQpM+ZDmOZ69FHR8W6N5VAuNkvNHK5bt1cXV9RIIlATIiV8oicTnzrzx7+yaWRzxJUUbjLO1/EaQN8Jcu1gPVf2T+PdpUJTuSR9XXbbE9tQ29D5WUDoZuDkRbume9jB6tdokR3jmkYkHOziJYlj35EyLjhO/HFRwblwJd9rtQxgcMos150W7PTLgPqzQn0KabBGocFxxrhA+Rg8iD8UJf5dIplbP7kx3VK7hhGcD90yWOP71zsRkgnJAeuHEplU2uE2/uf31jklHAmxT2I=',SIGSHA256=>'e7DiidRieshIZnUF/NL9cVVGA1TxdzXGrhyC6GTKTUuRaNUctdyKn+WwY3PJRmhGiqzxPUNuPSGbX9/gSt7IQ64huFOhANgYaDkq3vDrtHLhsSPXHJ7O91gv5HZSOkxbcEQR9ojLDMe0wZlHUcMi26q/Aiw9sJpsh2yj300zFHg6KlGo1PJXBbYt7g+gJCUr8kWjSUL7ogD1+r8OCRsCQuHIVKJTRWVtYBR8bi3h7+LMOyzxpFgBWkbJuxQx2JLXG3Exvh+Jhe+0oAITbvIwRDsFDgU3TXRV9ZQGefT8AyY4PcIn9hO48ifzP0kai/ycLoj03XADCrbKGmOx55/0j09N8nZ9KkqsaTUqNB9mL9MR4Phn/UfBDXBXapoS3NbI111JZQXvQTm51DlKQ0FcNDj3f67BJg0RHGMPsvM2Nsmze9NMPdu+YGw2X6R91VFgi9PxEtENz4pB1pL5nrGuh3MnEo2XtKMxcvOhVK/3VVNolM4KbC0PEO7zjjbLURvIaFermqN1E2LOYy9jEBFTuBRymq6uwTAPCrwa/BkaZrA8lgaLCqzqDfMu9oZ//6q3FRxLL4G+0OOqSZL1sehQCsf4CyBf8XJRE9+4K1bETUlQLE0UNDQfxER6ba9k6aNap/o7cmQEgNgLKjU1KF8vtV8jSEVvQ8v/S3bGtHHhh1M=',SIGSHA512=>'gZbJf94FaaOwF1ww2p8FOxe/ki+WY0AEzZND91IHWZW4nw++y0EfkNCGvdi5V8xeFeCYGGglU099S8Y7vISVsHBM5x6ZdltNicYgZchALus+IY3N5VptEUlqjI1R6h8niSPcSzS8cycAZGcQ7cCdamx3qTuO2BxPvY8zgbJpXRdwyNbBA+5VbYvaTgKfMRppjZ9zvTiru20eJezdR9FOwueoSLfihj7NCdWmVY+hzHjDkJpeQSw1cNL9Z7wkDMDd7TlGPYIiCzZsjefvMdbv1/o2ymCpvkixAdljxSnVskqKMYYXGFj9Uw3LJdr9IrCjJ6eUiQ9CQeBfJFPUmlWAEXFicirWv7BRih1j0STq4Kxar7hICmlSLX17gP90grU+cVTy7avWq7Pq2+iF/kgxwR8MLHFM8sGuPgMycwE4ydjPIRax91afDZHzXhHHEMJ+270KbohPS9aux8NVucYNdeWx4EzqvUnARXgIH7IkbkrZkN5s6DJsJFOIVx4SsF/Z1MAmfp1o3iEO4d4G2XIy0cVAQ3YcR1cyOaeTxEcwQ+GV4+sR80PAz67IazlPikq5k7Mbx2D0mEmM4X5msizGGEDXTZfgGiap2TOAieA3N/CiWykqi3fYqnKm+DfUH1Zt8YOFYYH2gHSUsSEd5exK5HDT2GyidifdARB+E5JsiYc=',ENC=>'P22VZFyf3iviOmd1fUiwaCZMxKK008+clrRw05t3qTNEOdY1jBO3NTDjxNXxgUTx4Ov+hVj+0M0nslOdchR9VmQKJjJ73gMz89RAy4Ns0aS5lncik3+CHm+xzredcxFe7Gj7uxy1Ta4+EUM4vCzCRzDriXiWClgvCvM/vZRBMBM/2HslhLuuQ4jxqb0vJBugMawXsaV3ATNsstVKLiJsemIfRsXYbJkrsm7kC9XNMwRYxK3OUAteX62XPtprOjnNBx5F03cqgyJJ53OwOSqj8d6wJQBTgWWysiOHtn9NApdw6tFZwb7RKOYK0KEPA3yNn/qZnYG+X6m9mtnbgRQQPXeu3knJmzkoYtETPv+41t7WekX6vv/tAVYE+b1hGXow/+YLg0lp01T3rObHvFxNsRFCuzWr0pxM3S467KshF3UubrGCKAJXvzoTwC8/jsf+5lvU/6O+vrJ5+uBRS/V/MewrvUPJr8hABKGtbQFY5ynqIaZ62vho6cSx3LFGsEXNklghvzAp4SyXzjnzZzRi40wrvQJ8hp2zxbR7HIG888I9QnZd7bKoDkMQGMcSZdfxwdz8LKmiw6gBf9WjB5btbY8jeIdsJl3alt/wz9XZ+YtJ6khOytF6aWwy1rduKCqOdvum40YbBbvfzxMETVhBfzjp2b7yjEEwjRtClXJiV/Y=',PRIDER=>'MIIJKQIBAAKCAgEA0vTblaJXPEVyV4iNf7/74jep0Ic2GvJkF+AL88gg7kZcM0mOIK52PWNP48/uIlQZUsjTsdaRDY+nQj2LMwgBKmpMydggaX+cMOnC4A8ZmEG0vCH9dsveGSBPD/myV1l7BVxy7W6ZpImUYMlDfOL0lkEWKKv1iC8q7v5wbrCmmU6Wz9aXMAwU+DwOtwresdEq5u33VJ6ukPW0+1/Mwb7MCqGukFJ9j4UMptndYX78BM5OARsMLlMyyktikOFl5Pob39Ih31IA1LhEPA6BKCZ54sq0sY692M90/vqUqWMywNVNdWPxMFp2KQGmEManAkpZ9YqYW2fgirFa3CQ/wSlPhEw34QpUEa6KJVZ3jZPzRY9iW5ZC+nWNx8RP+htBLbjLGc94A891HeR7TnRF8qE4bEgmqtr2s0eJmVBZ1isRszA/0JKOgFQry1Z8qI+DjCLnfhED1oTkD05BOgm6hbrORZR2tJPb8IefYmRg/2xGXZ8ZLzdHyLuWrjCYDrbxGPwvEGvVZm+FlECXICwAPeyC9NGY6zI2E0/g1/Bj6vlPL1OVhfQxMxjlw0AWfkTHp2/6oO1btzfW+GrSnog+MTSZbaV5hFInloXNWCiMUhQxUMgCgR/2ZHiJEi6VoQ1OkJdtiIjFnCO7iLGOsSJaLQnmGxPnv3NrJqIup5Trn8ShFC8CAwEAAQKCAgAO7DtMTnuVS+RWxNYdn1sWGZHtqmLtbRAfkD3INPP/ZwLGrgFb1nuOxCO2ndLeosxXytUO03rXVr4iNXBPX9WVRofAD4XbcKd/3klmyCqrVpqOZGklqi4/4MU3ABbZjv7g1jVbDmPX+9N/NT2M7BEZP+ltXxyzUYLb/Su+6MggOCr68NcpEvG4zabM0/wE4CMEyvigB8mZf4gZ8CDv46tTZTSQCQXQzTyj4O2EJBN305A5C8zEyiXhoYuLbCZlGDw4jQjQX2Cnq5FIHk6MpIwiuuwlU0+isqo4D0nM4bOJaI1eLH+3R+7r3637qdHOm6vZbsBwVtzPctRWlkncRCvXsxuWSmEvXGSSbRg0pCjfFhNzjPpVJBGwb9tVFcTQSRy5XKYFWON/DG9/+5sXEvlVff7zEMeKXhg4UUoTigsluz61LoM/TTjPaZkbwGw/ZKxsB3ITw9e+/Y+KNINGb6NA/KXOBSPBVVg6YsuArkEifQcva2vldcNCaBw1IiqcYYbtBHMWGTra/ev5uglgOZtKjcZ7dq8MpCjbAFhvnc7YxZpP5sEDV1uYz+huLtFy8roD4XfapgYiiwLAgpHAPe+7fryAR52Za/J2HDX/rmj/5iB+TnwzAXsl6aY9zLQL/ZpHV62itKZIuyni5/Iki4O/uUsrc4YmxMfqoMiSicigYQKCAQEA6aZp87HqbycRZ2lKemt5Yt4IvnfwDEf8yobQEl3BWFpzGuajrFDg/G5ddZH3jvM0AWAyTYkn12ZpqLEYJg4SbSZZwypU81fkBSqQtfq4XbJLso2DIo44CCp+gu5dsMwuYmi5HMc1spKRpuZIPkITZVYx/FU1ZH22anl2px5bBIHOBPItUnT8y7V7dlKECU+mnJlR9Qfwc/JZq6CVDBw9VM1SQphkXZReye3rlkPK1TfE9qpr0pnflU01N1JXJp+MKi+fQQ3gTw6fZ6IvS4gxceMnpTR1WvJT+xO7UvAfDRiM2qOV067Uiui3DzfLND3Fi3yUD+x5y83Etxv3Cum69QKCAQEA5yK6IJobAxcpC9h+DfYO8BOVvvNYP8/QohvxNS4wMOUjpc2QyoWmRR8Hy4KTleRy2MCrXq2loenYUu4Nh6B3GsO9NBbC4ET1iriByaGTcYEkBOO0dyACtwonwT+8FrnUDa0W6Z6krvjzeOb5ydubY9t7bgI1mHA0xYiMOVzfUBEtc+nt/zF9khg4Xgnt2bqyNPDzvES0BV/Z3hW53H86Mr1LtfbJaP0BwWj0WijC+QYVa8YNAOp04LbqPLJEiTqFBHSUN98fC+aWXp3wLgHJ53CcBVT1NRqkUG8nKrHl2mLYrE/WCN8gTWDyrz0U4HbmJtnKDXvl4ihfoAJHL+7kEwKCAQBrJbuU29QsYPgkOi7DcSHbawMLhaj5mNGedrBYm9IcmG4MuhP446YpXNtTHTsvvOvubZTj5a/1oat2hrASU4WztFCZpYILjhStIdX2/iEqJqd8HFU0tY+QfxxBItqoRxpGWsv5HInNeFV++j/K/TYz1JFbrB+uE9Bhh44YGV2X9Ybq0bxjAe8j4/fYTQLr2jEHw2/INHnaUhs5D40KXrDpgLbmf0gXegD2DTtqT3Bm0wpqK8ECdToJF7z9v67jsWrvtaMMjDZ/Sq9jMQcLVkuGdKsroaDnshU9INFYuXEj6kw9v6Lnzlb91LaOLgHr1SAQVXL40nMQOS6q4hIqWQE5AoIBAQDNK99q10EJIkL2V+u1eulRpSD1CtAYfOGnNQSNf32ZuZ1GLc7MZ4zrqJrjxPo7QTnNPGIiviPcMVcsblImRYPUh1JpbZb5O113EUdsc3gNdmRBzttAL3MZhfM6MNhGmBgrN62yHXf0NdryRJ4Q2Fb8cjUDtwRaV6gQfKB0vwMf8M+XKF1yfT0JNWS73TZ8YqSUKBtD0Py4FJix8jk1CN7hcXVGhlXNU2F+jSry6WIBaawUKg8a9ARiARy2WkxKQF8ZUF7NpcrKZpquTKaKQF44ipaEiSDNTePz3mc3GAmALORHOOs2ntHuvhNPCPqCMikk7YjVJVkvw0T3JW6JlxZvAoIBAQDCSUWfPsjnPiYpdlGsVAoBVKgl5Pq1ksCiKHcURdl7dHTcYuKnrDrOj6rQ3Qg7VHB97VCvrScr4HMIRKHdt6fb0dPr5v2XWW4uONkohI7U+b9sIcnOKUf4Ne1D49pl36jgj3saP9leHU6KW3sPpPdo1UcxfzYtxiNR2drnLbZ5azJ7+obxEkqJK4NIbNPeBDFh+s75Uj9nUdvOwoqLihX4ze+abTIAkhc+NZgm4F9H51vDj3XhFXZKydWPIl9iKTmx31iU3Nylaj0LCZCvELaIivPHGM/fcp0BrA2IkArJMIieiQC1zl4YStnsGg1Q348jZnDfEoV0gmtYdODipINd',PUBDER=>'MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0vTblaJXPEVyV4iNf7/74jep0Ic2GvJkF+AL88gg7kZcM0mOIK52PWNP48/uIlQZUsjTsdaRDY+nQj2LMwgBKmpMydggaX+cMOnC4A8ZmEG0vCH9dsveGSBPD/myV1l7BVxy7W6ZpImUYMlDfOL0lkEWKKv1iC8q7v5wbrCmmU6Wz9aXMAwU+DwOtwresdEq5u33VJ6ukPW0+1/Mwb7MCqGukFJ9j4UMptndYX78BM5OARsMLlMyyktikOFl5Pob39Ih31IA1LhEPA6BKCZ54sq0sY692M90/vqUqWMywNVNdWPxMFp2KQGmEManAkpZ9YqYW2fgirFa3CQ/wSlPhEw34QpUEa6KJVZ3jZPzRY9iW5ZC+nWNx8RP+htBLbjLGc94A891HeR7TnRF8qE4bEgmqtr2s0eJmVBZ1isRszA/0JKOgFQry1Z8qI+DjCLnfhED1oTkD05BOgm6hbrORZR2tJPb8IefYmRg/2xGXZ8ZLzdHyLuWrjCYDrbxGPwvEGvVZm+FlECXICwAPeyC9NGY6zI2E0/g1/Bj6vlPL1OVhfQxMxjlw0AWfkTHp2/6oO1btzfW+GrSnog+MTSZbaV5hFInloXNWCiMUhQxUMgCgR/2ZHiJEi6VoQ1OkJdtiIjFnCO7iLGOsSJaLQnmGxPnv3NrJqIup5Trn8ShFC8CAwEAAQ=='}, + {ID=>'key-512-2',SIZE=>512,PRI=>'789F2924364C2D28482AD386B9061370FAD795C0E446796E5BF321BE61D668019D13900FC8355D8C61965A5267DA4F50D3FB790F64038C002C1DB1501FCD6E81',PUB=>'AA1000B937AB6D662256A382269F1318117E842D58D6FDC1F3A0BBC8C551A0C0B1D256F68DE56F54BCC623B875CE0E3E0EF35CD6E13E83B93B0605D0379DA303',SIGSHA1=>'ibYmYqh21vATqib8SSBsHJR6sMBn5Cl4n07PMVK74ahVuIvql2bQK4DuGIgoccdlKjdmCoAYNcozOwMP1bx0Xg==',SIGSHA256=>'BtACjhTzcNBa8BNg+jCajWXJ/knWvgyR86dNft8UOVh1OUNrKCaNewHiLG9j3xOWy9HI6V7RNTxDsFXbEbVeJw==',SIGSHA512=>'',ENC=>'K+5L09f3pg+I9SlOJjuXAtaBu9qjhy66ycPWwT0lc68kOOVXu/NfIW2iyQYz4VNz5QSmVwSHGOGMKeTYH3KFqg==',PRIDER=>'MIIBPAIBAAJBAKoQALk3q21mIlajgiafExgRfoQtWNb9wfOgu8jFUaDAsdJW9o3lb1S8xiO4dc4OPg7zXNbhPoO5OwYF0DedowMCAwEAAQJAeJ8pJDZMLShIKtOGuQYTcPrXlcDkRnluW/MhvmHWaAGdE5APyDVdjGGWWlJn2k9Q0/t5D2QDjAAsHbFQH81ugQIhANSrAlK+4beidJa6qQC6TZInhqL9RpDnCejH/gF5P0MRAiEAzLalRRqn9O16mD9Po1s4NMCm4IRvEQHYDWnFu3vrnNMCIQDPd1y22Fxexu8yNDq26QjPshuYWblDlwCFxMS5L01V4QIhALWwbWK109fIZgR2PIJp1arMSc/++myHzG+rLvnFdEpNAiEAoMhrIdV2AMHbElFURodgoryK4oM6rCL3v72BRaoBSpc=',PUBDER=>'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoQALk3q21mIlajgiafExgRfoQtWNb9wfOgu8jFUaDAsdJW9o3lb1S8xiO4dc4OPg7zXNbhPoO5OwYF0DedowMCAwEAAQ=='}, + {ID=>'key-1024-2',SIZE=>1024,PRI=>'18CC62F2E1C55DCF866B1562C7095A74254C57641BE1A96189BED388DC590DFAC537F974A853168ACBB027CF23B944B0BE9AA79393E46F6EE8646C4BC9A48A215E65DA88DDEFAF62AAFED173BAFB83FE3B3781A235F43E68279B5F3727A5C554390915C1CD43D4E560C476C50BCC08D6666DCBC603ED6823DB3CE09A319AB371',PUB=>'A9A9FDE558F97E9EE9EA223456CE84A66FFDC604BCD5683BBBEA034089BD32288C1CEF429EAFDFDF8FD5555082A4B0F9614A4622089B1838DDCCF930D33E8108683CDD02436ECE7D3E99404E14187F3DC2D751503F9D90FE2F15BCC4AF43C34F48626AEAB25D66A2D771344E8FD6D3FBFD035BA8D2DEF9D145B753611FDA5339',SIGSHA1=>'bH2k4H+NffHp0STfAQJO3c/Awr7mrE5mz7yiw4PYEvu6A270aA8OJbSxq8t0Im5ZyclN6k4xD8+T5+tO522WEbHvDhW+1AfrLKf47YiPJb8pvjnFmiE6VE6mFP0iv4u3JB6Eive4hhIMdoZ10UcY0mJU9jRa44Ajv0XbQWaDg0E=',SIGSHA256=>'VfLiyb3unwX5mBlrAPmeR9V9kGFx7Ft6JwKX6HwnpxbGYb6C0CPTHbZOao9LxSuO4lkyAhtxUIGQ8hhL28xW+dWIuhy2Wx+vPFiogerY4YFzkPPytsjoArnCzVywO+7Djav9a+pmMZqTWNr/i4/NHq7F1svq32tuwOrRbzLOHnM=',SIGSHA512=>'FIivdhZjOVyTXJTODj1Ie1I3Oli86KUR7zxsPcR8VedTWvLbsNiO4kvOShMT753vJ6x0h1MAwTjZ7eyrc/EmQJkG6qDtiryJHEgoXxC5+qXyK4OUDPlQ6nBN6iSxAkTR2E2BSMgrfgpXQvtGCskpaI1Zru6qOZIwIwdRq8aOEx4=',ENC=>'K1dLGpiOcq5eJqNOqDvkwpaVnwzyqjIJIBLr9897vaEkVtMdw/upZvhGFuuWyWNtop3lSTNHYuvZDmntTCjjlEXnnFYUQUnMY5nE50yNqXlb7kmnmjYwaItf61cRQE5hbs0/jyJ13PiUZiqiCyXTuIy6BuJZaoJq55L3XHteS1c=',PRIDER=>'MIICXQIBAAKBgQCpqf3lWPl+nunqIjRWzoSmb/3GBLzVaDu76gNAib0yKIwc70Ker9/fj9VVUIKksPlhSkYiCJsYON3M+TDTPoEIaDzdAkNuzn0+mUBOFBh/PcLXUVA/nZD+LxW8xK9Dw09IYmrqsl1motdxNE6P1tP7/QNbqNLe+dFFt1NhH9pTOQIDAQABAoGAGMxi8uHFXc+GaxVixwladCVMV2Qb4alhib7TiNxZDfrFN/l0qFMWisuwJ88juUSwvpqnk5Pkb27oZGxLyaSKIV5l2ojd769iqv7Rc7r7g/47N4GiNfQ+aCebXzcnpcVUOQkVwc1D1OVgxHbFC8wI1mZty8YD7Wgj2zzgmjGas3ECQQDeWf5NYH0zlMFUIaQr6Q5FC478PpEwt7VNWecWYCwXjWHF7W5D58G0919ww+2vNCvyzzAULkGOCM4/roneCkYdAkEAw1bb2r5Qyppjae9fTjccr/AUmLDyiQ+UWmkLhJg9umcoxkRgowLNVP1kHcdWd5GjADrmSZSD3riHRN7VHRGGzQJBALhj0OvB9JHt7lUigM6ZOmgvqaetCyJndkZrI6P+pRHzAP3uY96UNqMn8VHGaTk9/qQhBTH3Gg37Z26QA2zLAFECQBOtilRM28KtLtqbHJS6hI9MtiZznNsl0KIS9vASjhVbEwZ2GO4S+DBZnl5JmHJPH4aEaHJ9HZOwLyBG+l0FSPkCQQCdcD3XJzzYFxZ8C5NVmOAa6wnzI+ma73m0fkAxR1/0sCCHGSUb8f9flK77cCwQOgha94pxqVijw8Y4M1sEVY+9',PUBDER=>'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCpqf3lWPl+nunqIjRWzoSmb/3GBLzVaDu76gNAib0yKIwc70Ker9/fj9VVUIKksPlhSkYiCJsYON3M+TDTPoEIaDzdAkNuzn0+mUBOFBh/PcLXUVA/nZD+LxW8xK9Dw09IYmrqsl1motdxNE6P1tP7/QNbqNLe+dFFt1NhH9pTOQIDAQAB'}, + {ID=>'key-1536-2',SIZE=>1536,PRI=>'A1011F8D52219AA702B569684D1EAB62F4100412D2FF4C548E65AEACEC31B0FD6E34B9083F0F065AE440139269198EE02A6F08138DD96E10F0F2DB1A2B5AF18165A16DFC5BD4881F4868A3A53C6616ACF9FD3C88202271CF3C7D97D97EADDFD30EC1668715AB1A98DE64641435EEC73CF91514D29505CF5C9A09FEA7EDA9698616941C04B58CFC01D5D84249DB23A5EB575D6BBCA51A89D3E1553923C5213C74029A56F75BF015AC198E2F34E0F61B7AAAD4162B4C5CA41487D0C548A05BE5E1',PUB=>'C0A60530AC3838B9BF7BB0F1A74D888ACB4F8CFF575FF638B2B42CE1BEBEDEA9577CB720F5FE91298908D79C396A0F7CF30A4691D10F4AECB85B70DA18BD55D0956DDAA2BC582FF41CADC6D1942DC80A194972CC40E2D33B503EE99DF3F4FFFE106799AAA54A0A0E64A9E12DBEB2F833A97B8F1577E9D09F30092CBA6AC69C8AFE3D36178907E7FCC58E1DCDD09F3E5E36EB34B71B59231915B8A56EFA0A186B80F05A837BF9994393DD1F29064A1534545CAD17D32100FE5F7056E69FE48997',SIGSHA1=>'gGCMUK24og7Yh1WZff6+2v6aNiqz+/4xLvrqoVlt+ClbXIvIaeIx7zSe1thiZHk6JpPQrt/iY7AaPkNLI5oe7bZJTAMPWXNJiItWxf5UHfPTnOjal736SUyt4lSbbEYZpWzLWfnWIl5ZoiX05r/vif9ax/tiZMo1NiSzfeFNVal4OhfJ5f1Cr402I0Pv7K7mEgQcv1+g1Ws5LzzkCrjA3dr+/X5xXo4fOQc1DC92m2L+TZj5P2qXSAQMM8dQPd3t',SIGSHA256=>'YtvZL6+shM4NMl3I0leTOyNe2PAHCesST8dEYbIEZOFEeBRsSaAl7q+skJTljC8VpTTOmdFQ8VFc+gbdgyAOjsK3K3hmKu48JCBjS5GVMVFfiSRnAXNvuV0yw4NAj0OHZGYAEOenQ0MrKdNMDsn8xpiNIDYo+CLzYxLqDlWe9cbdFGI/Ux5HDhNeakjx5pwAj4KGXTrD8Rvn0qsk86Kcv4looH+IwJBGYftx9CK5em5SV5KFuSem9RagMtpTxHzs',SIGSHA512=>'P/nGEs4oMvEJr0MDAKfqHXZw1UiDd+HBfeycr95WZBTv9k/egT236S8MopR1pgerC4Ymp0iXFCDF8yWGHDIN/KbDGxjO3uDeaorO20Xskl/TwRdm3GBNT9jsmVKf+QqOfQ9JUSvfi/FTPt1cmOkux/JakIwczr7EetIJ2ZdQGGG+WQhHAWI+yLHJf4ZVgBuYA6bIEjsTINlmD6ns6bOTuTlC5kGKgYtBa9dtdFeVlSGqD4obaRJWyA42ufrkM9uT',ENC=>'OZti7pHvJbHuCMk//MUuCFgfcJi7TwytEFw4SMHr+osnMeKGf2JFpHFHvVZMBcJyUrkRntSRsnl/AKWf0cF4txqZheWIJpP/ZAZ8LM3cLTRWNWDWr7VM7NSD1WDhI5+u9LQXm1OFMYrJgcyUI9bqeru2tsDeCGdf8ZEE+Y1pobP6Kdr4o3dClXOmcDe/o0x1r4dQwR1xmaV3JY85MeTzZr0z9zHn3kJ4Q6/Nku9k7D+RnJcHQjfqfvt4gEhuMcYO',PRIDER=>'MIIDfwIBAAKBwQDApgUwrDg4ub97sPGnTYiKy0+M/1df9jiytCzhvr7eqVd8tyD1/pEpiQjXnDlqD3zzCkaR0Q9K7LhbcNoYvVXQlW3aorxYL/QcrcbRlC3IChlJcsxA4tM7UD7pnfP0//4QZ5mqpUoKDmSp4S2+svgzqXuPFXfp0J8wCSy6asaciv49NheJB+f8xY4dzdCfPl426zS3G1kjGRW4pW76ChhrgPBag3v5mUOT3R8pBkoVNFRcrRfTIQD+X3BW5p/kiZcCAwEAAQKBwQChAR+NUiGapwK1aWhNHqti9BAEEtL/TFSOZa6s7DGw/W40uQg/DwZa5EATkmkZjuAqbwgTjdluEPDy2xorWvGBZaFt/FvUiB9IaKOlPGYWrPn9PIggInHPPH2X2X6t39MOwWaHFasamN5kZBQ17sc8+RUU0pUFz1yaCf6n7alphhaUHAS1jPwB1dhCSdsjpetXXWu8pRqJ0+FVOSPFITx0AppW91vwFawZji804PYbeqrUFitMXKQUh9DFSKBb5eECYQDgdVdXXLPlsuAFxJmRrZRlvflwg3GtNO33rDRRu9UBiwDyYGi95ir2AoGwXRovVYLEmv7LZzlH3xljKjGmRriD+vsiBv6R6QH96zI449JhB7sGKDPpAbw68BxmKMGTefMCYQDbuFpA557VkvI6sZ40v0HCvQo3EDYrr9D1egBiC3/1TW0s+/e8mOqEvlPTYMIwkEzsX7arEZaF2cgXz71J3lOPNZL8dxeI7AG5kX1ZDdURZ+2kg0kL3j4yHSK1o1mrFs0CYQCKtll8ptCSMmIZjm7tRV1BJw8hBkpZJS2u8t/+ZtrzMikqoIP6X2TLVa86A79r4yeGQtcVcrxGe0xgKTI3tNrQzWknlTT7jQjrF8+YsspPpoxg+LVj2OuvbLXQOH2wmxsCYQDJ5PApy6tLnKcv/53b4hJPGt2UEzVzly5vIhfP/7kocmjreOv/RJPaPflQtgw6C55jZN+4+YRSofcWyjCo+73UTeouSlA55IMBPQrtFaS/Rbw7+tbYLPMBoXwPY3Y1m9ECYQC4ooeHvm1nQik3Z9q6xYG4j0hUDKtBrjG0iw1PNRhedSxx6fWAo4Shqs4KSovgp4GNsRId53BmhCI5Y8te5MEPE7vjOC0gQoXb1AKg9rhhhDV24WvLeaRqmTh2C+KQmNY=',PUBDER=>'MIHfMA0GCSqGSIb3DQEBAQUAA4HNADCByQKBwQDApgUwrDg4ub97sPGnTYiKy0+M/1df9jiytCzhvr7eqVd8tyD1/pEpiQjXnDlqD3zzCkaR0Q9K7LhbcNoYvVXQlW3aorxYL/QcrcbRlC3IChlJcsxA4tM7UD7pnfP0//4QZ5mqpUoKDmSp4S2+svgzqXuPFXfp0J8wCSy6asaciv49NheJB+f8xY4dzdCfPl426zS3G1kjGRW4pW76ChhrgPBag3v5mUOT3R8pBkoVNFRcrRfTIQD+X3BW5p/kiZcCAwEAAQ=='}, + {ID=>'key-2048-2',SIZE=>2048,PRI=>'B8BDB1741EEE884CA03C44930982108B007CBD28FAC7F6210DE0C90B51CF23AD817C7733C67D24832B83F646A88E19078F767977DB9191C933114E53B607E932CFB1A43F524E28201EEB5ADBFFDA3D80B63B31D97B5984644AC373BE6827EC011FC450000569492008C23B686B4B32F8A88F6765FF27A9E3E572BD7D78F72D3B604B608F89DCDC9F4D0563D59F85E1F09666544BF71461EC558A87011DCC656A5CB973C1E59E33EDD030BB77F4645CD3F83E06EEFC1D395F4F74703B71324565A81C6ECCE33DDF5BBADDF20866B1EC5C93C1DB13AECCDEEE694EBEB8C5E3D8557660415CEF73506579D6CDC390E25C1BF19034A373075B2C55DF460D5B5625E1',PUB=>'CBFA97A6C6712B31E9703E72DABDA41AA42AD7EA055A250FB2FEE8928CA5C780C5D16C4A72EF8995B1BDEEE5C14222145BFA72ECAEB2C08ADD1C3F4D26D9792BE0119D26B08B5EEDEEE6B30094BCDC983F0E185862E684969204B876F373618775DEE8F3F6DCB6B3E032880660A90F7DD53739133AC4549577910C822CFA74547354BB3F699DA2F7D5EB91799FFA35FB0A1018492A519B1099169C177CF496181DABB987605DBBF779EF90E4F1A9E115342AEC46B0CCB0B2ADCA1AADFC4193286B39EE1C9F6E7F17C2987DD69CAD602C7E2E48D2FA32EEB0E84F5EC51287553244411CF4CE94063F69945F4A0DA355E5AA6C7039181E8B743FED943AFC6BBDF7',SIGSHA1=>'esT5L4F3vT6O7VZLHRtUQ+OwNk4lSQp8OWODOFuBxD5B95d1A76qJAjhSFEo3J7e+YhXK4cJnyHRW+/KjioBxcYAQFfqbQtgVXUxAr+cEvK0reu5YG6hKEj2pYA/BqnWSjthcUZJNcgaB9SAg+Xd4r59Ndhi2WnhED7yurGiwpTKe1Vk6ZYizjhroA78eahZoQtwFOpP8DkEigF70gZCx/RP3le3vykAe9NPl0935UL7tzQKIQpaXNHwAATD6xMGEnb2shBaNBd7Ox2DrzburKExaSl/owaGVgAbzG+lYYbDqqdCl6EcWDSgcH+AWpDlnMkKds2AxoXkw7B25pTHKw==',SIGSHA256=>'PL/Omq1oZFNqOVzrxsrYKYyQgNwNtnZtGR32o+nnZxN5wvvIrHADRoQlMBgydqOnCr/gtukIZMAYQJp7ip49juCLRjNiS7jaP/B5ahoASlvXWyioueDtOih6N7PGGk68xiGic8cIOzeizIsEFqoVWHqCB79Xm5AqWv91DLD35ZuI4r5zkapc+2enXNo/820UTZvyOW6W3q+Db4Lvt+GfUVPaltlkpYApjsCElicB8QNKwKi9F005zdj49U7b9wVyzrKufFwa1aPlUlyGgFrOKjGlIkidH81CNovmBTvnEhDdypIkMd07ncTbQrPQgaZ2Nm2B7jFYfr92zMBejg/tlQ==',SIGSHA512=>'liR5dmgVey+thtyQWDv/SXGxwcCdRctd/4NaJrDORoSGxGRQqquUu5iWQCo/68/4Uk8PXIXIvObUUsfXIE5ZtpvPIUH8oCcp18/mz0EGJ7hZRXKPkzvmjavhYPEGwuF05+ETNO0YsWnKE5Z5geMk9QARBLJfD+f+gXXDJwo5jiMa/9YCVDMxeixd24PhM9645AOkaKFErdeCRN/tiY8rgX/5l+mNEttYtbgVhps/9E6kiX236Db3S8DHMNUwAZYYl6gWg5Bqi5Cll/1LVMSI+9vm4Dbs5m3SuS9pg0FhhlbLNr59n9y5cVcm3F4SW8aIh99viFLKT5WSvR3WWeBbWQ==',ENC=>'COyyr9NjdqgyfSe+vEj9jSwa02gwRT/X1jUO0xpwZ0RmGmXTO/EJgo6TsjrGIjtOjQhRm7xU8+SVTcL9Mho1eF50CYaoGiWd3We4WJaH8ERggZJokRnSoC681yJpEpmpR2f2SCufW0SmmYkzDiTO0jMJSrRqgwmR/J1dyjyLcHSWCqaQXfWjOK7EBzH42E7mzDQy2mbaxLBFVLzd0usCdKKAnxBX9Ao2mrdaImsEmh1r2WogBKEPwfwCH017cYVuZi066t/KkYxorKbM4mPqdi5rAeiuTLgt/IqSjF/bdhr4OjJy+tKqVQu2nol6lIkNFZtt2+sPefTmji4Y7+MTHg==',PRIDER=>'MIIEpAIBAAKCAQEAy/qXpsZxKzHpcD5y2r2kGqQq1+oFWiUPsv7okoylx4DF0WxKcu+JlbG97uXBQiIUW/py7K6ywIrdHD9NJtl5K+ARnSawi17t7uazAJS83Jg/DhhYYuaElpIEuHbzc2GHdd7o8/bctrPgMogGYKkPfdU3ORM6xFSVd5EMgiz6dFRzVLs/aZ2i99XrkXmf+jX7ChAYSSpRmxCZFpwXfPSWGB2ruYdgXbv3ee+Q5PGp4RU0KuxGsMywsq3KGq38QZMoaznuHJ9ufxfCmH3WnK1gLH4uSNL6Mu6w6E9exRKHVTJEQRz0zpQGP2mUX0oNo1XlqmxwORgei3Q/7ZQ6/Gu99wIDAQABAoIBAQC4vbF0Hu6ITKA8RJMJghCLAHy9KPrH9iEN4MkLUc8jrYF8dzPGfSSDK4P2RqiOGQePdnl325GRyTMRTlO2B+kyz7GkP1JOKCAe61rb/9o9gLY7Mdl7WYRkSsNzvmgn7AEfxFAABWlJIAjCO2hrSzL4qI9nZf8nqePlcr19ePctO2BLYI+J3NyfTQVj1Z+F4fCWZlRL9xRh7FWKhwEdzGVqXLlzweWeM+3QMLt39GRc0/g+Bu78HTlfT3RwO3EyRWWoHG7M4z3fW7rd8ghmsexck8HbE67M3u5pTr64xePYVXZgQVzvc1BledbNw5DiXBvxkDSjcwdbLFXfRg1bViXhAoGBAPZ6+DpTE1k0mAQV2EY1hgAYBlv+Iptx/Me2dRsiM4CwV71skVcmbClJaai+LGcUD45N9pu//SwzUOsVEX/0cJ/RXaZ+IWx/bLHY0ED5PvXJqxcKRdzY2miQRug1pAzoEVgQSYDixmxE2cea3pbVUqnyqV123wyXqIxwNtmd8Yl1AoGBANPbZaPuuKIS+QPBR7rqYFo1aT9Pllkmx6LVxeBwBOvVc3wx5VAjT2iXzIC5RhQ7n0VZBWoPhJqLBX3g0EliPW31KllZKmBSDlt+ZKsLd5SSv+ncGwmUMXVjLDne0mXwUrv25Tv8tXeBlQsQu0+4lOFuhv4twUu4H3i24fmpitA7AoGBAIts5B2aAMflSFiHQt/0RuimrnI7P7hOsn8GZxgCMMALAJbWYyC5S1XPgUVCzjtAzcvhri5MXBo0rQFN2ahXzZ2aAS+9CYsmSYYQ7zzRwRuoCG/wD7Ttth6P/ow8S6BBZg46qFmP7k4wZEDVCjSoVypragLEy0eEQoOutlhDT+5BAoGACNdcG4ZH4EOobravNqa3VKxr8v9wR9ItfKctNduW6PykcCdo6Xo/wx6qoyiYOxnt4KgBaNay8vwgQ4uRRa66347esJHfCdwCy2Cv9M9qsyGYrrrHyhOMKNj1rIiXATgRS9TW5jT6ob0fqjGNj5slY28IZS0lpvJNJe2D6rZfm6cCgYBfONBuQ+fITHAn71J5OLmp7uFQLTl1MmW0h9TYL3vyMyF26exjLBfBJTRYlo3Qy3lw+p37yOK2Ovu8k++ZyUdP/alhJdVwZ3xucITMoQOO+uoZzvF3yav8kBfWHDy7vGW1QaeVIaxrwpmyhpNBZojuV37Fbl5kitNnwRC9SfwJFQ==',PUBDER=>'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy/qXpsZxKzHpcD5y2r2kGqQq1+oFWiUPsv7okoylx4DF0WxKcu+JlbG97uXBQiIUW/py7K6ywIrdHD9NJtl5K+ARnSawi17t7uazAJS83Jg/DhhYYuaElpIEuHbzc2GHdd7o8/bctrPgMogGYKkPfdU3ORM6xFSVd5EMgiz6dFRzVLs/aZ2i99XrkXmf+jX7ChAYSSpRmxCZFpwXfPSWGB2ruYdgXbv3ee+Q5PGp4RU0KuxGsMywsq3KGq38QZMoaznuHJ9ufxfCmH3WnK1gLH4uSNL6Mu6w6E9exRKHVTJEQRz0zpQGP2mUX0oNo1XlqmxwORgei3Q/7ZQ6/Gu99wIDAQAB'}, + {ID=>'key-3072-2',SIZE=>3072,PRI=>'20B38022266C2E3A07C79EEADD0989D435AE04D5EA05455B744856B6CC1694181BDDFCF73DD8517D5282FAFC4821AA90E68DAAA89216EB3C315B18E7EFD3EFA9F84067CA44C8D719E23D05BAC0A896FE86D7A23B91BC71B46D5FFE97AD64C48391137EE5017BD80CF169B783818F9F542951F3AAA9F780F56AAC48497A12F084CA9F404841A7536B5B14B624041538D2DBE26F393F381A4AE535846A740A286C28A016851DEA7D558ECA116AAC12621757475E0FD455AC13542E40FE0F0D491748BF81BCD3330CDB43758D9B1218B3C41A7307B6555CAB38294C900E8D7479BAC27E3DE28A14F9E839FEF0B96635713F5463933DC46607894F27DFC85BDA2A64A35E77672E692BDBADD949693B97683A8929332B77069D613C5F37ED8D01A39DC50396FF15EC2D4F5FB710B79F54ACD559DF604836F0D5D7588E390C5E54DE3C7F027AD82BA3EFE5F292A27D1A0A538D4FF4442D6CD96A0D91400E14E8C22A70416D00D6C0BA92A9921CF7EE939A97E0B168E50A7BDB2A48B3E0124FE15AA401',PUB=>'C4F61D5A91C8598CB775108105BA00D74F50D406A7A2D144B6F169BC127A4C86DB76E71D13422A9F77BCBF4E6542933326AB2A6CDACA99CCDD9C2811555491898FD4B5F9C15978B0341C537829ACC09ECE1A3C11E1461313DBDF3FD25B57DF42080635E3A291DBA53820C59045567BCB98B7D16E376F2416C4059F4012BCCBED88CFDC6A4B6B25124ADD83A6EE5C337AC221573540A93E58DFCD07F99C7E7E4D3DB7C05109C12A236F587DA72629999A58F31D75F390DDEEBCADC0B81407A04FB93062DCE5E67837AD22CB5D6726DF18DC1FD33206B2CD35782B5EE39FCC18BBF5D58DAF546257949358B2495A08CDEBB3465D62FD33F0E72F7187D6D3B1F1CED8029E36AC2197394EF53D4B5016E5CEB22961E94C43D0EF65C37E43D1C0B24AB1484553EBCF2E5733F3D63C20C31DF4D1F5D21398403EC0B96E7E59BFBF9E1E505A7B60D3E53D2F7547F2776DDF936B637578C6A9EEBF7B83E4DC7BCA2955332E6F56B9674880E586B829DD505F0163203CC107E614444C1937B483E07EEFF9',SIGSHA1=>'YcnZm/GkeNLB7Y3xJuvUKEYfP8fEqAv4zlFrSnNb+1NgL2tJScLwp8kZyZKWakxZw5KPRy4/d3NDFcUjTiErLk5ZO6xdoVwVOaDXL5Io828NV2pLGj4rPkgqY3Ccwxr7qnkZo9CFyEzVD8o0YSfwh2Y02BB5k1HH0IAQEVc2YYb+ZHptyJS8JqU2XqsdOlUX9lz3huZonrDai9THqC03FjXfZTlSqYfXwW/Fm4KYMScqMeZXh1/6V7ZYem1d069KSZhK58KdSYUYQG3d1imEBTXSIE5JM0DcYxnDmVMJrdnZd7T0mhbadJIvo6hKOn8CYRujky9uA7e+kZw3zPhT7HeIjFDIM7rT+KQdk4B1vSSfgplAy8s2DCi23kgtmkrNk205h+/mWxU486gdpPq3P3RCkMg2P1/+Rsi7qacJsxH9RpzHMGHLdl/0HeX8M5O42XYErXsFpLQkKdCkkVeNhrA7YVU/puT+qaRalAONbgwZz6mBd2bXwINW2VoFm9E6',SIGSHA256=>'wQQVc+RQlkhaSYYBDsElyDZX+jp/YSNU4No/tYyzCPTJ2eHDBS3xwo9N9oEV0i1ZMhiyOHJRppZj8VzUMJCm41vOQfiaJ3FjA3cXb0LbOuqfAHfwn2CNIKvhGI2pij0oDCUC9590Q1bp+6bg+QRJTIGztxqcG2R563u5f/uwp+tIGTjUjaSV1c76hspubl1/ZB6njN48Zt6LSMOCZgGirtU9zzOsuSIuo+r2InQasi/7ErbAuE5/3ZPbzbvf0B1qPYaKYg3x5uEKPbm85YKK3a7LopRYWRjacdGOYMeSsG+gfd+ZKo0TVcKLbTeyaCyXYzDq59FVa5F6lO12affvymA21qtUa98WnJ39Qi6vuTGtaTdNTueXpaNk+OFoiwv09b+eR0XlBgRtILyQWLs/WY8ACkocPvlElcWb9rLSWf6apgLv7rsMGrgHXrFG9GbYur7kKkmfdnpw/KNJCPyg44byDufKXslokFhSHZI5ZZocFWfEYCE5Gi/v6IkaOKoH',SIGSHA512=>'UsB5Rk1NUWRH7kUqt0HoJUgxW/wnoLWVqnyht3Icb4g6+Zx6Yzmq5Tg+i4gn58kXNlrdCb8uCN8Mfi3EbllBHlrU2NJYF7AZKvr2SZvP03tcV4td5y76bkahrsFcDMKpkcLXXiEH9IWeMASLmEBKcnSwjQN9pXrqWVMRP5CcN4Y03/k/vDr/q3lzvziQ7QjvwKSq6bOKexac3U3sI9zazbgpyKhhEO3O/3SRQV5xteHaNKHUkwvWnvLG5uEJ0EJky3UmvK1eDyPOOeOxSYhiILPXJKr6hbMiFDCLC6gOY3MwOzOE1R8sxwGUeYW1KvFnZKlx9Ip8Zr9BQyWnBLjS0wo1vdHmqn6H4Z5XRA1wGLhYCT7gmOgBCszmm3fsLeyiWTLBwTpK/1e637xAqZriXUPaRXrmPiGZX6fju8P91F/wGZFmiFDN3YGQjiw4z+QPkBvOuzz4CTkxP6jfbBOL7jpfqysA/PoiTVL/JKJKwmV3lPnYhpe9mr0Maqa0of+r',ENC=>'QRCsicZ8VrCdwT2i4L9v6LRoDUsFIVMYXUyul9A9yHDrcktst7NY/zkJb9h/o1Xat1kVO2x/4Ps2nMRDqlLiZcJeLD6M2luKL3PYD3gpMdC2+RrxJCAAFNoLmk/XQuiBO4c73OPqXFgarHz+Bs/At7D7jWZU+QqbEGqxFMPpj3QKas+BJ/dd56wHiCAuqkoPIDfRr84ZzvhjSmI4sIrXYWkNJ6VjLDsaLI/tReOWpvKThWgmCN9VEU57QiOvXzp4VjntI7TXtDF/hK+qjUF4FqtXR8YRLnPaLBanjQIvfuqebH7RkAzFf3Xp4eHQvkNS8zBy7s/SvC4/mHj8M4FzHlj7uJfah+qn0f7lDH/2gxJauhnjx/VaOiCNfFg5f3fU07zFtlny7rUHAlG1hHVQ1d0m4r3fptqMhuVne174tBu/8rnJI4cQEKfzjs4Bn9PXeqyIZkVlAlC+zoI8hlFuKjJ17qiiWsjWdSbycqql+g07JNke9van+NF4Ga/0MXLD',PRIDER=>'MIIG4wIBAAKCAYEAxPYdWpHIWYy3dRCBBboA109Q1AanotFEtvFpvBJ6TIbbducdE0Iqn3e8v05lQpMzJqsqbNrKmczdnCgRVVSRiY/UtfnBWXiwNBxTeCmswJ7OGjwR4UYTE9vfP9JbV99CCAY146KR26U4IMWQRVZ7y5i30W43byQWxAWfQBK8y+2Iz9xqS2slEkrdg6buXDN6wiFXNUCpPljfzQf5nH5+TT23wFEJwSojb1h9pyYpmZpY8x1185Dd7rytwLgUB6BPuTBi3OXmeDetIstdZybfGNwf0zIGss01eCte45/MGLv11Y2vVGJXlJNYsklaCM3rs0ZdYv0z8OcvcYfW07HxztgCnjasIZc5TvU9S1AW5c6yKWHpTEPQ72XDfkPRwLJKsUhFU+vPLlcz89Y8IMMd9NH10hOYQD7AuW5+Wb+/nh5QWntg0+U9L3VH8ndt35NrY3V4xqnuv3uD5Nx7yilVMy5vVrlnSIDlhrgp3VBfAWMgPMEH5hRETBk3tIPgfu/5AgMBAAECggGAILOAIiZsLjoHx57q3QmJ1DWuBNXqBUVbdEhWtswWlBgb3fz3PdhRfVKC+vxIIaqQ5o2qqJIW6zwxWxjn79PvqfhAZ8pEyNcZ4j0FusColv6G16I7kbxxtG1f/petZMSDkRN+5QF72AzxabeDgY+fVClR86qp94D1aqxISXoS8ITKn0BIQadTa1sUtiQEFTjS2+JvOT84GkrlNYRqdAoobCigFoUd6n1VjsoRaqwSYhdXR14P1FWsE1QuQP4PDUkXSL+BvNMzDNtDdY2bEhizxBpzB7ZVXKs4KUyQDo10ebrCfj3iihT56Dn+8LlmNXE/VGOTPcRmB4lPJ9/IW9oqZKNed2cuaSvbrdlJaTuXaDqJKTMrdwadYTxfN+2NAaOdxQOW/xXsLU9ftxC3n1Ss1VnfYEg28NXXWI45DF5U3jx/AnrYK6Pv5fKSon0aClONT/RELWzZag2RQA4U6MIqcEFtANbAupKpkhz37pOal+CxaOUKe9sqSLPgEk/hWqQBAoHBAO9iCoIAv6KLlQLDxNFdA6dOfoXphj1fsGIrzfrcabGyEZUElacQrVRS9W5exSSIFtb+juOZBNsXljQ3Bqu30N8f8A67tUCh+8Wb3tCVcG+DH9p+12qvxKXsK6wWIQuOH9njItbV32q4BJR3gFUgGO/hcfWpOyta+oypMhjfHZEUV7SpIS8d2m2IHwdi4V4dHBUCTU/fv8WwBmePWftiygrqItGknufmABKn+c12n+iJPuxGMeogmaym/JVCZguDgQKBwQDSojhZplA3v/2pST70C0Qk94vvcq81ES3txfB/a3BZjU9BBU5I5H+1fXXnzJYATniqbbG3Ot/272ooPJkEUilvMfz9yMwA+OP/qx7BYaGwtvbYp5/XCUZVDmRoK40DJJrQ9rKTvozZoV9bmHQJRWyh96BxZk/Jm5CSCsh8proVGah9r+46XNF0uPBti4mH/SEiUprfcDgVRm+8IoBkGetluSEPDPtaboVBd4q5HdSQ7WytDIf+aCuOJmJof0rRyHkCgcArgL+0HHq3CXLNC9LK0YKGdydbIrM4mBkv3hIS0teKaXf0gt7He6pkNqdPpX1iRDESZTSGfBp7zm+HkbBuqHsW8XDo3If19PoSUV9OvLmwKj4xsPdo9gRguui831CmDvAO4s5ECJ4PgN2kNYtm7OxbO7dAE78jA+eghGcMSg/Pe8jslgfnzh8R5Lju2LNoLRYbY021hE4PmQuw6kZJ/wwEq8QkISyXrB67RTeKdVJeKgL7YU5U5BPJYpdocKam1QECgcEAtHER0wMd71SC6pX73zcTjpOehmd53v0zmmEacR3KJn1e6rWv5dQR75ll+0iRK/wNdPr55p0CJlndWFDpSQFVy5NIRuTQlvig4XJnq4SG7osfFmUrEh046j6lF3RPneSq196vBtCTexC6Tw5gQVz+/hXTlbHvIigphmLEc7yk5tSPOfUQIWFIcjTIix+hlyTrUKrxT/6jnN41dDceRCLMPN2Gi400erj5YScWaRU791fd5LU6f2AgB+usHBcIMoUJAoHAdb5t/CkkYTKy6Cizif+xphgl/VzZk8h/okcLPjwcSi7rFk4djS2KN3/0Aeifhg5mLszAYStElUrKxcJk1F8gUeNpeLCDC+WXWoSWHA5XroRVwejfx7AgQzNEGIEkaH0B8uUX+9G6SEopH8LscQdnX3L4Bre3062092n+ya4GNUFlh9HN9xPShFkQ1OGiJYn/XOHKGqt1CH3SD42hjSPP9odvBI54wEAF3rXvdAp0Ff/TG+CMLIxnjkA3HNsMjbJM',PUBDER=>'MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAxPYdWpHIWYy3dRCBBboA109Q1AanotFEtvFpvBJ6TIbbducdE0Iqn3e8v05lQpMzJqsqbNrKmczdnCgRVVSRiY/UtfnBWXiwNBxTeCmswJ7OGjwR4UYTE9vfP9JbV99CCAY146KR26U4IMWQRVZ7y5i30W43byQWxAWfQBK8y+2Iz9xqS2slEkrdg6buXDN6wiFXNUCpPljfzQf5nH5+TT23wFEJwSojb1h9pyYpmZpY8x1185Dd7rytwLgUB6BPuTBi3OXmeDetIstdZybfGNwf0zIGss01eCte45/MGLv11Y2vVGJXlJNYsklaCM3rs0ZdYv0z8OcvcYfW07HxztgCnjasIZc5TvU9S1AW5c6yKWHpTEPQ72XDfkPRwLJKsUhFU+vPLlcz89Y8IMMd9NH10hOYQD7AuW5+Wb+/nh5QWntg0+U9L3VH8ndt35NrY3V4xqnuv3uD5Nx7yilVMy5vVrlnSIDlhrgp3VBfAWMgPMEH5hRETBk3tIPgfu/5AgMBAAE='}, + {ID=>'key-4096-2',SIZE=>4096,PRI=>'6B8990668B8843A5CAEEB0C0C688A180B8A3BEC24C44D97F122CCE9574132C311E18F9AC8046108F3A8A50F58799FED4EAADCA30EC2FA05697C453D72013B1567DB9E84788E79F837DABAC1B093DDDA367E4B516D5CEFEF1E3FF2CAD3462632DE6E7DED023CC6FD0BC49C2313E4DEA70B7FD99099B25FB1838627122258672EA0EFA09E3C5754D183E549EDF7FBA60EE40F6D2AFF2ADB60F47F0E6BE2D47B1CAD4F9669D83D8DA5F709B06EFFAE5640D48A334E6A1E29F8381DDB9349F272B8CF8D11B2B6199A6A8CE716B0F8D0DA4C01BD53869472F8D5694FEE719F794837E9B59A0FB1E1296E678EDB4684CFE368E93FA8099DA900A477850A1F8437CC66E50EF678DE000713411BE24EED970362E5481B87018A139EEA95BD33376971FDC8054DEE7A28E356A2F8218DCBD3388A127C0A81A6F984DEB6F4B1A71A727A932D0D93416A7ED6DF5E3EE9CAE60414EC1EC1EF3C815D71D0D2854B8BDCF3E75E2C974CD365B6506228F6C8D4DA85C9B87EE10987EA36FEE6F47368247F1472E6755610F0424D49715E3FFC1870CEB7A0A4B6B4F885F6D51797E59920B5C2CBEE7484DBDAD600419CB45DA706FAEF778FAE9FC0FE752108877C92133DC642E27E95BE78F27720F78A0D412762B987C4ABBBA1E18A2A6B93B393FFB5731823DC129C1CB9BE5277CCE91594F0CB5E08E35B0B2B411E131C207E25B430B9E718FA531',PUB=>'E00AA4E51A61D45904E9448AF5D4A824DDE17A2D73941219358A1E25471FB760C5BD7A349AAD5D4C2836FA15150CA4591BAEF3A0B4BC38DAC0B7B099ADD82F05FD7AFDB56A76BCF9C05E9C952A7AE472561E43F30901EB284CA30F70E88D036987003FFF801B3E420033079E057A6D69E78E45375518BFFAB091C82943F74FE5528BA3F4E4F316DF5A7A6C495440AFDA62874D150824B99F281D38A8756E7FE70E0A4455BAFDF15EBE566814008830C9043A480129794B1B86AFF44CDBEC1141007F3F42E8D6D907C7E5D712C25D1922F536293721DE8E83EFFF0E889865D94DE9AFF0AC851686A95A322865C5264510F8E77C1170F6C950F02C183196D0C1FAC1C05BF4E921D2035A0B2745A69B25C3E5AD4F81EBA422D0B6E01235DF54FC897D0918EFBDBD6EBD43E6577DBF184F0A8C565F1CB371AABF893C3C4FB65385777E05F1BD2F97BBCEFC44D232969937909A6E8751AB093FBC85364F518447B4A8E59D563B1B203DDC43126C2DC54315C7B152B6D4DC0DC705D03B5F2ACCB6B0510BC9240D7E339A61F1BADAC01EEEE1E3DD5336881C4567E89CAD867C83B55E6AF99D64D6FBCC7A66D9D3BA856BBDD49978638460CDBFF995A64A4877F1A08F81F9C4074CE81654BB1F64DB23B1E1531C14274AC813DE15CC3F92EAD1B07931B72582CE4ACADF493BE67E5DA881FD1175CB61C77AAFF3C870F9BEA7A16F0C6403',SIGSHA1=>'tFCXrbLB8DZLSP2561rZ/Y82NSqeMh7tNek1kBmvK0Fi2stAlRjxRzm7paoeOPEX24dG08a192ClUUfYdIGxFBKcV3t+Xyq+txmGMhNVjUD1wr2WGyi8YKipzq/9G1pVcHHdb25pE0tF+tqNYrxa4kClDYvQiwVwFfrQEllJxl12p8XvSvLvbuBWKqcY82qGx1Lvcfd/9CY1m4I48tvChSWQrMusM6N7gBqKdilDfZd/5k49QEo8xw/M4MjPqq4Vi421Kyi7HjhmAYDd5naMh2vz4508eVGIJ3n/2kN7pQM+0Ty5qpDYuPSdUHv1Ls9713/5gJ9FeFaxlxVFG32gY9cf7SX0NzjzSsiNgBBtxvpN+kWDxfS8ECLopFnubbs0hREBmH9s05UVqdtA9RMaPWi0n+3zNrueKEsetuxwoiL2YwTqUPo13G14j+D24Nbwl2yauo3Ppp2qjjHBwalLYwhmS/omnQcdNUP+vbvpb+uFOdzeWdhZVz8Y4D3SAq3v+H6fS+//8x+v0x6lsisj3mwLis7I0I96g3sPq1orJxwHTmRdcL74j+RQqqbcWbuoFn6M3Qn77ZzjgYFPp3xzPbggM29oJmRIG7YxS3nnJNMF7/HKxrum5p+uubEIzMWb7HorKwkVuiMvfK5oeqDephHOYxF/7yKCMcKigxdDQBQ=',SIGSHA256=>'ZPqUxZ693Fc88BZxSi0Lb/2n1BVg7GbWzlSkpWvRoT9svklkc72dvqyK1pM1y7DLF2wbxeIWkqGGupYVgeYwINpfq6tutV40H8oGP+Jul+vN4CI62m50wVfl4Jxj1YUm5vD4Fo3vEDi+KwJLq+e7tYEnBaZ/EChH3KEkimm+Vt6Zfsfv9rXG9bLmCNhlY6APQnS8aNQ6ebtsiXzHMacg73OuyTIE6YA66nMMV5ERhNX1Zb+FL2wxFIMrzskP9/UaENHCHviEiLp9jph1rXsjOQCPnMHaTlCgnF47iWZJIGu5TgwMlZYYX7TcBjAM1QjmFeTUTAHui1KKu6pholjgj1S3RAGlo9RnAO1Eez4axcqtMZhXetMYPhQGFPGboXZrjYj4a4Zqhf3PB+dL2kRgVgywv43EZjJRT211rqRPwdK6/9kPYt8jTZLXll7sU2fqm1BBa653wQJrMfvmGh6wChKPrK8N5mr3wY9dl3XjQ3AjrhdFSDye5y2dejlUzRx8r9iEI1YYr1JAyEr5DG7xvOwDUUrJ/0RnLUess97ATRr1eBadiG3fyJWw9q1VpmGhUIY9TqonYWTanXDO9EZd0knyycWFBoC0EjRb3mPAR8cuvWwcBudjbwq9OZtNwfOXvYxY24GIgDDG9HP56C5tBn4LvWPEw4llq1mg43NATCA=',SIGSHA512=>'N2zOjiz3GWXCynJXX1xCF3jdUeeahQ4/C2E2RzIZSWtB9iGm8KmkWIBAxya1yzRclUU6/Tpm2K4+6Nxz9iv/nOzXEZYN8Dge8gMk2OZnTAofsKWtonR6aLE3LQW9dOjqVg6ffv6+jDMyT6tT6i1aviCSbkkdsCxJ4UyheWAu8voPk4SLGkrmtRXK3Js2rXUaMmoHtMt5XfFKuOnzC1baMg1SgjiQ+QgYmRwjs210PjcgrBLMO6i0eTjx+Uwy2xwOM3Hsa5npTGIkZwUN0GXDGIZuE/8HappF67lWoM3N6rZNERzTeAlLyMIbTnegR/fcnju8+1Jop7JJ9L7J7vXp4l5RClcsiG8HSm1OOR7FHjXIIX5MIWX2c7k134KlsQbJCHf4GDUwlvtat294kDMsHhkS2dNWkUrvmf+Xbi7lh2nTD/EIM3ki8XK6f1cQSL7vJamwDAIYcXSc8UoO+CygY6lmWDfmxyVaqNTwnOmK0KCIy++MGNcNYed17+zy02NyV/RQ/9/lJho/buYbGwfbVTf9wXr57gotRFl9UIuOPBvB33MApndtm6/8fP4PS6zhYlFe7r6V34AZVwOQnDPdeEVg8tz8IyhHOvno69YuQUurGvz79165zJvKZOpdwKujq9QgIcVeoS1w4pJT+HV6vpN32c6/qfb6qk1CdnHQVrk=',ENC=>'znyPxBD+XM9r1DoTGrGnu76/WSiAQQglq/aI/EPmBzmUfGIFkJ8DdDLPYGvRzUVXCS20TGI9rJtXjanKt5mRlt7zTFM9jdpgOoEhn6ZHhVY/kX7/v8/34XKqUezLdRyyozRTwkniYAUuWzYkZ5/3SqMqq0oN0nnGpgTRJtvD5+BIjxjNK36oJnLHJnfObVT4XHILHLMrR3gnNotHmUza7IG+9tY7Ga7a6neqH+mA/CWPja8k1+M+FkPh8z832I03kmoLAS/bSuyBmfLmdEJWhWOI4u9W20Ihyf3evHBs8ByEglWFUzGa/n1VwmhOT9zkdhWhNmk/d+Eq1MihtYVjiwi11iy6m8+11mIQF21VWIebgKg5yCq/lxGV4iPx37kV6+JgqF0Vj815cDeeWyWJDafsJqd8YvZJs86mur3BIkls8GuPYU+USwoYcfc8F615zOLLICxbbVgNiZ2+Y9J6VfNWtprRw8dJnWJJrmbilvabPuBPsaJIR+CVSM/VRXGVTMHk8DMUAvP4Q19J8NMHWxeoGeqk0BtgWKPg1W3LOMgmJ+c1k7LbfRRnr/tNL+WM9BtryDf+2UhuZsw1XuhN62g4IARR9nsL8MSNwAXHT2C2ex6zrhOjHMcFkNzE/V2n84xQsGPPLHyFIHTNvVxekO7GRZBy+je6WXDrUAxjHtc=',PRIDER=>'MIIJKQIBAAKCAgEA4Aqk5Rph1FkE6USK9dSoJN3hei1zlBIZNYoeJUcft2DFvXo0mq1dTCg2+hUVDKRZG67zoLS8ONrAt7CZrdgvBf16/bVqdrz5wF6clSp65HJWHkPzCQHrKEyjD3DojQNphwA//4AbPkIAMweeBXptaeeORTdVGL/6sJHIKUP3T+VSi6P05PMW31p6bElUQK/aYodNFQgkuZ8oHTiodW5/5w4KRFW6/fFevlZoFACIMMkEOkgBKXlLG4av9Ezb7BFBAH8/QujW2QfH5dcSwl0ZIvU2KTch3o6D7/8OiJhl2U3pr/CshRaGqVoyKGXFJkUQ+Od8EXD2yVDwLBgxltDB+sHAW/TpIdIDWgsnRaabJcPlrU+B66Qi0LbgEjXfVPyJfQkY7729br1D5ld9vxhPCoxWXxyzcaq/iTw8T7ZThXd+BfG9L5e7zvxE0jKWmTeQmm6HUasJP7yFNk9RhEe0qOWdVjsbID3cQxJsLcVDFcexUrbU3A3HBdA7XyrMtrBRC8kkDX4zmmHxutrAHu7h491TNogcRWfonK2GfIO1Xmr5nWTW+8x6ZtnTuoVrvdSZeGOEYM2/+ZWmSkh38aCPgfnEB0zoFlS7H2TbI7HhUxwUJ0rIE94VzD+S6tGweTG3JYLOSsrfSTvmfl2ogf0Rdcthx3qv88hw+b6noW8MZAMCAwEAAQKCAgBriZBmi4hDpcrusMDGiKGAuKO+wkxE2X8SLM6VdBMsMR4Y+ayARhCPOopQ9YeZ/tTqrcow7C+gVpfEU9cgE7FWfbnoR4jnn4N9q6wbCT3do2fktRbVzv7x4/8srTRiYy3m597QI8xv0LxJwjE+Tepwt/2ZCZsl+xg4YnEiJYZy6g76CePFdU0YPlSe33+6YO5A9tKv8q22D0fw5r4tR7HK1PlmnYPY2l9wmwbv+uVkDUijNOah4p+Dgd25NJ8nK4z40RsrYZmmqM5xaw+NDaTAG9U4aUcvjVaU/ucZ95SDfptZoPseEpbmeO20aEz+No6T+oCZ2pAKR3hQofhDfMZuUO9njeAAcTQRviTu2XA2LlSBuHAYoTnuqVvTM3aXH9yAVN7noo41ai+CGNy9M4ihJ8CoGm+YTetvSxpxpyepMtDZNBan7W314+6crmBBTsHsHvPIFdcdDShUuL3PPnXiyXTNNltlBiKPbI1NqFybh+4QmH6jb+5vRzaCR/FHLmdVYQ8EJNSXFeP/wYcM63oKS2tPiF9tUXl+WZILXCy+50hNva1gBBnLRdpwb673ePrp/A/nUhCId8khM9xkLifpW+ePJ3IPeKDUEnYrmHxKu7oeGKKmuTs5P/tXMYI9wSnBy5vlJ3zOkVlPDLXgjjWwsrQR4THCB+JbQwuecY+lMQKCAQEA/wMR9FT9OHEqcuwXGe4zhsaTef6P3kRka1okjYGO1vHK6yc1dk8et95yE4s1oanF/unbyCCGiuIsFF6NurHwikRBNJC57zm63GhdCkIQxHUNFyPNkR/SiHcxbUO3dQCBjGx/1gYAof/tU+QDafZkjeiBF9NONkAKDmwTRCNuU7Ba4IDO8ks5/3+OofgFUeMYnX6tiqBioNT6vvAeOb2glWY+d2Xl7bqsslX+xeytKk3t3oa/ytTX5MI6Hq+FnJAd9erKglcctO+d3a6CvjemJwZ95Oqw1Ecyun6TFq7RLewGt9k3w708U6SBEVacVpGj+gcsLW2ubXtYvf/ucuiw+QKCAQEA4OjbP6kg501MIhnr51Vb6mZ6ztl5qVkv5EeDRBtQRWIMQnU8MRnruViw+xBg+3wsRf099eO/hDF4J06Nv25fvYclNVuxZjdT3vruCGFtI1o5fMrN7MjThXkodlFIAdaoPrA3tXlKyxsPDk2/nsELIYlFtvA0Rw2BIIO0syBVdWds0GpdlAxITuOzt35Kw1ehmEc5xLaBzg+KXyZ4WGdjLPojckM60kItgafJ6EXm4GTb5o8q4QyGqF+hzXe5aZ4Doxhv+tb4tQZYyU+GPtGqF6yNINCsGE0ozjpcyRTzF/SZuU7tzyrrpUYtZOOwWF0L2OqGKj5c4JeLES88MRO32wKCAQEAmJgNtlbk71FIRVxgtnODAbLxrJ5XGHl0XYijNsm/337wHaZop1LQ3tWNDYTPot0kTVVC3o4X9CNCnS23QXAYr6QIIJw5ppy05A7PHcRKpEQmgSI7cAvKvz4TpX5P2QNkgdKq7DbLSiUKrphSMqXtpbzrAoa+1lebrOWe4bcR3aI5vv1U2EeLfQenIeR3ynhJ0nRrA/jVC8hmArtMWuDNpph36Jpg69A4Zr5upaDqPdZD8FRRj92tEoXmoVYGbZkPVIgahcP6uYpovK4gLhK+qbuIueJ1zZCNGmuDOJ+DLCeAHaMta0NhReu6D9Xz1xlvNb31AXoQVhLpF0h+NuRmgQKCAQAf77DCV2e+sHExHnErBinpHOgvWx41d96fEbCICUDauVN4VGFZr46TYQ6wd+DtlPJMdetIcTCOut+O5U6ncirSJNCZxQ1psE2Oih8mvX7b2EH1gG7BQrsWZt/h/SS2bh6x2B/w+uot8QewRkYBavQDrRRjJ7Skqjw9u7X7AYphA3CmH5RuI1hZK2gnlB1Vo6nkj6iaUDgaZIaHgFTyaKvihRpnbTh7Br6jfInlG5fvISNAl+/EyRyN6BZ3sJp5buChViUAf2oNens9CrfLT8ZRWkUn9bmaMcqrjgoC26CxNCBn+dc25adUbqSfgN1Xjs7R3Gt0sCpMEfjDVeu8JEqlAoIBAQDWoMNybnOrWa3D+OtE4hogMRSAnSXXqdV3J/I4YDznnZjfOpYn/DT7xv+XCWmnjGQ5irB1Y2iX1ml5n4iGmuz5iZiKnWTtut5X2tX5KGHN7rmtNKWi6L5k1Nt8A+wcG1L/nDDaI7XjpyC49VItoV0q6daA96RpqcQNV/pIT32IMTf2SZpMrDE4ckSrfpKRkSqrAxNEy7ebNdu11rLsYv2sSijz/i0K6f933bVSJRuRHaAL/looX9oNNmicX24V7Oq7x48kxc9gnjeaVDYezBu3jFRcbWLvI7tgO19/SnCGrn9xYhy+dvW19CXeFR/KFKnyc2Mm19VV3EEYaqm3o+tT',PUBDER=>'MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4Aqk5Rph1FkE6USK9dSoJN3hei1zlBIZNYoeJUcft2DFvXo0mq1dTCg2+hUVDKRZG67zoLS8ONrAt7CZrdgvBf16/bVqdrz5wF6clSp65HJWHkPzCQHrKEyjD3DojQNphwA//4AbPkIAMweeBXptaeeORTdVGL/6sJHIKUP3T+VSi6P05PMW31p6bElUQK/aYodNFQgkuZ8oHTiodW5/5w4KRFW6/fFevlZoFACIMMkEOkgBKXlLG4av9Ezb7BFBAH8/QujW2QfH5dcSwl0ZIvU2KTch3o6D7/8OiJhl2U3pr/CshRaGqVoyKGXFJkUQ+Od8EXD2yVDwLBgxltDB+sHAW/TpIdIDWgsnRaabJcPlrU+B66Qi0LbgEjXfVPyJfQkY7729br1D5ld9vxhPCoxWXxyzcaq/iTw8T7ZThXd+BfG9L5e7zvxE0jKWmTeQmm6HUasJP7yFNk9RhEe0qOWdVjsbID3cQxJsLcVDFcexUrbU3A3HBdA7XyrMtrBRC8kkDX4zmmHxutrAHu7h491TNogcRWfonK2GfIO1Xmr5nWTW+8x6ZtnTuoVrvdSZeGOEYM2/+ZWmSkh38aCPgfnEB0zoFlS7H2TbI7HhUxwUJ0rIE94VzD+S6tGweTG3JYLOSsrfSTvmfl2ogf0Rdcthx3qv88hw+b6noW8MZAMCAwEAAQ=='}, + {ID=>'key-512-3',SIZE=>512,PRI=>'987EFFFEA6ECAE6537F986A2F0FCA8F88EE705311A4BCFE4523D601A432325B46D67E809F5F63F20F66CD04E9B7C6765A628A02F35792EDA2E6606C756841741',PUB=>'CB3A550F2096DE1D9CA3438E7E4706B215F9E8EB2B5CE8274864D5FE51DF38109527DA48E4790427C261FFA0C7E985E9EC983F9BE5087F3956A3582F0441BAE3',SIGSHA1=>'RRRCdaNSPBrUNM+Wa8swDSNCPGl/9wnKv0lwjxAawky78v1jUlQw+Lg9ASJ2mJn0ZAO7nnLWaCs3tfhcuB8mkg==',SIGSHA256=>'jnVH8iSQkY3hOgNEqVkhCJX9QZN32N83ZL0WXJ51MW66RpNPxC/ioOPUJEQRpq3dTulvRYca9ufkzJOXPhQeew==',SIGSHA512=>'',ENC=>'ZHprbbXI4zqxSp9xpM6d/oAu1qb1JKSiFBSh3L5nXee2RajU91xzqYFZcM38jI3pmgUxvJq22dT/8DvKPJic4Q==',PRIDER=>'MIIBOwIBAAJBAMs6VQ8glt4dnKNDjn5HBrIV+ejrK1zoJ0hk1f5R3zgQlSfaSOR5BCfCYf+gx+mF6eyYP5vlCH85VqNYLwRBuuMCAwEAAQJBAJh+//6m7K5lN/mGovD8qPiO5wUxGkvP5FI9YBpDIyW0bWfoCfX2PyD2bNBOm3xnZaYooC81eS7aLmYGx1aEF0ECIQDoe9pUgy2swh3GTiKxS9BT6efhgTTwOfBnzUGhIl61AwIhAN/I5kPm8FR1vxs1PwnEs1TmbQPAAbEfnVotKvq8p0yhAiEAs08LVxGSAeP6OP/8zAgwVvhai1gvb3UQkc8C5nfu2ecCIA/4YV51K6+LW6EQcrg6vmWPsDX1TOmcDPmzgX61WechAiAGtqyZaNukznXSxJchSpRr7Ko3HDmS9J8cayZrro0F4w==',PUBDER=>'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMs6VQ8glt4dnKNDjn5HBrIV+ejrK1zoJ0hk1f5R3zgQlSfaSOR5BCfCYf+gx+mF6eyYP5vlCH85VqNYLwRBuuMCAwEAAQ=='}, + {ID=>'key-1024-3',SIZE=>1024,PRI=>'5C6E2CE5768B7A181B65B00404F728550E0193AC11FC260F5C0F9FC75A5F5DFD559A64AAE7CF12083C10AD58F4CE08B89F5FC89E50B4F3FF3EA64A701AC024B807FD29F64CB3DA87F035156244CF11E09EF1423C7862B5E8D73F0C969334CF5638B0D889B947D79E31F849AA5F2C7D01EE9CBD3FA3C342C42B9903267D1BDD21',PUB=>'F8995152BFFF2A8E343BD609314BCB22CF5A71608EA1C5A4FA289291B2EF7A5430DF00E2B989324393609E1C93F4C0EB15624DFF679232D485BC9576725EFD64BECE61D4520F71FECB7E18EE8644F189B27009383CF89C9C02B75FA0BE513CEBE05F99B843BEE096A87237B3AEE719D40FC10F5C832CDC78A6DE6EF5360DDEAB',SIGSHA1=>'bWT1q9eZl65JhUgOE1BKCz5cFNMF6RdjKRyW7VImofkyd8F9XztefH9dfjbZ0H/BJ4Gw18PNRXUV5Ecza9ynOUhVytc5/FJgsEQ4Siv8oDihW7AaKgiaOCr/u9/7BgXrMkSiMMgJbHgFwJYLdNYlcuz6FZH++cB7zHM/iPJYY8k=',SIGSHA256=>'sUIIjHIMEEVH2p9VIducRTyjOqFUx1U3otIlo48TmbKOHcT+xMny2nLtWZlZ//TnMqN8WuO/DWqg0Up1yHOjKUok3kTDlIOrWpHVQywy9BbDqVutDO+jZQFIcoNrCj0aSUxXhDSg/NgTwnIO7rv89mvkELeDQKd9+qrk1r8cM/M=',SIGSHA512=>'vwIT/VmvaiqccuS3CzIpxPCJsG1T6K/VthutpTTVJIPRCUGT9hwSWliWZBHLXJaN31k9hKNmVyViWyH9dlFBbfiSXmRjrKS3alkSefnxiw0KDv8Fjf6zY09UCvs7dfZbrtaXmg2rDS5geDuKelf7JWOAsuFxQ9DdvIfE/H8SAh8=',ENC=>'Jj3DnngbwjZVLPIdP1gt9CfDcDz1G6fUMd2XRpzoNS67NQ/EwHT9PbSMswqyUHy1HXPgOH6SptUEZhF/QVVlCMeLDtuBqVkjeVmWRmxAAw9kHjYd5TglV0lkGLj2Mebi8BpVu5BvTfrw7sfKg11gyYiAoCc8EidoMq5Y1vgPO3U=',PRIDER=>'MIICXAIBAAKBgQD4mVFSv/8qjjQ71gkxS8siz1pxYI6hxaT6KJKRsu96VDDfAOK5iTJDk2CeHJP0wOsVYk3/Z5Iy1IW8lXZyXv1kvs5h1FIPcf7LfhjuhkTxibJwCTg8+JycArdfoL5RPOvgX5m4Q77glqhyN7Ou5xnUD8EPXIMs3Him3m71Ng3eqwIDAQABAoGAXG4s5XaLehgbZbAEBPcoVQ4Bk6wR/CYPXA+fx1pfXf1VmmSq588SCDwQrVj0zgi4n1/InlC08/8+pkpwGsAkuAf9KfZMs9qH8DUVYkTPEeCe8UI8eGK16Nc/DJaTNM9WOLDYiblH154x+EmqXyx9Ae6cvT+jw0LEK5kDJn0b3SECQQD8pbFcpyQCZX4jrOjIQ6eWUnxQBCvr8rmn4VWO0Lbis2eumauyQzlbmuvVQgtc2EgQ0XZvpmUph2lTo/Hxv0GbAkEA++XfIVqRbbBdmGQGDixAUeY4W3tquhVQGVe/kLo0F3m+uUl66jNJ9TlEU5o8Wfqged7HWOqo2QhZjJz7DGPwMQJBAJTP29phMJqgwV2uGSbsgqfOSh6vdldyDtzNoyGN2ktJtQZoyXMkmYJVjBd+4UZ8tmYBmqtE7U06z1VOudHU/4UCQAcx+b2qKJ1JfGLt+H5PJUcxnEqAq/vEwBT5PK+VogdJovkH8ErgTCyFBj6dGTw4vHy+sFMJ4OjSJDyv/zvLXwECQGQED2zrrPhaaACJNB0nkXS7r+FKGHOjZoloA7Mvb4UYTUGnfp3xnG8pa/dQFHgjNEZyGbYFiUYi/Ycy13RdrvM=',PUBDER=>'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD4mVFSv/8qjjQ71gkxS8siz1pxYI6hxaT6KJKRsu96VDDfAOK5iTJDk2CeHJP0wOsVYk3/Z5Iy1IW8lXZyXv1kvs5h1FIPcf7LfhjuhkTxibJwCTg8+JycArdfoL5RPOvgX5m4Q77glqhyN7Ou5xnUD8EPXIMs3Him3m71Ng3eqwIDAQAB'}, + {ID=>'key-1536-3',SIZE=>1536,PRI=>'718578C4C5955E7B711EEE5E0FA0723F9CAD0DE78E0FAC7502CDD4D482EA507707866739E23C3E2764FC3BBFF5404BD91E055CFE21928791A980711CCA0200CCE6746E4F45D203F107FBE98B2A974EA99CE60E766EF5AEEEDFBB5F8A0B47AE9FB39FD4C01A6DA14A7424D7385F75758F41EAD10016EF55A86EF0ADD9798397F6F8B88CF5179F76906A6E15DE1C09E1051FE5781CAABCB61C6591AA5204C845F1AB336C95EE2D345F48D78DA5158D986E34101092E904430E5396D16FEC9BE601',PUB=>'C18DF7D61C47953B26F35B1394A12FB32985FA5B3757106001B9522264146DD1FDFC20FB8C27CD9EEAC07B28CE692816F9F4B2AC539A074CFBFA5EA2725BD90B69109D85AB28C21179BD39121A5D1DC001CF30D255AD0E00D1242F9D9C07CAAB37A1DA2D9FA65B94A05DC452450FDBB556989241C69BF007C5C965058824AF0183E5DCD95288949977DCE577052AED0DB02B0D886823324E7268F884342552A2FF73A0881F0631AB9035B5567E75418F5CFF9357C6D639D0E5B4F21DBF810C89',SIGSHA1=>'BVVhtXAQG+OUHTz1OsiRGuhiG75drci7qifEMMrdOMikNbRtvRRjCRjZ7ELixj1xjwLTEiqmxbcytSPIMXHeKy+FqHz6rioIUMiEgSFnnFhMa0e9zUgBd8L3JCuEJxPYi4fJrb/MYoSg7B7+tBV4m1BLGLwM7flPrJEikNRHpgtpyNypLqX7kqj7gdT8cqKyefrDuQUM7kFr5HZk6z8s/6TFyzRr9nWpwMUfEjr6HqdSp4XGwQihb1eHsttUCCbO',SIGSHA256=>'tmAA/bfDCRbn9sy30iE77KVJmgoljYla8g6etapmGeElT8zE8bGnFI2wNEm+VRXu5pFx7emqOQ6X5DGJG5Fi7BAA/XDLT71kzJoQdqr9yeJuAyPFOA0LC///LiEhdQ65tZiuZjcadJ9Uxl9MkjteuTCULIXmxcUxXN0FdYoZgoGjIT5jq2J/eqgRnbTliqfLyyumTbXkHj4kh9b1a1F0UGCOV5/6F+Ib+mMxZpakiAxAqpNcBLXEojzAJ+OG9Nnx',SIGSHA512=>'U9L1gTB8xZumj54CJJr1hOZ3UAhCPO7gWETT9s4nYyE6l+xqigNMg60uPK6YXuuo5htHMCtQDgq9Q9sMnhqQZg4+GqE7Tdc2nN/1M4GWlB8Rw2FMtI+pIPW32bneY5z3DCBkNkHMsyCZPpHGA0Jf3ZJ4lvRleuPpXsjBVfvEZrSRLysI8Au2GNQa0FmBFeAOcALGEfHP8Fdnw+gJMwnRXNxd/E9fve00uby6Li7CRbXo6dWH1zlcyB6WnoZyfNkg',ENC=>'LEv96RAFrnDt2yUSwY40o8AxfmmQrRcdeOACZjgp/FEuQ6+aLDTdVWHiZKArKkaO74N5WnlR9zl6zs0HLeUS0ehv5J9u022eFrqKxOmIIHuKVtC3e9MpLc+8bJPWdGNrgkytmIFxs3WyhixWglViC+QJKEkfg4YxjS3y1RCcm46A9h8EW3SgBWruljf1I2RobRUET41rdWB1XVhjsVpQhlILrmlXG9GzmnIegllulkKs3VY44cwbpV9DxZLMalSe',PRIDER=>'MIIDfQIBAAKBwQDBjffWHEeVOybzWxOUoS+zKYX6WzdXEGABuVIiZBRt0f38IPuMJ82e6sB7KM5pKBb59LKsU5oHTPv6XqJyW9kLaRCdhasowhF5vTkSGl0dwAHPMNJVrQ4A0SQvnZwHyqs3odotn6ZblKBdxFJFD9u1VpiSQcab8AfFyWUFiCSvAYPl3NlSiJSZd9zldwUq7Q2wKw2IaCMyTnJo+IQ0JVKi/3OgiB8GMauQNbVWfnVBj1z/k1fG1jnQ5bTyHb+BDIkCAwEAAQKBwHGFeMTFlV57cR7uXg+gcj+crQ3njg+sdQLN1NSC6lB3B4ZnOeI8Pidk/Du/9UBL2R4FXP4hkoeRqYBxHMoCAMzmdG5PRdID8Qf76Ysql06pnOYOdm71ru7fu1+KC0eun7Of1MAabaFKdCTXOF91dY9B6tEAFu9VqG7wrdl5g5f2+LiM9RefdpBqbhXeHAnhBR/leByqvLYcZZGqUgTIRfGrM2yV7i00X0jXjaUVjZhuNBAQkukEQw5TltFv7JvmAQJhAO7ZSmTu+lFa8PnTn+k49BfSx087/IXwHdwMYkm7jWMKunUz9tW0f1sfu7vQGFNdC0YMyQsZPdaoiL8gPJkP3VK/VrFx479f5iLybWJi/Fyaai8IChV88TTFOyIOSRM6oQJhAM90CvSxKqnGB65Zz69pRerNSngVhVuX8CtmNhhWqRv3vcnCpfT8YAzhQdXGFOVUGh5IW/IDggz1ZW8TusqHO/GoCvrTgX4wCN85dfvWnah4qw6jckk0Ofr9GmuYSXKw6QJhAMarFqY94RgqfKZQ0II9TUtDl2TgkHsX7r5JzrdluYTYN5+lSXsYV5aEHrNps9IjYm0x1UfWBwm1xYi0V7M47u8VGBcglD9qlRIcc7+SdjbQeeIE3d5hvoAWTclV+JJ2AQJgEW9rTE1njIU8OAcMUW3DloxSae1FHAGVCdC5UypVZChaJw7Y69IaMHruEY1oTC3ZVBo4wApTb8tgDwnVdRgQjarV4WbNR1G6LSijJdtPvM0Hc1+BR23AQbvr8IcIBT+hAmEA6HY4G8I29oyd7zv2Z0bmZspHR/yR66FOTqZ++hKwHF9FTGXiwhKDxOCLXsPdEfm5TW8kYFhaE/pn78r7ns3kQ5XXXvJB1RjIxGV4Cr3XqeBeevMKp8YJPD82zXzufudu',PUBDER=>'MIHfMA0GCSqGSIb3DQEBAQUAA4HNADCByQKBwQDBjffWHEeVOybzWxOUoS+zKYX6WzdXEGABuVIiZBRt0f38IPuMJ82e6sB7KM5pKBb59LKsU5oHTPv6XqJyW9kLaRCdhasowhF5vTkSGl0dwAHPMNJVrQ4A0SQvnZwHyqs3odotn6ZblKBdxFJFD9u1VpiSQcab8AfFyWUFiCSvAYPl3NlSiJSZd9zldwUq7Q2wKw2IaCMyTnJo+IQ0JVKi/3OgiB8GMauQNbVWfnVBj1z/k1fG1jnQ5bTyHb+BDIkCAwEAAQ=='}, + {ID=>'key-2048-3',SIZE=>2048,PRI=>'6B4CD1833925E1FFB0EC80F61048B8CE6F3636F9E13708B0B21450CFB4AF45320674ECCD3849BCCF71291C3EFFEFAD8A20C683515DF51BCFC238F702D686D24705B87CA8307CC1919CD801AEA8F17C6EB8799DEDBA456982AE1EBB942C69A28C375E76382469E954F33477D18FD1506BC17701E2BABD290B0E268A70F7F6229268D7FD89AE705E8FD9FC2972210E9962DA4B1A67DEAEDE4A8ADC9CA526CCF22547A4A9946EC420E5582043C189F80670F2C798BA3B4562DDF8A111C5AF08AA90881A3F181E9C6536D412634BAEB2B9D082198E98A4E7F11B6B3F10607D1700B6BAC2034413801CE7D81D242A4C701EC46602A49D771C9D87791B7F86AAD1E079',PUB=>'982FFBBECB63D90CA7515617F963A5E907B2F533D76D91D8B669FAC24E5E01C4DC6E5BBF7908692395C8E1C741E4F5E34D958CA9627B3149205D64D67093A45A0A6C91CD4A62324375F79A954D97AF1CEB76CAA07578B1A4ED3E2D4D6A142C05B4BE983A6E6DE54CF3B6C62FF1911E37945B4188DAA4284FF3F4039C0B5D1B843D6E4FC688D0A80BDA6E2AA362957644B7D0D61AA5E90C072E7E932D1A08AC8D47246CBA71E4A78F32335D3246A26554BBCCF9F3179ABD834D2D1B2DF5BCA2ABFF34B72D53911E99739767861677C547AD7CB55C29A85F0C23DDE44770A61302C4F9996C568746DE8F54E4A7D5E879692B1E474649E70C01F7235055CF14BCB3',SIGSHA1=>'T+InLHHGlX4CRhN44n09zmbsTg+E9sA+FVR8cNkL4L/We6l4+Zpn3MrqNL87r07r4DRoneQ2DRH/eWjoRdzzaIyCMtFOSpZk4l/Pu1yY1npW0rqXTSTqle94olYdV0n6SEHnH2+F0Od96Xyu1CsMwyTPaITIwUXk3uMqXLFwrgH3NqYH/y+rq9uYRaQvUMcwBkWX59P6lsDYU8EQFXyLab9SL1fVEMeuCdXjA9E01CxF9GFkHv9FJLUw+4BY5F8NvFXPi8Yb4N5UM9fcTweVIEICLF8e5f4SB3WMVB+2JvcGDssA9HZ+/Nh7ZfMsbtha+fdTl6+7XD+4w61ABgfYdQ==',SIGSHA256=>'kaJA6EGVDN+IMZ6EOz7Lo0yJ1yiN1z6LslEL1t5BU7hGc5Wgv9uoJz1Q301xBl63K66vcJh/PBEUc9816Nc52m1ioNKhPLleTrOzvsgn9e3DEMgOgZGTkACfmRuqjyzfKD0roK9pnwqpCGuCH3UIcPJ2kGD8MlqamC28dnouhGA6flxkj3hcLpZfvuEAYJUOwvW/S4adNFaeNX0TB1nCzsL99/IP5zx1lMP34j98VHj9fGr6m2DgGWIDY3PoQhAqcXAq8eOTmB4aSavvQg6+dOTj/ZB22deXCxGGYd/G15vX5csZf7+ZFwRm86Ki4yQZdo0a82F+ENEUSG4egB+kXg==',SIGSHA512=>'Dg5HED0ShODMhXsZhymDXssEVH/HpEsVs4vlVQupBCaVxSzSp46uE6YrUFvvJU+eFeGZJQAVGkdc9hJPSCc73yjrjt8Z4IBhF4MyR7Oe2e+zK6ZHDnHx3hQk72pSok/sMyqrJPebNRGiHztBYaY2GaDlA0zdU9hiLemDluPIFJ+NvfqtzbE1GA1edX9jrE+hqsgEWAEUXHm9L3RYxOJNn3Wgjb0tQGu2QOJv/6irwvUzK5FPe2xsOcSL7VgljVj1YCJHd4LGpqlcd67JN3hoMkxDyX1TksCy7pFY2bqntU/UMSW2zdQdSMXXz+nEP81Xn9QDs2eXzYFuJImFtFJ5BQ==',ENC=>'Zvr2SWqDaHDtRRZjqwBK9zouTKN+OYpHzOXHdYVPAazGYp7ldtjFe9+m+NNorv9zs3T4MVXcYkEujXds8crkQ+qfQc5N2PHvVhLSdd0Q5XM5mM62LK1px+G9GdmLCGLgrFAHcrMBICprDPVTMT5ypQFbegrVNCp4iCVJ+lmm/zSdZUZ9IoxkGIOt3/BPX2h1giKzXR9c/zYUyqZGg2w/vB8lgzsXO6UMQ6BjHIi145mGXHLExWaFArdnMhp1ncO+bgjxZvmFJyI8xhy9omsyp543Hb2hxH89F96bHOBmAR04ZeEJ9OY6rZRHT1X5+JiyYfAuTwN0DNjBoCyG4AUT4Q==',PRIDER=>'MIIEpAIBAAKCAQEAmC/7vstj2QynUVYX+WOl6Qey9TPXbZHYtmn6wk5eAcTcblu/eQhpI5XI4cdB5PXjTZWMqWJ7MUkgXWTWcJOkWgpskc1KYjJDdfealU2XrxzrdsqgdXixpO0+LU1qFCwFtL6YOm5t5UzztsYv8ZEeN5RbQYjapChP8/QDnAtdG4Q9bk/GiNCoC9puKqNilXZEt9DWGqXpDAcufpMtGgisjUckbLpx5KePMjNdMkaiZVS7zPnzF5q9g00tGy31vKKr/zS3LVORHplzl2eGFnfFR618tVwpqF8MI93kR3CmEwLE+ZlsVodG3o9U5KfV6HlpKx5HRknnDAH3I1BVzxS8swIDAQABAoIBAGtM0YM5JeH/sOyA9hBIuM5vNjb54TcIsLIUUM+0r0UyBnTszThJvM9xKRw+/++tiiDGg1Fd9RvPwjj3AtaG0kcFuHyoMHzBkZzYAa6o8XxuuHmd7bpFaYKuHruULGmijDdedjgkaelU8zR30Y/RUGvBdwHiur0pCw4minD39iKSaNf9ia5wXo/Z/ClyIQ6ZYtpLGmfert5KitycpSbM8iVHpKmUbsQg5VggQ8GJ+AZw8seYujtFYt34oRHFrwiqkIgaPxgenGU21BJjS66yudCCGY6YpOfxG2s/EGB9FwC2usIDRBOAHOfYHSQqTHAexGYCpJ13HJ2HeRt/hqrR4HkCgYEAyQkF7m9q85ZTeKwaiEZ17VrCk9vPP9R1S9yMyCr9Xzmtkut3FuCLzqduMq2XXYLIRYpMpgj0r6fUel3hNzlnq2F1pABgRO1yEQ5XClvSmwD4EsYZPBM4YZSwUIyzhfS9t+clyAeGm2oHrWK6oYBxFuKunj/K5Zlh5KRWRl1c+x0CgYEAwcv5vSxtifPqKcrM8KpH13kq18APRenCgvOJUW3zDAcKMnoJvXxpfDmEvR7zLFmtEiOQwLuc6tzl608ghGSgz0J3QrhlPej9iZwe9a6QqcpGOEubFn0lGKo77x0ILU+NU7e6uo9Hq/tUmzCe1YKRwDnCfVbxTSK2MlYQVj9FPg8CgYBjqD1wfXsfVZ37bBWbCJLdHujmM0kB82hSOvrvH6CK3CTXeDKI/LdRsl5GcRdgG7z7/BsTE814ZlJGdtN2dNaXdrDCpA0VHkA1hE5RrEMy48AWTm2kAkMo3HSq+ZTlCvYhfEyWZGSuFlnH8fFirjFhju3RNP534xlMJss+BnpZYQKBgQCwUhA/oKts50I2kfBSSusgTXrAX1rGBj/V+xQFxV5rpAAQGt6/yvECeCagFweyY0jHBxrNcCT9vstlg1GXgyKYT+XIC5L5eAEtcaDtcMzn3kRzNb6+AFB/F2t+S1DEQOvZroEy+eeAvyOkKuFoauqHFUYx2aejwaA5PfqRLfGm2wKBgQCKW0iGocJgd23CGwV2w6q9d0N88Y8z94gqAp1eFYML2m/l/8ZF14U4oXhbf+DqHEzMoq5tKy2zBt7ASNYRKESNSN27VdBjqkCNHOtddypXIed5yTM3DoQ4HEC/726PoZ5MEtKzup6PegZqyPgfYblnplllDTkd2eD0KfQRejeRQw==',PUBDER=>'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmC/7vstj2QynUVYX+WOl6Qey9TPXbZHYtmn6wk5eAcTcblu/eQhpI5XI4cdB5PXjTZWMqWJ7MUkgXWTWcJOkWgpskc1KYjJDdfealU2XrxzrdsqgdXixpO0+LU1qFCwFtL6YOm5t5UzztsYv8ZEeN5RbQYjapChP8/QDnAtdG4Q9bk/GiNCoC9puKqNilXZEt9DWGqXpDAcufpMtGgisjUckbLpx5KePMjNdMkaiZVS7zPnzF5q9g00tGy31vKKr/zS3LVORHplzl2eGFnfFR618tVwpqF8MI93kR3CmEwLE+ZlsVodG3o9U5KfV6HlpKx5HRknnDAH3I1BVzxS8swIDAQAB'}, + {ID=>'key-3072-3',SIZE=>3072,PRI=>'028B8D8BCA984FA61FCD1F8F03EB33C2BA156DBA955B2DA052089511A266A68B1E74B4D9393BED2E7149241DA37C1F2430D671334E12B91D0AC2265BFDC391719AD799F057ED6FF2B2E330E87E85A50CB542CF7E0DB1B0CEE6DCAEB51AB0B5A744FEF57D5D98A1B9861C44AFF6749586DF2215CDA1BF3B416BEAC2398F013AE0322CD9949796ABBF8DDED033B723AE295F1F937E56890B8DC7910008DF2590EDFBAB22F2EBB26FBE7DAA4D22C33B9EA61D55290109B4FAC61F222381959C00C23DABC1D3A993D57E1565BF963224A20826E08AB1D27E207F07BD06885832025B2506EBB73B86B82CC65536F5EBEEDB8FCFE1DD907EAC8E3C9A348B5D8C8C16EB475AB940E91099A2CD8F0DDE5925400151AC551E5F8F0A498AEC6B2EAE8AC1E0283261A4306EFFFA404AB88A9A916F1AB387CF3BAFE8682660E40B616C96697596DFC6FFEF049AF2402B3C449312E1BD9E6319181C8891DE7A3931310CF16478274F39999D5202D255712CA005FB0BB7BF8AA474617B228E08553634D929F6F1',PUB=>'C22DEC229CCA21821240C71E8A58B6F6B707FD9E928E2697E3A8B5DB7BC37C34BFDF9B3F80CA2E99EB03B2269FAAF3DFCEB7979E085A5B1FD99CCB4AD70A31D230A38C59F665E2D5A1CAE430B4A461428D1E531B7937E12EB0E68A37D933A8F8BE3498AEF6C2B40D105447980881EE8D756849D329AEA41B2BDCE034D1721B3F3214C9E4559C436B78CED91DE761D72FC4ADA1CCBFBDDDACE35307698DB0BFCA88D3C764A024C9BD113929255CCC683A681758923DFE5AED32717045792BEB37D22292454737416EB49E44C08661ACBA236F63588534BAADA012F4488F3D7D8E95C60FC3746728EEF27646CF086CA4D203441C1E81E3A596AEC396B58A43D2BE6DA065748451A4B50387C31FF260481878F7DCA1A9888590E10435881920E55A7D8DD1F1994041778D732A383A49E0BF4B7A3825F5D8E6F39661122278C2B0DBE35150B4A262675409BF84CE6C30F87B48E6AA61EB91D6F06A1B221545CEC5250E14A910DFD233936E6D4E1858AB16955364A3E5D4592B82B4D67FC931413149',SIGSHA1=>'Y4Kqi4zKizlEVCmiZUhFf6psQPeELXnF7C9Mha3b8tKCT8IRryMvbaxBbd6Gnc325bBkTwX44VtVjAe9qenO7b42fIFZcZgUHWByCTzZCtnSM2h4W8qAO4fJHI2ye0GV7Dk+w6doottLo6RFL3+ZHb6VSkOYeTHl0TeQC5YkktY67erTDfpq6xTIu3yPAw2RPtT/UsBeo7HRvHD2/5JrUgeWUzl41rySjleeax7pXxsMyrBskw8rLvQNSJtsAuhQqsFfIOz642sJSeibxXTrs+Xh1xsEiOUytyZHcHaGgIyPieBDYofE1CADag12GlrZ9l+1AvdbhMD3iX9LYAFLvXCa9EbyNRDiua+CvDnIKaFWOJ4uUOaKd+cZbo/0F9b2eP7OlIbkfse7mIqzDF8WocXYInxvScJNjHiYTmcj2CXm2xz00Yt4aIBfbwpKy8lhB9t0deX9U/PEE2m+zoTwJTCGxheBSXecYC7W4abnRi/LvX4vpws+oTp6GJ76t3Au',SIGSHA256=>'tJyBBJPCcGSi13J97ip8C4hCPoSDNX7+n/POkXmLrIMCQ5eSOgxx3W6AdAFQSWtg/NDR/NhVpCkYD63cu0gQxU+IYVgXaz3dUsj273lDM9QnY2lmTvh/pvPwZA9P+DHmZjmiBh9OH3ltS1o+QTNhJZQSUQX4n1wcfhU9w1zFCbiu0th9gldKG1yJcjsmpO91HAnuVxUKwurypIea4oB/0GbVxCUc3IDHtvK1TEGmeQ9JyIr0/q5R+W1oHLQLGRiNFggE3aXUujYGCrz/KurP8PSYPQFgucgcd2D8iG1KvdypnMWdKXAsiUJQWB8sr5eK0M4HozwthX5reaBadoLmRVXh/vSxa+0Jf8KuAUmCFcS9+KmEcaMEb/3DoYfX19S2ZofzxcnF0Ug1Tvkcg+KcJBOZlHjNmTU3KcZ2BOIK64KHTxMouaWeAFB9ctsReSlpk+y0jrXYlYI/0IN7pvBIA48jema8ilf9x8gRU1ykm5XCpw70XigG0HknyUYgimNn',SIGSHA512=>'MqM7BWBoqpz5gKfMJkLM2oyYkRQNgnlefu1knM67BLoDHIlSlBRIDPZdogBDdalhVEKMN/NmiL//Mu/sjoenTo1KH03+gKW+S9NlMxS9zUhWu2goDnyzVKgulmKi1RngcA/Z0WGd0WqMLorDna7S2c5hwTRDKn8vVCt/6ts27y/6LCrdqMXBQtyV/ochYrmdWfU7N7Bo/W8ZzbkuGFPJjG4S1LrrwQGDZyrj7SmmwhMPC6NSJLrNGETCPp31DsNqmzDrQUYbuv32HvalMSp4UXE77dkgTt4XxWkmlqgIEYb8wLiJbIQl66rZ5I9Rg2c9S57iIa+C4X9hG2qtgpfXts8vHPQZVyvV2plsQdSvUtqXVG6wWZ2TANJy73fgsqaTAj0stzwzMSMQyEzrCBicq3JVKXxH0r6ufFji+Hd5Vm6ajTx+tXy2blzVwXFVnFO9L5aQsGMt9HtghdFvAxsOJbooURYSvdJ42SjfKR95D4nuUlu4S9n2K9UTjrJRrL8H',ENC=>'Yz968huyr2owVhfL3v8whWwzh3VwzP6pAoFd3/lGAlHpOb9MBxxE3dlXoHG9P9HCfEJ7omP0QmYVjlFjxHKayNdKuB9TMPVkxky81kXqNbs1bLHWut5q+PxKhqK3V3Fv0TD4Dne5f3SgpvIYT3mlf+/iR9dw2ruh8CGBqliMeqCzsGwp2qQHzm2jd4AdyuoU6pYfYUh9wJzFNuCmLiM+9Gqecs/O547yy/jjAYUrHTsOQb3W7SZSZ9/xZPPXHV15mE69KZVjqGKQIbEAwdORFaAP4+eZ7+lPCJpScIkrNQfiOyg2w5h4o4ok/zuRb+6Kq/SnygMTUukGdArhu7wSTZSwmzdL9tOqaukycbYl4t6ZL6mZ90YHgri9lUZTsJPCTj6IukOkWS35YIzeAW7dAybLPvHTyS1jBVO+CwECgBhVzLxtMU0JIf8hVO6KMNhpesjZ58pTvpmoPIpeOl8MbOuku07nRB/gpMmoHpfH3+qX37qBbL3cax3ZbBUp/3oe',PRIDER=>'MIIG4wIBAAKCAYEAwi3sIpzKIYISQMceili29rcH/Z6SjiaX46i123vDfDS/35s/gMoumesDsiafqvPfzreXnghaWx/ZnMtK1wox0jCjjFn2ZeLVocrkMLSkYUKNHlMbeTfhLrDmijfZM6j4vjSYrvbCtA0QVEeYCIHujXVoSdMprqQbK9zgNNFyGz8yFMnkVZxDa3jO2R3nYdcvxK2hzL+93azjUwdpjbC/yojTx2SgJMm9ETkpJVzMaDpoF1iSPf5a7TJxcEV5K+s30iKSRUc3QW60nkTAhmGsuiNvY1iFNLqtoBL0SI89fY6Vxg/DdGco7vJ2Rs8IbKTSA0QcHoHjpZauw5a1ikPSvm2gZXSEUaS1A4fDH/JgSBh499yhqYiFkOEENYgZIOVafY3R8ZlAQXeNcyo4Okngv0t6OCX12ObzlmESInjCsNvjUVC0omJnVAm/hM5sMPh7SOaqYeuR1vBqGyIVRc7FJQ4UqRDf0jOTbm1OGFirFpVTZKPl1FkrgrTWf8kxQTFJAgMBAAECggGAAouNi8qYT6YfzR+PA+szwroVbbqVWy2gUgiVEaJmposedLTZOTvtLnFJJB2jfB8kMNZxM04SuR0KwiZb/cORcZrXmfBX7W/ysuMw6H6FpQy1Qs9+DbGwzubcrrUasLWnRP71fV2YobmGHESv9nSVht8iFc2hvztBa+rCOY8BOuAyLNmUl5arv43e0DO3I64pXx+TflaJC43HkQAI3yWQ7furIvLrsm++fapNIsM7nqYdVSkBCbT6xh8iI4GVnADCPavB06mT1X4VZb+WMiSiCCbgirHSfiB/B70GiFgyAlslBuu3O4a4LMZVNvXr7tuPz+HdkH6sjjyaNItdjIwW60dauUDpEJmizY8N3lklQAFRrFUeX48KSYrsay6uisHgKDJhpDBu//pASriKmpFvGrOHzzuv6GgmYOQLYWyWaXWW38b/7wSa8kArPESTEuG9nmMZGByIkd56OTExDPFkeCdPOZmdUgLSVXEsoAX7C7e/iqR0YXsijghVNjTZKfbxAoHBAPb/e2VZ0lLXWVl5xrhdEzl9hSyWGSFxQzBf4F09P6oanulmoPL7vboP9FMoj34hRwKpV8ikNl0eRSttXsOjgqTgaatHivaAfTrcVSvhYdnjHI3Giwvrb7DSJ6ezbg2XJIA1w6vwh/cXz/gAoAmL/NZ8zdAvuxNk3xFixYIZeY9SsKFiSKf7jxClx3/BQ7JbT0TB7QWGGFRM0IYaI4RnTyrSiJWxZVn49ymXp6+yvbyyJxK5AlUQpcpuTO2Wv/Mi1QKBwQDJQaMeF90Dei7p5rVXKJunHrRmVZa1HY9SLcgckycWKfDhzb7k+RFa4VGVu6nfdx/haJD36xKjBYrt0kn8rP0j5p6OLXmmoUQ+IeobsvBg7QmrHeyw3Jwb5b8Etg3jMx3UDn4obkBdExGIBu1kScJ9oOyNEQJq5H21cdm/rIWdgyNg/k2TIDl2BQ2lJTIxe1iuZdzjgsaT6QLhy/hFl+pXR/OEEpzaiJbTb2io1xR7U79tCeA8+AvHghGbHqmvxqUCgcEA9Vb18ckTghfH93lfazeAZgWI5628DpzbWUySpuq0tzk0CbBYRKLLZOp+DK/oQCe7yif9Ox3ppfrwR9+eVoOuvCjwrSImJQ2h1nqO20RHFs9hSG4jJVbZnXBR1WED+tnbdsJwtvP3ifeMKtIsJO942HAlWxpeHzh93l4Ww1Ccj0FakyL1+m2EQMv6aqrEnH/YL/rUfT0iI3IdWmbSSqz3VRjEdLQ9cO48S4MJHBtWHf1zlERSzb34gCepoAGybkZ1AoHAPNce3KYSJk71h7g68dJQ28CogJc3LCF3hjxY1mqV0llzfI+aOdYhrPuYkk9dFzUH6jiWOpxR0f6G9UYxH7WcARJitFCDCiCOZMoT37PEf0ipN5WgTAclGjnl+SKgKCL3zXdkJAzQYFK3ZgvSEBNMPHY9jJerx2yzo/p6/TrGWcufEl9OTD/dnxQAAACyn8rOEEqy8AREy8oRGPl0YHWAXkpeD3sg99962QhA92mtw2qZ3/iwVT4XMYTclaw7V+wRAoHAdK3FTrMTjbA2ndUf5A0Chuf4kM4viSEWomHe30HfP+63YiIK8+8fjg2G+5xNFIcXho0Qc8JIY/N5NGVxHCh2oPwPtAlNS3xnhSm4q7FKB9zbZhZv3KpTmwZHwiKfJLSBGNdxO+9seVfYGgcM36K2Lkb99kjOaYDbpooQQkebOecq2g8vmuLDHwuwdAMCFE4tD7Da2fopyRRKYR9SWal7sf+SWnzGXMui0DX2pvwrKy9Kxcg+zReUOoPZKBo5aWgo',PUBDER=>'MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAwi3sIpzKIYISQMceili29rcH/Z6SjiaX46i123vDfDS/35s/gMoumesDsiafqvPfzreXnghaWx/ZnMtK1wox0jCjjFn2ZeLVocrkMLSkYUKNHlMbeTfhLrDmijfZM6j4vjSYrvbCtA0QVEeYCIHujXVoSdMprqQbK9zgNNFyGz8yFMnkVZxDa3jO2R3nYdcvxK2hzL+93azjUwdpjbC/yojTx2SgJMm9ETkpJVzMaDpoF1iSPf5a7TJxcEV5K+s30iKSRUc3QW60nkTAhmGsuiNvY1iFNLqtoBL0SI89fY6Vxg/DdGco7vJ2Rs8IbKTSA0QcHoHjpZauw5a1ikPSvm2gZXSEUaS1A4fDH/JgSBh499yhqYiFkOEENYgZIOVafY3R8ZlAQXeNcyo4Okngv0t6OCX12ObzlmESInjCsNvjUVC0omJnVAm/hM5sMPh7SOaqYeuR1vBqGyIVRc7FJQ4UqRDf0jOTbm1OGFirFpVTZKPl1FkrgrTWf8kxQTFJAgMBAAE='}, + {ID=>'key-4096-3',SIZE=>4096,PRI=>'CCEEBA3A5E569A0B551465A378927C200112F9B117C813877AEA1E01C6A9FA1EB71D3521ECF947C1E99AA5F89322A940BABDC5DFAC39B1D2346112B80DC70CC6199BC4D107908D707A428B93A770442E901BBB6FEACD65C2A43F142964722872BA0B2DB66A8F93A10A8EAEE4A940C8A51E0F96A39D70C7B32C941FF57754B0B8B4D5CE3FFB3FF11DDE245B91F6A9790CD0273B53A76287EA9F07272F9BB3DE915601392BC88299B81C2E93FD69192E30BD16F594AB240D72F7D45F04C62C7A2A48A90091ADBA629329EFAAD4CEFFAE840E00058266D2D392F252D1DCADD4E6227473D1DF1B99CDE8395B97E6C4F2B37E67767515B95BACCE0FD410B6334B1F2D8D3DD9D9D6E74E2C6638CB93B672F2F2CA06F96B7C9218B996AD6FA1EC58B43E55F9FAE2F3DF7E56CEF5B624B20728631070EBA15326F3780A631274571A2181741FDB721E51669F35A6AE8BEF601DE61CF880E6AE28DC06902B1E0124F2AF81760C73FE2FAF3BE6F0A0D98D24E6DA932150F5119F00BA5E4C52224530CAE4A7F6F2BC5B4E3FBF785D26B1B957B80BAE010EB3E0E7C441CD6E5F442D92EC6077960C2C646BC482F02FC5A7F03233615DD35310FA0A45D49C4C1EE18CF009F89B765DCBCA6254D485838DA088FAD8ABF77DC9972C7925B68029EFFFEEFDDAB0868EC67A4325F8F6C1CB2BF2197753FCC9C9928FC783C3A08F6A829E08F683C7E9',PUB=>'D73271F2080D423B6E9CFD1542BDA9EDD13E373C54F21AAF4C50275C5F4298BB14F2A2139B73D187F1D7BE27708C1AA49F8E3377B66F5B626EC57795E97A2ADA409862985A2607371B64666C7D5A186AE529B17F5E03F6F5AF13E6530C61B16FDD02CAD7B35628F275E90F6CA1311E7F2D26E042C30B4E24DC3BB133B36721FF685300483B3AF2F59F975C60FE3AD3D1FB76AB111A7E9AC46667D7D466ACD616964B33244BBF0502E218A71BE493D805EB8C06FCEE41194042B5AA72D0BF71489E4766D4F3D04E16C8A1F5D239069B27B861D5C91C4BA1A1D2415C07EC6A843751E0C2FF437BAE488263798D24CBA234214F7BCE7E1AC2D61C496CD7EBC23C874B088B833C999EBE495A13CE1EB8344E87C7011093C71EB82F5CCE162B1E7F7B4F26986C717673803C655E8958FABEDA9A41210E75EDBB61FD1AD2D0DA278D4E33ED85E3A44E78A6D9C46848643894124E212697118A76B907BFDD0BFD223C95CC37410A153F136F8493CDB9BC8A696DDC2A4F680258968BF653F057E2F699E5DEAD4521543E1A0A84B218981051C74F1049336DA1F6F42B551527D937E8BAADC7D2454F139C6F2F6FAB992ADB749B67EB1C3376C2A21183B4E2D00AF859DBFA0D8294AF0B0E893082128642A60AADAE35A67CAFD026FFFBDF2C22A78C5103DEA1B688FE6C6881E39F5A2D9FA76B3F966CD682A6001F8493C0F09C81501EC8CB',SIGSHA1=>'0z7pv3ZkLNZ7m2OCfeVsK/onLnHpPDrv0oVf5e15pMgVnCZKeGkwC9gMAp3iEmbYVdBxObKlRwFRitWeAqqbBWJICFIdxp144WEus/8gWWnM9jTTLSnuj/iWhylh539nQ+PaJ1GDJdLizmRFC/qSeLx8VLAz5vjlVZi1yg3ROjjJkkdJjysBx/e9PkfIeAnDn80WR64nLAgkneJcOvUla+Ld8RVjpzY6Lqr8W71Yi+pAczh2nE3zSKlE8Jjq7Oq17fmdkpluLqk9HcItooNfTCpJjBW+XMAuU4JWzHutmjQhGJmLQYnCRFVMmnC6qoEacVFeXO22bId3W5kquaiV6drJvisRwdenHIuNepbvP46bvYvArKCfBIFWm/ELvP8OmPJ3OIthNBVgyWaLFW1HmmuIOIXOr6SMmqzMxZhnLoP9wBPlgHz5guVPAGU15PTnpHSIqJSWkOqUoYbdIJosfZk43lvx+6f3KSjksddHoDQzvXKh7URZioLImIdZuThD2x6tTQrTdjl+foikq9OZJRDzSbF4ujDi+5plbcA6wDOJjMkIJSj6AJIXp35HlqeIVmddP8NPzhYGFuX5QBRKOSn7tI38pEPbWntLg21LndL6kkKUek2+yWoPkqqxdO+llXueK5uENnsfcasab7g6YGvxU9feFUEGtHNUlX6gM+I=',SIGSHA256=>'Ik1d9Z1GYsJYYrAKo5n212XICiiV8txKBH+0r+E4IdkIJYu0rbE/hQIstVoJ0jAFKu4P6Qsctad4Z/UfZFwlY3+LU9Aohimukb+ZHRoRPbxbncanE263OQJN72Pi4hny/L0w/7BNzhB6FizmkvTv04QBSoj6kLko1n2DZkYTGkjNcolEUgVBIecdWJY4y8TcXZ3O/85kn7clHNqC+g5wv7SAOiPpnaOHwkmISiLfFTQ5kE93mgvgSrI/GazXOFNbV2Kb2/KrQstyHgQMvgfWSDyOqyfJ/5UID85NeiTjoGNLTuk9X0fcCS0K210Nkbs8N+j6E/zF7CjTrgO81Xb8GA9p2bEMmKJUczKLy9egpcBKnDfsr2XFgPmBeej2RYnfsNjxs6vM5unVrIkC8207a5f0pKR4+EirXYmVIY6waq5L/oTvpvDdkn3uKYptPkjRWDxCDqjOLsL8kkFGS/fJ1TkSIQPhq6TkSRQfOcB7qMGGjeVnYoHN8GcVnAxOKb8wZcX7E5Zx1Vj6t+ibSooaYR7fDKU/l7gyhUEKDRxbzL79OUC7sZVE3NOSutdtgDqprM3A3unxCGSwe2x94hUto8RxR/hJTHIDgWiaGQZeucAzHmX+cw7QlmxiZQsVOghaZlXr4+1HS696bbmcjXDBng8LOPIBUWmGlaNPA14Cdz4=',SIGSHA512=>'Vu7cM0ta4RWQeXHIV+BkvhTrXM2gJP6NrqXAKN+eke0RSC39wxb8yuwuD17vzjOmv9JEfvzSKhANT9f2qcicxTJs7phwv/2FgSHCkAixRDQ71OneME79YIxw7C+Xq+jXNIVejYAxFBHL6kapDekptDn1EjEOKLdECVNeIDBQ1pFn1+InqPacKg5G7QxX47HyRJavTi85/HqOE1ZMZGuFXNVbSIsI4j15QkVhDtsv8hnkx47J//FLwpUCVtMwG1gfhh1jMFecppR/170wS+DoCOE5I1e+1HDfATaXDhlgYEOAGTNufCut9ag2nF0vEP5wPW1e093hOO1pEHQ7gWbrM/EpLqb5nh/85kVDrtwFrRYfGgxoPIakLhf4EonfKESamEsS1G6sgUo4iMTUuQR/zD77/H/pIpNghnuTh4hB/oP6u0Ztq+3DqX5ht6Bml7HnsFGwIqwJYZ2akq8+y61BNOSl0WoG/gYoqMljDKgWzfw4t9Qtm+qLTiAavMK2CxG6EoBrY/rjCgkHjReBVU7KChFSFiai/fHyxvClJyB/pygr31cjd4hUmOYIMWhfABt85Jm6rwhnx7kgK0h6PDN8nBuQJT8PBtwFtQ5EGwxQ3LescmhFV9502mF8aTxnlPyGfKhdOD3LNSnkaSQeLQvZzm6S8BjnuhkKpHfSdMegzqE=',ENC=>'uilkgenihQCM5wSfQflJbFiykXMbBrdidxfzDmwUDREvDPgsld4o/yRehSnGGVCbpNgXy7wB+9nlzd3wiSJu3URiqAX97greBaSV/UuBM4Ko3jMoQOg/UcTs5EfebQqoiPruje6SJa3T449S1RDdcm+71E2QvuCvHEOL1JzjznmXYVPIQjhpQ6JOuNR74eMrZecMaUoz5CTakhzhJY93y7oW0O2iz7GdbCNMK80NH5bJEyNvY3kC5zrB5KAJgJf6o3KRKXONtng5YT0HEIjyOS9uyPAwbsuNzHxvsMfxhZlyQM53OTy+AVwkrfTSptxHB77G2UChie/KCqx9ajwErGLT8DZhYUScozPh1KF7IYHqmn0YrnqTY1VEutODHaaOoxSkBd9IPiPjEKf28Hixq6QCqveV2Q5q8upzkSyTFLGD605nLCWjlGpiPUitl6Rlj6gJPMj0DuB+nl+rJtV9ggqpFhkwMR0Vm6Mj+3vGJUmON7dSbEol8Ede66eMbaCXSpjI3exkNqGO2MQw3JNuZNCU8tm68huqlqsRwUX13VRFEwRmzM/z4WaltP6/RhDHRDM5IXydTPcF+xbiZKMFIeK6dHvPHutQhjavIMBQibi0G5UQ4BMXVAbqETQfKR6RFWlBvsCgRs5RPmdOZaTAE80TqQv42ewjWjPqqQX0AcU=',PRIDER=>'MIIJKQIBAAKCAgEA1zJx8ggNQjtunP0VQr2p7dE+NzxU8hqvTFAnXF9CmLsU8qITm3PRh/HXvidwjBqkn44zd7ZvW2JuxXeV6Xoq2kCYYphaJgc3G2RmbH1aGGrlKbF/XgP29a8T5lMMYbFv3QLK17NWKPJ16Q9soTEefy0m4ELDC04k3DuxM7NnIf9oUwBIOzry9Z+XXGD+OtPR+3arERp+msRmZ9fUZqzWFpZLMyRLvwUC4hinG+ST2AXrjAb87kEZQEK1qnLQv3FInkdm1PPQThbIofXSOQabJ7hh1ckcS6Gh0kFcB+xqhDdR4ML/Q3uuSIJjeY0ky6I0IU97zn4awtYcSWzX68I8h0sIi4M8mZ6+SVoTzh64NE6HxwEQk8ceuC9czhYrHn97TyaYbHF2c4A8ZV6JWPq+2ppBIQ517bth/RrS0NonjU4z7YXjpE54ptnEaEhkOJQSTiEmlxGKdrkHv90L/SI8lcw3QQoVPxNvhJPNubyKaW3cKk9oAliWi/ZT8Ffi9pnl3q1FIVQ+GgqEshiYEFHHTxBJM22h9vQrVRUn2Tfouq3H0kVPE5xvL2+rmSrbdJtn6xwzdsKiEYO04tAK+Fnb+g2ClK8LDokwghKGQqYKra41pnyv0Cb/+98sIqeMUQPeobaI/mxogeOfWi2fp2s/lmzWgqYAH4STwPCcgVAeyMsCAwEAAQKCAgEAzO66Ol5WmgtVFGWjeJJ8IAES+bEXyBOHeuoeAcap+h63HTUh7PlHwemapfiTIqlAur3F36w5sdI0YRK4DccMxhmbxNEHkI1wekKLk6dwRC6QG7tv6s1lwqQ/FClkcihyugsttmqPk6EKjq7kqUDIpR4PlqOdcMezLJQf9XdUsLi01c4/+z/xHd4kW5H2qXkM0Cc7U6dih+qfBycvm7PekVYBOSvIgpm4HC6T/WkZLjC9FvWUqyQNcvfUXwTGLHoqSKkAka26YpMp76rUzv+uhA4ABYJm0tOS8lLR3K3U5iJ0c9HfG5nN6Dlbl+bE8rN+Z3Z1FblbrM4P1BC2M0sfLY092dnW504sZjjLk7Zy8vLKBvlrfJIYuZatb6HsWLQ+Vfn64vPfflbO9bYksgcoYxBw66FTJvN4CmMSdFcaIYF0H9tyHlFmnzWmrovvYB3mHPiA5q4o3AaQKx4BJPKvgXYMc/4vrzvm8KDZjSTm2pMhUPURnwC6XkxSIkUwyuSn9vK8W04/v3hdJrG5V7gLrgEOs+DnxEHNbl9ELZLsYHeWDCxka8SC8C/Fp/AyM2Fd01MQ+gpF1JxMHuGM8An4m3Zdy8piVNSFg42giPrYq/d9yZcseSW2gCnv/+792rCGjsZ6QyX49sHLK/IZd1P8ycmSj8eDw6CPaoKeCPaDx+kCggEBAO4Esx+B5FV2tQYgTvy14ZeUyky4hXLlX3VszBFoHmi/T0LcFvcphXg1001/Oppds6VRbnJ8oJNBVhCjIcy7MkyYOVH6Vn9t81SO21Su50h1dRSWQIH/hRwcHOn3kOe19Oc8r70sdB3DNcDZwvZb1HCA7QQb8XYn3/I2bOoVhqR7nFbH6gJr+7akLj1SnBHxXAkP7HhCydYvMR15SUlafglLjwAaoOX5iuFvhqnQf33NhKh/f5XmAA17WLwmc/KjFJOrqSJIkOVavBrPQCFKRdPEhn9KNPXvyy2ETCmnvaI76b4bpMryWIS65P0ewc+0NbwJI/TJY5zyGRRoqWHuAEUCggEBAOd0YP+hBqNDTb0R4pPpDuh+0u7/l3N+x50ke0FXhoMNMMUai5YLJMPcK/vOhbXuDbkUBfdD6rbQcQv6uz/APFOC3bHVd+l6eVKCyIlyQJM75sA0WGspS2vJrb6vlmAv6CII+A6fzH/iRxrwhtIcMQUJFl/Q9x6RYKRU2EUi9uhKLiVNfbJO47D9h//5dBAswJW5D+WgUzqmXb5A/H6vsaoCKxm5EXM9Yhg7yU2gKvQ+UKz88e57RZuln0ToAnHotCB1mFffyx/WHhhZSM1SogqVBRPrexTo3tcF0M+NnjRf+OTrK+keyhX9nYzrnva9faXtQ61dMkY/muG96tI93c8CggEBAIS/HEObRwSfQxDanhL1QY8vzbACTXMqGBY+ioW+ww76e7M3WpuYjbbgliunpMCJN/Mgum+hsFDQZLa8tNIhKUlssLNW4j0Jzmc/kXXmYlmYIKdNsUaPguaNi1a12xxP7/mzb/QawdwDjowzJzgNOStRzF65Uu7qCE1nK1FWlhRQWH5R2uJk5SsU4DEVTLP5H7JyLhlYbodFJKhih4wgqyB2Apg1Qb1hcqKOd9Vn0mMQZ0cubLLmZusd+vxcmdgeOhCt8ZOMUzuHYle1dPfcG5ujBLwjX+w2Q+Pr4CpvQiUkMxXzBvKlPNcyARpmuAMmZ72qf2I7m5HhuDkYsjdK7N0CggEAbc9cOcu273x+BGbY3Z3j8dBB2RwwSZ5rrBVj2NNiwQhgDBOVCCHPVpE92ODZtT/1CMsELZTuZb+s8qcJcayNsn1TGw0RMBdoOgpMhFFNa80upB/xlx3nZ4MuyFpb+NShyIwCzEVqa336iEB3ZnXzl9UA5YKpy7njZPPQC7UT+Y9AJ3iFWzRseEtA2+QI+aeR0zcS4LnY4umNbjc81AodO3B97F1OdyM3SBINZqPH3Us3UWtMiP25P6grUTDWAB8MXp4MIhzOLROUAa9Sh/9dW7Hpz9KX+YqmNtPOhrpExcqGtm0QzzBJZneF6Rbcu2mZlEBmLHkb4hJJNDK7lvW9JwKCAQBdIeSUEwgACb9wm1qgwxlAxgq77jdt9lNBcx6etNOWoZql/NLFYCMF8jwUV8Tf5aJL4nuE9dyf6oZbDcJx6iWLy/B0syiDNfiscsFFKIjj0iWoTkcGc02Ry4Z2RpT5Bu8aRlDn25MsteseCMs/SXfJOmwcGT7o2c+/fEn7uHVmt2nu3vKMFFU04IAFE5hKs0w+2NQeF6fT60jb/uE7iV2oLHQRb/gu0LtnC9KVLl/FLvt2jVdm3D3t9XthTxD63jKXrli5RW/F/9bwpZjwi4rG8Gylu0eEVdmwzojsLH6WD497tlcBdKE2kBDza0x3K5WpUHOwTEzdbXPFF57r1/ro',PUBDER=>'MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA1zJx8ggNQjtunP0VQr2p7dE+NzxU8hqvTFAnXF9CmLsU8qITm3PRh/HXvidwjBqkn44zd7ZvW2JuxXeV6Xoq2kCYYphaJgc3G2RmbH1aGGrlKbF/XgP29a8T5lMMYbFv3QLK17NWKPJ16Q9soTEefy0m4ELDC04k3DuxM7NnIf9oUwBIOzry9Z+XXGD+OtPR+3arERp+msRmZ9fUZqzWFpZLMyRLvwUC4hinG+ST2AXrjAb87kEZQEK1qnLQv3FInkdm1PPQThbIofXSOQabJ7hh1ckcS6Gh0kFcB+xqhDdR4ML/Q3uuSIJjeY0ky6I0IU97zn4awtYcSWzX68I8h0sIi4M8mZ6+SVoTzh64NE6HxwEQk8ceuC9czhYrHn97TyaYbHF2c4A8ZV6JWPq+2ppBIQ517bth/RrS0NonjU4z7YXjpE54ptnEaEhkOJQSTiEmlxGKdrkHv90L/SI8lcw3QQoVPxNvhJPNubyKaW3cKk9oAliWi/ZT8Ffi9pnl3q1FIVQ+GgqEshiYEFHHTxBJM22h9vQrVRUn2Tfouq3H0kVPE5xvL2+rmSrbdJtn6xwzdsKiEYO04tAK+Fnb+g2ClK8LDokwghKGQqYKra41pnyv0Cb/+98sIqeMUQPeobaI/mxogeOfWi2fp2s/lmzWgqYAH4STwPCcgVAeyMsCAwEAAQ=='}, + {ID=>'key-512-4',SIZE=>512,PRI=>'EBEC266767F57B6546D65E283663987BA1240438E5A5BB1B6BCF2C107032285B32036A0E6DBA174BA1F358777A640DC7A97CB53BE03A6DA9DEEDCD44FEC74001',PUB=>'EFE10FCE3C6BCA1754A8CD1FF35663523C8F2130F05485539FB458B5DB787CDE0A9B3F029CF554FF7EE8DBBF9C366E353997E220C2F6FE445FACEC5748D96489',SIGSHA1=>'ZVcGrrM5ETnQ5PYONgyZw91dHWpUh/GPiHtxB96sN/9+aivi4hLTvX8bV4s4wXyVw75af9g6ITN2wEfmV5KWIA==',SIGSHA256=>'S3TE1TltPDVSTlV7VINZqgO/MNtBXGwD70Jc+hnAiu/1YRptX4/W66RYt+w3rklyaEzS0j94tjpkR9KOob4AAA==',SIGSHA512=>'',ENC=>'PVIb9rhsFtTY8xvZELeZfGPdusSKcpbPo0l1tTeR+AQmp5TPk2fG5lybdOAcgm6o4Fwn79ZnlMGH/XGyugXJbA==',PRIDER=>'MIIBOwIBAAJBAO/hD848a8oXVKjNH/NWY1I8jyEw8FSFU5+0WLXbeHzeCps/Apz1VP9+6Nu/nDZuNTmX4iDC9v5EX6zsV0jZZIkCAwEAAQJBAOvsJmdn9XtlRtZeKDZjmHuhJAQ45aW7G2vPLBBwMihbMgNqDm26F0uh81h3emQNx6l8tTvgOm2p3u3NRP7HQAECIQD7YqPn1wBWps2XLvMlfhom8Ye2mvmW0N5D6zNUKYX5AQIhAPRIWXP2cQSNJVw++lVgH8X/2y08bnJD0F93tI2DHCOJAiASW6fAnJDnwxKsgb8787OROH5CtZqYivRQXXLIKKgiAQIhAM+v31XHNclf0169MIp7oift4sNv+Jrvau5v0LLrwHW5AiBHRVVGyESfYAKa3AmIVlfIKw/81zaoIyLI6Cr82Jv4bw==',PUBDER=>'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAO/hD848a8oXVKjNH/NWY1I8jyEw8FSFU5+0WLXbeHzeCps/Apz1VP9+6Nu/nDZuNTmX4iDC9v5EX6zsV0jZZIkCAwEAAQ=='}, + {ID=>'key-1024-4',SIZE=>1024,PRI=>'138CE7314CD3B9C5BE126A48FCEC3007E04E1AFF13AEE9BCA37C87DF0BB386D925091B52E150879D8BDF7CE472FCA79E9874E298DD8CAFC2C38B98636CA0B4D50679897C1C7609F2A490D9591FC5EEA9E9041D9049CF883EBC8B1862C7EA84149B0D8318C02C498C23CA782376B5288412124A6AF43BE62D3DF695230C17CA81',PUB=>'A874AEB0A2CD88A1D218A63FA7516A8FEE6E1AB2574EBD46853060C8FD31289D1C25707BBF390C1E8B3E28631582BF2670889E3FF456E17CD8B330E7BBBF284078C16039DFD348FCEB34B89AC6429C9B7248A40C8B3516E5880336E4D679EAB197006513809A172FF959BBDDEEBBE2243C33A21CDF8DBF1BE485D135011834D5',SIGSHA1=>'GFjo3b7o7RXAX7fqZn7BbAOOrRDV5ZhHbIFfjhiZZTBLBbci1VlgW1SJk5phkENuBnxU5QyCdqZy5AosPlKqTlc4ZUsaZQ1EtDRrB4A4+BEAkgEwSIvUfV94Qfr6eVLpYoCL2zXWLjQ1Ibk6wCbOPMSprFpoREA1RIiEIHYtBfc=',SIGSHA256=>'AtDMYj0itx61ffpcrEpEaHT20nTr99I+EyIzHzyeWpv6SZL59dErA6jomYFXnB0zDUYEhoY8JDYIiO4i7BKWdHij/ZFeFI8zoaYYPWxg6R/tSJjkL07Rwnw7OJdg0taNFGLeqBWPMx5FmI/UemiMk/zM8gYutdSKkKj1AabUA68=',SIGSHA512=>'iUgH8mE3ZuyELgNNClTZRAkkHg8hCLpZAqS6ajG78KNXsDW86jKH6KfKB3/MDcAACBBX2hraO+LtKOwfDXKQDb8WJgOlPk1m+NJpLWs6su532pVkO61IIf4erjGNgPwj4lpBg+EIm8ROrMu/NqfaUR6XhAZze0rfuOs+GFDsDk4=',ENC=>'M4ppg8LSgapManQogWY9YJfZoxJ6XkudUyrdU1lJg7DDpa8tWhF0Fip62DlikQuUZGdymy/B+OyMj+pyrx+J3l/a/9WZg6P8IbWQ7OKP3I6T/i52Sj235sjtEbi9OMp3pqTbZ0oN093Z534TdOM1PvTeF8/ev9p6sxTfATckf0Y=',PRIDER=>'MIICXAIBAAKBgQCodK6wos2IodIYpj+nUWqP7m4asldOvUaFMGDI/TEonRwlcHu/OQweiz4oYxWCvyZwiJ4/9FbhfNizMOe7vyhAeMFgOd/TSPzrNLiaxkKcm3JIpAyLNRbliAM25NZ56rGXAGUTgJoXL/lZu93uu+IkPDOiHN+NvxvkhdE1ARg01QIDAQABAoGAE4znMUzTucW+EmpI/OwwB+BOGv8Trum8o3yH3wuzhtklCRtS4VCHnYvffORy/KeemHTimN2Mr8LDi5hjbKC01QZ5iXwcdgnypJDZWR/F7qnpBB2QSc+IPryLGGLH6oQUmw2DGMAsSYwjyngjdrUohBISSmr0O+YtPfaVIwwXyoECQQDSxSxtScsdnADiCqd9btYFHD2wC078a1kWqBu5pSFLHiRB7QzIe6UT1alM49SoiHW8lFGU50UtqicTPzV6gf9xAkEAzJru4VIsTdIwjMaFdJ0rGCF3/ABy0fHzixNzjs8oKA240LTNl9cInM0Z6z5DhVdZ/4JaP/zmRiW8gtLV0PEhpQJARIi0n3zFPQWDC/0m5RRrJxI9xMaIkm9dco6LJVxabRCJ/Z3U8EO0M7Tf7g6PEZX9oqoftOlWhziyqAF/pCwtIQJBAMbrint9zJ0MUS9MgstRUmhvgZt7RCZhOQppqtuZA82NKbWfUpLg+PqZXS2cp0CoIFONg/jaA3cHkTMPj9lH1hECQGq/MEn5L4zFw7uFBJsuQyhyobenrVsmrN6S2kAqEpWAJq2DwGtmUcdyR4+zxa4EilsEcm++bDtoWKwXIKmLgRU=',PUBDER=>'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCodK6wos2IodIYpj+nUWqP7m4asldOvUaFMGDI/TEonRwlcHu/OQweiz4oYxWCvyZwiJ4/9FbhfNizMOe7vyhAeMFgOd/TSPzrNLiaxkKcm3JIpAyLNRbliAM25NZ56rGXAGUTgJoXL/lZu93uu+IkPDOiHN+NvxvkhdE1ARg01QIDAQAB'}, + {ID=>'key-1536-4',SIZE=>1536,PRI=>'55B17891FE8D81B361F6EB4A32E996A954B21F79FCA5E9B018BE0864DFD172F80244DDC6F657D8B6AC9E388CF699776A10A043C70843A32ADD955793D2A5E0F5CBF12CCC4D0111CE1A0A63B49CE7DF67D459D4250B3D30DCC8D2D48058C17C7361D984F1166F84771E0A6E33F08C077B5877FFE177EB32638A3D3B522FFD351900B8E4E3867BC9E4A7800C4697076B686FB2C4887CADFB2E1EFDE634E3297873DF9E6EBA0E0CD2D01BD99CCB79E467125B1C684B6A0FC7549B0389396A93DE01',PUB=>'BDF6A20F8278E264AFA0CB65813170B2D2E5F465CC63F27975172E8AD368742F26BB3F1B4B768DA6C0B11B9052E81E3BDA442248C5A905B3BC878B2552B14D4E6CE391D557D9C03125EE744D2D082D4D6056CDCD379C7D552FB1014F1F040740D9FB7177561698A607B62697C6E1317EA5DB4F4004C2AD67373029C9F381BD01E3DC4DC9C4DF2F82E59C7E6C3477D22BDB5A98D3A85DFD4B0451D05334A2200FE145713CAE382DA4B28FAD8DFB6F11445DC221029A669941C6083973AA66E3B5',SIGSHA1=>'AliIydMDxlcEgZrUFEicveUH20lhn2CywgSkCHzQ3H9I51f2A8R4Ar89W6MuSARw5y42C8GfeZeeHAidxV3QugLsE5sdwlIMAG1D//js0g52CdyUBi9dKcIOtPW/WhagH+QkgjlmDy8AMFkX7pGx/VzDK94ZPQqvi7GwNb6EqnSWbjGFJeUHm/toB/9xj/Leg40ExIbfP7y4mXR26qZD7aZvGUQMIYGiO5MxWU4zJx4dhVeor7n9pbabu9/8qy2c',SIGSHA256=>'n/dvS6MCki66AQTUUc/X0RbypY8dNSDTKgD6rtKwIIpKEQwvlvoEmDIJ2pn9zNfYwrDeMR9rZjp4QCSF/Gv19F6fU03OtrhJK2Bl/gQOyOfd0lJEjIiWZTlSP4uv8iKw2AuMAFOjilDuch10JfhGtf++4p12TEctiDnOx65Ekt0GdpQ59gOiA+f2/3ydFk/g5nWX3wuCRWZmMeKLDiPnU477UcwheNXu/sezl+1phJijNuXOSjx6kCCufGJUZEXJ',SIGSHA512=>'ZR31PkjCEvSAE1r+6C/FZxM1/G8uJKU86QTjuEBVcjW0EDckbOf9oWI1JFc7Df8/xueCgXoChWAyF5GSB7Untza4hvCTnaT6pqW/GQXnXwDvshtFLnM5T0lQdThhINVOd1/N7ThKjXv60AA7Ml20bJQtOIc0HYkANjkYIZT4jg37lEyhgXqqCT2UQFt4AKpL6raDnJPTiSJBTWgSU36JFR9BQRHAd4oNyEaVfymjTVaGwYPgvl/NGcoP63GkZ89e',ENC=>'Iy/NxEEN65dGboxz9Zpa1GeyZZgOxsKkJfqvXrhMIWof02JEQlTWWu8AZmyM5clQD93l11Qc/6GXvki+R4pgNIrCuL4qb2nF//6zdSpNOWYIW7oKTRKUBh4PDwZU87QQOtFmLLxE36ZEeu+eG/MurQyC09QK0i6Ti72jxjuVD4+l5/n9zhTMXap4hwlRHRcoO4wjyfTNWZwQDUtkJTlWcQV1DBIJb4gskCvpdAGgCWC7ULZHJX8OOIbJ2Iur8fhS',PRIDER=>'MIIDfAIBAAKBwQC99qIPgnjiZK+gy2WBMXCy0uX0Zcxj8nl1Fy6K02h0Lya7PxtLdo2mwLEbkFLoHjvaRCJIxakFs7yHiyVSsU1ObOOR1VfZwDEl7nRNLQgtTWBWzc03nH1VL7EBTx8EB0DZ+3F3VhaYpge2JpfG4TF+pdtPQATCrWc3MCnJ84G9AePcTcnE3y+C5Zx+bDR30ivbWpjTqF39SwRR0FM0oiAP4UVxPK44LaSyj62N+28RRF3CIQKaZplBxgg5c6pm47UCAwEAAQKBwFWxeJH+jYGzYfbrSjLplqlUsh95/KXpsBi+CGTf0XL4AkTdxvZX2LasnjiM9pl3ahCgQ8cIQ6Mq3ZVXk9Kl4PXL8SzMTQERzhoKY7Sc599n1FnUJQs9MNzI0tSAWMF8c2HZhPEWb4R3HgpuM/CMB3tYd//hd+syY4o9O1Iv/TUZALjk44Z7yeSngAxGlwdraG+yxIh8rfsuHv3mNOMpeHPfnm66DgzS0BvZnMt55GcSWxxoS2oPx1SbA4k5apPeAQJhAOKQBDvCkng+K0QPqSD42TxYxQohMF7RsxeywyXH2WtCtYMMp9RqdCHwNuhYtMK/gVOQHZx1RQXcRTREsz6Bk5iexT0y5oZEPUZXBitU0CO7EzPtLvQFlK9ygPrmH3hzoQJhANalPu98GLFoJrGB3rD92po1pMMvdP6qFIL1tyRd9IubCghu2XM3LeJHsAXBukK3S7PszeZhsnpKDCW1lJa3mk8Uny7NyFQBDYRzvQ76273aLwettwUDc7et0zNbY/Q3lQJgR6Sq8grRLlzaaadaICcQ6thXVqCwHwvIylGpDCVqR1TM+SfjWnRfTOwdMNP8NSlByB7mfjdHIFdLOwAOflGTTsvGK1gRNZwWlEuok8M6HlJl/CGgm2G4ZtKanrxubzSBAmEAk7DkGxjCTN+jMCRyPEqPregXVI5E7C3PK0UzHPzhFWY6gw7y5IolMjutbGieZuWEW2snScwTaH2m2hOVCBeRP7SqyyOhIdwPlwGkJriJlpqYHapz8ikr6Ejct8u8fP/5AmBkbTPbfZID9SPHe2f0AnaqxkRWlpT/mhfFXraASJbxZotTZCmHPvr4wwGu5HtOTqitIROtqJA0wSg3fz98tNBhPdBXqUem1aqhXFvKY36s1uqWXh+aQ8mVnARUNqsVzvE=',PUBDER=>'MIHfMA0GCSqGSIb3DQEBAQUAA4HNADCByQKBwQC99qIPgnjiZK+gy2WBMXCy0uX0Zcxj8nl1Fy6K02h0Lya7PxtLdo2mwLEbkFLoHjvaRCJIxakFs7yHiyVSsU1ObOOR1VfZwDEl7nRNLQgtTWBWzc03nH1VL7EBTx8EB0DZ+3F3VhaYpge2JpfG4TF+pdtPQATCrWc3MCnJ84G9AePcTcnE3y+C5Zx+bDR30ivbWpjTqF39SwRR0FM0oiAP4UVxPK44LaSyj62N+28RRF3CIQKaZplBxgg5c6pm47UCAwEAAQ=='}, + {ID=>'key-2048-4',SIZE=>2048,PRI=>'B92632A9156C7BC7BEF3CF78EF1DED9C189BDA23C28FF64AE8D09B76BD3425EBCBEB5EBC8EC6A310F012AA4B4A20A3A7A674DF2DD9E8060C88C818BA242AED224A7A8D32094981D3B3C1626BA0B25A05E52C10744A8BD05BFAB5AD4021D41999231AF5D7ACB81B804989F47157FE560EF30A39F4DE0DB1A85F01DCB6C3D237DFE838082BE9E6D5B519DD0DFB956F85BB9D71CC5A90EEEF06E800ABD2E1F70F662C255EA8754753B18DBD203EB2D5465B7FA1424F578CBD754E1FA4EAB375C96885B95AA50E69C379CD77D29601F4AA3FEF4EAA19014CFE3C7005E3CBEA8D0C30A234F48DD8D9197AE3AF18F50607371A890FAC2F9B522AE6D32DC3434D876EF1',PUB=>'C4B124670789C9B6E294B1BE5EDDB4A42C00DBA26B271B369A35AC6E2B5C21E946877B8A7403AD0DC2D2C1D75C05052F27565992075E8F313D63AB8127BF0998548A9D9DEB5B806D1C60484ACEB0596707A7F32769FADFED0E8D36EFF0E120BE02909F18286694F3936FAA2196EFABCCA18FC11EA98B04B3AF747C473A584BDF591C39F1A6E759E2E8056F17C736B5701AFC6D81B7DDBA185B633D9C412A8EFA35F4877CB169E03B2926C3A2BE17B40831563C40B89E3DC8CF48AEA5DDD751603A9D5CEFBD8BE271DF8D4F3C410747437C07AFAE8FD6C05E07DE2BD04EDCE2214F752F28434ADE844C4048772B406B1615581459B882CF619ABB0FC768628AAF',SIGSHA1=>'gOm25U+tNjkUR1HD0Y8mHfwsfD9I1vxVQf3euMk1TS6xXY90VoDHsUpzBOASdwOYoz8VXFUeBiIV8aPxpuYLSlcH1+lHSWFKuID+7ScwyTSt1qAKQAr7u/lZyKC7KjI6JTogqpHtMKD1SzslkHTmDzD7qKg6o3nf/wwbOkrOXY4g8amqBkF4OKozWCdedX2Ez2hqEPPIQQdcC1bDO8zID2UzqMrhD3JK/dzxOworV4P0aCAQU5TFgTe+DO5K6F/fY7ljA9yhhFf8aX4bZ2r5AWApLmOpY9oGTGmt21CBj4t0h/sH3HxSW5Cs6cG96MMNU4nKuFzQZvFhP6U7SFET2w==',SIGSHA256=>'OjtRR8XDn+WWenwNzdUAumtq+ZFBbrG2hgmGccSOkfQ4D4+hHRVO2FzRe/OXB1qnlv0QhEg6t+1hQsLYIZM6BPg5MAk09juHCMVqpXk3LkHrmbGzN63Pk/C//MPzUGuAp20+bI9EXJK5NORvxDx6gUK9AlyDytAULMzvNd9DgdffTiuabtKckiclTA1YHTcq8JPGVNg6tL2/hWRJme1Pn5Lee5aPlPD63oCwRjvgK7WAYZiBEvG6AwgrgPXgusIXR7l4cDcCMlPIV0YQ0oYxiutd7LVAwrU+t5vFAy/ZicccyJjVj/AuBqrsA+a1JIi/mUwTgqb4eZKlPuxcc8ZT4w==',SIGSHA512=>'RA40wsW4nU+cUBBs4fNmBWZgfy6NjXfAw8Mw97+x55QZXLRuSJODEh/kgKSzuCBzJdE8g+Vi2Ll4sL/VAzGr3iLv3s1eq4YH1mLHODoAC6593tPum58b4tcg7R5TwN88BIxDW2TwEQEyxi1bQy2lK8S1zfAXewQuj1KMQOkO1NIw++Ok78TG6dyNW58HFU+e7nXGxj+nxLt/1uFZk4aATIyLKvdJv8wx4YtCY1i82AAzS2cY+J55qx2IItTmbjuBW8uctbrASGXpz5DQC0KWD1GbqOWYzyteUjcTCHEkMr9FGLqV5Mli/x9SoTIow5dQ0NDyWHNiG9+4MywbP1MBJw==',ENC=>'YlUUrLX04jonBaZpHJsA1z7sf0hCdq3r15pyJwAOtIItEwAJgJBBdBIYij9P9vX6siIi10idXX2u26qqd7Y2nRlNApxcEq/lpsygnrS2xm5g2YRzlOPYjSt0Vj3tJ5XAaRMr+rZ5qXrZl+OABbLlKe6Pck45daXglPwC5tETrUquUUuTwFhhtHOpx1yIwpTSaT2HJdvXJJl937g7hP21SFBEnwFd9uizKZ4feG44jWQbxJ5AWtd7x4Ya24nJynEU7rpiJ1FBcSvT/cQA0OUCsXGlU+o7dAo5ZifN30zI3b8+U6SDVDewHQ/gtLX4eI4StrEwQ9S4oaYLQSDx6ZpBnA==',PRIDER=>'MIIEpQIBAAKCAQEAxLEkZweJybbilLG+Xt20pCwA26JrJxs2mjWsbitcIelGh3uKdAOtDcLSwddcBQUvJ1ZZkgdejzE9Y6uBJ78JmFSKnZ3rW4BtHGBISs6wWWcHp/Mnafrf7Q6NNu/w4SC+ApCfGChmlPOTb6ohlu+rzKGPwR6piwSzr3R8RzpYS99ZHDnxpudZ4ugFbxfHNrVwGvxtgbfduhhbYz2cQSqO+jX0h3yxaeA7KSbDor4XtAgxVjxAuJ49yM9IrqXd11FgOp1c772L4nHfjU88QQdHQ3wHr66P1sBeB94r0E7c4iFPdS8oQ0rehExASHcrQGsWFVgUWbiCz2Gauw/HaGKKrwIDAQABAoIBAQC5JjKpFWx7x77zz3jvHe2cGJvaI8KP9kro0Jt2vTQl68vrXryOxqMQ8BKqS0ogo6emdN8t2egGDIjIGLokKu0iSnqNMglJgdOzwWJroLJaBeUsEHRKi9Bb+rWtQCHUGZkjGvXXrLgbgEmJ9HFX/lYO8wo59N4NsahfAdy2w9I33+g4CCvp5tW1Gd0N+5VvhbudccxakO7vBugAq9Lh9w9mLCVeqHVHU7GNvSA+stVGW3+hQk9XjL11Th+k6rN1yWiFuVqlDmnDec130pYB9Ko/706qGQFM/jxwBePL6o0MMKI09I3Y2Rl6468Y9QYHNxqJD6wvm1Iq5tMtw0NNh27xAoGBAPAnxUlfLwyN1z7oywpao+QBjfeQV77szwqC83dtPSoRyp9Fq2ATqyiy3DzSIHescdQrysC4JF0DmQ63Zfg1LMzh30TPzJcrDOB/YcbYsypC6by0rr+1MXgC15keMyLVYjYH0YoT4ry1lfE0cYe8s88hKMh+oTpBa1+NnVyitg1nAoGBANGrRhw3/UneF0LGpp95nrpvLwEObjouj3zKR79G5CfIGVpqf31h+MxK8t0t8lVVgNoTzHJhAaLIIGyOCDw+gj/7hQ4NPPzbzC/+WF0/8vWXBFuU8DzLpgoojd3tPHOY1obnC2rDsE+SEDqmkZRgGB/M9OaH9jccxBb/dT4logN5AoGBAL0aQ/Irfiu/gM8rlb24c7b1NmnLAhz38WvQg4/1t6Tpz4gs3u5PboYkmOFXgHNbmWI9fXDVTuTjEWGSLjwM+xL1hM51Zh9eqcwY4dAnEKVlfRG3oKaaMbLTYhtSuWdjaOssquW0FOUNg10kM4VzpI6kCK4fcCskGj1qkI/CG+JfAoGASCVuV5Fwh7VzPZgLh76avr45Z1ym00BoQWF9dLUZFxNEnhcdTXCj4vA7R55iz7g/QUskw4rbvD6u4YuyC8DaoteSfjZR8RRU24LitxulJ5rSdgz26YSN2tr/jgjvDzvdPchM5mz1wzuYeAYO/AZg5rho4NaSA37TfrJijoL2j8kCgYEAhVKy1HTeKwvPPutcFfgRjn7sS61XpTkCAleDjIGOOQ+kz8zuTwONvotEoMd6HFiMeV3pM9zMyFk7rRrlJPmvecjwTznKbCVA+oidUFQ70h2fAhyg3m6ujZKuZjhMwkn3WnR8H+r89+wfRZMXVHfuO/x0Z6/uDe3c/zBZNpViQb0=',PUBDER=>'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxLEkZweJybbilLG+Xt20pCwA26JrJxs2mjWsbitcIelGh3uKdAOtDcLSwddcBQUvJ1ZZkgdejzE9Y6uBJ78JmFSKnZ3rW4BtHGBISs6wWWcHp/Mnafrf7Q6NNu/w4SC+ApCfGChmlPOTb6ohlu+rzKGPwR6piwSzr3R8RzpYS99ZHDnxpudZ4ugFbxfHNrVwGvxtgbfduhhbYz2cQSqO+jX0h3yxaeA7KSbDor4XtAgxVjxAuJ49yM9IrqXd11FgOp1c772L4nHfjU88QQdHQ3wHr66P1sBeB94r0E7c4iFPdS8oQ0rehExASHcrQGsWFVgUWbiCz2Gauw/HaGKKrwIDAQAB'}, + {ID=>'key-3072-4',SIZE=>3072,PRI=>'19BD174C627D45201D3EA4572E9C4FE90F1A130F823941F31D5F720537EB20C688478772118334D717C9E6F85341EFD6F38CCA72CB6FD6F3484E930CB14E77152891EB66817F35AC80ACD2EF8B363D029EBCDCF653FDE00412501FC4F1DBA28411615384CD0E07A34CFB04C1FC21C2837D8053A2D8D303583F84A2EB981E75B9B4A4D2EB1369516E8A3D403CF8BCEF08420B932C11DDB81DBBE1C91CB96E477D5BC477F4AC8A6FA3BAECFF47AC2A14297BC8F4643910A4F69DB589928132ADCD21902C1C4A919098D3205560CDA13E6DB7BD932CBCFE04EC0B2E38F949E0D3C67546C39D23261BF19F93E28AB01771837450406E347D088ED134EFF599E40EF3000379F4B8EECE6B7026A052A457E0ABDF1900E545F3965F7B3BA6587CAC8E4EB96D0A7C4E896410AE0AFDE1A98D0C3C87C3C05550FC827604AD88B4EDA685CC5CED1A575D112E1F23F216216F4D867EEE40680CC77E00E3D9F28975039E458E4E33E8962387699F92E76488DC058352F9A589551DB859425A93C1B7DC17B521',PUB=>'C34D99317675E56CA42B158B0281207F111398C80C5A58FD75E5027AD37622BA590A46E302CB571EDFB13D54ECD4AB5856A8D435A51561C18E6A6363FC6B12287A53864076BAA5CC14C98A38CB61F76E0BA9ADFDF4173CE89087B1A9EA249634D0B4D485A23E7134645EC7DCB211AF3D169C1E16F47746AB58254CCDCA87FBBC9C197A33D202B14D42F34C72AD18265481765439E34D63A9B0411E656276C3CA6395C32749A0FAD164A62AE111B00A89F14FC42989FFE1DD29D393FE4DC03E99C824B3185EBD67DE0AAB771794E4750E4791C204568B6070225373E61227F61914E3FD5C978B78E7F52DB16C1FD8F99423620E691CE020F1C11B4B088476AB28A3CE24F90F6E9BB736A9EFEBA31E387C52317EE51632D17298B3166254F05A348223047372C34DD4023938FB189F5B4C8A2A2AB3CC8E0ACF6C360875BCE1DF7C6D33472894E76960EECFBA8E5DE31676E90D4761612642C5861B1EFA848C041626FCECFA0653880FCC744FF6027B4080A74FF537F6F83C4975F7B3F64E1F48E5',SIGSHA1=>'JE+V0sgCaRcvPPQ0Rrfa4HPH+S9PFYrlvUmLgqtcsZ57zucMSohFFzd403aKNNYsHUt+7Zfn1XUS9Xba1iizCiocpJkwW5DkGCEBYbxFte9jrbrA0vKSNbR5UPtLfLaFS0FEZ3WkLh2FK+9HlkHHxJ9Qjn9P+6AwFBcMiSAkSE9k3RbqAq10i3OJvse+/HQFVzr3XbZURMKenopzlOnksK1/xy1ECvA15scCsmZETmwFJikLap0ZhyIDHbwwMwRDzt4fM62yujHk/njYT3cmlXEup/44hY2ZFm1Y3X9+ztKCjO+auEFbLbYAr9cXmbqYvV+sKM6dUsAFMQ5GhHImefGNcoRA/Quy3HpiHj7aZkuA71JXESXrZbPeT0UhwuO5ElsJqbugtZfrxvjVWBoMwnoXGarxqbRj5d6xGJGD73UsbGEqggJRXoxkRWhfi84OO7fVWWLdvqinx3/QoXD60zbyu3hoKOzNLisoCnZZOBmNjxzdWEMVltemFSMH1C85',SIGSHA256=>'XlU5ni0u19ozXRFP7hkkohW3gQ/LN10vSDiYcBDsg6L6agVARqd7fdEZ2Ir6Co9aDz1vdJZcsuq1iKyzky7y2Hvf0A2NdXz/79GuH5IQMCRXU05yC/GqmlY6DZp4zuIWxDJlR0tIBHt8OeigITQa7xkJjv4rFRlO4fggDDIqmQkRltLylrwBb/XhwN24c8K/1lz1xxgmwU7Ju2IIfO5Mhw6RYkixRSNqUM00gpFUH1C3JgDOMKznoOusi7F5dKkEBFREO17EeT7zBkyYc/IVW7gnFMvQ7Spyp7l9d2jAs0CPV/p91RAC4d5y8XMRkEqVNqKI/qVFWC1ffWj5ki7xaw2Cvf+pygz59ssDpkKc5P4KIV1QsH+CZ//fuV2VBim3HXDAKYWtcbJFGzfR82j7pEeti7FyXcfLjWt2gqRQVNkgLjwQQ1gbyIVO5dqgekrvnVEwlcNoULE43laCVGaHj0JtJ7ZaQ071K2ssHcPMT/XHCCy3IsU4gwWM3HphSske',SIGSHA512=>'b8DMjUYBWvpEvw1IUzw/v7lyPUFGZsRxORcw9FQDrJJ+r11zp4sXwO2xUxWbFKif8vmGXEO2zKLhLwobCOKtptKgHHatSz2Q7w13NKiv/i00IXYCYf83lJr6y6BuYiksfdtM1hyP9nFMNooCDo2XLn+ugmJ6X3d6R89OXzH6uAXglrWBkl+sQ9mJT2IlCBvB8dRGWK9c9QxmEQxA0UuOlxNvCOSQy2z1V4+ef68hqRx5utoPOFeOn2Xx56zF/fiRucqp63OM3ZzN1tjEeOarI06gmnuJA112SR6Axais4EQ18StsmpIJqbWmvtZyf20AjyPmaSXOlVTH3IssF3X5mvjrdsK9gSkdZ9CnNkjvowBm/XgcZlLWfdMSuGEocd9FdL88E46GHtq83PGy4t4XpGZts90wk7EkD4nBM41QjDbk1JwDUMoqbGHGRfmEtd3mWTanNAtj1lrhNtZGlrqIgRS+EFfCrzMZgbqY7gC5vFJbjhwNuxb77pb1Y3XfDfw2',ENC=>'VwnZ1Qu0QJS0AfAmfQp0IrIKRaPTlpHZ/7VSpFbcq2rgc2ECn00l8fwq9Grfs29LvBv3V8abbcLtusGs5bWra/65/ZIVCziWXanJmbrsVYhp9EL0z839oC+UQySO7qBfIf/ShZvyECdxklccdmzWRAj/iGtOTe3vwREreAvaSain9lItg3Vgoh/52kbU7xkOT+0ezA5A2/aV327lVqZX05Irrev/uL9qSGg88orG5DhSkLbwasASW74h5qy8GwyInRQTqTWG4/t1yJRVHGGTY7Dzeaq+f1yetAfwxb+QbFiKpYOLwdRvAyw2xwP/Ike2mRqoArhaLWFhSOjTsnnDIw5zgwdHpK8scujvKQt3fpXfe+qjnj9Hd8yrU1ZEssyZAGrpkwl+udaEGUsJwWHqgb8DHqUyrqLfvt2O4/59UPyWBGfY6TPOFD/WQkgp3mD43GUs4aIu9o3I2UC/k/xxDkeViykQFFlw+x4+nalAPbmN3YxSJO8djMaT2m7FBk6i',PRIDER=>'MIIG4wIBAAKCAYEAw02ZMXZ15WykKxWLAoEgfxETmMgMWlj9deUCetN2IrpZCkbjAstXHt+xPVTs1KtYVqjUNaUVYcGOamNj/GsSKHpThkB2uqXMFMmKOMth924Lqa399Bc86JCHsanqJJY00LTUhaI+cTRkXsfcshGvPRacHhb0d0arWCVMzcqH+7ycGXoz0gKxTULzTHKtGCZUgXZUOeNNY6mwQR5lYnbDymOVwydJoPrRZKYq4RGwConxT8Qpif/h3SnTk/5NwD6ZyCSzGF69Z94Kq3cXlOR1DkeRwgRWi2BwIlNz5hIn9hkU4/1cl4t45/UtsWwf2PmUI2IOaRzgIPHBG0sIhHarKKPOJPkPbpu3Nqnv66MeOHxSMX7lFjLRcpizFmJU8Fo0giMEc3LDTdQCOTj7GJ9bTIoqKrPMjgrPbDYIdbzh33xtM0colOdpYO7Puo5d4xZ26Q1HYWEmQsWGGx76hIwEFib87PoGU4gPzHRP9gJ7QICnT/U39vg8SXX3s/ZOH0jlAgMBAAECggGAGb0XTGJ9RSAdPqRXLpxP6Q8aEw+COUHzHV9yBTfrIMaIR4dyEYM01xfJ5vhTQe/W84zKcstv1vNITpMMsU53FSiR62aBfzWsgKzS74s2PQKevNz2U/3gBBJQH8Tx26KEEWFThM0OB6NM+wTB/CHCg32AU6LY0wNYP4Si65gedbm0pNLrE2lRboo9QDz4vO8IQguTLBHduB274ckcuW5HfVvEd/Ssim+juuz/R6wqFCl7yPRkORCk9p21iZKBMq3NIZAsHEqRkJjTIFVgzaE+bbe9kyy8/gTsCy44+Ung08Z1RsOdIyYb8Z+T4oqwF3GDdFBAbjR9CI7RNO/1meQO8wADefS47s5rcCagUqRX4KvfGQDlRfOWX3s7plh8rI5OuW0KfE6JZBCuCv3hqY0MPIfDwFVQ/IJ2BK2ItO2mhcxc7RpXXREuHyPyFiFvTYZ+7kBoDMd+AOPZ8ol1A55Fjk4z6JYjh2mfkudkiNwFg1L5pYlVHbhZQlqTwbfcF7UhAoHBAOcoZhqT7LU4n41n8B3Ra6yo+oQDOLYZeq8YgB0by5QwEBU9j7a3TBgfRiO+GfsHel1ylo/ZRS93sj1Y7GXn+s35054NotDn7gTX8oDBAI2V3xtSAuEQaG6czhs/MqwXrPd+Kb0Jo3ywA8GiTXMCN4CFfoAANoHTdziiI8pBATw462dYknh2EmzF9NUlZqHYLP07WM9ZqmAtUQel+fImVUaGDMp32HOgvGkvI9DwS1VamM1AZs7bDT0eacysvnpFzQKBwQDYSsRtMEblnYNE7ovTXyZ1j+kNB6l5VjEcu6yD9woF/QYxsMaaAwDdIODhg556olAjT1TM/tz6ycRM2niKhBy3SjKqe0y8yLvtvEeJ/EXFG/xxFMc1ymZQ+HPMc0eU/+P/E5d6mLwmUtn9eW8YCFL3cNF8BEGrA30ZXBHi/SdJOJP7UXsgbZHeUB8JOq9hFSKRHKUtLZt4T2MJPCKYpItBc/9gPz+zlmEnmyUVQajHp7txwL4YvyqkA6uI3a1qd3kCgcAX+VOlnAPnw6iglNANd6PQM3JP8LmYAUp9EHBxFGnnw5hXa5wVGiuVMOEoYdX1+A+T04eUAbewNZzRygAyjX2wkSGGeemR+wvviqoG+n1hMdMC1V2hE/+QwUiLAOHzgT0aKgaQKYjALM0m7vtTWz6AYNf+1IbSrijmQcKuflFveoPHoyMFxVEh4OIEnS1oya/Yz6flUWpfMTP/NBKZL6qWdt6qvQVA8MG5sv7m85UMlCnW18AR4hwcY6QbaysSKV0CgcB2kD2usPkcI0TzA2SooI7/gLy6xMl01vejDYma6U+YSsQbdxDXGfBeRwie9jxocxNE19bfbJIL85BkpJnRLGxlWQn/BAnjrpG91yjMDfrc+uNdxYsSBHojxp4Lo+HIXqFHkSDHNnRk+aO/W9K3NNDuDOz4c4jfytDHlv3DFQx1Ccusx1ScSRPd7sOkloPOzvwc2bv90PNZdwMN6+X3ELO5VHHX+7PaqQNm55fjWBPCJkMNLx/Fhv1D3TMpmoLWStkCgcEAyPMUyS7UZCoHKWrUJ6zjsrGrLFy0f/wrw2x+EWThjUcuUXByzppqTv9NmdsJ9ngvblQjtKmVasxaSRf17UvIohBf7nDY+OjgbtEgrUt5DJeRoAN/usKcTAEAvzuzs/pt1GFfm96aM1g/p+LNX18jw2WOqAO4YelALNHVU60UA+mEHDnXoEeX80reFSIR3Pq0C0ApJw2ZqlaUOHqiDbvNMGOBhI61rNbZRSHB6Ex64OCgpTVUvhUokpXGbNo0Tg4N',PUBDER=>'MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAw02ZMXZ15WykKxWLAoEgfxETmMgMWlj9deUCetN2IrpZCkbjAstXHt+xPVTs1KtYVqjUNaUVYcGOamNj/GsSKHpThkB2uqXMFMmKOMth924Lqa399Bc86JCHsanqJJY00LTUhaI+cTRkXsfcshGvPRacHhb0d0arWCVMzcqH+7ycGXoz0gKxTULzTHKtGCZUgXZUOeNNY6mwQR5lYnbDymOVwydJoPrRZKYq4RGwConxT8Qpif/h3SnTk/5NwD6ZyCSzGF69Z94Kq3cXlOR1DkeRwgRWi2BwIlNz5hIn9hkU4/1cl4t45/UtsWwf2PmUI2IOaRzgIPHBG0sIhHarKKPOJPkPbpu3Nqnv66MeOHxSMX7lFjLRcpizFmJU8Fo0giMEc3LDTdQCOTj7GJ9bTIoqKrPMjgrPbDYIdbzh33xtM0colOdpYO7Puo5d4xZ26Q1HYWEmQsWGGx76hIwEFib87PoGU4gPzHRP9gJ7QICnT/U39vg8SXX3s/ZOH0jlAgMBAAE='}, + {ID=>'key-4096-4',SIZE=>4096,PRI=>'55C0AF46546BD90CB30E805CEA97BD0647C5CBB00AE70B62A9132D3EE580C6479F0A5F10B29520331C6F18EBA28CE31B0A9A4F008FB41DFB21AEB556403D54DC07A2487AA94ABD712C869385A4CC8E45C68F37C14E8D620CA5F6B5C46046477ED733AE962A19D90641ADD05A5E50CD822D6B9E69912060A481DCA2D1D05FE518A544A2A87B97CA3290CBCAB1EEADED146C749ADDD875F16B223E7187B0FC3AE2BD2A4EE21CF84E30953FA28D4BFE701E28EA07B8B753855058F853830104174D99038E9C1595208C80309BB90E69C185EBA4167ED15C6AE2350143709C6B432EAA045BE8E96D6B4C8FD523EC9D59C26E1A1A413EF460E01F9C35B72D56FC61A21C897C4EE0BF996EE0338EE18D8C9477195135B577F90D65649F34001959DAC059AB9D35B957A3A7BCE4B736F52DA22166A8ECD6BBE0ACE8D380941351A58502EFCED78B32E4AE56D7A312F48541CBA2F33AD1749104609BF2A746FA8132080DF087444BB7E0C4EEC1CD40FF94AB6DC544B504FDAC6E382617E405D7C9C7B1DBF9E6C04CE0F8207250353E1B99FFA2D606365B3FFD7930B279F4318E3E9B38737E67A33D28247E20980DE16C753614F851051D829C6AC57BA7BB5B2D3024FD4AEE2B6940988FE612F660B93DEA964B5A0A86F21348E79B05637D0B27AFCE5E6394564E2B07D8A5E5EDFBA6297742604D2AEF4C3A604AECB26372CF092EDFE8A1',PUB=>'AD1BD1E8ECC4D4E104DFF0F335A2455C39E93D0A2B408F66DE6E3586DAB919BBB4FA64F115FDB420DF147D35DC70DE7E8AF7A978E9A269D50596E9461F24E3854E8C90F911215A6BDF4A116DB25080B556EDC375BD538CFBCC13CE58A1E48A8A3083E3C8E6F2B8D1B5D49140334FCE90F0F5FDF993DFEFA308F174EFB5D3D6669B9EF21B593DCBDD4BD63C1DC12F04D21C71630D605194E092EEF93E46729B08EF4072A8420114E133F9782442EDE762EE405DA3264D23E2AF2C03261D477FE41EA2D4B2C796E371A88727C374F47A9991DB495D7AFFA19DD36151421A31C0FAABC8B0ED5C8DC102DB05DF6A605CDB5F03FC25935E1866C43D3386BF14A652F7023089847CF541A8C5970CC8F6F0ECCE31DDF2B81319E6FDB364BB320C409A14332A8C6A4D818F3087B7B0AA88DD736132A984CA600F46EBB1544459D95FED495C9131C5672C32AF5A1182BE3399585D4B45792E02FF7D749F4CA0B8B68243EA3D918DE6370F06A3B477071EE24D25991843E4615626FBA6A17FDA36C1D4B5C3AF9468D526A8E76642DB1BC7EE13C2A92B45FF2D441E688B9E4143BD84FF41373F2BBF0C1AB31C603E82F5B222409D09B42F7AC23DDDFC87EFD1AF0A492C87215B00FA83A512A99BDB90F906E23EC25F8C5A1FFD54242465C3925F7979CF2B6584EB0C8791CF19D26FCDE437BBCBAE15C23BC37C63152ED76E67FF0FD922D94B',SIGSHA1=>'IS1AaCvHlIoGxIhsLAuC5+fBIBO+QLmIkkEHdaM2FZro6LsAu3PojEaYeJJpvB1kvwpqmQ9b9s9tvrgnG6vMuhyGxFhaM/ntLBtn+Aav3hFg4eljNmmkkHbJutcY79ZQ7pfGSSqorocXb7cArIi1mJjDL/9D6hN05o5z0qy3qXo8kX+qGy2g7/IT9AgSQTYc72ygbd56G3mXVqXJgA5JSH8im2/qGU+YgzbIi2nnZmZ3yftZCZbzLYMoR3Jf0owj80vXVl1k53+Yi7qSjGsRFvx3z9P9l8lnbgiyKBkPZ7BDZb4B7wVKEl5RGWPyfG+r9N4KvIiioCOHQlsuN4Nw9oykx4RuPtT4rKq8Tlc2ms+EJpud1BED/2e6VryF8Rqxh3vf/Fjgp6eDO5yHqxNe2bNevSJXByeF5HR5C8rFuOWzi5XYLp/Ul2yRk04+gksnAtMeKYQCKEi+vTB7qf2s0vCQ6pCTxcdj+x2EwPpNgbeRUqdkiL5eOn1w0FZcLI6ofwwRQ0wKl7fNVgDK1KdLD2gGxGm0ftHLseEJ3SSGd1ehhfxUNAS1RsX1u+9VMQwoaAIUvAX58ljnGFGpCgWDLmPBb4apCw6hKzw03BhWYpCWH2IRZhsWzoZmJC3qxcTmMaXT93oiHfEY80yuzvm65vhEhIrXvRJaTEQsKq/k+ho=',SIGSHA256=>'mp9/Hw2AgI0UBS5qg10uzz3hVaeVzCq7EvE/DLu7aCtftC7K1Ijrw2cqH4zI0kgZMqpEAIfNEzO86X4hUf/IoIRffljthP6fgwAzfYVEqS8AuWLOfKYWvbLbdciQD5nusMVcV1tQNEm2TIInHeEoxsTAuhBmyF5xDYc0EuzbArjBSzVH8stxODEWeGrbE0t5dFZUpeqJ4FV8encmJzbfi+pTBwra+Egm9Gr52okSZsUeCh6l1wsnMPjSdI4fokgaiVq/EKo6YKnk8EOUHu7MoDe2SoixL9X6HwAqewFyd66m00ua8pD+ASpCBx25Pdp6phBtTBfGeSF7L/7YNSNed5M1WknOxA/MUnAOviDJf9A8d4BnUp/RYTTWzjHALoR0b+SfevPWdqueg77khSqtdm8t8F/ldn2jPcIoSQAJ2Wufz3f9/ioXj5iU7S4n2s+DPgpxkVycejQ266JT4DcPI0MIm71D8VJ7Q2Y6My5B1NoruYkN59UD0SBcCKrbX8KdJbJDCfBfMCdxJXCikbB7iQMsb8VlQCZImxs/WY6Wkyr0NKxDxyFy8ugyk3xOkS4Sf0oYUKK+RVGuww/0RJsHq15GO5d/MzxC6x22r+ob0yFVCEb+nwZ8c0AdgteYecJcJmMhOkK4P0rnET7aSCwh4lXKWakYompSQjbCfRnBpQI=',SIGSHA512=>'F6/tpLHh96uO6opjzcM4GBYNOw+8vjfmy9oLKFJ7Up3ZP1SCI3iDnelUJGDCpb2JnZUJA4eXwdXP7pFml0gYtFnlkz91a1SWlDGxcpkgYkKjA1BjZrCat6Z5z5E9x/T374ulsnjtMW4EO1SvfOmyk8HdMePfD51+ciXmx2GygkTY0jIXtJRDi4+qf15M9u96mremlJtISvhlxur8BHPgkQUG3JNhXe7RUthXQZS5Ds4f/bDaoa7Hkb3618LQ+vN4+nkmPoEhxk3FcfN/Gkeg7j6j/XzvT3mPhcZpEnSLGpWlsU8zC4cQnN8hxHj/RHoWOEl8wBrPXbrulzGb5RWzPteAP6UeP2oTkkNkK7tk6RwUIrDFBGi6fI6prZwsZc0AjsqlO0Vo78WDfjVQ7Dzw0wUjXk3CtHLLF3Lsqv7zDXaEutskAg2NpqJUdOiHrSfodvR8PHCyAhfqDuYUdU2UYUR85JBPs+EGeO2johYS7zNWia0aPk4Kx75ofFddLWefQtbycsb+3Fq2CpTXPv7kBd1bOZbd0byS9pl9XXPdzbQz8gm1Ab8P9drP/qwb8tcCXsnAHGGcAdDM8Hshs3J3SGdj8Ae+r8mo1DSVDGw8oVgX0/pjFB+hwZ4SOoSbiMKLqs/ZrHg0jPo4BI3JDOyVB0w7N/J5q7Y8syQYfHgeo+s=',ENC=>'R8CRZVFaYglslNiGkVlDAl/D6ACtzyIlrphS1QBoOmLvotb/hdq6PNYWk8YcqYwj5r/gmsBFlQNUucXpAS3ArzrxbASvmmxTA0gZLoSKbvfbIKrkT8qGxfi3NpQPXG5nUMnry2SDcUXVBuPWJkbcf6gxHxufnJ9UXo7UDFmdCLh1G7nrVXEpvZVlBGyF+FrtbAIZRMhqCTqnVQTFcq8yUTFhYyuu7gL8rqLIpsS5fHDrDK1L2ht7CaiN3vFTxMKB5kq1SZTz/RKnSdSHVoTZX+5oW3BaJOfYs4u52gane751M2gCfk1rpledb7LsOjxSjb/8AvRvtpHfXC3l+KvLAgBUQaNUOaLAEG/KH4/7uUT8PJVI1o8FD2mMqGhYWNwIFAq1GFgr+OGMqD5CBJb1Oar+knVm7PkgOBa6B3Z9oAU06b6vUnMA7/Iug0s2shRbry0IKYXZ41EmKjzwTYHZ6uqwcPH2Y9QXmFP8OxGgFN6MgPEpzW4s3hZfhVuZVx4gw+dGOrWMLs6D+tbsjfMBQdlXUzSCjYeFwP3RxhvYAskSFfNdIAS+hD1QJAByco56HJ24hiDZLjSZNi8f/9HLcWI4lLkpQ6YvZavdDZ8sZjtNqUGbjdQM9TFTL+wz+ZzhN99RjQRR1fPIDqfiRyZfL3A7YZWohHuNHKC9snRagkc=',PRIDER=>'MIIJKAIBAAKCAgEArRvR6OzE1OEE3/DzNaJFXDnpPQorQI9m3m41htq5Gbu0+mTxFf20IN8UfTXccN5+ivepeOmiadUFlulGHyTjhU6MkPkRIVpr30oRbbJQgLVW7cN1vVOM+8wTzlih5IqKMIPjyObyuNG11JFAM0/OkPD1/fmT3++jCPF077XT1mabnvIbWT3L3UvWPB3BLwTSHHFjDWBRlOCS7vk+RnKbCO9AcqhCARThM/l4JELt52LuQF2jJk0j4q8sAyYdR3/kHqLUsseW43GohyfDdPR6mZHbSV16/6Gd02FRQhoxwPqryLDtXI3BAtsF32pgXNtfA/wlk14YZsQ9M4a/FKZS9wIwiYR89UGoxZcMyPbw7M4x3fK4Exnm/bNkuzIMQJoUMyqMak2BjzCHt7CqiN1zYTKphMpgD0brsVREWdlf7UlckTHFZywyr1oRgr4zmVhdS0V5LgL/fXSfTKC4toJD6j2RjeY3DwajtHcHHuJNJZkYQ+RhVib7pqF/2jbB1LXDr5Ro1Sao52ZC2xvH7hPCqStF/y1EHmiLnkFDvYT/QTc/K78MGrMcYD6C9bIiQJ0JtC96wj3d/Ifv0a8KSSyHIVsA+oOlEqmb25D5BuI+wl+MWh/9VCQkZcOSX3l5zytlhOsMh5HPGdJvzeQ3u8uuFcI7w3xjFS7Xbmf/D9ki2UsCAwEAAQKCAgBVwK9GVGvZDLMOgFzql70GR8XLsArnC2KpEy0+5YDGR58KXxCylSAzHG8Y66KM4xsKmk8Aj7Qd+yGutVZAPVTcB6JIeqlKvXEshpOFpMyORcaPN8FOjWIMpfa1xGBGR37XM66WKhnZBkGt0FpeUM2CLWueaZEgYKSB3KLR0F/lGKVEoqh7l8oykMvKse6t7RRsdJrd2HXxayI+cYew/DrivSpO4hz4TjCVP6KNS/5wHijqB7i3U4VQWPhTgwEEF02ZA46cFZUgjIAwm7kOacGF66QWftFcauI1AUNwnGtDLqoEW+jpbWtMj9Uj7J1Zwm4aGkE+9GDgH5w1ty1W/GGiHIl8TuC/mW7gM47hjYyUdxlRNbV3+Q1lZJ80ABlZ2sBZq501uVejp7zktzb1LaIhZqjs1rvgrOjTgJQTUaWFAu/O14sy5K5W16MS9IVBy6LzOtF0kQRgm/KnRvqBMggN8IdES7fgxO7BzUD/lKttxUS1BP2sbjgmF+QF18nHsdv55sBM4PggclA1PhuZ/6LWBjZbP/15MLJ59DGOPps4c35noz0oJH4gmA3hbHU2FPhRBR2CnGrFe6e7Wy0wJP1K7itpQJiP5hL2YLk96pZLWgqG8hNI55sFY30LJ6/OXmOUVk4rB9il5e37pil3QmBNKu9MOmBK7LJjcs8JLt/ooQKCAQEA0q7h2gl/uUI37usxk1Wf0sri2SwF1JJBLXYIRfOk/1jLFL+YSir++Rua4op8yzm03vTwv9l0hhD+RuaBRanPYJzMRuPgDteCrKxi+zaXJGXYWRa7utW55Z3olgylJf4YzRWKoNrZoAjX2P4LbVCAYBB0I/mg4nT1xDNyZFposYCsYW7s3LtkVoYF0WI9DKATnVcOyVXmX2R5oB66VHrfg1DbMAr8w/BPi0BdV7uzH5SA7FL9hyp2mNisP1nLVRHYqabERIELtcrCfvcXkhzqFlLdch0CQVvbtcjs2JSNfBKsyy3OuwCBny9zee00HHzqt9FgQp/CidfuTtDX9K02GwKCAQEA0lftMlD27FQm09jpHjbE+hhSR95YtuDJJ8ytI83GjjNVIP+Rd3CsBn8zFKOevj5BGk4MVffBya6X0hhiWmjLjuVug6URHkbjnHtA9mRD/+7IrdkKPvIOb5qIGsaf4JB6OuCz+a63vYWOt5wDnigVKqDDPWQwF3zrGxZwm5Rlg5cUrujgt3bLM6B7EC4xcKKnZhPUy+rt40ouRJ75BBxVSRu7z5pyIS3m3+NJyb7bcaBliUzAz5u3yDy+af/vQZOcpSiqHWiMKeFapd62qFxGufyotuk/Dm4BwiF9wccsXHTJBFaJy2pFOa3OWnLMKZvUcPIqT7AuvANa7s7yYhjckQKCAQAjZodEn7v6YQoM9zAJVaXZQYYEf8UrBrg071RMjLf4v+6/ucHZFIhrSxwnXKXDcBrYK8gYNG3D6S8QssKd9f6GeVJJxxhq5gNrCDxJgc67qvFDZvJ8XlUyI+pk7BMD40I/k5MLnDpdDZ9XMriw0YoAmkMpmFRUONri8NIT0q0sxjYw2Par0ED32OU5XYxshqlFEs/FPM3M0ZEuOnuMnmjYI8nwtKfsNIDpIROOHlfmwok3LGq1P4lV/XJT4r6ruKfzObZY3GYfUcaElvg68OjUf2/+MKmkWc79KJnDepKbenfWXAgUm+0r1klM/3J2Jvc5k9Dc4QNLLiE41Ra0YjZpAoIBAQCp2709A6rS34XXT3O5JWtdtuRDCyfCzrVCQYOTxSlRTdyx4A/dTwxr1q4uPY8EfAtgraRCi+de8XHChFRwQ+4Vv+rFvjebpo1JoTKthfxvoalG0lz2xcuojjbYwIr88k7yWuCbgV75WfAND5zQS/gDy3y+h7haT1MgNbfLu0Nax1c5g+9r2C9xymd2gocEOSVLRjpyTY27HP1OBr56dlLczduVY1hEuOeW5tmAZHKbSHaWMHgHbu0zcvIlcTsJTqWRrcvqIbIGY+gqyDXisVmf+YtY4fQ8t9MNrLP8FtYY92oY6bUuoeuzD0rzOX7rHt6oMra+UTz8MQ1uiYmsc/0xAoIBAFeW+HArJqF23lHRMWna6tfO+eufClWK2lzGNRFyc5MhQU5Mvek3tx29IXBwuSuxV8gW5nnc5rUbx+Zb8QA0wQq+Aml4GLEd5S9zPfWdIXoPdraT5MCZI4/WXi08PvqCgjV5pNWowXIy/yprUn5jF7eNSuIDn5ofCYOLoEg6DjAMZEu8n1Cy4Bq2V6A7vNdO4tDX3Uty6luh2WLtsgdgiRnIrYwOKhTCO+H59HPkVUHn/Mlt8O6RO6kexmgqCLKGSm7bs1aXYm9gdsDfTz+5kdHHN2rH9Gt9YfYCIrP0TN2o/5iEIVmjeBgDFtfCoPg3onQuWZcjIDKeL2Q8VUgmNKs=',PUBDER=>'MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEArRvR6OzE1OEE3/DzNaJFXDnpPQorQI9m3m41htq5Gbu0+mTxFf20IN8UfTXccN5+ivepeOmiadUFlulGHyTjhU6MkPkRIVpr30oRbbJQgLVW7cN1vVOM+8wTzlih5IqKMIPjyObyuNG11JFAM0/OkPD1/fmT3++jCPF077XT1mabnvIbWT3L3UvWPB3BLwTSHHFjDWBRlOCS7vk+RnKbCO9AcqhCARThM/l4JELt52LuQF2jJk0j4q8sAyYdR3/kHqLUsseW43GohyfDdPR6mZHbSV16/6Gd02FRQhoxwPqryLDtXI3BAtsF32pgXNtfA/wlk14YZsQ9M4a/FKZS9wIwiYR89UGoxZcMyPbw7M4x3fK4Exnm/bNkuzIMQJoUMyqMak2BjzCHt7CqiN1zYTKphMpgD0brsVREWdlf7UlckTHFZywyr1oRgr4zmVhdS0V5LgL/fXSfTKC4toJD6j2RjeY3DwajtHcHHuJNJZkYQ+RhVib7pqF/2jbB1LXDr5Ro1Sao52ZC2xvH7hPCqStF/y1EHmiLnkFDvYT/QTc/K78MGrMcYD6C9bIiQJ0JtC96wj3d/Ifv0a8KSSyHIVsA+oOlEqmb25D5BuI+wl+MWh/9VCQkZcOSX3l5zytlhOsMh5HPGdJvzeQ3u8uuFcI7w3xjFS7Xbmf/D9ki2UsCAwEAAQ=='}, + {ID=>'key-512-5',SIZE=>512,PRI=>'497BC8E89C6C3C234807BB86ADF92AC9C22B207A6322BC8039A26FD41377D8BBBB6B466436E5EDD2E0B3DBA29371623B0BC556F834F2B2FE15F352FE455035B1',PUB=>'C30BE0273495EDE466D781FD61CD19ABB783DBC4C5EB3D3BE0A201D48239217093F5A1286F5DC751C1A49423736C3724798BBADA4B45C62C3D13A13ABDC9B233',SIGSHA1=>'B7DyETogGrrAccHJGX9KfCEVSrBkYzZ5dy52sXKJNghEeyhoFdS61LrsCu7AM9HL8EOONotHrWm/AwVRYPZVJQ==',SIGSHA256=>'AYhisiP6kZNBRZrMMsMmaVVRJFsp11himCSPkozj0118VIhP+pMAcO0ZRmkjYG8T0K5AT852jLUGE4cN2NBVhw==',SIGSHA512=>'',ENC=>'WHYvUGeB9Suuxree7bAFKjqaVoxVYQMoAVdwdz9nLBgVbNkwXkClV5mxCx+70+M1uqN/VSVLEuQc2zlpS3VXjw==',PRIDER=>'MIIBPAIBAAJBAMML4Cc0le3kZteB/WHNGau3g9vExes9O+CiAdSCOSFwk/WhKG9dx1HBpJQjc2w3JHmLutpLRcYsPROhOr3JsjMCAwEAAQJASXvI6JxsPCNIB7uGrfkqycIrIHpjIryAOaJv1BN32Lu7a0ZkNuXt0uCz26KTcWI7C8VW+DTysv4V81L+RVA1sQIhAPHkqWRTJkqMJVlO+WB0Me9NrIIO1/UQPv1jYddLZmhpAiEAzmvQxtgrSXZB8t4po0iVkcJKAZF7pFHtnL0FkcoOUjsCIQDany/53Kze84tODHKXGm2HO0yOv5uvgd9sZEYpr5v/AQIhAIAWoP+yhfHY4wVs3FOJJ97BvCCLATku6Y4YMQuNYSOfAiEA02//44uiXZhTyBqnbW5MQ8hnN7dIdxiamlrJHsjkXlg=',PUBDER=>'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMML4Cc0le3kZteB/WHNGau3g9vExes9O+CiAdSCOSFwk/WhKG9dx1HBpJQjc2w3JHmLutpLRcYsPROhOr3JsjMCAwEAAQ=='}, + {ID=>'key-1024-5',SIZE=>1024,PRI=>'12AA04034D59BAADE4CC3B211560E6EFCCA91ABECE7D8086AEC8FA38E853283FFC4DFA8A3C108BF888C46751C5975CC670AC33CA581D66F7862DC08DD41CF2C99CB0F57CEB0F7791A8AA00D95E81E58EA709B90A9C38464F260ABC84CEE5A089C72793FE4BC734460E440137FC0FC0C613FC99D5580F7ACC932AB55A5639F7C9',PUB=>'E908786E7C06D454D61C938C56E8D95BD10755E1B97DED92D1044ACF34EB7ECFE3CEFA34E5C01C88FC4A54DED4CB96BDFC5320F27C5AAB6D5A24843F3D70DA0AC261A3DB6648A85C93C986B7CF5A125B0E56403A23C8F229DFDB9F300CF0C39E6E7CCA8FAC879BDB3648FF77DE7F885DC40689F6CFD4115F77F9F0502E3CBAA7',SIGSHA1=>'D5oXoRS/S/G34Y1cXFHpwmD5Jx1jRNM25gheVyCEwUOJxMU/oOgeYku/g9ajKg23eKWK52Bm4w95ulhSMqU0tITm2XrO0wMz7Kwg5RVye7IkxOE9kNt+wUi1PuYuHejq38RJ8iZP5hYDZOTp9L8ciH7+BiMgcBEP5FmKYZY5G1c=',SIGSHA256=>'mG4rSBDJWE2Azmv1KQ94et+a3zDgqVYJhEIVnKcLWyI4WapZyccdBtYMiBdSnDVjmEHsy1LaeJHDwClBWNo9Zzb3HMPGatgGcvk9FdgeOHC6dkvilE4tx6KZQgf2uWhads1H8vPMecE0kxS/jPghQsBT23fBbFHuITd0JR5HOAg=',SIGSHA512=>'R8S0lj9FXRluVUY6M8gmLyD4W1KtW7v4yPyWqgayeBcZOPuH6evAtOorYjJxgxcYL73b5wgeogOOpNJdONcDS6k2S7dKllJbTWECpbLaVE9qsFMIqOVTnZud1ZNog/HprwPlniA9MXf1HPF/XolPBcAJpIVLqyftwTka/9e7iYA=',ENC=>'ywKO5B5JkXGlQrlfWx/9ySOcWEQNjhShMKnM7aGS1xW865WmyUMHBBqfZWEepvdqJXa9GJdwTB7PXyscXYiqPs/R2EXPIirkhVJe+7n6NB/7RcxZ86/uXu5Ey7Xwsc64V+GB6p5kUISuphn5dGHZTF44XwEE6/vgYsPjbAayE1s=',PRIDER=>'MIICWwIBAAKBgQDpCHhufAbUVNYck4xW6Nlb0QdV4bl97ZLRBErPNOt+z+PO+jTlwByI/EpU3tTLlr38UyDyfFqrbVokhD89cNoKwmGj22ZIqFyTyYa3z1oSWw5WQDojyPIp39ufMAzww55ufMqPrIeb2zZI/3fef4hdxAaJ9s/UEV93+fBQLjy6pwIDAQABAoGAEqoEA01Zuq3kzDshFWDm78ypGr7OfYCGrsj6OOhTKD/8TfqKPBCL+IjEZ1HFl1zGcKwzylgdZveGLcCN1BzyyZyw9XzrD3eRqKoA2V6B5Y6nCbkKnDhGTyYKvITO5aCJxyeT/kvHNEYORAE3/A/AxhP8mdVYD3rMkyq1WlY598kCQQD3sSWF9HcUlX20brB3RS3pcXJnRJcT9fhw49QUPEljPceulZmceZ9Wo4jnSoj4FguQPxLVzEmM7cDXrjWv14TLAkEA8Nlz2pyrdM1E0lmPGw5OGqxuAy3FJA9jaCVFApR/aWFl7CUqW0jAzyq37RBZr/vEPbIDyat4CjiOo9FkHCfCFQJAVzbE45nkpBbPIE0pTZXKSLxtb/cyyxB83iMaddWUcaE7Qjni0LnyZOtINUiFWfVJNQ1AcI9yBnFgyZDJzpSwaQJALzpEuIJuMIory5+aKzED6cEUFXV9KdQGpx5fyOC7lzttFAA5rQq4HCeBR3AkVhjlYz+r9Hi2IjLy7XaazdaR/QJAIYKGeXMzIoc0fqyUYAMLYfY4GBQktMTmc2oZMIe/ixoLqI10muJ6SqYqSA4FN0LIKIboqW/EIn+CHiioq3PpPg==',PUBDER=>'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDpCHhufAbUVNYck4xW6Nlb0QdV4bl97ZLRBErPNOt+z+PO+jTlwByI/EpU3tTLlr38UyDyfFqrbVokhD89cNoKwmGj22ZIqFyTyYa3z1oSWw5WQDojyPIp39ufMAzww55ufMqPrIeb2zZI/3fef4hdxAaJ9s/UEV93+fBQLjy6pwIDAQAB'}, + {ID=>'key-1536-5',SIZE=>1536,PRI=>'0BDB3C6581DF6F498CA3524E260786DF2E9E8C31827DC855C51B8D10DC340691AE00147744DFF4B3FAD9D51A7FA131693419E39FDAA46398E9F6F1AA4BB4C18D4F66910A178D141759CC33084F031A00B902A585106E5439B74B7EA11EFE12091B8D728B8DBCDACD275463D0A9C3DEAB876159CE8755691883F1A69F1C671ED226148D41926157275B884406C8CCBCF2A38AD6513118FF4E3A10CB9598FEC98194443717B4B562C1F047003000D29F8F51CE4C8FEAF0A32CBA1E67FB4F0D6101',PUB=>'C09EEBDDE0135D9A755496E029FD84CDF5F4C16E7701D44F8B50FC9966BC45EA34A8333C1E6971D81E527EF1325E3DD5F547F267342E166BBA702CC142D3C8CB226347C093AF006872F6479DA3905FAFFA1F211BAA6AA7CAEAA08CEBEC2624410CE47DB9373D66A282B9B530F29CE5C65222BD7D7B9C00B82A225C37496A1241B585972FFE08BC2C1522D9F8C067977895F6B42CE2E9CF9352B8A7166952C6BF8D1C5E95F6599BF3DD94A5F6188D290CD078618D41E1D3AD6D9E29F8209D5125',SIGSHA1=>'jsmwKnxqKXZgC6Jp9lH02ZkAibcuY6ILFczWf7HlGNYGpGRikgyePyji0UoxP9zbGFpo55yfJM4KQ0kzi7wxblMixuex+Rg6X0fIVrPZSQUL15+NIC714jLgt2hHzlPEvU+SDNWiKc7WNKAWy7kxUGcZYSSArOVeX8jktDtbeha6qcKVENdI2XgV2XBi11g7S3BmsSJTdYLAltjLTCWGirUsBFBTiGQQGoELo0isSgm/lF0BrcouIqdaR5uAkabS',SIGSHA256=>'ATGAbyuVhS70RmcmYOe5tkjrLc29wSDMWSo95eclTd1yJhV6fpLTtfUH627+YubQs4zjTJtyQnYnB+J5SDskIehwTOvNZyp4dEhN7RDpyISbOlO2wN9xm6IiPL8p0XSmux8ZXUnLx0SekO5DlIhCwFjpTJFAMdC9VN3wyqcQe2aJDiznVUrcWRRGVOqDGSAu3h4fGwt9RXY2F5fLfYYsFfVvTnOOYz7f9WHs/aWTEyP2aRioea8I9nPNWiwwWSla',SIGSHA512=>'ZWRve7ER2mwD7ICyJAbhg8v7o0HflbJNRs/7a6CtjeDbN2maExzem3DFVAFw7XBAwdOLzIAqzeh3RgqLMtRfvTAdsFrcUpukgD0hPQ/H/rNKqCH+eDQEKcyYZBgqrRPxaVriY9o6R/exOeMBr5kjLyPvs0R1sJRdPHDVeHLpMGEU4nES1Wb/wWaw9sQLRAjmapbZLL9iLA3wgOEmVS5jPslBZe+dQzEUP+oSZ/Tn4HAK33yvts2ncBuSzho+GWqH',ENC=>'iHSXIxn7yjMw3xNQsZVzy577dWefYKIkcvzsNSGxydhD2sHGgHHQ/rOYGM4oNz6FQuPWzEC0+s8/rX24wbEktX80VhvS4E9wKM92/3Mk1Bx0KTD08lkWJw/CLEdU55XKT3/0L4ATbi+bT+2DDnnkvQR3oWhPU+u7AfMn8wvHxn54N6HnLfZ4uJo+gBasZ7Br87GslUoaCGRnN5HT7HeoNC+7cycWNbr0fqts6L75oZ7jzWZb6fFW8vYhJZ6T99Xt',PRIDER=>'MIIDfQIBAAKBwQDAnuvd4BNdmnVUluAp/YTN9fTBbncB1E+LUPyZZrxF6jSoMzweaXHYHlJ+8TJePdX1R/JnNC4Wa7pwLMFC08jLImNHwJOvAGhy9kedo5Bfr/ofIRuqaqfK6qCM6+wmJEEM5H25Nz1mooK5tTDynOXGUiK9fXucALgqIlw3SWoSQbWFly/+CLwsFSLZ+MBnl3iV9rQs4unPk1K4pxZpUsa/jRxelfZZm/PdlKX2GI0pDNB4YY1B4dOtbZ4p+CCdUSUCAwEAAQKBwAvbPGWB329JjKNSTiYHht8unowxgn3IVcUbjRDcNAaRrgAUd0Tf9LP62dUaf6ExaTQZ45/apGOY6fbxqku0wY1PZpEKF40UF1nMMwhPAxoAuQKlhRBuVDm3S36hHv4SCRuNcouNvNrNJ1Rj0KnD3quHYVnOh1VpGIPxpp8cZx7SJhSNQZJhVydbiEQGyMy88qOK1lExGP9OOhDLlZj+yYGURDcXtLViwfBHADAA0p+PUc5Mj+rwoyy6Hmf7Tw1hAQJhAPRq0Z8hfwbttjss309MTmau22aBH4ryJuhAxJM33LY0HIBvtdrrLI+HJ8KpBoTeqyv8s8DhkbsM2IgSJhDLiRzfndfGsS30YAKukoIfrbTEhvAUv6jQoekV/BaIa4osIQJhAMm/uf/r1XB1lXB/nxYlB5wtDypRMpE4VETqsd1/tIAlJduxbrzCVZB0HOFNpJfauto1SGJleQ3ZBBaVzWfcf/3yzmaToT77AfT8IXpBDR8fNHzaj3Apz1EEDAx5SafkhQJgd7Y1843xbJBTWApzWaCTKeHs3fjSXTiba9gFL+IFfUxqxVFxrcbP7YCSLdqhscRp7EJ6PDd/LDFvgL363PEDuBuicMQFle+Ccu3UHl2rs8UqHj7bXLDLDKHS9apdmbBhAmEAgvOy3H4Mhbmc7W+5KFuSy/mnbVVVGFPSxwT7vIVG+SKjpy1NbrJJbcEgedG282ZjgH2zZULuR2HEuJA1yqOiZIi1Fnne4Q12YLlDVaJhzQCpRh1rm2dYDQMueu5DM/otAmEAySDf+y82WDkLV082VT9lTQk3ZWrtcQInSp1OiwDJtBGm2nle/1gZaIitkqUP0husWQ+g0dkaDd+/aoERKSyNM8s+DTJHuZL8tUVU2/u4g9ayC8jQxTrBYWlEBJCnMCDP',PUBDER=>'MIHfMA0GCSqGSIb3DQEBAQUAA4HNADCByQKBwQDAnuvd4BNdmnVUluAp/YTN9fTBbncB1E+LUPyZZrxF6jSoMzweaXHYHlJ+8TJePdX1R/JnNC4Wa7pwLMFC08jLImNHwJOvAGhy9kedo5Bfr/ofIRuqaqfK6qCM6+wmJEEM5H25Nz1mooK5tTDynOXGUiK9fXucALgqIlw3SWoSQbWFly/+CLwsFSLZ+MBnl3iV9rQs4unPk1K4pxZpUsa/jRxelfZZm/PdlKX2GI0pDNB4YY1B4dOtbZ4p+CCdUSUCAwEAAQ=='}, + {ID=>'key-2048-5',SIZE=>2048,PRI=>'3E6121165F1F794322F9E17E749CE560D804FDCA988B8D2F40044B8BD68F8A49FFC64B46416BBE1AB975BBCEF6CAE76A757D68FCCEAB792C7E688D350463BCBA458077F838CEC595545E99E155B48789FEBDAC32AF2F407E3846FEF435CAFB8046F874F97EB393B35238081E9BE16DF3A458F81B91016662999835451D0509FB7C66E80AEBC19083E288D3B82D2B908E759C3316F8074D1E0F1B8BCDD7F5116C72B21A86E5DD00A17A0B853B2441947179E12E627E5864669DEF1F8F15F2EE16E2AF001BDE32AE2BF8590F3C0643303F265AA8FBA216CA8C826D00068532081D9A8D1F79ED05FECF7164F01DAA885543E2BC1D3B366D026B638226ACB6C3CF81',PUB=>'BB3ACA8506BD5A15BD58FB2F6D1042F1536A9B57929D32397C90B836B4F20BDC0DD68E20DC10A4975504AB5ED849CB8FBD1F823F6CA6FFC0DF1A27036E349BB8E21398C992BDC026928789296AC585A6C2087FD88D5EED872DAE2DC929999D7BD969879D4712D27C2ECBB9AF683DBCF9190FDE49863E27B2CE9770EEA3C449C83A10B49CF928EBA554103DC98E17ED3432F5F71316FEA5C3467CBC9BAE0074AF021E4815B7D7ACD9F615F5E516C38A2B5ADF4D04C56DAF9887C865D7B61908443DF9C2C9482AE817712993237F018489B046CA26F9614481656A74975047BFBD4E09FA82ED2F1DF49DFBE2A2732D756BE16935BF5F1EE80EB72298B347DEAD89',SIGSHA1=>'K9aM1mc3ZOy166WMDKDPwSMmVqOJDyiFNK6BifTHP4N0+ig7oxn7yk/BKoXHdBM6txsBSGOP45ARMS2Q1cGqf2ZAPsdzGH1lyb9OD0Z956Oj3DdE1s6ZY6DTCDDsdkIhbWhDSAs7SWwcrKnXfM2F8ZSFNuoAXcqI4/AiF0UfvKa4yJYTMugmHxRo/jrp9D8FCDZvYqEs4SrpHg8IWMEwBmcD+OHf20H8EY+FW+0yGJtdezwGr8QXXeMDlviZ57ZRg1gGMxyVWG4c/++wK2ceA91285GrUMd3quSgXWK3XyBc0mwwjGVhxBAAI/3xA0iylunWhdWV6GyK40kmWkx6qQ==',SIGSHA256=>'ql5wKgWx8y7cDJ3Ux1Y5Q9EGSF2GD0izUJ+Rl2ZnuGmW29vD0IzirpCDwOrskNn6MZJ2orV5MHXWIzciTqzxV9pb29tIgSZXoIg0zh7cSjd/DQ3CRDrE+rbmlN6rzfJ7y8suiK2UkORaALjn1cPEOxd0R6d8t6MrmayHAbIpqf6Wbv6zY3Go4zsYpaEO4cWWI3Hvb6gN0YCwTNJpUXSYCYVn3yuJiRCIdLuxpa2Nkeza4MQpkag3azDQQ7hfU40XtnecMNx2g5hSaYHxJBCzpk9cKcUJXGIN1S+ZrKIsuR//ypI9NQTue5gnBiocZKQwQaM/mPpg1SLkR2Q+VG1PKQ==',SIGSHA512=>'Onok7KNm/0Jf1gEUb6jWfVHHIJQ/lb34pRQtDdN/YGZiHjdpTbBCofiwtJb+/SJsXpF3KEM4YhCDPPzxST5xJzg4pSTFL682q3EBMvph44XlUzWN5Eb4Y7Xqxghr7u7b7KpVCZ181I4s/GR4bLwL83Xb6WydElR41M3VBbm5kXtHPfF8tdxxkvjf8eUYlJtCPLb1ZB3yhgRqIZz3LJBnL4FGWk4N6Om/lkd1BwAuwJsjmPjeMZnTXgSzlBaOrVXiL3sorNcEIlPe0mSSaqvNJUcvytHg4iPyKcmBZHZCSFLZFwBtF0ZLDxwz2JsDgtcvl2INmnrkkuo+dxxr+7A6Bg==',ENC=>'fJTsjrc+XwWd5F0lRy9DjDbstm9JYw/6YC/JDdgdaapZFlNYR8FI7msoJn0cMtPkn8tDQGH/ZyVq5EPrI7NdF7z1i6I3n3bRXhyR8F3pAYnXasuEaHGgA1itei8Ji3V+8pejwaLMBVB4iVxxWeBIp5df98VCvv/v9/x8EQhJ00RuWhcPDTJroPzZLLe/AhrOixrg+vDwBJ9m2Iwerdjx55ZaFmnm3MdFLwWfn6/Ixt1M3R+7D/DHa6Za6j/uGUu0NJ1CDyZFRcPR/tit4MNhqXYGoJHTW33LGWJyr3Hw4rL6vuUaMg9miCaIe7mYhUp0qXfUwJHrvYrZi8hvYIRRfQ==',PRIDER=>'MIIEogIBAAKCAQEAuzrKhQa9WhW9WPsvbRBC8VNqm1eSnTI5fJC4NrTyC9wN1o4g3BCkl1UEq17YScuPvR+CP2ym/8DfGicDbjSbuOITmMmSvcAmkoeJKWrFhabCCH/YjV7thy2uLckpmZ172WmHnUcS0nwuy7mvaD28+RkP3kmGPieyzpdw7qPEScg6ELSc+SjrpVQQPcmOF+00MvX3Exb+pcNGfLybrgB0rwIeSBW316zZ9hX15RbDiita300ExW2vmIfIZde2GQhEPfnCyUgq6BdxKZMjfwGEibBGyib5YUSBZWp0l1BHv71OCfqC7S8d9J374qJzLXVr4Wk1v18e6A63IpizR96tiQIDAQABAoIBAD5hIRZfH3lDIvnhfnSc5WDYBP3KmIuNL0AES4vWj4pJ/8ZLRkFrvhq5dbvO9srnanV9aPzOq3ksfmiNNQRjvLpFgHf4OM7FlVRemeFVtIeJ/r2sMq8vQH44Rv70Ncr7gEb4dPl+s5OzUjgIHpvhbfOkWPgbkQFmYpmYNUUdBQn7fGboCuvBkIPiiNO4LSuQjnWcMxb4B00eDxuLzdf1EWxyshqG5d0AoXoLhTskQZRxeeEuYn5YZGad7x+PFfLuFuKvABveMq4r+FkPPAZDMD8mWqj7ohbKjIJtAAaFMggdmo0fee0F/s9xZPAdqohVQ+K8HTs2bQJrY4ImrLbDz4ECgYEA8PL8H0tC77cWA/2VXajlmviaAXnq8M6aehXz8am6DFcKKiqtOU1IYkQvHsjCU7oODJBTAhqwyjVk3NoxpOsq/iBMUKa2pWTOF2Va+mfw8MFw77CimxMcI0rMQMNBbnSFsTnmT9aqvcnlUnTdNrSlKW0i4MzDnBfly96KhDa5LfECgYEAxuzHOvts6nTHMLjbyg9o1u5UxqD6pQwIHsTxVMWrF2SeIJUf/Jb0gbMV/f4NTwkMCD+FWIPxioYbJmJLbq4jsTJTSdcVddhHsQGx25Mv+A5gB6Dh4WnCy+b9bAFMqh+Sa872+2dGZCjj04NWCQ+XH+EWgkIdKtj4yqd8rNoPQRkCgYBGAjPjW9jNEeNhsXKOzh44kvccarIq2bzksDA7DVezci7P5aqDNcNMWgde6HIeJbcjS2Py/pJTjoQJ75PxGStav0OtQ2NaVxnSjm6Kx1yod2w7GJWGfVz1nCwQvSrrzwtxXSNgGz1s+5aYCMClvoMmsEEsFBLZ7c+lFrokhEn14QKBgEDBV2G18xCnjygnJTUzqvc8glBemvkbX5FUnxLvffCRioAky1LYeSO3fpM+Hmr6EPamZuwXl4t2eGQYX2HaQjgun7pLz+qay0utt4447cacN1qEXsOYQBdMTHbaPXCr8mgx6WiRh/KW9QMnn9w3PQTdqwwgJYqLMwIVX5qNKaYRAoGAHjyXYmuAAU/sAdY9AQXhwSUYt07YDadpHmhpFatgAeUoGpS07KlcYE4mvyK2+JTuhNbFe8gIGVBK/5g8HIAxPXZbV/I8bKVfqYtJvR60lBqSfKsYmVREjfgIzRLKxh6WPaxLg54boBZie/5UUTAsWl6h8pMixqVn+JvFD34nSeU=',PUBDER=>'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzrKhQa9WhW9WPsvbRBC8VNqm1eSnTI5fJC4NrTyC9wN1o4g3BCkl1UEq17YScuPvR+CP2ym/8DfGicDbjSbuOITmMmSvcAmkoeJKWrFhabCCH/YjV7thy2uLckpmZ172WmHnUcS0nwuy7mvaD28+RkP3kmGPieyzpdw7qPEScg6ELSc+SjrpVQQPcmOF+00MvX3Exb+pcNGfLybrgB0rwIeSBW316zZ9hX15RbDiita300ExW2vmIfIZde2GQhEPfnCyUgq6BdxKZMjfwGEibBGyib5YUSBZWp0l1BHv71OCfqC7S8d9J374qJzLXVr4Wk1v18e6A63IpizR96tiQIDAQAB'}, + {ID=>'key-3072-5',SIZE=>3072,PRI=>'775608030A89E4C9FCF420B9CAD5ECAA4C84BD71AFFADAF8369E18E679E90CF7CEEDAAC388EB70D7A767F8D797A6917204BE1181449852A6C7B421EA02D500D49FDE2FC9AEE4557E310C434CD610CE8D24412B70CAD0B5086682174F97A5C8AFC10DBC1FA7F4C85325887EC61FACAD595B102ECE5EADD0A527B8B6061CFB3950581850DE0D921DD886870C24205B8A05C1ABDB9D1202B63DE5BD36F6336B2CB85C2E4E35E55D2E2AA37C7B8211A1CC9FD1E789113F491DE2EB8811C0C0218F27F31D80ADE1D125C1FFFCD7AA795F46EED8A5DEB81D0D62237A7DC2D916057630D197169F068D8D9F919319ED3FEA0834B68481CDEB0BA6EAA829AB5E1ED732B8760A2795F44C0EB9C84AC6EC274B96C1A93E98239693D79A02093172437FCF1C54A1CADAF8683625DAF076F8E59761F0EF3880B8306B8E37D1B66C6554DF825F996F66F1258F24D35086A1069BCBFD9CD6A99A0D29B72674DB8EFFC283F144C0CDC1501121B1DEBF0DB3BC34B689F34630A9B01E77E36475CD95E783D0407FA1',PUB=>'A4D3FCBF3E5BAEFBEA15C608674913814DCF8CE0CBCAFDC1854528C931A0E5A08EA3212E961F8755DB3104701DC59E4B7DD855D88CE3C8B9DE6CBEB3AD5C5C185E6926E20B335ED31BE13A2EDEE327A384C8DA7442327CF3162EBE5D687452E12CE9AFA680F5C44626035B85F361202ED5487ED87F9C1E82940618641BF466DA602872B7556189B23104E2E61C5DD3635CEBAC13849EAFDB4A5E740C8D2B4EFD558E6BC421BF700DA5ED3AD69E7AD73F5C060982BC0F330B78FBC0043D742962A448AB7DFC39262F07CFCE7421CE8888A500CE6567D4B5DC8B02F29F8986A2F4CE32C3DFBFCB5756BE8EC4AAC017A2C40524F57BC6E5B57589478E0289B1194F88BDCEEA933C9E00577D6902B2A498CD8D4E3A85675AFAA5ACF276C063CA93765419E99E29DFCFF08231FC5159B7C4D61F76F5311521BE503A7885707EE6326597283EBC54420FEA0B6E1B5DA4D57AAD61A622700DB9A2B2B7F451BB70698CD7D72885677CDA86A49C92AA83ECBF9196E16172ADCA3D2A854DE0E61BA113245D',SIGSHA1=>'eQrZXVydUvzndnZd2jRRk9QFYzApxtT1aK/e1vDfhj6v+vAV1Zs3CzRVza/FX05pb45zUQf/DoJrmdJcqbHCZzEkMqTWNDMX0CUIlhOvnIC+bgLqAvm2pH3dTKKVvXEgEH5D5lld6r4vMPCde7P0m2rrZNbJWazueFxrkK3cdDZxm/PTwxitgRUo9wd5BRwOCOmRKTGGfJNx1qb5Cuw+idD4HXSbwSBEeq+SC+hdKADn0T7p6F9IU+s+ICOQaL7+akSZS9DFxq2nezVNAmUr2SSzTT90URTk5Wuo3NVRQyBUgFDQv+Z8ddJxkkyveJuNHpulrV/5bmSh8x1QOr0gmWTHpL33G382ST/ApdUjc2kiaY6msZ1OU6SZ2YbfW4kqR9Lq4GWa2PDqlud9miR7eMACXZUfoprjKkjrPgriNQthv5tHEFqk6jfJLdATvl8Z7UwG7LMElbvDYw8pS4KucIKPLUVtkwP0zqnejvDMY6uibrR+mxAaxDofYDhLXIU9',SIGSHA256=>'VsmZbsrygjQXjDNNLcuSeeaP4U06hto5lpcJmdcnGxKBQ4gLor3ogpQooYCwWGkr4b2hWdS3oo7CYZwzgFhAohWJhEwZs8vEf0xet3eMmINt10dtSSSTVVYG2rZ+OxnChYadRh93cQO3NalN7BmZVs0NjI0U/RGrK+eiMEYbQ1Qo6OG/wq2w5CiefKm+hRaLx0nic0zrQuRJ3u09jqKLQW5XkX0iDo5vPc1VCIyAI3dJgzKCfMzfyP8e13a2nSOoqnKWF4+erIdVjjIOsm/u0BnONiviDcjQbkaOSjYQs4eTnwxFw2atgxcvjSUBxiIzy5FZpeuTzQTYoeP75g+jyyk2+MKeMjNGW0KOQRjPjUGgbBHBW/Xoi+R6tGLgmY93NFPgMR1GgGQ45FcndbjRNa6k8iDCCWgwYSSHBomO73ov8ev8TJcN1jDzT8gS6Ex44Q6JIgHtxJRzbG0Ljefmhe37IU6CDl8NQOGl37LkXkLKOuKS+dIq7kyDdQB+JjQX',SIGSHA512=>'Yvbx7o7NWufXxb9OrAKEhvbHRHZxG2UU77ani+CIe4WLf++GdFceE66F7i4S9tpT/VkV07QekVKk1VHzXY3kJVBk7YPTwWjA9kCxsjWlCF70PdoXgNI5QqU9avu4dht+CtfQ0fewiFkeO7XXlwIS29rS4SHmX/UMZ636aH7FxUDFl+JgN6fwyU/3RmRbXtfJPX0aL6f2/JAoo/WeAFtKbYfhdfedZT9D5AajRtDOpDH4Rv0tff40OiWwleMIuRGazXHcTNt/XhhfIl34RR3y3t1q9dFg0ljfLbtGungP5Fiu7kTiW47zo7POG+eOyjOG+82Kr3yDYT2nOu8Eo0ZLcEYNOsJ2kAb5+Xm8uXpfLz1n/ph9vjIF2leAKE9KJDQhsqnoytvCo/mAJz3+lgXwiLIZcqPAo3Q8Rw5BmqKmcSw4eR3Ai9A2il799KcFDa9rBZp0HAslSNBrD93/jU9JDULc7zlDDR3JwE5i08Irbb2Yv31QEWtofRF6NHUReRcM',ENC=>'K4yf8bh7N8GDz5Sh/lniUNIHkjRPJPzUOU/UV+Uzc6Y9gQzxwsY/TywHpCH4MOqLy99d5yiaXt6hzKCPp1ELs8554pKmlOaIk9PYA+mU40XPjEY44ut+1cAh0C3UGE4EIdSvYicEBDy8dtwbwxEt4xx0i3a6EP2xX2pmGaJCi0KvVgHHJY+ipze+3rpAyGj90Wm/Mqdclj/OwI0lLHefP3zZnn1IG0mWHzdhi0Ei9XakUVHaQeTz4o7gZWDEZV2Ri5uKoo3T8rLZai7edsnyBfgPwcq+PokwLV2hqoct/YjsMv7LsOsNGqutKwgErXUDYTN87u6dyuN6XYugEpYLq4DJQm4AfaZopipSyheWkRykHOHpy/GfI5fKp2phOExUTeEW4fpapBP4UFdISuwAW1fT4f4tyw+rmrlRV2jCHEH6yLqY1xiq/lkyp19ZrrOp9mUBVMyRhWAx4ZSx04PyWypUwOF9nKBKFVTk4WhqZX1MrhSmediBedXiUc3SBH4C',PRIDER=>'MIIG4wIBAAKCAYEApNP8vz5brvvqFcYIZ0kTgU3PjODLyv3BhUUoyTGg5aCOoyEulh+HVdsxBHAdxZ5LfdhV2IzjyLnebL6zrVxcGF5pJuILM17TG+E6Lt7jJ6OEyNp0QjJ88xYuvl1odFLhLOmvpoD1xEYmA1uF82EgLtVIfth/nB6ClAYYZBv0ZtpgKHK3VWGJsjEE4uYcXdNjXOusE4Ser9tKXnQMjStO/VWOa8Qhv3ANpe061p561z9cBgmCvA8zC3j7wAQ9dClipEirffw5Ji8Hz850Ic6IiKUAzmVn1LXciwLyn4mGovTOMsPfv8tXVr6OxKrAF6LEBST1e8bltXWJR44CibEZT4i9zuqTPJ4AV31pArKkmM2NTjqFZ1r6pazydsBjypN2VBnpninfz/CCMfxRWbfE1h929TEVIb5QOniFcH7mMmWXKD68VEIP6gtuG12k1XqtYaYicA25orK39FG7cGmM19cohWd82oaknJKqg+y/kZbhYXKtyj0qhU3g5huhEyRdAgMBAAECggGAd1YIAwqJ5Mn89CC5ytXsqkyEvXGv+tr4Np4Y5nnpDPfO7arDiOtw16dn+NeXppFyBL4RgUSYUqbHtCHqAtUA1J/eL8mu5FV+MQxDTNYQzo0kQStwytC1CGaCF0+XpcivwQ28H6f0yFMliH7GH6ytWVsQLs5erdClJ7i2Bhz7OVBYGFDeDZId2IaHDCQgW4oFwavbnRICtj3lvTb2M2ssuFwuTjXlXS4qo3x7ghGhzJ/R54kRP0kd4uuIEcDAIY8n8x2AreHRJcH//NeqeV9G7til3rgdDWIjen3C2RYFdjDRlxafBo2Nn5GTGe0/6gg0toSBzesLpuqoKateHtcyuHYKJ5X0TA65yErG7CdLlsGpPpgjlpPXmgIJMXJDf88cVKHK2vhoNiXa8Hb45Zdh8O84gLgwa4430bZsZVTfgl+Zb2bxJY8k01CGoQaby/2c1qmaDSm3JnTbjv/Cg/FEwM3BUBEhsd6/DbO8NLaJ80YwqbAed+Nkdc2V54PQQH+hAoHBANbAPE9cPEqrSoOdSi1IqNrwDzMAiuJmjPhvuBe4XEXr31oZrMXseLnF8gqXoBTFC8x84vDpmGa7rmO1iwmjktr9PlVF7R/v1YRAD191M5z4EhjYNhwBP5GR4lMBvKO3t3dMu4b7algi6sxVTlNdHT+3Q7o1eJw2KldOcVsvxZRe8NbRb8KO8sCnSVWz5wV3ReVaxWP9iAe/fpUVtEaRxk3k9beBCyypjSR5VyjjcN6+SBq7IAHnBPiPQ8KdsDrXdQKBwQDEfPAnZeQujAXF6T+o/ZUPtAtXJ54DcbN1BiE6QWJSbSEyCqvYY8wVzW4m9ymIRjHm+fXFyBWwG+A1PxoiTY8A0Vd8yxzDwWQ4S50z9MCXMdUBhy4VJbgtO8HczMctfcPAg3C3zXNz2ngsRjJ743RCub9JVJ3KdrVelGyI2ObcEMh0M+rf1RSXbl+VO94oykp2gL2JjvQwpaljqYsxT6Nv1e03lIuSLvyhcwtC+vEPM5W4rrGn2NLUGMPRF3FaZEkCgcAVEC3aKtXPDRX16suHvYSyVLFo8zisFBrnky2fRfnm8ceqcrI7h4If1oZy+4Q8BUeu+uDXeFH2YZotNXU5sM2KpSQkAQPNCh0LJ61aU4iIcNx1i19jR8wQXxqvwY/bDv3zuZb7GlXH50TYXdWc35kq0rLV5MC7saRdg9gidYEPmHBO4aPwlUzCEKZkvYx/QL+eS1TpBcj92Y502Pgho9KreTWQlhueedLaLPybihNcBZXU6V2uUhZuur6OrCDI5LECgcBYCvu5S6jBSrDTi76gxG/kh3KFbRUayfn1t/dvmRirgobbW3jBD4bFRjXTc/DCRWHa86ozI4LEVNlUQqA9Oq+XWDZxjrmm5aM4rnkUbNlXZlbhxmbZxvsOGba2b3PYaIAsZTk+wuq2wPAUNqgsZzETLRQPkcDalfKTHMK9VyOq/EI1/4WBIoOFj0l5H0he0rYm/2zulIXKvpB2PeRHBj5fwGX4/7DCohdFaL1lF/ioLR8rj+u/ICLoMuibanu6WzECgcEAmly0b9QQhNmk4+gIqAjBwH/CahrKEIhAErfO+pHt3Lkf05ZeUy6fF8v+HXZxj/rX0MUvnKquOdDl5Cb2iZL9zLzRmyQpP7QA82Igy3ZsccYfuVFsNKx7TdUNGJaDo7zth7nAA70qhjegd96DmsUpDb4tAVsY2QMWH/14nw6QADkcAex+gHi4q0JmYttjO4XlQzJP56XU9OxD4jWv+VroKxwjFJX6g58HJBTnCyI8EoMF7sHaH7M1pXSqQhvjIucX',PUBDER=>'MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEApNP8vz5brvvqFcYIZ0kTgU3PjODLyv3BhUUoyTGg5aCOoyEulh+HVdsxBHAdxZ5LfdhV2IzjyLnebL6zrVxcGF5pJuILM17TG+E6Lt7jJ6OEyNp0QjJ88xYuvl1odFLhLOmvpoD1xEYmA1uF82EgLtVIfth/nB6ClAYYZBv0ZtpgKHK3VWGJsjEE4uYcXdNjXOusE4Ser9tKXnQMjStO/VWOa8Qhv3ANpe061p561z9cBgmCvA8zC3j7wAQ9dClipEirffw5Ji8Hz850Ic6IiKUAzmVn1LXciwLyn4mGovTOMsPfv8tXVr6OxKrAF6LEBST1e8bltXWJR44CibEZT4i9zuqTPJ4AV31pArKkmM2NTjqFZ1r6pazydsBjypN2VBnpninfz/CCMfxRWbfE1h929TEVIb5QOniFcH7mMmWXKD68VEIP6gtuG12k1XqtYaYicA25orK39FG7cGmM19cohWd82oaknJKqg+y/kZbhYXKtyj0qhU3g5huhEyRdAgMBAAE='}, + {ID=>'key-4096-5',SIZE=>4096,PRI=>'A05B5E14CF4BD1CEB276E3F91326C97EFD51B8D9B1A95009F305953CE15093B22A90BBD40F477A692014F03DBEBFC55BA101AD0100875B7D459214A957834E2A6A3486F53B4486BD3B38F2B315BFEF7DAFE12778564E1C4CF16B4515F6BE0E8C183D0F78CBAE237A8774A0639664C559F0B9B216E0E4E9C4FA537F023216E487F7B4FA33C0666A4A4D35182A8791BC35B4EB93B02D70997ACC5AE31D5E7C6319F6F88482D49C80B9CB7B35E8ADA5426A86C9B54EE1F7A33B976702AA1D35C57BC7E84841D10B7EDCCA4E32F4A90335B85A113E60FB0763C970BECC9BD073ECDE6EA2E02542D1938B3D3FD190AA118BF7B02D0A090777E2DA5B7904C42634E5249F86ED0A1C868DBB827D574C661375F1624CE72F8CA10529B3788D679981569325E21BE56E16C41523B745E4009D348BEBB9F6BA8BE3379F7A382385DFD22EFBCBABBDF48DF3FD82E313F0C603CCB423147E219033E678FA16C4ADADD3A72F67C73269369BEF302151BBA10CBA0775CDF697DEBA0CDB83C00B6049B3F6A9BB87DDF1F5E2AE0A41F0638DFF00530E0FA107E05F774DEDE98BFBE0A2A6647A0A413D5AEFBFC861BC86912D60A44248A104A867C5E768E28B24426082700CC09CDC9382638BCDCBB1B41E6EBD0FC4DC62DCF33AAC17FC41C96D49577184FB602C3F8AC60408B3E3C646F9665DCBD422785751D2D05C7BBDDEC607C0B6536C6F2BC1',PUB=>'E36035CB090541BF60293E69026A03CC5F5BD26C92AEA269DF84AFEC738BC23F4F2199A065888CD1E8D0B3783AA706C6AD1A82271CA5F6691080776F15EFDBBDEFA4D11B985E7ACAD121DD047FFBC67901B31315695687842F8BADADDEEC3EB5D73DC9D76DFE446B0643E1BCD1CF1A4A6E0A9B0B12632E1D666CBE62F32DA754695A11FE6B549487CE8C0126649B5F04F261C036F34F3DFC7176F2604B4AC818125BA6E9577C6DEC598897BD05F2C06FB6340ADBF32FAF1BAFA2EAA071F6D7C0CCBBDFE312A9655C3CC3EC40EF951E20D5184318EE9C4630FCC9F31375385E91F9D9222F8F945CC462B1E5BA1966DAB85A1051799DDBDB258B15C793F1DEF6A4ED667275658C838FF5D14C6D73523A662B8AE9BC82D0B158D6F8C443D83BEACB591A5359016C2CD515FC6D2E1A8D13DA66B29EBE9B3A646565DCA9C97D9A3CBF5700F9603DF37373AEBE6E51D4781E7A3A9BAEDAAF01C1B9D86B2F5EB627D3D7B0CA3C37A20D71D8745926C8DA6590CA23318668D9E2BB599A5CD32A8FA53FCB1E037CB7129AD8BC9ECDE9AD67BBB31711F2C7E526F894EDE37E6548770D5ADBD6F9412200ADF8C411E391C5B25C1C44D7D9EED8F3EB3126D7EBFB9C3FBFA8C33771FD8DD7A2E2B3228FFAE267C32FA7D4E5DDB26C5BF9AAFB199511832294A5737B8553EF71307F3F73AA36116BFC70978EC54DC45037D1F6D8396808111B33',SIGSHA1=>'f16UOf4fb5p/vf0g/l3a4wFZo+R9Xo/VvrSEtUP0CaoXktQI55WZOl5cFBcgMi4DAfB0ubtYQsZXVeQuqlrcv13Q0tinQ0y2EJB0v2ivOPbN+2guLYjCvsmp2kTKU5fkxiXOAzTFnX70awoVoMsSG6quQOTwWb0bzQb/hYh/qqzIqHyZRP/DNLQeI3Pl4GXhrIeCD/WVrXUsKTVqcsvnkxEutO+MXMw8baaCYe3u+W6P75Tch5VyDkpAPVv9pdSja/s/pLyTqGNSyD+Mw2a0LLbHiVTTKamVxKA8GGYWjvNvZiprm8W0vughgJXCDpWeJ53D2Ydt3VZxP5JOcZhv09dCsnhSKs16+izZ9S0wPkgamfF4r3VT46AYzDjaAfbXm2ppxz0IIPGkAAV0MlFf9idvXmrKVeQHD1KDus5SDwk0I4YdeYEplgN9vgESgQ4iIkduHnZdWSNUF6ZH6dbyHSde/8ejOm6WFlS4IrMdFjAs4t7n9am9T3xINY/Be5E9b5LOjG58yjmhmOkGJ0k0xObPaT4AeuKr0sROblKJHM33N837Teob2GcRb8xWi6LmDOt/ngbsk+8rGIWNmpDrTqjCQVaGnwR/wTIzpLeW0wYOfG4ZKzXF1FD4IIq4NQegIwfmSXg75rG+/ge3x5LYyl2+iVXPNeGiK+4lHy2Livo=',SIGSHA256=>'jdhbUKJKcc2tsQsh02yKXtx8fTLqTonPTGmfIsU5lR/TDRSWcFg3Ip2jpwiymBStNtL+gaNaMBCUkv24aH1GO0M4xK+nodK5vQkvLrleJfLiDqozxZ/LrPwDNcO8Z93mygNhArs4yANshDEBSiVOKS2qRmPgLrbBfb0+lDuYoXa0lHi1XxddcvzTqwnpnCTJgwqzUX+UWZsN99bcowwJIwNh14JHwiynTKi+5zG2VIshF7OQMkJzQEuImhm0iMO7zkEBAknVHdMSn1D/QVO4DVuBE8WmnqTnQrdaoUUswnQas7uOSBR+TiHz2BNjP+D0ZHQD7AoODXr7nDnOauWvqm1dx5lNcUOB0GVqzgsD7OrxKGqEhoI8WoS5K+aagXY5NYm3tDgSfhAIiaImRvaQZARHzaLBy7ruAnI5aG1aJ0aIKqpnfAO98KWwD45O3Q/KpktCCJ7vvgy56AqzyDEjpHVobUq8ilsa+f+P90kWbcFhfrIak3UnmKJOuw6XSYUu/8Nl7cSqHDjRdPk8A2OaHvTtsWX6B2gmpUgaK1RkMUT9GIf8iLwTNOFcg6cIqnqP+cfU+qmJav8JNJNoUV0x+vHzMQGE/qiCwprk8zmI6PzThPZckRQkLgP4sVFBVre1mjVUPRJH5tLRmQyeuy8WkIKmPdR0LeSykPmM/nMYebU=',SIGSHA512=>'SeCwmfSwBbCw7d0Bsrdm/gb3qi4HH+8z72YhWJw+SOQrgQmSX1Lu/bRnwJFdnzCSYNzcdUCtTbAmNiFWhZknlJW6+O3KJmfABJ/Snmxzj7PgdQswmQF/a+JTyvLAn79hLpMtA08oq/G5A1BLoCkAHgMIvHVd9O1DReJ9ndZQ59wMkT9+twP2HVr4iAQHSleENJDZnUtHJeNQthrlbx8Dx4tjaAds7nKR7vo0T0friGJZmGhh7Kv20NGWWziXJD/cC97/G0iv7v2W9PgdK75d+DjM9zOx40bK89ZURL0wtHeB7V1avHRheaHNtPW9dZItsrniE5W02HrfFFiOpbRnVdqFYPKsWkhjwLYZKpQ/SH+LbjB8spskLa44S1jH7oQ3vMCMDafhOCZpzfUhlHUe9xBfG1yYc1WM3Tr3KwXtQLONVy39ka6V+1rBdqVarf891jJiifT9uafxCD5G0mP/s65KlYmtqCihHmkWLX33+mztZb7THlNNPTO+hVh/R08L0ZHPSk6suNNY8F83LfxqccMslgbwCH0CcP2m0DozC4vsP2K+bz+QdSNKjeka0cg8vsJQm/xE6viUzSormEfDl8XS3lNq7RpWB5wJaMLBj9DCuXfzyMYFJqluZp+rysV0HMk+ank1aQ84TsjdNXsroHTsoOOjtt0N1L+0KSh3KD0=',ENC=>'rGSh2uDhVc6qoFtyuIH5WgVQtV0sngA/JWnEMVn5FpAHdEdikiShbM2rOHochRKibG7YA6hpuAQAbKhvWujmZerBRB8knIhkCX5HFY7mLVUm4u4vhrPGLlXmBnHsIgcgXjDNRplcRC1syM2M0ZS0/bST7Evaw3zRJfLjbk6eKk4KoguPIeqd0yFSU3z7TsDAj6bQ9qHyRinsA2KT2djvRu3q7QFalao6gdGhERQzWVm+tOXOrvyRxOyBNhchcpYL9NI2oCAFf8DiobFSY8k98VRVBykj+bR1G7LHgdhYfwUXNkYmjHp5wVMjABryOQZWiSXnpV8YzlkaPF1FPn3XXqOxFE3xUNTpZ9z+kaaK1Q2164NO4TIHJ/VEpDJj0LHJnVNmiiLtfdd6wWdYbMslQnkgeuwbqZKcAZgvyF0Ts7nClIdgD2hzMFB4Uco9ht/yxF37xXILWPmD115Pmp0e8vbH2r6o8rpUKTwgisRC/nMw/orc+FIujbApqbHV4yq6W+EcxGbff3hJRbfGE1ydbns2Xdxoqa087i63WFVlERYogpvqB49b2EPodprJTQNYzZOi/lW+Pz+E7eC7x3EiEsI1SYKcG7vgjiGOIOlCX3bw25MhHR6UUSea25m3S1MWkmRNpO+U1FVzLJUqamrzIR2+c5J/4pUo42wlieY8HbE=',PRIDER=>'MIIJKAIBAAKCAgEA42A1ywkFQb9gKT5pAmoDzF9b0mySrqJp34Sv7HOLwj9PIZmgZYiM0ejQs3g6pwbGrRqCJxyl9mkQgHdvFe/bve+k0RuYXnrK0SHdBH/7xnkBsxMVaVaHhC+Lra3e7D611z3J123+RGsGQ+G80c8aSm4KmwsSYy4dZmy+YvMtp1RpWhH+a1SUh86MASZkm18E8mHANvNPPfxxdvJgS0rIGBJbpulXfG3sWYiXvQXywG+2NArb8y+vG6+i6qBx9tfAzLvf4xKpZVw8w+xA75UeINUYQxjunEYw/MnzE3U4XpH52SIvj5RcxGKx5boZZtq4WhBReZ3b2yWLFceT8d72pO1mcnVljIOP9dFMbXNSOmYrium8gtCxWNb4xEPYO+rLWRpTWQFsLNUV/G0uGo0T2maynr6bOmRlZdypyX2aPL9XAPlgPfNzc66+blHUeB56Opuu2q8BwbnYay9etifT17DKPDeiDXHYdFkmyNplkMojMYZo2eK7WZpc0yqPpT/LHgN8txKa2LyezemtZ7uzFxHyx+Um+JTt435lSHcNWtvW+UEiAK34xBHjkcWyXBxE19nu2PPrMSbX6/ucP7+owzdx/Y3XouKzIo/64mfDL6fU5d2ybFv5qvsZlRGDIpSlc3uFU+9xMH8/c6o2EWv8cJeOxU3EUDfR9tg5aAgRGzMCAwEAAQKCAgEAoFteFM9L0c6yduP5EybJfv1RuNmxqVAJ8wWVPOFQk7IqkLvUD0d6aSAU8D2+v8VboQGtAQCHW31FkhSpV4NOKmo0hvU7RIa9OzjysxW/732v4Sd4Vk4cTPFrRRX2vg6MGD0PeMuuI3qHdKBjlmTFWfC5shbg5OnE+lN/AjIW5If3tPozwGZqSk01GCqHkbw1tOuTsC1wmXrMWuMdXnxjGfb4hILUnIC5y3s16K2lQmqGybVO4fejO5dnAqodNcV7x+hIQdELftzKTjL0qQM1uFoRPmD7B2PJcL7Mm9Bz7N5uouAlQtGTiz0/0ZCqEYv3sC0KCQd34tpbeQTEJjTlJJ+G7Qocho27gn1XTGYTdfFiTOcvjKEFKbN4jWeZgVaTJeIb5W4WxBUjt0XkAJ00i+u59rqL4zefejgjhd/SLvvLq730jfP9guMT8MYDzLQjFH4hkDPmePoWxK2t06cvZ8cyaTab7zAhUbuhDLoHdc32l966DNuDwAtgSbP2qbuH3fH14q4KQfBjjf8AUw4PoQfgX3dN7emL++CipmR6CkE9Wu+/yGG8hpEtYKRCSKEEqGfF52jiiyRCYIJwDMCc3JOCY4vNy7G0Hm69D8TcYtzzOqwX/EHJbUlXcYT7YCw/isYECLPjxkb5Zl3L1CJ4V1HS0Fx7vd7GB8C2U2xvK8ECggEBAPg/VEAdtoxgzIVARFW4HrFwi653nXgo3dz9PRuWXufG9I/6SHcuZD2mKTwwge5Gtkg6RxNj178KdJ+WTRbi7rfDgyiEHx70pJBPcSzjWliyWHLuoPpdC0uVIW7Tku2SZwpyPHUVTpGzZusaS5fPA+W//EwuSxM8MYvs7KjDAV62XaHDVz/i2b32St13VvrSnAHo4SKUj/sH+dio8KSyq7vVphx5JY5+jZtGGSoiC+NWhH4rqXFYaJX68DCFo1Qqcsql6KNy5VMPH3E314fhM8ptBHF+ZFdhkIz/JqQe1Zynqz4NGBFRaBawVpPSw7G/+Wb66dD+lfvEL2tlJYdlxskCggEBAOp6BL8TUzHcdK99seR3GnXrgOsLLvD4nQwXv5tsrv7fGn3jEfJpo2Tbt5PT4wKDn/als73mjfB3thv3j0I6ANS3RjKxvRRe9N4aKJRKDZ87gaVLXhNt8NmggCl/5c78nEfRmue4KMaTPZyPBikQiUXjm429+6vNQUYFnglzrcUzieSHFEDNIckUU589kIedHNcucEFVpzESnQhESn1BPDB360ZdQz4c0/9bBLp5zI9C8xIg/nc9zA0CzDjijSx0KR7ATO7n2yQDXb1110Pd9AO+jXtA/XCzZznQSQFcB82cTlXNZ4kRnSWWJsYKwwwS5J9+0fygtzrQTqpohQpqBBsCggEAOEEJk3noOwlYbz2v/oi5k9YAISoD6g3AsOpF5bF+kiE4nEPIFhHSL1Iu9++6Ece+WMG0B4XRhv4UjXFeyLfmBohseUrvTnF7tSP7boOanozTlD/VBMb+30LND7MsEV/ir7BRWOraIhQ4V0BfLuh/ZpnJz22SH6q9Q4sN2fROpCrJLvX4GIcMdoqQTn1TnYUKSzh9g/uMYQNer6Ug2wGN/wOcH8moJBEzf6Mz4qNSdFLPtVOpkwDIumvh7+zopRL1bkyIWjmYE+lSY7KWybjTpqRrpFhS3qZCPmE3XWuLVnN8T5RiBtKetr2A8QCKzgXFu3tSbsSyMhoz8K88AOGkWQKCAQANB77fx3kmGjQ51GhgY+YKi43cggCXz5kapO82+fE3pLpaKJZEvG4iGru28V16NEpdcJPuh7N3m495OmaxrXuCVrUF+C6jxSsidJ2wr/TV1n676tZNihyKW4sDw2HIAO3GZ/WNzwQlFOWln6Ud/xdB1QY9+ELWJ0/rTkCcEdukS9rr4j3T5BJulDyZathvUOHba289kj76USh83x6sm0V3BBMFFAW6m+uEE1DN9BrUE0pixYaepcaDKpaiyqRBxirK1LDxzdy1waIh9zyBPwJieuJt6QysiKvB4LtN4glk+by4s/N/AIWVIyUAeHSiZSJjYq7UtTG5iP32JlzOWVnlAoIBAEfoYhZy2dp6+QHIjLuFmOle7Roo3w71R1tSuFliZGlC14pJnV9hmbdFSdeoE1AzK/aw0wgTi3xGPsTfnUbuNuydiO7LJ2SV/QstYfgCu/dJ8C4U9ukO2fg+VDoV4p89JMGq4Qaw6Zv+FgaYau9m5X621RIJGx2b2G6X+W3l2OgcJd5s1AXYjT9VlcnL+y+ej37zZBE0RUHPEFjZHLELNMLbH0r+n8PuQFSBlgxoi5rr4P8IMmSlhwAe05GOa+2pBPsALlyxVi9aFpb+eOIe9em1xmJyEwopvGtd4VTL5bCRN30hEuVw15HptZdCfAF821CH69sOQx+EPjNv4P8Tp6o=',PUBDER=>'MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA42A1ywkFQb9gKT5pAmoDzF9b0mySrqJp34Sv7HOLwj9PIZmgZYiM0ejQs3g6pwbGrRqCJxyl9mkQgHdvFe/bve+k0RuYXnrK0SHdBH/7xnkBsxMVaVaHhC+Lra3e7D611z3J123+RGsGQ+G80c8aSm4KmwsSYy4dZmy+YvMtp1RpWhH+a1SUh86MASZkm18E8mHANvNPPfxxdvJgS0rIGBJbpulXfG3sWYiXvQXywG+2NArb8y+vG6+i6qBx9tfAzLvf4xKpZVw8w+xA75UeINUYQxjunEYw/MnzE3U4XpH52SIvj5RcxGKx5boZZtq4WhBReZ3b2yWLFceT8d72pO1mcnVljIOP9dFMbXNSOmYrium8gtCxWNb4xEPYO+rLWRpTWQFsLNUV/G0uGo0T2maynr6bOmRlZdypyX2aPL9XAPlgPfNzc66+blHUeB56Opuu2q8BwbnYay9etifT17DKPDeiDXHYdFkmyNplkMojMYZo2eK7WZpc0yqPpT/LHgN8txKa2LyezemtZ7uzFxHyx+Um+JTt435lSHcNWtvW+UEiAK34xBHjkcWyXBxE19nu2PPrMSbX6/ucP7+owzdx/Y3XouKzIo/64mfDL6fU5d2ybFv5qvsZlRGDIpSlc3uFU+9xMH8/c6o2EWv8cJeOxU3EUDfR9tg5aAgRGzMCAwEAAQ=='}, + {ID=>'key-512-6',SIZE=>512,PRI=>'BBB69FD9A0683F82805A0E73535E1033921E98D50761129958E3073DBBD5D63BCE0B83EC1704B68B017A7DDAB76D1A7A96D1BD3D6D8095EBD949CD1F3E709AC1',PUB=>'C4369075B9568511F4EDD35211A0D0574A008D0F690CAC7A8194E8EF0D2FC17E61D8E6549E9B9EB81258DA9BB9C0D104B74E3EC3E8BA63FEE8CDDF86D15AA7A7',SIGSHA1=>'FQp1Znk/8TYc363qnNpTc80rdX7pZG+GmHtUxxuYueu+6iuDQEZypDPjIFfGxkOab+fGmjItZtweVHnMVHOssw==',SIGSHA256=>'P7FHwDaA/p0bGASkokVjZseslhy6gNWVRFsvX5aSBM5LvuB1OZs2M9LkNdp3KBQWe4x6tMqCdAafqzOT1t1pkw==',SIGSHA512=>'',ENC=>'s6tkTZzxdTmrb8uWLzxo8WcGfw7HaPDrLnTbrFRptlTN+FGldg3xOQRTt0ltIg4BBi6HXmLNDq9yc5UPl841yQ==',PRIDER=>'MIIBOwIBAAJBAMQ2kHW5VoUR9O3TUhGg0FdKAI0PaQyseoGU6O8NL8F+YdjmVJ6bnrgSWNqbucDRBLdOPsPoumP+6M3fhtFap6cCAwEAAQJBALu2n9mgaD+CgFoOc1NeEDOSHpjVB2ESmVjjBz271dY7zguD7BcEtosBen3at20aepbRvT1tgJXr2UnNHz5wmsECIQD0zEfMMCBlYfuIRCrd9j4Kqfdw+sZGQ3MdGFH7b57k9wIhAM0xIVLCikrSNL7nDUzPr79Ozju2nnK1ZYILQTg0D5bRAiAKY0TEsGIfiznePW5IPvPBBhde7vVM8/3FhUutTL5EXwIhALY/mepo8e3M0J5yl+SOXvnbY9+zrv4RUax0lKP30ZTRAiA94qsxTTA4fcZRi8OlFnu1+9jElazXyomF7Mj44PhrZQ==',PUBDER=>'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMQ2kHW5VoUR9O3TUhGg0FdKAI0PaQyseoGU6O8NL8F+YdjmVJ6bnrgSWNqbucDRBLdOPsPoumP+6M3fhtFap6cCAwEAAQ=='}, + {ID=>'key-1024-6',SIZE=>1024,PRI=>'B673C14CF50DE43FFCD33425AFDAE605E446C302F37369DF5CDFFED3ACC404F928F218D3E84F964E7063F74722084F4660E9B2E3C31A2C12B3D2CC9C0CCD3E7358AC4EDA84559544C5241150BE42D84EFCAFBA970EE4ED8E92D9DBC4B1ABF3272455B9FF75A19DD9EB849C6AAC1CB2EC57DDA07731C02EADFD62C03AA30E1EE1',PUB=>'C25B269D018C1A89E4A897CC73F66331BCFC23C685701BB51CD44755E9522F0875857F74FE1685AB6688B4A2B3CBE47B51494DE7AECD13EE4E8AB4C264AD7EF12424E97BCAD544DE8E18F9BEFD2F2C88B3604AF4C14133E1FA2B9142B37A8A7B5BB2E3FF9715E3CDFF9010EB9657B1C72AD72B6AA6923F688E977CC28FB23A03',SIGSHA1=>'ULBdJR3sSXlkAuaYws8ymIQDcuY9JAjHc0YgGIlBHz87sanlLiCEIqLX5XDHX7VkB4SIAWzfAKEgXOgmENBU7SjwaJVRVtwINJ6zmI0ruc4Pr5WtZ/TjKg05Mu4msi9+20C7Pott0JMeespcRHf7Teqpgd2VDd0JahRZ4n2lGnM=',SIGSHA256=>'Y6goUfxWcoFK2uZXd3BYM1uQSPOUwmewYV1yyCzvhSfu1TKbUKK8BsuUptmRdj4iYyXNJ/YgKdCO2hQjFqO47OhsMUjXd0AmFqgaNt1n2t2uP8XnD/MeGLhDKy+YyJ78s7BvenxagW+TjK3ticr90qFx5yb7zyHnybKD9JEOSdA=',SIGSHA512=>'WOqjwwqoJ1AfcbMVFK3VN3nbY1q1hJBZ4c4xTv8Kkz7+9rhairVY+sYhiM3U2APPZkI/pIWxhkPPaQSFWdWV5zV6o+bTbidqk6DKopyAr+CFrVSnGTr25RO2nwGKRc0f95utCMyp9lAppThzZbJflDGAG/JCn/Yxg8djq4t0hkY=',ENC=>'b01Hb1XB1W5z8thPNZ0Mnoa638k4f6xs1dKsnO4HI8Dq03ZXQYOAKZ/CPt/Ow+VtJUQvgfu2xbrjofPZWMBv4xKrh0VBDDjM1PhHoPSno1/hpPiZscYHLUJ2eFeoJXW/uOfaIEYB8UNvubbuFHVNpU+nqihC9p3SesrhLBzXViI=',PRIDER=>'MIICXAIBAAKBgQDCWyadAYwaieSol8xz9mMxvPwjxoVwG7Uc1EdV6VIvCHWFf3T+FoWrZoi0orPL5HtRSU3nrs0T7k6KtMJkrX7xJCTpe8rVRN6OGPm+/S8siLNgSvTBQTPh+iuRQrN6intbsuP/lxXjzf+QEOuWV7HHKtcraqaSP2iOl3zCj7I6AwIDAQABAoGBALZzwUz1DeQ//NM0Ja/a5gXkRsMC83Np31zf/tOsxAT5KPIY0+hPlk5wY/dHIghPRmDpsuPDGiwSs9LMnAzNPnNYrE7ahFWVRMUkEVC+QthO/K+6lw7k7Y6S2dvEsavzJyRVuf91oZ3Z64ScaqwcsuxX3aB3McAurf1iwDqjDh7hAkEA5Py9rkvaufu/OQkvVisUIwr2Nz9TnXErdqCzh9b0Yg8pUWXjQ7dIysAyj1kAH5fnV8X+SE1adDX+LxCdHUxuEwJBANlIkitY/OhbtKCoF9lu1QJ5p1n00/9PXu9DBNmLCz/qX9L71wu5b1pOutOAngC/HQjKXLy+QlCzJO//zbOjwlECQEJuhIT9Yq5UN8zPOllwU/46nuW2TIa/n1FiG9OL7AhKx7zip0Us9kRD8CcgNeX0htwzB6toLZbLVzvGQR6P3tsCQG84MGmz0TD20Ax0PlDz5GCx+LGZGnLTI9sAyRi5jXaX95i9hCPiNVdaeVMNwNLNAIWhX7rVAIjiSgP3QkmzhyECQHY0Kltajao6C3h9eNzSG38R7SSzJa/J1kArEOZewYpujTgKAiPG+UfWntD8hUubDQYqHJXQXt4RkC4gUlbUD+s=',PUBDER=>'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCWyadAYwaieSol8xz9mMxvPwjxoVwG7Uc1EdV6VIvCHWFf3T+FoWrZoi0orPL5HtRSU3nrs0T7k6KtMJkrX7xJCTpe8rVRN6OGPm+/S8siLNgSvTBQTPh+iuRQrN6intbsuP/lxXjzf+QEOuWV7HHKtcraqaSP2iOl3zCj7I6AwIDAQAB'}, + {ID=>'key-1536-6',SIZE=>1536,PRI=>'24E9ACD23DB3D0674E3541DFDB847B6AC2CB8EEC8E0CA0849F445DAF985AB30F1C428A4E63453646E2C7FEF7D5920012B50F10135497F95E2F68CE18696DA73F5392EDE1DAD140E6AF7DDDE939ACC1E291965A974D728E41A30FD16EBFE6D1980694443B8F2BA1303406EA18C45D0E7837F27D20B42DEE9E6B6413FBECFA6060F054738CC87A60C2E62B74644EBD3523232686E53399C8DF751B51CE7CC0D04FE12627932F0F722BC113A67C0781F1923F51C18866F2AC5A771611743F8FCC01',PUB=>'B0949FE081458D402DFA786F2BCE7FCC8AD80B36BB2EB0455BE125F830A0772D352C987F053981E8668751FDD7AC17B50D698F7ABE3639F7A4A4B0B8031A65BEE020511CCA2AD2C746B7F8F5013BA34DDFBA4445CFE635259F0240672C20EA623C5F929B332E97B2B3D9631DF2FC6BE7865F53CD56E40876EEAFE48CAFCDA61957CFD337745C4FB18FFAA37171F2D8500C470B540857E85D9AE5CE77FDCE3A2657846D04BD9494DDF6805EA9D93839906339A72046A73B4AECE609C0CA7C1479',SIGSHA1=>'kL62p9L1ccnobou2FjEO6uawr2eOFMBsvkzSARQ1K6XfDmqPhED6QtIgGQ+xaOQK8R/HHEVKhz6SGhaha/vYpGdLEY9e7optmrA1IydiWV3L04RS3FNJz3TecjAlTCG1dwANqNDoqPsF8dBx9iP/HOPtq+NkQ6VMc++BYNE6LVr7B+CwmxKg6+4ognoFjllJ/wAsdAiQeLB10rGcYmQox3pZLg1+HU7h9p64JMYlxxumYak4yRSDZBZzojKXaIcF',SIGSHA256=>'rEyxs2x6TBd9j7p4mRaIoATqYSl1KOxZmSQW7346Cy/xVI8hYxjQyBc1tZ93hjdBGT9TwQuIM6V5NfLgfGKnogHgRzxbTUBnynRwl/bO/btja0bWbNsMRrfC1g+HuHlsraaUJt2mJPJpvEdiadxwwwtbXtyA6d/LYZYQXRNhSB9CdEDy+gpn0szyF+s9fmyBCYgP/pF6MFAe0kjJ5RW295ZviShAiDV+zkXcpjIvpD2caozm+u0NPS6bi9jO49GF',SIGSHA512=>'nOObxwLzDBmX25gOLAQBhksmYfShwAJXtNVndzqRpzRyfwKcWDGriYyjzGp+PODySkhT6n73Q6M/naC6GDw4oUH9evUPujEBQsqR+WqahYBFL+X8OPMGAUz8mOPpds8dp1BMIQxaEOIBdJ7A8JXvvFxzr/FCN43hk/lyPAlOjzsLLQFUXfaN8LeAru13RlasDGwAs3QsciCEsLlem2NSsMClADALAabMl/JHlDVgqh271B/v+Xxg1iUS4swkhk+4',ENC=>'WH9GeChK7CgU6mV13XSIYhz+aiijPF+DgaKtW5QIeUcxdYlEd9VcWc/P7J0OWzWdm+QnluwIzSX/Cjl9Lb+dcZT/YY1s/TKU6mFG3HHEGqjX1iyuxvVuHPCxLq67laSsTOH6Q4hFrwrcvxXAx/VbqnGtZacQUZuvzF2oaSgnBE2AMtEBWPMDRxkGFRvm8dx+bsetV6zxmlgkIiAagWEv8HMG4YDa9r/xzfNNLpsJ/YcqrO+cEuXcGp5+MQubfsei',PRIDER=>'MIIDfAIBAAKBwQCwlJ/ggUWNQC36eG8rzn/MitgLNrsusEVb4SX4MKB3LTUsmH8FOYHoZodR/desF7UNaY96vjY596SksLgDGmW+4CBRHMoq0sdGt/j1ATujTd+6REXP5jUlnwJAZywg6mI8X5KbMy6XsrPZYx3y/Gvnhl9TzVbkCHbur+SMr82mGVfP0zd0XE+xj/qjcXHy2FAMRwtUCFfoXZrlznf9zjomV4RtBL2UlN32gF6p2Tg5kGM5pyBGpztK7OYJwMp8FHkCAwEAAQKBwCTprNI9s9BnTjVB39uEe2rCy47sjgyghJ9EXa+YWrMPHEKKTmNFNkbix/731ZIAErUPEBNUl/leL2jOGGltpz9Tku3h2tFA5q993ek5rMHikZZal01yjkGjD9Fuv+bRmAaURDuPK6EwNAbqGMRdDng38n0gtC3unmtkE/vs+mBg8FRzjMh6YMLmK3RkTr01IyMmhuUzmcjfdRtRznzA0E/hJieTLw9yK8ETpnwHgfGSP1HBiGbyrFp3FhF0P4/MAQJhAN486/f/pc9FgqAq7L59s6H0DL0kRGMhNyO8bkbcji4ikdcpOOEODxFvTSTmMnGK3rqL7cQw4/IUTxs/BWoiF7Hbbgx4ctOOxlNLfBoMA5HAR4IEuPL3aYZQf5ga/P+mWQJhAMtoCTqR86kvusUaAFnVS7gI92FO1MpACgOPik3hLqAwdn3vjvs3W4J5WwDT/aB5KWje4T+E9Db96qVuwB0kAUFoKtf2+lrAElg/uy1mi2nrv0IevPmjDRgJSwCqV9ZbIQJgNwoxiscm4pGdi1t2LKtnHLobmZBs23wzcsdNLIGdOPHY2sfbzWk09CVznqrgXVx+UwcqyMcu/RpoiR/vkFyHL8Zfl/kQvzKCDckJIE5PZ/6N9zaCM7Jw0RIIt7wfYpVpAmBneU4wkGzOpWwytm51RI9XWKBXzR1sobU2aH/n7GSmsuCkYghvfZK8xfVob283gktxgOg/QuhlTThf3f43FMjauB4LbSWgotLyN8GFcAP95yKNhUuHBs4zaw7PkNhMQGECYQCJAQP9LlOCZjZ9rQoe4AM/Lsuuxr9Xr5/vYndwxBbhCdS78x4PYs3AOs4LrieEJLncbF7BGT+WKP/8YqOZNOFShz8QdbbMPBwo1cFU2x6Q9fw9pS0iC4nErobkjEHxdJw=',PUBDER=>'MIHfMA0GCSqGSIb3DQEBAQUAA4HNADCByQKBwQCwlJ/ggUWNQC36eG8rzn/MitgLNrsusEVb4SX4MKB3LTUsmH8FOYHoZodR/desF7UNaY96vjY596SksLgDGmW+4CBRHMoq0sdGt/j1ATujTd+6REXP5jUlnwJAZywg6mI8X5KbMy6XsrPZYx3y/Gvnhl9TzVbkCHbur+SMr82mGVfP0zd0XE+xj/qjcXHy2FAMRwtUCFfoXZrlznf9zjomV4RtBL2UlN32gF6p2Tg5kGM5pyBGpztK7OYJwMp8FHkCAwEAAQ=='}, + {ID=>'key-2048-6',SIZE=>2048,PRI=>'7EC4BDD99A49898D28E94937515CD953E014A25A64AC4FDF3805836B067902DD4CF9DCB31FDDA9502A0A32DE67C1E96F4BDE7B8EFAC575BA1CF88704A4A0D2EFD4BF324B3CB4E35FF35975A8C37A756B668746BAFBCE233D8BFB383F08884800795071C561B1AA0A098ABA93310EBA4EE634B7EA49DBAA9B70040DE733EF41D491600F724E2FB473AC538D0490411508F037DB7AFD713CAC81A6403A44889AA7C660B820BA20620CF7B8C01B4C9659CDA63D7E54749E5A6CF840EF7C3E735B7817D896A1F8E14DD56DE625CF985B26A47028002DA95820B7FDA1C41AE63FAA59EBB56D4D71421CB51CF51701A9A8CF6D98CE103FE4CB37897820C2EFCC020B01',PUB=>'A64DB84D126078A471D0BBADEB93311F03D73E20E22A087E6DC75F57A4657319D4D144D4BA2F196E79494C8E7E128156027565B0EBFDCF2EC62762D9C675DE8FBCED415012F0C15BC19789FC6DD28296F45B0E91ECE446F60F4E2F2A952B006B4015DDC4A0399E123082F5BEE32CBF89C5B68980D4E0BD0647D4D242C7CAF0D260AAD2B1406912495DAF7E9E38C750B32C6FFA4F65DCE35A71D8C6EE0D62E9707BBD039BA8053BBE36FED27CD0E12333097BED9E93E2EC63A7C6F00712479B88A42D6DF40DDED6402378F7329DB6A5169FDC2EDCBE577A2C5D03A38B25FE711C7E518B6EF6B474181C27E10A00FB684B65969D878A222E2CABAC60FDD989D2F5',SIGSHA1=>'JdSm/mDI/mDzAAmPPoQ7bVBtJ4U3a7DHkt8nMgh6Z/SQMpJoyS1eTisgVy+6HYgrgJc/stbjzB9avcn6ITdY7tWK5hMhFxFXI6ICLwbOdwR4xB4+O0V4gQSEiVbq+1SeK62g23G3jqnDmBZKBdj5sdR0eXtlB4FItNSO6MzFES7YAoaqRI6k9T+iK4TfNKYEIqkFxPVh1FpuMn7dWVuvIs15E93gmQf1wKlfbRuKZlJtPX9UV6A5pFBTXggtfMJsRgdgvj4v1hz8RkkOp0ZWjoytLvTKIQDn9niS1hqYgSlXOihLYSoKovYyX5aLcgkNwPFTHWkTnivPwrORBBvd9A==',SIGSHA256=>'Q+avXg2WrgirrSe3u5Hgx8ybpX2E115jzFFbt0L7ZXvGwf9gyu9N/jv6lG3/q6heAUry7o0OLVQJpYYTy1VzMryt9XkDkBiNCd0rWea7MM9KxlMsaZkr+Bd0VWNFo+6Q7VC2s9Ur2GVxpByodLCrZNz13rZ56QlO+/IbVsTVmYvqiai0xWTB4Un7ChdwuYjsHljdRC8HVyz2q0oZpCqMa2OkaQ36J8hNdt58zM57wsQusOelkdPgtTXiE/a+M4YXFjQV06OHu4XoIiND7LPe4rEwSd+lXW7a+Q+kmkadXvx9MW0F0tb88Xrq7tPDX1Z5si+ScOU3I+lu0zZIdfyj+g==',SIGSHA512=>'aLA8+vhasUXdYp3Kya7lyKJLfdbVVwc76U64+k62lbF4UB0xXQ+9guK3dLVkhhlOn2WQxg6gXh7YhX4ihkQKYpbwD2d5FBe+Uka5fDU/kR+ygDoQkM+NBdZ9B/QNCP67S7968en2mFqueRkFw3a4rHDl99DmRvBv2hSgk0l/kJ4nXz0k5HPgcHpCPTMFm6fGVrbbBW284Lm4102KrbiVdrJ5MSjo9QsE4L4ZRmOf+0wdi82nQNn9t0a+VsmEmVqD389GfoeAlZYrJ/nLHUZN615PbeTinru+/dWtxxStCblIknXAHwpNUgObs4IBhGs9tFYI9QihYOXZFNGHROApKA==',ENC=>'V8KCfS7javTY7+EACNP5YTpxH+Qt7BAp+MfllSF3TNeclfdQme11GuJu9ia1KAfWyQi0Wx5LsO0IVqP//7J0hVa6OgHGRJEAXgjTzufu7uKkrHc8cC+0XOtZoXSLd4OvVbTk84rDlauFsQEjkKWlZUuS2AI6GWhUozM6zPBwKxOgGc7OQHP9b3NVDGgzJEv6c7R/Uf8S/laOlbUla6XeJBGEWNT+elmu3pQC+qiR+mnQxZYFAF70geCfXoiB18XvDN9G08552RLS2gn4QQKSQhTCiFnVKdTWgRQHcAihQBgIdmGgYjX8G5uUx5jqGuk7r8YtVqabNIFQBsmiNuBUjg==',PRIDER=>'MIIEowIBAAKCAQEApk24TRJgeKRx0Lut65MxHwPXPiDiKgh+bcdfV6RlcxnU0UTUui8ZbnlJTI5+EoFWAnVlsOv9zy7GJ2LZxnXej7ztQVAS8MFbwZeJ/G3Sgpb0Ww6R7ORG9g9OLyqVKwBrQBXdxKA5nhIwgvW+4yy/icW2iYDU4L0GR9TSQsfK8NJgqtKxQGkSSV2vfp44x1CzLG/6T2Xc41px2MbuDWLpcHu9A5uoBTu+Nv7SfNDhIzMJe+2ek+LsY6fG8AcSR5uIpC1t9A3e1kAjePcynbalFp/cLty+V3osXQOjiyX+cRx+UYtu9rR0GBwn4QoA+2hLZZadh4oiLiyrrGD92YnS9QIDAQABAoIBAH7EvdmaSYmNKOlJN1Fc2VPgFKJaZKxP3zgFg2sGeQLdTPncsx/dqVAqCjLeZ8Hpb0vee476xXW6HPiHBKSg0u/UvzJLPLTjX/NZdajDenVrZodGuvvOIz2L+zg/CIhIAHlQccVhsaoKCYq6kzEOuk7mNLfqSduqm3AEDecz70HUkWAPck4vtHOsU40EkEEVCPA323r9cTysgaZAOkSImqfGYLgguiBiDPe4wBtMllnNpj1+VHSeWmz4QO98PnNbeBfYlqH44U3VbeYlz5hbJqRwKAAtqVggt/2hxBrmP6pZ67VtTXFCHLUc9RcBqajPbZjOED/kyzeJeCDC78wCCwECgYEA1vXsRspYGbGm8QXZyxmr+WOYePVLen1fEcJobHm34O099XS1XHeXzsmR7C7hmL2+2gdMVSpJHl9suwtB0rpIpae0B76I1MTGHBnDsPLji6y/8doljvzU0fADU3GZoK22qjK2vgM+1ReyOE4bVJFxJhZtj8LlP8CnHCG1slQVasECgYEAxg22Smo/1etAyL6SRkNfPRieoDuAINiq39cQGE6vGd9JJzaBo+XCPoyo+/MdzIBjQl0plgR8qsopmnyZw0rXEtTJjYKo7eP/udd+NiCmwf5InW/+mJW5kYLoyHAeQ/bEVnU7v7OI5jgvOCavhFLBq6OkoOprxbwMu+mo8KaF+TUCgYBsec2yK4op7SyBlKJDi8DtKQVYhPCB76J6I9DubL4OE6qgozSiZPeGstGgjkfp/FbDT8uFbsFXQnBsM1IUNU1Tyz1eaxhBxsryg03tjaSmZ5a1RZCOh6geCTCkez87hm4XlWACo0Ch6ENXhpLkKkEfJ1JCqedmNKIf4CMAys3EAQKBgQCLJsszUZ90T4v+/1aKo39gz9Fzxxpo+ZJlHxeh3HbOeMFPGc7QNvfZNr7r9o6zRml3ETnMu25UGSJN9smaGxUtl+/cyzahnhXonu2AXkSL/HtMkomQ73GoORAQ9CVvnwunq0rFkADZsBQNIbEkCXklfR6IKOx7y3ou9SbLnlR3GQKBgGvUaWGs6qFobXbPJvFBmWwhwqTyV98F1GSTP+IqiWcWDHQoZ/GDxAPHjkLRmifWJ7271xlK/YkL3wD6mw8Mvb8G5VdMw2/T24H3WNbSPdiy/sx9shvbx7EFVL9O1sz01eGSUyuMAYGhRAZ32JWvgkqT8Hdq2EFOoOsnlrsDmlXh',PUBDER=>'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApk24TRJgeKRx0Lut65MxHwPXPiDiKgh+bcdfV6RlcxnU0UTUui8ZbnlJTI5+EoFWAnVlsOv9zy7GJ2LZxnXej7ztQVAS8MFbwZeJ/G3Sgpb0Ww6R7ORG9g9OLyqVKwBrQBXdxKA5nhIwgvW+4yy/icW2iYDU4L0GR9TSQsfK8NJgqtKxQGkSSV2vfp44x1CzLG/6T2Xc41px2MbuDWLpcHu9A5uoBTu+Nv7SfNDhIzMJe+2ek+LsY6fG8AcSR5uIpC1t9A3e1kAjePcynbalFp/cLty+V3osXQOjiyX+cRx+UYtu9rR0GBwn4QoA+2hLZZadh4oiLiyrrGD92YnS9QIDAQAB'}, + {ID=>'key-3072-6',SIZE=>3072,PRI=>'16FBBF8203E2D8B2348D325B0DAD6195F89B74474CFCA36C51949AB49C938D6B741F878D62E2A8F18785F9D1FA9F0BD0EA3A76F29EB682F85F0C139D20C755FDDD80763AC91C0A2EC5A3862ACE4907E5F91CE9B32E92E9178C0684B3226360945BE4A0CD3DE401D43C37356A80641877578A749CE45A91B0B7AEB2DC1036E270102B3753DA828D5079336DCBAAF6570E030324B66CF63CADBE6D7419E434BE5475D83B2E0E55C82B3D41A1CF6C442642116637D396DEC2E48D93627431CB81BC628587E30EDFE516B63385CBBAAD4731B54B993552A3DFC5EE01748FB2B510811FAEA89E0ADA99AE285B363F0DDCEC62C4BD6D96C5BEA9A02B5831E114A1D700D9E337C75D84DD96A85BDFBE99DCD2691310291BB0C0BBC5DF72CC6D6D78724B3F55CBE31ACA06DDF8ED74B054D6CD4B92E8D1F37243B01CC4ED8486718D4D5EB50A32E0BC2773433BA2628BF3517EE8BD83CA1C680DDD1CD00D2CEB3A6E36208034824C393E14B703CC03AF3B05CC4764C023DFC2A021786FC15FE532B2225D',PUB=>'ADAC2FC057FC5B6A53C0544EC085A177C1775CE974F940B3235BE4FF98576DCD925820BB53BDA4170975D77144F3C36E20FB4851A23A8D5A5A0A2C5EB3A74B8298E83B212FDF09CB470E4F59E46D28ACA5068C1708007660512C62A29C746257ADDAA6F19630755DC6C7A431A44774C81FEE6997990778154AED187DF3650E39C0C0E8545ABF348A730DD055446410114C832A39D7EF84DADEF268878CF63EE81123E4AD0381FA4DCA20BC778BB0D9E66DA2597D51DC562B491C8B3071CEEDD9B09BC364085695803325887E1617CC900102953BED86ADF05B690B067CFE7B313DCEC69149A3E56E56240AB24928167743BFBD113E8C434B81B55E41855643148349A0A32DB8EF0B559B6661334D67BFD4F2BA539A74EE0D55EA5807B714BCA884F6D893B2E8B6B52FD055D96BA879F22178B534DC3E70A47EB00FF18A266DD342E0140B8E92C04C15547ECFBD3A74160A14A9AD010AF6A22B31DD04E9FB80E48A5853EEBB64CC3A6B5D8072937F532D19894484EC72E43AECBDB0537B1812CD',SIGSHA1=>'CEyhH4ii4bEPnfn4DimH9NmIJnQH/CktEOtf31/kdaz5PnIZ3BJmrNSl6cQ1BNzA2DVB2bCdp8hJKNujUZyyOvFnjB2obkkvneNU8qUBumxGyAiUOvIvyqOWpLvFBpzw59ozcCeI8ttD9DRQnlEiz8f19DMlLUvIkS6B2QX3R1isUGeLGT/78pI6eps0HLabXvdZorxVmD9miv1sGhi6nuarjErx74952vgP4eb5pzZBiuWo3Uxtj1JxYnmV7HfXpSSKsgIPbjXhwPXCyJccp5glFmOL8KRtK1F1mmm3FrBbZ3nmw2mBeHtdNHy7io3oc7/ESjwG2Mntgck4KnLXzNoRgTChmIEoUEON9QX49VoQAj/cbhBzQ5QO6vL4aEMwqkh5HOuTQ9LeBdHwmfsoEee/PHAXfxRU69FLb3lEQxkU+G9Do1V+pyL8XvKgK8YJTKKyQvxuzt0WUX8uiB61uxKY1g119adniFo/VSvCHg7kS9GFRoOk2flDhZhlWpbd',SIGSHA256=>'PphQHkIPb2AhcBdLd4pHJBn89NR8DWXViKRTncx4PRxr5p3XfN9tZGjuIRBRHoXb3BVJM36r2mbabHkNXIj85jdE5W4mkg8xjQuqp/XocRzzjuwAox3uKJfyKUt5c2S0t3hWCwkA71gl/61PH3b7RITeECA4Op3d6epu6xREPDVvQ5RpnXQRf1qVPXv8sdfQyKJ1U8ZkA6XdmpTNwVSn/qQ8R5R4EIBssi5cS5UDyPdrzVTz6S7KQngkfU9Wlrn+RtfAWheRrszZFSYD9MjiwOwJNuncXc+zYCceGcDC+ADE67NTPFTxSGM0+JM0btXSIb74wCZzXpVLR9HXcmIc4l6T7jgG+5lMEWcHnou87Lq8PLPI6v474YyhRWbm5cOwVKvvlbLsBZUJAAZmumlwD3xS72BEht2JugwzvnBsYxlYMthTlf6H0WGktTgEE/+2AxG64XO3graJIlAuRcZxzv/Jdo1Tc0hTMYr6kwGjiNRwHYwHkbJ+aDVEeqr1HE5z',SIGSHA512=>'NF4+LH+6+/wNOis3mjCklNpQ+j4PK7/rKmEpB2ZcL3qb0gbKAYjCNX7hZoay6SLWlYtBma3H7xf9vKaZsr8zFy2OV81HlQnG4eaz363lEoDfzPgl3of29BiV16lnfOSjr+qh2q9fYq6YvALxsBY0l5tfNkKBERr/rCWDZCg5Dv5fFc9RFFBGwy0dah16pQmJ5cd1EXsE942Kf8btDs2Tnjyy03802fuS6VKX3knS0Nbl0+zvN/UnhQileX8Z6ts3rD30fEz+k/u001Akw0AH7lj6BIjJnS4IUCMoGNTIN0BIorjOfXMFmJy9DaLqFuk8Ju1ZWxN0xtk6gDQrIPgVy91pGFSBVPhxyHMIXY1wDy30HVSzcac1tMZIKeceV1RjF7+iurmFlsJmnCR3qE69QmUFtmSEbGtprRyQxG2UTermqTrZQb2ToVoQYTsFvt/qgqHa1ZkK5U60tEPq+4QHwqlYC/LpVFvEcP4VAEqG8Kla99od4QaYEtg9C7U5ZR6/',ENC=>'OFH7LDDe6C9m6aSZpm2n+WFzeiVT5ahldTopxVITobxH1q5TFEk1uJHV4JKUFEOCHwPeWiCsv5BzvzUVZOS3lp7vp7MgBNUNE4JJ4L1Wb6gL4WajBMwaqUUrz+GEeIjrWJ81ZWxkiseZfc4Z/4duU4R+Aaq3U6rZRGp4GbEp2iCYEdBhOzQhvzNFm62tW9ajFpU0TpZ8XJYqXQgw/26/dkv6W9zS3KvAvVuLP336fnxtKKBqr+HVKU8BSwS+wQJwNchK7jgOp3/kMGZmy6JVAWfv4E+FOdQma9a5ewNgq8GErz8PC8ScA6egWQTn+edFixnTPcWEU0k6UBvZQe8taDd0Kf9ymr56r5hVjsJh/Wa0Gfnp66y3nK2ZhQt+odI8Kzi+JLHePHr6+qRxrgYT6/0740bktgRQhQC9mYC9K/274QAkCj7qWWcGyZodzvBj4vPyg/Ck6ISGjyjnl89lkwS7L4Zi7P9AjFlPsaaXdtdcBXnly3Rhbuvg3B7EHgB5',PRIDER=>'MIIG4wIBAAKCAYEArawvwFf8W2pTwFROwIWhd8F3XOl0+UCzI1vk/5hXbc2SWCC7U72kFwl113FE88NuIPtIUaI6jVpaCixes6dLgpjoOyEv3wnLRw5PWeRtKKylBowXCAB2YFEsYqKcdGJXrdqm8ZYwdV3Gx6QxpEd0yB/uaZeZB3gVSu0YffNlDjnAwOhUWr80inMN0FVEZBARTIMqOdfvhNre8miHjPY+6BEj5K0DgfpNyiC8d4uw2eZtoll9UdxWK0kcizBxzu3ZsJvDZAhWlYAzJYh+FhfMkAEClTvthq3wW2kLBnz+ezE9zsaRSaPlblYkCrJJKBZ3Q7+9ET6MQ0uBtV5BhVZDFINJoKMtuO8LVZtmYTNNZ7/U8rpTmnTuDVXqWAe3FLyohPbYk7LotrUv0FXZa6h58iF4tTTcPnCkfrAP8YombdNC4BQLjpLATBVUfs+9OnQWChSprQEK9qIrMd0E6fuA5IpYU+67ZMw6a12AcpN/Uy0ZiUSE7HLkOuy9sFN7GBLNAgMBAAECggGAFvu/ggPi2LI0jTJbDa1hlfibdEdM/KNsUZSatJyTjWt0H4eNYuKo8YeF+dH6nwvQ6jp28p62gvhfDBOdIMdV/d2AdjrJHAouxaOGKs5JB+X5HOmzLpLpF4wGhLMiY2CUW+SgzT3kAdQ8NzVqgGQYd1eKdJzkWpGwt66y3BA24nAQKzdT2oKNUHkzbcuq9lcOAwMktmz2PK2+bXQZ5DS+VHXYOy4OVcgrPUGhz2xEJkIRZjfTlt7C5I2TYnQxy4G8YoWH4w7f5Ra2M4XLuq1HMbVLmTVSo9/F7gF0j7K1EIEfrqieCtqZrihbNj8N3OxixL1tlsW+qaArWDHhFKHXANnjN8ddhN2WqFvfvpnc0mkTECkbsMC7xd9yzG1teHJLP1XL4xrKBt347XSwVNbNS5Lo0fNyQ7AcxO2EhnGNTV61CjLgvCdzQzuiYovzUX7ovYPKHGgN3RzQDSzrOm42IIA0gkw5PhS3A8wDrzsFzEdkwCPfwqAheG/BX+UysiJdAoHBANmu7jrGdzex3pTBh3e6Nr6slimPmbLuF5n1TgBe/noeOk5z9jcx+kwivOneMiKp8erMMsGj/zloFEodD58umISB9KDWZ3QKVbXWichjI/TG4JrGnLxyIqdxiu8ZXnD81zWmir3rDkrTheQrN4vqaJFwCFfW3oyVMe0wRibgGrlUQdxjBLNQ6KY+ivk+c5vVs/rNjGYURcKUak4FM/4+63FC+/DqpsFLuI+3qHXqmcvG+pEp9oLe5JS+89B1i9/pAwKBwQDMPhSidfET4LX24E+ZHIEY5M+kOtbn5bFyGW3xkMTJfQhoUQzYg43HYFEPs2lYLpLzd2l7dLoZmKl5n28pODxqI2R51cSyqd3qjJHnuS9u19ogKPeaFH04KfQmL8nIF27LGzJUCLKsHDs4txR49fB8G7e2DrtWOcUgPAEMZWWdplZ/hG3AXKGkKNr9izYJZ3H07t6yCWxaQhUDdN0STWCQhStBfh30/9ceAD1eyFTMdnjzTbZGZa8NIIqDFBSbg+8CgcB+PdPM5EJJW28BCAc/KRAMnlxrd+sj+K5ZTAjTcEPWoGciDmAw/FvzAYZbfs/GiJZSm9+nqysdqL1zic0AfO5YkmFDUXQnuMKiNOws+Unl79xcBmjpZKuyPcfcB/NcRVWtuIrnv0THokoY2/NXwjaoebds8aCZGQEeVAurCfaVmkajwAz+zSJPHyBLkatMKbA5+DC/FmyqfpXz71KK1QSH59fijMLugLJlLpaU49wTcK7pttNObGNV3DPbpf/bd+8CgcEAplcdOR8zQ4wsxq7zRPDZF2wqzEd7hYwlk5awWyAblTn2ofb4rlGeI7YG7vGgp0fvOMiVKQ3tDzGtPTejMf/x/ENs7mkydIwyB3eK0R2aSv0TUkPrPBrZzOcmR/99qC+ldVdmCti2o8OuW8eHregnfvyYB3dCDbypFlKoS+887kNtiRdSx2rp3qfDiuFZFhmgzunIh1lzXKMbOCByeBh6v9klXIaZYVMIYQ+y68HehlMquIUfIYBpLBjHlm/BRNMTAoHAbYrQCsryLGBu8QBt2MoPTwrl7Q39+0nbkQVco9aZ/A6X9+d6lylZdBJ227GSROPjxU4q8oBXKSq/p0HVG8QkBf9mKJdgQ86NZ54gzIXFAWs93sREFfAqKSBKwUfvA8q44Ui9Pn5SDsgRKG33TaaFE1Z5GJFhwiKdPPDW0CIWKiRx+92LEc65UPCLyCwOb3I1n65QxOlIKGW+tR3An/z5JSrmrJU6CD1R6m3PJ28uZ5JMQHBUKJFl/p9sOrOV/aXv',PUBDER=>'MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEArawvwFf8W2pTwFROwIWhd8F3XOl0+UCzI1vk/5hXbc2SWCC7U72kFwl113FE88NuIPtIUaI6jVpaCixes6dLgpjoOyEv3wnLRw5PWeRtKKylBowXCAB2YFEsYqKcdGJXrdqm8ZYwdV3Gx6QxpEd0yB/uaZeZB3gVSu0YffNlDjnAwOhUWr80inMN0FVEZBARTIMqOdfvhNre8miHjPY+6BEj5K0DgfpNyiC8d4uw2eZtoll9UdxWK0kcizBxzu3ZsJvDZAhWlYAzJYh+FhfMkAEClTvthq3wW2kLBnz+ezE9zsaRSaPlblYkCrJJKBZ3Q7+9ET6MQ0uBtV5BhVZDFINJoKMtuO8LVZtmYTNNZ7/U8rpTmnTuDVXqWAe3FLyohPbYk7LotrUv0FXZa6h58iF4tTTcPnCkfrAP8YombdNC4BQLjpLATBVUfs+9OnQWChSprQEK9qIrMd0E6fuA5IpYU+67ZMw6a12AcpN/Uy0ZiUSE7HLkOuy9sFN7GBLNAgMBAAE='}, + {ID=>'key-4096-6',SIZE=>4096,PRI=>'9B4353CAEBE8457014F496E6865D04E3DFD95F1D54965675A0B257C297C519AD1359390ACD4797F29AB4B2F21552F23309A8223A2F61AD44A15B77DC3F6F5DE2F4E4767D42E681510303182A9849C10396C105BA681626DEB97F668ED5653AAA4A2E1137FA1FED9641AC4D45B54F6FEF2439E173C86AEF262226C006AC68DA79F330DC37DD5772782172E14DF778DD9F09E7B4517671A868A99E1F025BB62B151EAD2710F976266CC4B291712BEB9E8CD815A27F8E1ACC131C32958F55B454CFA6B3B0A096AA66D17E1B09E5497F1AF68C61438CF962FFEAC0B3739BC3C8250148F5A33C67753E7BD2B2489F8F551E98F1F8202639773E1450A0C0380B2F48F6F61097E1586E5F125F7ECDED98A6C242FA5118B53B6D9150E04753FB8ED333C32C91B9F687730BCA3059620A4B8BE8931D67AB7B9D48491ED8BF3C0CD87071DDEC12DBDF1772109253FC4DB3FA800BF8B52790E5A4D4E01786D2BBC1702690D50A5CB3E2714590C3BA595B48BC6EA70962DA2D63106E1B2CB7A9CC626250E3079E08074CCEF32595CD21813B59302A1AA70DD371B5B1DECC9CFD27E05FF90295856A46D347B9B54261AAF854273AD2593BD8F6A01D4BC1216F4523403486CCAC37DA149813D844C5332735407885B39C20ACF99F2B087D2B92AB5CADA2914D274B5A6D47775E495B2797C9542072DAA97BBD1D30BDFEF2A75DB127AF1C4B4D01',PUB=>'B91601C0831133E391BCC4D5CB769C824602F2883376466F17366505B6199BAE6C4AF3E5DC2597C9E2A206941FD1654623DC465C7059E91C304C2F968956389B17C0045449FB346F3C5F364EA678A31D273977D04524677D6F041A45E4CC0C3C2A734396D5AF9E479AA63DBEC185156D5E2785D70A776B1BE4CF690B0AE60DB19ED03EB2C9E49C10A6B769D763C28A154BED75798AEC201A755421BBDE9B2874FAB290E45B5B372B7478425CF59188142F2764592A53129A2D8077835EC5A47FF54978BFB1F89A63E2D58E5AEB7B0CCA2E8E036DA4386C9435B0B851A7465709586D2AF00E03B00B2E5B1B13A7A43D23DA5CA568D9344B81F3B89C5016C1FFE09F4E2F6EF2EC5F86F86BFEC1BBF9BF58432A7AC36D0AA8F43756ABE217581E5AEEA5BA0913DC60908F6268BDE41680728A5722A730C17EF86EBADC126B8E6883212E1F5FFD277F5F2FEEFDC5FB124CEEE80E6005C440882475216BCC9C75CF06CAF649D502A04544E8D04E351E1838C6540ECC06226FE162AE908A34DCD13BD15C02A8ECC5C176C86812222A01AE206D01C993A4D80BF6AEB6C934790C35991AC52B9551C203F0BF352A58A5E614A1D85E870ED69AECF584DF0FEB26FD9AB2D785A65BDFE4AC53878F5AB5D8C56FC91F83F7816F35D23168E91CAF91DAA00F2786AF54C06EC9526565319A2CC2B3F3BC76F1610D6EB891FAF9285272AE1FB0AB',SIGSHA1=>'oG7/hP8GnOzxxPjk4tMUoiuE2winrQvLCZjmoRn4BzYfwXYuUOwi+IIgOp9kX3UYLjIN93ATvt74eE+Pd66TSvcoosejr08Am57JReN5dZQqy/dXA9TB23CTlJah61W5Cv7iKmImjefMfFuIB0nNEKTwsgSdeZmdsP+Ehuvcpqayte8IEknVGpS7pHKIEqqYr9BeqG43Xj3uJIySRYZOIDP951pvUluHOBTLz7n3bbCatTYE+OxGtlS5Yx7Tl/iMaixii13L0BIFpxJN1m74S0ZhwQWsLALJeNl/WFQWYe42OHbuKY5EHakUVxmAeWM5lEq5uUVGSgTmdc1BkK2ZZI0piVRMyu4Bs0jj9PTsZ03cJ2SA39fyKZQAxGf8Ivs2vgnsPFxj9R5WQC0heEkcFSjlRbWGFaC+IwktfySUdVYymd9aSxar3ZvwsfM3K9z+hOLFQ40OXlvACHgsX9RfDQPZnA6eFEm148P4Mtk69uJxZbfArqlAQJlwc5eJCKsLnnDyCPF0iltuvMChxKz8KUWuxA2jTLCF7hq0/E4MNmyq/FEdPQ/RNAqO5PMIkh+gX9i5cv74usfZTDupfnsJ0PpXxwEcTkIfLfwlRbSmQI3H/4dFNk7CwxV6Ac0HuAGOJMSmmDBHa2O4L8Dn2/PsJep2bi+jq8z9PCT6FB/c6HI=',SIGSHA256=>'AvNlYUj7fO58cfoK9UARP4ZGV0HH+/u6EjD6pQOkO5FGVXSQHOT4Fpz1tAsqSJeTdYRB7n5mVdErpav9/WRupQGnP8oeNRwPR3lVmsQmahbKo+qj5+gFQqNwl4ILi9pQ18BhJ0E5/MvZWye39iKfjtWvB/VdcbD2pEcoKbyTy5sWOQT3bFPt5hUQ5JGJrGgVwj1ZA3afPmbCJk1AzkWFVc9bn8q/wOvz77m7uPRX7s5WSmZQt1V853puJeoW+OLURLFUvmb0XBFcd654ub7KQI1XTdpM89BZjTq/uG1aodElpOodcf5tDQ6mVy5G9i1Z1EMQGPwFXhz9BI1KnoW77uGo2VgDnFJ0Kn7Ns7ijlI5xzJwXQOfyo+Mus8zalyUkcUp+f0KXgpkg1jbEkPA3SldcLkVoa2k/WZOesDGNu2hF4rbp5KtfPpyD15AHmN/ae3CKkvguvlEyeCda7wwGdYJ0sAanuxeFW2tHrxzdOrAPrcyYLz5idWqGenPXSJl3XY+A/LcaUgKFFnWw8AfPYEjThN3fJP2WNRBe7tUgP6xfk33DJUF6ArPUbs3oewZjU/ilSAbRN8ozc7fgBSk7dijwUh1J8FYTigdKlkp505bPFj/QcvAymVISlJQFCPU9IjVlrY+NaA0BcN1/7yFZqIBeOWi6mjTLsw7XWPHixiM=',SIGSHA512=>'TKMhcP73ggPod4FRlNHue5EiPGj9fSt5Wk3M4h14/eHHmR4HV6f58d2TRtZiCBPZK4hJResiLF3x7ycJOBG5YUhcEltVtiwKqLJU+g56c3BDocuQkhiLKS98TcLhpSHWyAk8YLAENFw7cwVsXzh/IsKTsQordTe3nBu2OqnqQV4gSmFqptLB56z2wA+B4lqSPeQMf/9s7WluldE28uZb3hOiyfiTtH0n7+l2mL/6wyCGhAtdXUmLIi2C8AN+nqTYU2hQ3HuFXiNl3TVuTkV2izEy3PtSUvu27vOETOtw2SLHiyDNVpFEhbfgJ3eRSo/dSKNhrHERJzdq5aQKljC3dPbsp7eKDrk95Vv5hfUXy7RwgvS8F3yNgfBN80AlBOChKOlO8str/eEKiQLvBArrvcqbsB5QJY6GGxgeRtxBV3p48SsRfK4TlBtifnS55Mvj+BgdyqKeKymj83R380aC8DIlv2ooaCFGduAvgoy9lmIXXdQxiPBmS79DfMr1Kir2+UMJqinKguCU9YCITxMjDw2meZ71nQfEJ2Oam1rpscGTSPuwAPkQIY2m4oXwtUI7ECYn3ZZuqXdT8Y6gllgAGky5gROiHVYRZMFTSmpJDh+mkezlPSEvg9NV//6hNCUaGZWfsvHjbjYf2MYlRKm+sJhC8ZVUpDYXKDdcSxDCPfc=',ENC=>'kawY94mUiF6MpZNZzWoBssLR3cT2skUZnm3eYX4z25piUigiEpolH9Dw0nilU+D5xm5jGFFCXtXH9IpNLD2Din0wu0pQ6vOVnMl0tCWabO/gmkSZ2uKJlzLhTR3T+jd8BKKDl+52hELsYbot8J7fZPmkfaYvEYmh9Na6+o1BbogcT5E52Qnrr/+ivIoljLl8TPnP5mUrmW0HGxDVB/KYv/icGTZrTGx8J/ABkjCG5KcP/EK8Mj7YghCXjcv04nNAH9SuWGzVG1tRICiaUHYWQab5dxENwkQz0E3l2+oC4PUyu342e1Ab7hRX/U/TZz0/cEoj/LewGSgMMIEhsTdMJPvxRQvgLYqMuoMy/tGby2eKyYjrCubrJCJaTOkYGqoNGtivkdcSxS0vHgh5P8nD+jsntzbDwmrsE2392xFiUKxURuLNspk9AyZjRXo0Sm3yiY3FJqyIEV12bnp+aslabW3NtNy4ZLkygdVYFw63NvJxcaB/88ImLSuGDWHDIjC8gxfRWaS66s3a8RyQv/NgfBzoeYFx5iShUr6O5Sm8OnQr+14cfcEHNVz6X++fQL7oUjSKRQa5Y2mS65IIfq3IodGfEd9EP8YofS75t5dh+bZsaupCDBiba/PN/f2243SZ87BYsW+vEUBg4SSfPBrJiovpmByNbXJZ6xZVRndsHbc=',PRIDER=>'MIIJKQIBAAKCAgEAuRYBwIMRM+ORvMTVy3acgkYC8ogzdkZvFzZlBbYZm65sSvPl3CWXyeKiBpQf0WVGI9xGXHBZ6RwwTC+WiVY4mxfABFRJ+zRvPF82TqZ4ox0nOXfQRSRnfW8EGkXkzAw8KnNDltWvnkeapj2+wYUVbV4nhdcKd2sb5M9pCwrmDbGe0D6yyeScEKa3addjwooVS+11eYrsIBp1VCG73psodPqykORbWzcrdHhCXPWRiBQvJ2RZKlMSmi2Ad4NexaR/9Ul4v7H4mmPi1Y5a63sMyi6OA22kOGyUNbC4UadGVwlYbSrwDgOwCy5bGxOnpD0j2lylaNk0S4HzuJxQFsH/4J9OL27y7F+G+Gv+wbv5v1hDKnrDbQqo9DdWq+IXWB5a7qW6CRPcYJCPYmi95BaAcopXIqcwwX74brrcEmuOaIMhLh9f/Sd/Xy/u/cX7Ekzu6A5gBcRAiCR1IWvMnHXPBsr2SdUCoEVE6NBONR4YOMZUDswGIm/hYq6QijTc0TvRXAKo7MXBdshoEiIqAa4gbQHJk6TYC/autsk0eQw1mRrFK5VRwgPwvzUqWKXmFKHYXocO1prs9YTfD+sm/Zqy14WmW9/krFOHj1q12MVvyR+D94FvNdIxaOkcr5HaoA8nhq9UwG7JUmVlMZoswrPzvHbxYQ1uuJH6+ShScq4fsKsCAwEAAQKCAgEAm0NTyuvoRXAU9Jbmhl0E49/ZXx1UllZ1oLJXwpfFGa0TWTkKzUeX8pq0svIVUvIzCagiOi9hrUShW3fcP29d4vTkdn1C5oFRAwMYKphJwQOWwQW6aBYm3rl/Zo7VZTqqSi4RN/of7ZZBrE1FtU9v7yQ54XPIau8mIibABqxo2nnzMNw33VdyeCFy4U33eN2fCee0UXZxqGipnh8CW7YrFR6tJxD5diZsxLKRcSvrnozYFaJ/jhrMExwylY9VtFTPprOwoJaqZtF+GwnlSX8a9oxhQ4z5Yv/qwLNzm8PIJQFI9aM8Z3U+e9KySJ+PVR6Y8fggJjl3PhRQoMA4Cy9I9vYQl+FYbl8SX37N7ZimwkL6URi1O22RUOBHU/uO0zPDLJG59odzC8owWWIKS4vokx1nq3udSEke2L88DNhwcd3sEtvfF3IQklP8TbP6gAv4tSeQ5aTU4BeG0rvBcCaQ1Qpcs+JxRZDDullbSLxupwli2i1jEG4bLLepzGJiUOMHnggHTM7zJZXNIYE7WTAqGqcN03G1sd7MnP0n4F/5ApWFakbTR7m1QmGq+FQnOtJZO9j2oB1LwSFvRSNANIbMrDfaFJgT2ETFMyc1QHiFs5wgrPmfKwh9K5KrXK2ikU0nS1ptR3deSVsnl8lUIHLaqXu9HTC9/vKnXbEnrxxLTQECggEBAOypoHOiXVG6ZpGkbgrGsi0qEykB/ER3q3FD/586Usz+wYlQdHP2ugTfiKuYd6OOfCzgCLmY7zl19sU9H2Lw6oqISmQUpPzNkuARwBL0F8CgCZm/8G2W/dBv6L4T/RKIeRGpR4ZmyUcG+i1h0DP1K1BIK6VAE53N4d0qq0uWCMHIz5pxVo2XnPJBPrP9r2djl0ggJo9hJfwe3inRA1NN9ndpfbSZbEflhvYkHVg8noUl3g5MRxiBsEW6F6JPRV3XfWF/w/qYKpHJ3C6PKTPDMdCzFYEBvLGKBvAwiVfrQxwGD5xwX8TOTUiQ9zV1KQznhUyXuOJFW0haTYqARGYvlysCggEBAMg1h4SDGznYlxTTvQrqFtm1iiJm+AlzvCnbIQhXacPS/8HYh5WhqPYWTgAW5IQGTUPAynHyFVK5YhstLBePql+qEFFazD47q5yKLN/FQvHtiKFm5C5ixqa0xRxu4zIUcAdJ+MncWJ7TCYXKGUQ7zLZgW63TJezirRCQxVKtd4ILfIaD8KgYsaRVSqdMtvOzom23g6uE71rJO9lQ35HZWet7h9Lm0qBbPIkAGo299GhPJAQhm8n7CagZkqBQMroLtH5Mj3BTYgUatFIas5WAQrgEzV884S2w6gy+1dryMcyfl9tXg7g+mdbEhaNXv1GpPXuANCS4hTkrjHUcua/rjIECggEBAMaZAgCHe/Adj/0gEwgP/W1RJYsAE4YRNllySoyAEQPdtONaFJ9LqIZ2XuZAqAUkiKfPyQKWiAmcKF0UEcahjPB7tpGNkXZjvKEzxA8jrtsCcYwIOeZ9Erlbb+AyPejThWWAvHjYwIdOH5r9vg4b6yEPrzCZONzv7F4AdIaVfPvBXBWqjot7c0UH42p/tDX6qPTppfIkABA2hxBoSXYasn06lTZ8mRUsU7kyTT3CgPQS9ujgsbiq/BVHOJYIF5nMP3cWFIuyLebxkkev809wudj8r0r2/jWuMmxVDqwszMAzhd4tnvA0fz4qCIlfq/ccQgwoNgoLUbLBtNhJExz9SskCggEAD/1Gb2zRFdOYbU9jv6VmYci/2XODx614j5cykin5BmyphF+4pFie19h8LkGlym1+ajTRdjwxO8QWc7kt1kvg/XblirnHqgi18fCPGOf2KsAfs1Q2UQYOe23geB7bAjrjn5FmzyhL45NTJV44mlx0QvR7HezJEJwh2jrVp363Fqm4Lj4HUEV4mnk9VxMnYVstU7neSCp7uzJrFzYARPOo3Mem108b7zaaJQ7fEAblqBb592J/wKfN46D3Ntpw0q7woU2X/w6Ju4KgeBYt1XjC21N2225PRYjliFMNXUkOdRsh06Cvol1Nh/t1+M+fNfRgNqbMg0pBSYmS1B+RLN2RAQKCAQAuUdM+3CIQlReGY4gplnQdJvMeAl9BVD+zmjcU6368ZSXYw0IIQpL1OSayFo0gri8dqdc7gvFkYjv0GpawD0mi3bHZwyMuqWsX7+MbGkgkzSlYj8JNhq/Flx3UMoN/cd1X4alixYNwuhU5WYv/7ufYv4MD2DXBEcnm7Nhj+GwSdPoscjmLXe1g66LzOlcFimWUYU2+37Lx+CuoyLU10r2EICPt9tLvcOReLrqREph9xcuw0YCRcfohonb3Nyu/nd8zZvhqMek599XA/sIBA296PYoH/3YOGhkfSMELltZfZb5OrZSd3jYI/fOewfZoshKtsUHFj15aOEqWkYlvb3W8',PUBDER=>'MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuRYBwIMRM+ORvMTVy3acgkYC8ogzdkZvFzZlBbYZm65sSvPl3CWXyeKiBpQf0WVGI9xGXHBZ6RwwTC+WiVY4mxfABFRJ+zRvPF82TqZ4ox0nOXfQRSRnfW8EGkXkzAw8KnNDltWvnkeapj2+wYUVbV4nhdcKd2sb5M9pCwrmDbGe0D6yyeScEKa3addjwooVS+11eYrsIBp1VCG73psodPqykORbWzcrdHhCXPWRiBQvJ2RZKlMSmi2Ad4NexaR/9Ul4v7H4mmPi1Y5a63sMyi6OA22kOGyUNbC4UadGVwlYbSrwDgOwCy5bGxOnpD0j2lylaNk0S4HzuJxQFsH/4J9OL27y7F+G+Gv+wbv5v1hDKnrDbQqo9DdWq+IXWB5a7qW6CRPcYJCPYmi95BaAcopXIqcwwX74brrcEmuOaIMhLh9f/Sd/Xy/u/cX7Ekzu6A5gBcRAiCR1IWvMnHXPBsr2SdUCoEVE6NBONR4YOMZUDswGIm/hYq6QijTc0TvRXAKo7MXBdshoEiIqAa4gbQHJk6TYC/autsk0eQw1mRrFK5VRwgPwvzUqWKXmFKHYXocO1prs9YTfD+sm/Zqy14WmW9/krFOHj1q12MVvyR+D94FvNdIxaOkcr5HaoA8nhq9UwG7JUmVlMZoswrPzvHbxYQ1uuJH6+ShScq4fsKsCAwEAAQ=='}, +]; + +sub test_rsa { + my $h = shift; + my $rsa_pri = Crypt::PK::RSA->new->import_key(\decode_b64($h->{PRIDER})); + my $rsa_pub = Crypt::PK::RSA->new->import_key(\decode_b64($h->{PUBDER})); + my $rsa_pri_h = $rsa_pri->key2hash; + my $rsa_pub_h = $rsa_pub->key2hash; + is($rsa_pri_h->{d}, $h->{PRI}, "$h->{ID}/PRI"); + is($rsa_pri_h->{N}, $h->{PUB}, "$h->{ID}/PUB"); + is($rsa_pub_h->{N}, $h->{PUB}, "$h->{ID}/PUB"); + is( $rsa_pri->decrypt(decode_b64($h->{ENC}), 'v1.5'), 'test-data', "$h->{ID}/ENC") || return 0; + ok( $rsa_pub->verify_message(decode_b64($h->{SIGSHA1}), 'test-data', 'SHA1', 'v1.5'), "$h->{ID}/SIGSHA1") || return 0; + ok( $rsa_pub->verify_message(decode_b64($h->{SIGSHA256}), 'test-data', 'SHA256', 'v1.5'), "$h->{ID}/SIGSHA256") || return 0; + return 1 if !$h->{SIGSHA512}; #SHA512 might be too big for short RSA keys + ok( $rsa_pub->verify_message(decode_b64($h->{SIGSHA512}), 'test-data', 'SHA512', 'v1.5'), "$h->{ID}/SIGSHA512") || return 0; + return 1; +} + +#diag("samples_count=". @$data); +test_rsa($_) for @$data; diff --git a/t/pkcs8.t b/t/pkcs8.t new file mode 100644 index 0000000..96eaef3 --- /dev/null +++ b/t/pkcs8.t @@ -0,0 +1,54 @@ +use strict; +use warnings; +use Test::More tests => 8; + +use Crypt::PK::RSA; +use Crypt::PK::ECC; + +### generating test keys: +# +# openssl genrsa -out rsakey.priv.pem 1024 +# openssl.exe pkcs8 -topk8 -v1 PBE-SHA1-3DES -passout pass:secret -in rsakey.priv.pem -out pkcs8.rsa-priv-pass.pem +# openssl.exe pkcs8 -topk8 -v1 PBE-SHA1-3DES -passout pass:secret -in rsakey.priv.pem -out pkcs8.rsa-priv-pass.der -outform DER +# openssl.exe pkcs8 -topk8 -nocrypt -in rsakey.priv.pem -out pkcs8.rsa-priv-nopass.pem +# openssl.exe pkcs8 -topk8 -nocrypt -in rsakey.priv.pem -out pkcs8.rsa-priv-nopass.der -outform DER +# +# openssl ecparam -param_enc explicit -name prime192v3 -genkey -out eckey.priv.pem +# openssl.exe pkcs8 -topk8 -v1 PBE-SHA1-3DES -passout pass:secret -in eckey.priv.pem -out pkcs8.ec-priv-pass.pem +# openssl.exe pkcs8 -topk8 -v1 PBE-SHA1-3DES -passout pass:secret -in eckey.priv.pem -out pkcs8.ec-priv-pass.der -outform DER +# openssl.exe pkcs8 -topk8 -nocrypt -in eckey.priv.pem -out pkcs8.ec-priv-nopass.pem +# openssl.exe pkcs8 -topk8 -nocrypt -in eckey.priv.pem -out pkcs8.ec-priv-nopass.der -outform DER +# +# openssl ecparam -name prime192v3 -genkey -out eckey.priv.pem +# openssl.exe pkcs8 -topk8 -v1 PBE-SHA1-3DES -passout pass:secret -in eckey.priv.pem -out pkcs8.ec-short-priv-pass.pem +# openssl.exe pkcs8 -topk8 -v1 PBE-SHA1-3DES -passout pass:secret -in eckey.priv.pem -out pkcs8.ec-short-priv-pass.der -outform DER +# openssl.exe pkcs8 -topk8 -nocrypt -in eckey.priv.pem -out pkcs8.ec-short-priv-nopass.pem +# openssl.exe pkcs8 -topk8 -nocrypt -in eckey.priv.pem -out pkcs8.ec-short-priv-nopass.der -outform DER +# + +my $rsa = Crypt::PK::RSA->new; +my $ec = Crypt::PK::ECC->new; +ok($rsa, "RSA new"); +ok($ec, "ECC new"); + +for my $f (qw/pkcs8.rsa-priv-nopass.pem pkcs8.rsa-priv-nopass.der/) { + $rsa->import_key("t/data/$f"); + ok($rsa->is_private, "RSA is_private $f"); +} + +### XXX-FIXME password protected pkcs8 private keys are not supported +### for my $f (qw/pkcs8.rsa-priv-pass.der pkcs8.rsa-priv-pass.pem/) { +### $rsa->import_key("t/data/$f"); +### ok($rsa->is_private, "RSA is_private $f"); +### } + +for my $f (qw/pkcs8.ec-short-priv-nopass.der pkcs8.ec-short-priv-nopass.pem pkcs8.ec-priv-nopass.der pkcs8.ec-priv-nopass.pem/) { + $ec->import_key("t/data/$f"); + ok($ec->is_private, "ECC is_private $f"); +} + +### XXX-FIXME password protected pkcs8 private keys are not supported +### for my $f (qw/pkcs8.ec-priv-pass.der pkcs8.ec-priv-pass.pem pkcs8.ec-short-priv-pass.der pkcs8.ec-short-priv-pass.pem/) { +### $ec->import_key("t/data/$f"); +### ok($ec->is_private, "ECC is_private $f"); +### } diff --git a/t/prng.t b/t/prng.t new file mode 100644 index 0000000..210d28e --- /dev/null +++ b/t/prng.t @@ -0,0 +1,66 @@ +use strict; +use warnings; +use Test::More tests => 19; + +use Crypt::PRNG qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand); + +my $r = Crypt::PRNG->new(); +ok($r, 'new'); + +{ + my $sum = 0; + $sum += $r->double for (1..1000); + my $avg = $sum/1000; + ok($avg>0.4 && $avg<0.6, "rand $avg"); +} + +{ + my $sum = 0; + $sum += $r->double(-180) for (1..1000); + my $avg = $sum/1000; + ok($avg>-100 && $avg<-80, "rand $avg"); +} + +{ + my $sum = 0; + $sum += $r->int32 for (1..1000); + my $avg = $sum/1000; + ok($avg>2**30 && $avg<2**32, "rand $avg"); +} + +{ + my $sum = 0; + $sum += rand(80) for (1..1000); + my $avg = $sum/1000; + ok($avg>30 && $avg<50, "rand $avg"); +} + +{ + my $sum = 0; + $sum += rand(-180) for (1..1000); + my $avg = $sum/1000; + ok($avg>-100 && $avg<-80, "rand $avg"); +} + +{ + my $sum = 0; + $sum += irand for (1..1000); + my $avg = $sum/1000; + ok($avg>2**30 && $avg<2**32, "rand $avg"); +} + +{ + like($r->string(45), qr/^[A-Z-a-z0-9]+$/, 'string'); + like($r->string_from("ABC,.-", 45), qr/^[ABC,\,\.\-]+$/, 'string'); + is(length $r->bytes(55), 55, "bytes"); + like($r->bytes_hex(55), qr/^[0-9A-Fa-f]{110}$/, "bytes_hex"); + like($r->bytes_b64(60), qr/^[A-Za-z0-9+\/=]{80}$/, "bytes_b64"); + like($r->bytes_b64u(60), qr/^[A-Za-z0-9_-]{80}$/, "bytes_b64u"); + + like(random_string(45), qr/^[A-Z-a-z0-9]+$/, 'string'); + like(random_string_from("ABC,.-", 45), qr/^[ABC,\,\.\-]+$/, 'string'); + is(length random_bytes(55), 55, "bytes"); + like(random_bytes_hex(55), qr/^[0-9A-Fa-f]{110}$/, "bytes_hex"); + like(random_bytes_b64(60), qr/^[A-Za-z0-9+\/=]{80}$/, "bytes_b64"); + like(random_bytes_b64u(60), qr/^[A-Za-z0-9_-]{80}$/, "bytes_b64u"); +} diff --git a/t/prng_chacha20.t b/t/prng_chacha20.t new file mode 100644 index 0000000..f2b8182 --- /dev/null +++ b/t/prng_chacha20.t @@ -0,0 +1,66 @@ +use strict; +use warnings; +use Test::More tests => 19; + +use Crypt::PRNG::ChaCha20 qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand); + +my $r = Crypt::PRNG::ChaCha20->new(); +ok($r, 'new'); + +{ + my $sum = 0; + $sum += $r->double for (1..1000); + my $avg = $sum/1000; + ok($avg>0.4 && $avg<0.6, "rand $avg"); +} + +{ + my $sum = 0; + $sum += $r->double(-180) for (1..1000); + my $avg = $sum/1000; + ok($avg>-100 && $avg<-80, "rand $avg"); +} + +{ + my $sum = 0; + $sum += $r->int32 for (1..1000); + my $avg = $sum/1000; + ok($avg>2**30 && $avg<2**32, "rand $avg"); +} + +{ + my $sum = 0; + $sum += rand(80) for (1..1000); + my $avg = $sum/1000; + ok($avg>30 && $avg<50, "rand $avg"); +} + +{ + my $sum = 0; + $sum += rand(-180) for (1..1000); + my $avg = $sum/1000; + ok($avg>-100 && $avg<-80, "rand $avg"); +} + +{ + my $sum = 0; + $sum += irand for (1..1000); + my $avg = $sum/1000; + ok($avg>2**30 && $avg<2**32, "rand $avg"); +} + +{ + like($r->string(45), qr/^[A-Z-a-z0-9]+$/, 'string'); + like($r->string_from("ABC,.-", 45), qr/^[ABC,\,\.\-]+$/, 'string'); + is(length $r->bytes(55), 55, "bytes"); + like($r->bytes_hex(55), qr/^[0-9A-Fa-f]{110}$/, "bytes_hex"); + like($r->bytes_b64(60), qr/^[A-Za-z0-9+\/=]{80}$/, "bytes_b64"); + like($r->bytes_b64u(60), qr/^[A-Za-z0-9_-]{80}$/, "bytes_b64u"); + + like(random_string(45), qr/^[A-Z-a-z0-9]+$/, 'string'); + like(random_string_from("ABC,.-", 45), qr/^[ABC,\,\.\-]+$/, 'string'); + is(length random_bytes(55), 55, "bytes"); + like(random_bytes_hex(55), qr/^[0-9A-Fa-f]{110}$/, "bytes_hex"); + like(random_bytes_b64(60), qr/^[A-Za-z0-9+\/=]{80}$/, "bytes_b64"); + like(random_bytes_b64u(60), qr/^[A-Za-z0-9_-]{80}$/, "bytes_b64u"); +} diff --git a/t/prng_fortuna.t b/t/prng_fortuna.t new file mode 100644 index 0000000..c14a5f9 --- /dev/null +++ b/t/prng_fortuna.t @@ -0,0 +1,66 @@ +use strict; +use warnings; +use Test::More tests => 19; + +use Crypt::PRNG::Fortuna qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand); + +my $r = Crypt::PRNG::Fortuna->new(); +ok($r, 'new'); + +{ + my $sum = 0; + $sum += $r->double for (1..1000); + my $avg = $sum/1000; + ok($avg>0.4 && $avg<0.6, "rand $avg"); +} + +{ + my $sum = 0; + $sum += $r->double(-180) for (1..1000); + my $avg = $sum/1000; + ok($avg>-100 && $avg<-80, "rand $avg"); +} + +{ + my $sum = 0; + $sum += $r->int32 for (1..1000); + my $avg = $sum/1000; + ok($avg>2**30 && $avg<2**32, "rand $avg"); +} + +{ + my $sum = 0; + $sum += rand(80) for (1..1000); + my $avg = $sum/1000; + ok($avg>30 && $avg<50, "rand $avg"); +} + +{ + my $sum = 0; + $sum += rand(-180) for (1..1000); + my $avg = $sum/1000; + ok($avg>-100 && $avg<-80, "rand $avg"); +} + +{ + my $sum = 0; + $sum += irand for (1..1000); + my $avg = $sum/1000; + ok($avg>2**30 && $avg<2**32, "rand $avg"); +} + +{ + like($r->string(45), qr/^[A-Z-a-z0-9]+$/, 'string'); + like($r->string_from("ABC,.-", 45), qr/^[ABC,\,\.\-]+$/, 'string'); + is(length $r->bytes(55), 55, "bytes"); + like($r->bytes_hex(55), qr/^[0-9A-Fa-f]{110}$/, "bytes_hex"); + like($r->bytes_b64(60), qr/^[A-Za-z0-9+\/=]{80}$/, "bytes_b64"); + like($r->bytes_b64u(60), qr/^[A-Za-z0-9_-]{80}$/, "bytes_b64u"); + + like(random_string(45), qr/^[A-Z-a-z0-9]+$/, 'string'); + like(random_string_from("ABC,.-", 45), qr/^[ABC,\,\.\-]+$/, 'string'); + is(length random_bytes(55), 55, "bytes"); + like(random_bytes_hex(55), qr/^[0-9A-Fa-f]{110}$/, "bytes_hex"); + like(random_bytes_b64(60), qr/^[A-Za-z0-9+\/=]{80}$/, "bytes_b64"); + like(random_bytes_b64u(60), qr/^[A-Za-z0-9_-]{80}$/, "bytes_b64u"); +} diff --git a/t/prng_rc4.t b/t/prng_rc4.t new file mode 100644 index 0000000..a88ecf4 --- /dev/null +++ b/t/prng_rc4.t @@ -0,0 +1,66 @@ +use strict; +use warnings; +use Test::More tests => 19; + +use Crypt::PRNG::RC4 qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand); + +my $r = Crypt::PRNG::RC4->new(); +ok($r, 'new'); + +{ + my $sum = 0; + $sum += $r->double for (1..1000); + my $avg = $sum/1000; + ok($avg>0.4 && $avg<0.6, "rand $avg"); +} + +{ + my $sum = 0; + $sum += $r->double(-180) for (1..1000); + my $avg = $sum/1000; + ok($avg>-100 && $avg<-80, "rand $avg"); +} + +{ + my $sum = 0; + $sum += $r->int32 for (1..1000); + my $avg = $sum/1000; + ok($avg>2**30 && $avg<2**32, "rand $avg"); +} + +{ + my $sum = 0; + $sum += rand(80) for (1..1000); + my $avg = $sum/1000; + ok($avg>30 && $avg<50, "rand $avg"); +} + +{ + my $sum = 0; + $sum += rand(-180) for (1..1000); + my $avg = $sum/1000; + ok($avg>-100 && $avg<-80, "rand $avg"); +} + +{ + my $sum = 0; + $sum += irand for (1..1000); + my $avg = $sum/1000; + ok($avg>2**30 && $avg<2**32, "rand $avg"); +} + +{ + like($r->string(45), qr/^[A-Z-a-z0-9]+$/, 'string'); + like($r->string_from("ABC,.-", 45), qr/^[ABC,\,\.\-]+$/, 'string'); + is(length $r->bytes(55), 55, "bytes"); + like($r->bytes_hex(55), qr/^[0-9A-Fa-f]{110}$/, "bytes_hex"); + like($r->bytes_b64(60), qr/^[A-Za-z0-9+\/=]{80}$/, "bytes_b64"); + like($r->bytes_b64u(60), qr/^[A-Za-z0-9_-]{80}$/, "bytes_b64u"); + + like(random_string(45), qr/^[A-Z-a-z0-9]+$/, 'string'); + like(random_string_from("ABC,.-", 45), qr/^[ABC,\,\.\-]+$/, 'string'); + is(length random_bytes(55), 55, "bytes"); + like(random_bytes_hex(55), qr/^[0-9A-Fa-f]{110}$/, "bytes_hex"); + like(random_bytes_b64(60), qr/^[A-Za-z0-9+\/=]{80}$/, "bytes_b64"); + like(random_bytes_b64u(60), qr/^[A-Za-z0-9_-]{80}$/, "bytes_b64u"); +} diff --git a/t/prng_sober128.t b/t/prng_sober128.t new file mode 100644 index 0000000..7bb032e --- /dev/null +++ b/t/prng_sober128.t @@ -0,0 +1,66 @@ +use strict; +use warnings; +use Test::More tests => 19; + +use Crypt::PRNG::Sober128 qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand); + +my $r = Crypt::PRNG::Sober128->new(); +ok($r, 'new'); + +{ + my $sum = 0; + $sum += $r->double for (1..1000); + my $avg = $sum/1000; + ok($avg>0.4 && $avg<0.6, "rand $avg"); +} + +{ + my $sum = 0; + $sum += $r->double(-180) for (1..1000); + my $avg = $sum/1000; + ok($avg>-100 && $avg<-80, "rand $avg"); +} + +{ + my $sum = 0; + $sum += $r->int32 for (1..1000); + my $avg = $sum/1000; + ok($avg>2**30 && $avg<2**32, "rand $avg"); +} + +{ + my $sum = 0; + $sum += rand(80) for (1..1000); + my $avg = $sum/1000; + ok($avg>30 && $avg<50, "rand $avg"); +} + +{ + my $sum = 0; + $sum += rand(-180) for (1..1000); + my $avg = $sum/1000; + ok($avg>-100 && $avg<-80, "rand $avg"); +} + +{ + my $sum = 0; + $sum += irand for (1..1000); + my $avg = $sum/1000; + ok($avg>2**30 && $avg<2**32, "rand $avg"); +} + +{ + like($r->string(45), qr/^[A-Z-a-z0-9]+$/, 'string'); + like($r->string_from("ABC,.-", 45), qr/^[ABC,\,\.\-]+$/, 'string'); + is(length $r->bytes(55), 55, "bytes"); + like($r->bytes_hex(55), qr/^[0-9A-Fa-f]{110}$/, "bytes_hex"); + like($r->bytes_b64(60), qr/^[A-Za-z0-9+\/=]{80}$/, "bytes_b64"); + like($r->bytes_b64u(60), qr/^[A-Za-z0-9_-]{80}$/, "bytes_b64u"); + + like(random_string(45), qr/^[A-Z-a-z0-9]+$/, 'string'); + like(random_string_from("ABC,.-", 45), qr/^[ABC,\,\.\-]+$/, 'string'); + is(length random_bytes(55), 55, "bytes"); + like(random_bytes_hex(55), qr/^[0-9A-Fa-f]{110}$/, "bytes_hex"); + like(random_bytes_b64(60), qr/^[A-Za-z0-9+\/=]{80}$/, "bytes_b64"); + like(random_bytes_b64u(60), qr/^[A-Za-z0-9_-]{80}$/, "bytes_b64u"); +} diff --git a/t/prng_yarrow.t b/t/prng_yarrow.t new file mode 100644 index 0000000..ee43337 --- /dev/null +++ b/t/prng_yarrow.t @@ -0,0 +1,66 @@ +use strict; +use warnings; +use Test::More tests => 19; + +use Crypt::PRNG::Yarrow qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand); + +my $r = Crypt::PRNG::Yarrow->new(); +ok($r, 'new'); + +{ + my $sum = 0; + $sum += $r->double for (1..1000); + my $avg = $sum/1000; + ok($avg>0.4 && $avg<0.6, "rand $avg"); +} + +{ + my $sum = 0; + $sum += $r->double(-180) for (1..1000); + my $avg = $sum/1000; + ok($avg>-100 && $avg<-80, "rand $avg"); +} + +{ + my $sum = 0; + $sum += $r->int32 for (1..1000); + my $avg = $sum/1000; + ok($avg>2**30 && $avg<2**32, "rand $avg"); +} + +{ + my $sum = 0; + $sum += rand(80) for (1..1000); + my $avg = $sum/1000; + ok($avg>30 && $avg<50, "rand $avg"); +} + +{ + my $sum = 0; + $sum += rand(-180) for (1..1000); + my $avg = $sum/1000; + ok($avg>-100 && $avg<-80, "rand $avg"); +} + +{ + my $sum = 0; + $sum += irand for (1..1000); + my $avg = $sum/1000; + ok($avg>2**30 && $avg<2**32, "rand $avg"); +} + +{ + like($r->string(45), qr/^[A-Z-a-z0-9]+$/, 'string'); + like($r->string_from("ABC,.-", 45), qr/^[ABC,\,\.\-]+$/, 'string'); + is(length $r->bytes(55), 55, "bytes"); + like($r->bytes_hex(55), qr/^[0-9A-Fa-f]{110}$/, "bytes_hex"); + like($r->bytes_b64(60), qr/^[A-Za-z0-9+\/=]{80}$/, "bytes_b64"); + like($r->bytes_b64u(60), qr/^[A-Za-z0-9_-]{80}$/, "bytes_b64u"); + + like(random_string(45), qr/^[A-Z-a-z0-9]+$/, 'string'); + like(random_string_from("ABC,.-", 45), qr/^[ABC,\,\.\-]+$/, 'string'); + is(length random_bytes(55), 55, "bytes"); + like(random_bytes_hex(55), qr/^[0-9A-Fa-f]{110}$/, "bytes_hex"); + like(random_bytes_b64(60), qr/^[A-Za-z0-9+\/=]{80}$/, "bytes_b64"); + like(random_bytes_b64u(60), qr/^[A-Za-z0-9_-]{80}$/, "bytes_b64u"); +} diff --git a/t/sshkey.t b/t/sshkey.t new file mode 100644 index 0000000..ba374e1 --- /dev/null +++ b/t/sshkey.t @@ -0,0 +1,231 @@ +use strict; +use warnings; +use Test::More tests => 341; + +use Crypt::PK::RSA; +use Crypt::PK::ECC; +use Crypt::PK::DSA; +use Data::Dumper; + +my $rsa = Crypt::PK::RSA->new; +my $ec = Crypt::PK::ECC->new; +my $dsa = Crypt::PK::DSA->new; +ok($rsa, "RSA new"); +ok($ec, "ECC new"); +ok($dsa, "DSA new"); + +my $dir = "t/data/ssh"; + +sub _check_rsa { + my ($K, $name, $nick, $private) = @_; + my $R = { + ssh_rsa_1024 => { + 'N' => 'B8E7C9348A016072F92B0E350AA3480880F5B4FBB4043DC93BFC35C8A460241F31C34D02EEEFF233C410C22FB890845D9E430691FECF525E3B360D5FCE4F749733742324EE0F4B79C79337CFED98EA9BD2C64A2701811F31E4B3E6C68355037A8E22730FE7186181B29862EB2E04C025A4482AFD3F6E0AF2C8BAF4671A10530F', + 'd' => 'F952104B778A43B2C3A6FA912AB6DFFA1769378FED3B8AD43CBDE707941CCE9801518615DE784BECE10277D440D91CA1DF342137DA8D52531D23D504C9FAF90858771098B47CF5C2D13A50787326FE7B8922E3CDD13ABEA78833619E229E69E5BD4063041C801B7FC51B82E036BD4E29FBDC1C7A636215425CC2243BE34CCD1', + 'dP' => '2F010FA8E263C85825D3449D76D82DD4E27393750535501FCDC0718E248440D40A7670A1FD920B78D951BC7EE8D3DF70FD0658FB91F5291DD7CCA6E59BD0BECF', + 'dQ' => '6AF292E939F528716A83C2F2A35B809FDD7AD0E9D36FBDC9C9F2C86E8F8086EEF4E24461F533C4B2964C04B53E650DA90C01371A3B2B60A9883BCF5B27893829', + 'e' => '10001', + 'p' => 'F61B2C906F31146E28B01A319B1F5DF5695BCED85B58A5859C9108607EB05DC242C40940D12F8820A86A4E8239C5E161576B6502FC1BCBC920048DFC01854CB7', + 'q' => 'C056C228341621B96B42809E14753BE5F0126C25F0106B4C20EFFE193F617295000798908F039E00C4046ECEDA7B34AE7C66C8C9450BE802411A844645570469', + 'qP' => 'C5F7EB4D275C6D5B5CFFC12FEED4819390C2D8029CAA50C7F67B07F9CAF0FCCB11F83C4798102F7AFA49FA6DD104AE4EACB0E3F63B59FD8F022547266070A3A', + }, + ssh_rsa_1536 => { + 'N' => 'A460779FFE416176D1301B86197DA9D863DD9C9835FD82AC3B384D9DC4CC90CA3E44CA7FF3B5A208111246BF6046ED39448BC19DF37C05BD2AEA9387621F27109B615B2EDA76E7C6EECBF3D8098DDCBF160BD62994C6DE9A3DE2E9873C50A6DD9D4B00A89BA3390EAFECC41E1857E96F56959912E205CEC7C6B6A88B3BB538C7CD255C2D78DF432D37967A9D84CE56D92D6241490A63124E162271EE8BE111DD4CD7A34199662867CB10A791DF04F00487CB3BD5C5912947CF6524E2AFC296BD', + 'd' => '7DDD37FC146DEFB951386AFAE5ADE94DBE3A44DBF00B6BF1816EFD4F9F0F9C969FD380D334C3918C67B5FCE231505DF909D991A9E674C2D834726600B64B70583101FD16054622F79A8624F2F96DDCE79C73F7CAE316DC0072FEBB1E483AE1697A0EA7115B8B6740DCECA64428075C9916DD0949CAA7E218B945759B4E4C2760415AE4F3D71E283D95640D3BBE0B28CB53BBB745BA1A38609F2CFBEEA5C8D149331504E4667E1CC0A2968BC7A7835F80C52128CD8331CFA447EA6F63FCD2ADA9', + 'dP' => '1A7FC0D04F8FFA3C484040330045C3667F04C83B262816AB0F79786A32F9B9B85D603AD4E1118237A2ADE048CDCD9B9C4CEF6F71742D7112656B3D1653311C52D997D8E675C913CACB47AAC3156142AEE588EA54EED7FA545C093C5C4FEB7C17', + 'dQ' => '4C35FBA76395AACD9D3CC3439020793BFCB7D70296C5149895D7B76CCCD63E677253311AD255FFDF9E9F263C38908AA7907522263BB9F61B4810AEDF390DEFCBE29002BE0F327278DAC3F24386987DF9D2DE7D47E4C635280791D824D1C17329', + 'e' => '10001', + 'p' => 'CDBDECA70F14F35C6CB658B7AE804737E8527847868AFD17CFDADFFE6789BDC41AD400089C33A8535E75188E5CF01EDF0CC298D1FB0DA7BD7993139BECEFD20574E023DB71EDCA50B4967D56B6676BC2BE64FD1D3DDDE2D5A4849B53BE9B3847', + 'q' => 'CC87C6F19BEAD9549437305A1B7765A668F4C2579DCA318A4734836189DD7B3766A3279B0FD139E2612FFAEB65FD1933E74F121BBCBDE420B03E4D1252E9D391FE321F98DD941515BBF38E8631B0CB7B80469DD179E0FD6C72292CCFEC45FEDB', + 'qP' => '4664ADCFFF062FA8ECD41D317B900CD258332F413B165D772E15AC1D96F8AA9E11762B5C1059A7C8B48870D6325EF023E52186B5BC2981963FFF0F02F41161B36BC6283DD05A51C3902A4E320A3346DBD0123ECC5849BB97DC1D8F48E948C84A', + }, + ssh_rsa_2048 => { + 'N' => 'DDC63374FB6C5CEE976B781A9873F983442F0EB96AD2EF0ADEE5F114069CA5A2B4236E1B5455453E3B1FFA45265B6DE360DC4BDC5934FB35063BD70ECB19282234AF5B814D4AD79D7ACE9BD8D05D881A0C7DC59BEF2095442D25D044580805215EB1A99566F251779FACCE0AB58E631389BA3D7F23C9A192CFCACE521713C70DEC8A533F25CD81D59AE3A1CCE8528D234740654FD07A1EF0DEDD41A154E3403C252B14879EBBBE08D796DB35DCA12B19A05ECB6E38A1EE09FB1970CD61EC8A0023D43A0218C68375243C59F13F044509AB998D129F86C507B88473306DB836449659F2415128E882522710915085037C966A8FB9A1D720C88D37B2A7E7AE091B', + 'd' => '4379DE8625495F2D28DD05F9F190B7C5FCA4E4B1FD92983092891BC4A00E614713D003DC44D87CECE648607951A657D4EACF9C353ADF27DF863A06C0F5827DF78A58205B430D16754FBC3526CE9EE69E2656CE1D17B0AE39C412D13F3A199696049DC19F37675AEA2EA70139B8EBCDB150225E3BA4C3E0692ED7E1D69036F044F72BF282247FC247DF06E4D701A18ADBF78902AC5D374A5826FB54F8783F205A1304F39EDC54434458ABBA264F70CD995E934A4DE5CF08F777B95D8FC90D1E8585DAE4DE50CDF649CEB50EBC959582850CF937692FB2F6B7F51B75C4CE05F1215A1CA0B17BC9CC01D1428A4EECD124616483B9E7DC03F62B98E186227379F221', + 'dP' => '4C745096BAD7E1204A1A5615B58ED2067E9F74343A66FE34738B6A35E44EB9C30A9000E1F86C8218AA7F6E89ACE6067E73B53349EBF9A6279AE4243785D07BE8DC3FF7A1CEE596D3A6B48361F9549ECBC6CCC64CDCC01AD3731E3FEA48FB28506C5BE30A394960540D8B9C22E57423B23CFC0D690AB05FFD49F3C03DD851CDD1', + 'dQ' => '362871B6C6DB8872F6EF0E643F889A53FA835B6BD52D8296443A51729AAAEEB5C49E65FF68EDE06839CB2F3DA340E22571FB44D582C40F35C681BEE91648308DEBAC96598C328486E434633158B0674450F00A216ACE7C64651172A34FCFD7601EDF1AD94129F8081ABED1F31846D676D30A0A0621B4811D17A3E11A2A971B95', + 'e' => '10001', + 'p' => 'F7DA46D9F3D35FD667777128C566B809EFA9ED004948F2ABD642A17F867DCC275C87E513DF5C38643FECDDC5CAE973A58FCCA00D5CF1566E080CF4B33C60DEC9E79883B85BAC98AF067C542A81C14B129C1E8EC2BFA1E1A73AE157BCD875542115BBEA31FFA3EEF2B3B65F35688914D9355DD6EF2F39FB1B946D225CE794B187', + 'q' => 'E51078436AC01128519553899B22501295821AFB90CCBAE3159A6BB3BD25828C30A45525FF868E6AAA756B27BE059B7D26F3EFB08EE74CCE3756C7107563B887AD90F9E7E340F533A442CD85C5B54A0B673726565B4BC54C1AFE5393FD7988F21C0A6765B095C52F50537A5709EDA3EFD5747A320E380DE7871437CF6BFD20CD', + 'qP' => '241F61FA8CACD86DE6C365AC0F62AEC0244E5AC45740B9A8674273D6B8CCC5EE09A06239D3F0422A735011F36F4BEE43EAA8E8F107D6EDC9A549693D64B853E31385DA2D9809820046DBE23746E826CD348555E64F2747D277CC8763063EBF0371D856023B98E16328F3F6AFD6B548BC5B9668674ACFED6B93507738F5CA1A80', + }, + ssh_rsa_4096 => { + 'N' => 'A3A14A915FDB49E98563F84ED8D03F68CB648252DA0B98DAA8BCC39CFDB581F8583C1A0110369F7D5EF1FAA7EFD70C8638326F7543DA35AF27569C09C72ACFFD2CEC92A4E50D6DB7E50EC16CB4DF19AEAAB2B8F888A19A9AC10BD87B1934FF467235C900F5F5802990C9A26D4DE43BAD04AE790E0AB8D321E4A4007A9E5A9D58B63C21A6F45782CA4ED3411B276B74F47C035D08E78903905C71F3634E64D27D86AED0618243B0BE4B7BF7C1F8FA8892C3F9AA8DA57DA3C97BDC6DC7B9B8F8520945040E2EB15E7FF2B4B4ED59BF45397553479965A1C93378B67C28117E2967B6241C77A67011625F8C6DEF4FF3A6F1B972E20F3302480393FBDB0EC0E627CA4A84CBAE4406CBBC96FDECF2C6B9B8D8D8398CD41BFA3B22B9085C9D4FC82A2A7BC4ED4ADB3C523E17300D14483C61B09027CCAEBE4F1B81159FD3C909E5BFC9D4293A6E32B096B2F00671C90A213F58D16ACBACFAA506A2F3870FAAE3883AE0D250E9258EC27FA12D3D4FD9D061727F9598E3DE7695189AC085CB8B454E01EC46FECFE7F9E222C138853AD9E65118D18CB2774E5915CBF0BD230E9305A26C17D0D6FCC37805E60C4805687558EA589C8B41CEEE95BCA682E32E3679210E34355D1D125CDC3D7F34FD944F8D0BE10EC31CAC3AEFB2F44AD5EA503C984C70B66BBF6BDCC7527CAE9D7533F1954587A99484FD1373B5FF17F4365D34F1CF30B88F', + 'd' => '70230C083EA9F8A8499AEE4392C07C8423C758ACD0F35BA89634EED5BAE55611CCDE3B6FF91D86059438BEEFB2252D571A522E222E02F0017E3313B27BC4B24F2E275E8414D93414EFAC42106E8FEA78D250B304D815EFEF185736DF7DB1DD33F8F7352E2C613798C4B9FA4F702EF65AA737AE8C59FAB9EEA3536564A2FB3493E427A764545558B3AE7B8645C6A914B8ABF85E1CC91813D22E188594CBD7BA8CFDECF5AFAD67184C014D0EC8E70942E959D6D2F449B2A5B961E1F97603A868BD47CEFD6D7EC05D23D03FD93243EC19D3BBBCFBF77B37F9BC058101EB2FB9C7446505B060AB3668238399A88975C063EB8A8CD9B152E2C0597B640186C5D9B4F00B9EFF91A343BFB7E39479B3C708322EAFD282E354DDCEF663BAEFA33E239A88BDEFDE0D7DC5288FC453C817EF201EABB51557DEC4CE873F0FDDDE0B87CC5EA62B44E72B14E13742316BEC034217FEBD728A59A3F823C448CDF3892C14777D501E40600D817145F903A748A575351F0D87FAB4BB3B939E5E8EC08575D9FC3EF6F332F8510CB992B637540427C60EE3808639A2821BB0912DBAC3F010F67759EA20005600C493566031085F57575A58D3798B187AD105598173FF739229CA290F29432DDAA99E9A69490EECAE379AC01E714F9E997F346BE52DA42D1671715E7DB836C32EB37A8749F2FC4C9917115F195E205747BAAC68C67F9B9C41FDBCFD91', + 'dP' => '2BE66D365291569847FF30473A0A330B879DC6323CAAEFAAA432B55260DF249F01987769C1D0FAEA78C8410A8CCAB05DDF3640232AA6C6F29A4FFA00D3B691517B58623A1BD3313FA4258478C8801BB05913B4C7066C33645ED226A14DD28DE1BE0DC6E4064DD88EDC7BE421D0070982731AC97A3077A120B4DA045ED6F86AAA7DF00CBBD1391DB1C8BA6FFFBFDD1BC0DF9A652585533082C7772759994897905790032EFAD4A4C4EF5A9B6F319699166ED00FA8425EF9620966298AA1C9E4EDF4631C40C05D6EF457B2145020DCB43465DC8D8AD5AD695A441393E904112E148B6B32E8A4C053B90027E3363066ED7FF0340AA02ACF9E571D0AAC80CD0447C1', + 'dQ' => '3B2CCC8217EC24F123E428758B2A5FCEB3DA96674BDEA03FCE3471473E785EAAED7354C79AE6E644A39A383A26B8099357F2F8EACF1D8267BE587DA30ECAD5BD565F1DD484C5027BD22710B40063F6EE8DCD72FD7EC2F4BCB70F3D5591E37E411D7DC02D3A9687ED4898F6CD9ECF299BB82FC9474CAF4A6F0F9B33F7542F628F31D368584BAD9CE742E8AAB71E79C9D60759C76151E02EC175507213CBF0A48FEA43B0712DB11761ACD09787D0E6B5382A25F7D0076D4CB70DCA7EE8034767ADD2B27D2F16BAE358255C3066D48D346DB30957DA2BB8E23B81F26C2886F03A15CC77F1FB9DDF59240FE8C6E5B351ACD67972A85ACF567F0A5CCAC9A1968CCB05', + 'e' => '10001', + 'p' => 'D36CFB9308B8FC6B211997126792149363A7C419F09889A9628706DE410B640C282C6A987AB570F0916F1A63E41B09576EB1E0DF8B6638298FC6971DE80F25061B939833BC396F92D6B5AA2EE6217D5FF53D83968F561EB67280A11984A9AECF9CF64F7F6BA4798AB4803CC2390E2D070281AA9C1AD2BAC6C5A8481B009687CE322A0A27FE967AB639B886BD0669917EC8AD770B2EF822200E5576280B7AAC56F8EEE50AA5EB393836C5F5A63F0490B990738E13E77441A30B240655FF7BAFC7E36CD2C5B167AE766AF9C121F5B4D870764F8723208337ADC75F1D9598A5E41D602A1BC3A4AA395D88851AE73C4BCFF8217C5DB0A3704B606228D081E8EB2B99', + 'q' => 'C620B139F1972C67CD6DD6A44310DBA126564BB9323880410F0B298F42686F289FA3F4BD0F484999A5384304FB737CD7081CE389C5268CA32033D7DE78DEEB0CE59D06246476A3990060B6D3855FF632A65C07FD8306ECD28FF7E57CBBB7B419940F8F250C6BE7ABE2AE5B0F88434819C31985BAC2F4F9EFA6FD9D361F016C16C302689FECD35B7BA472F4ABD0D30A399D123705D976C9B16CC299E96D363AF72B711CDCD8B72A980724F6EDC62C63E7D29117DAF397BD4DCC480BC04F4D04E84E79BBDAE87550D6CFCBF866CF5FD392220B490CF13576F1110DB52D442633EC1A05E429BEB2BEBAEEC5FE76855749D7F5075FAD0687BC00AD8AA36F4D105E67', + 'qP' => 'C27EB9DA8DE611220C7139C0C82B23D0F0767F48CC715F37DFE09FF7DF46FB0837D32F63170AD1484F3D0FCF1FE19780F6090C462B442F7E1C99A422CFB1FF1CD6CAC7EDD3E3F2166940E41120F2D5EC3EA0690E528BA5DF0F5A89B07CDE3DED92DDBF781E107CDC75939CFBB8AC5FAD10F61D11274147F690B00174EE86285D6D12A7468148572492C586CAEB8E24E935B9DCB3BF8F11BAAE94472338F69F64CCB3D911C29E40DCE3760CCEE7F604BB7C8F24E3E5FD60695305FB0ED152766386521596D5DDC00AE91214F1CA40B3FD9DC327ADD538CADC9F3C2D3730AEFBB8439BC14638F2838B7FC11CEAFAA4827C2D412AFC18A3F2D37572F8BF44F9A170', + }, + ssh_rsa_768 => { + 'N' => 'D879B7864050A795088D444EEBF5411B8EBF8340C4DDC35647181DB0EB10FF0F329E9BCEFAD46742A6AB0BAC66B0D83EDA488A0FD41E52CFCEF46285561E7E80A3B1EF9B5ED5DCAC5F9F8074D463504CCE7E2F6EA6758B39889346BBF96D51D7', + 'd' => 'ABC13709BFB1BEA51299F31EA33C7E21FD4A9A3B2377C86A8611EE4CD6D52F69C181F2A17086623F91B998937B0EC922EFB82A5E4364D9EE3F8577B30511605BD7FEE7C3FBEE50B3890D9AEDFDB850625F7CB6B16F02BB24A3B238DC81BFAF01', + 'dP' => '33F7E8BF9E0C5FBF35A5DEE52AAD59E5FFA098BA878A8239E5B4904AB7F330ADD24065D62F35B00BEF54490B42B9408B', + 'dQ' => 'D302842FF78EC4E9172F3880CDAD75200619A4CFFC3EEC113499F393897E2B05C560499D4AC0572405707248B5F12BC1', + 'e' => '10001', + 'p' => 'EEEC625535BFFDE8C95F108EFA915E099E074C2EC4E185226CE8C78B0ED0705E0317C2C587107D9882E2E552C45E6097', + 'q' => 'E7F2999513312DC453489E98728D02F063851FCFA3A963146947B3E73CEE90ACB70FC8AF83B5DCEBDA0B7F61563D80C1', + 'qP' => '48D2A86459D33635373676A71AA5A4E255613E7E71E6C6941C426D1F80275FC81613E2E6C40EA7C3779F33C36DC52A2', + }, + ssh_rsa_8192 => { + 'N' => 'A95F7BB6356731EE7E07A1EEFF018A8B22D611C1CB2D6D3BAF7B4C9367A1C77302ACE910A10A1BA74959DED9F93179CB8B76988064DADD8DAEEC431A8BD300E2FAF8D6B9C2E69748434368A93F2E3FF38F4399078D561D75A11A14900E87A48E684ABE4B4C91A95E29D3FC244C3F7954E2833B197C323AC947049B10CF7C708998230BD76C534E85AD92F16F2D27A01E4490660758853B4C0068815AE5FAAF1AAA2148962EA8516E101A579F40D6EFD729FF3F5C6493F243A4DEC1656ED75F571B01CD7DA7E32A56E31E908DF86E31CCA155397AF6385AA9AD7D6448A28BA701C942BA23AE7BFAAB60CA17C28EB826B31A5F5F67225EB98EB0EA7E30AD450B56ABA8BD0FFA531762F311180490B53DC55EACB485CA91CA63C84AC1AEF94A9511DD5D686418DD57A274CADF61923CEC6C0E446CCA3382ADF3254E472E3AE9C804ACE915617437D9BA1FA8E1FE60DD6ADBD0D6DEF6725813810235AEBB718784736E229386AEC612E427E5A563B23FD9D2AFAA798EF5B7B94D17591A68B6B8E243D672648CAAFF6EB3453DD268129FE27F2AD1670410F3B38810B27E78044C9952117FA8E97815FA60CD1EBE2B375045F5E5198D8B1474E53DB772267B01951B3795DD96DE58216CD362E1566C2EDD2CC83772696DB0AF76AD5A516CAB95F190663BFE5C91CC79564422006D2499803CFF696041769BE0E7802D22F449CAC3B59D975F0F46F534B8C3F281ADDE17ED5B2527FFAFD48A05B7E807EA82C2631E5CB69A9496E7795824792DB2B3DFAD00CD4F727F49FB4AA464E3539470C73E352524301227CCE4BA261BF306AF0E7E90919DA781A19514AA7F6E654770514A3488EABEE87D83C638249CF535A39C489FBF51ED707D3C9B377DD81BBA5970961695F17AB7FDA0B4966256432D497D9F176972519AA90CB2557C0558A29489EBB4FB083FBB662BCAB4352604EC025585621F3F4A8F725B2A977301642A92F47167F5B116D14EE2F3854232737D4C356C953753FE8F51C6284BDE2957C64F189A371F2AC44165B2CB0D5661701EF2C1EEC5FB3FC84C5E36717AF4DE90A2E4291FBFFC4110A7CAB08C70E538F5A6D6D40FB8A307B1B0DC8F1C97A853BA1CC10985F795D0E58AEAD04C972A528CCF3EF1F9AA1414A22469973354B4BFFF12E83D90FF73AB9C50F95CB3ACBAE6D361E4AA24DCC868B48DBC7BC6935B4946A738A908C345723C650F901992419777A31D433D7F570D300A42A26E117DC66ABCAD0D4DEB1BE0E84517B2B757C05BE837D8696EFA4ED25062D37FB06030792AE27F35D9DD76811DE942AE1F75928CF32AB11C258786B547D1F68F36DD4DE94E4E5B5FB42F10280BB8FE86E4BF0B73A57C548F225E157A49F11537D79CC21EA72EC5078A6A92E48BDDCA76EA43DAE3DFE6616954221E6AC5D67DE3AF19C4218D0859251D5301F9', + 'd' => '452530F922F61D21531C4494B0506DC1FD97CD2A038B6913BBC12772EA14D6BAF235AAF459FA296DF2F9188C7E3A1F91E43EA7658B46FAB9F3D68A529510B044F9D68ABACD819BF3295AA4A8AB9D730838CD8CF4D3537BB560EEA7C463DA2668E8D4D2B924EA366DB5BFD028F563D861BA137F161968DC2CFDAC38ADF536C52EB7085FB6338812FF69EC1A5A9BE19871A2E61C71154756FCE111C8F555FC306E3F545530D29D6E98F343FDCF8B05F4662FC3FF96F58C9C93D704058A2665108C1BFF7167C219705886621CFB88975C074139ECBC71367274E0D9D70DFC25ED294283D63FE8E4BE6226A27A6EB81B1FD97083CD0BEAB12729C4BA068852C4642B9EEAC53C77A26262C7FE8B82999D1439B63BE57AD5470D8C0CE1D00E61C17BF80E1A2B1AEA37BAA61CEE11A1E0B4B4842C92ECA2E3C28EC73BCCA82C8C6A9278AE2A7DCB0A4A1EBDE85CE6DE15A76F0F8C439C449A4BB0B2B3373D3D52CCD35AD8748F2BA5C0414819AD9C068667A0C26D6AB8338FC6D084536AD1E83BE8609EF7363E2C5B46EA678F75FCA6F62B85A90ACEF0326DC53FDEE58A292D4FFC017FCA9B065741EA1F0C53D1202BBE6A2C1585D117C2D6B81E3A42E0FC2AAD6BB4EFCD63E84A9F4A0E068250A21A8A4B4B13F5E6E4799E6F139113D537FB18BCC489A826609E390EB4141E9973F544216145983C6E9D4067E1BAA732A4EE5733ECB95E5DE229343087960003E9ADF8BB59760C852444F2037C2279049F346355DC4A7A8B84285CC507A8D37AC99B9A3EAAFE197A9B0E2B4BBA0FF89FE911C559608DC0E62B440CD6466F88A28D7CFB682356D067794DBE6F0F6605E0E546171D290E626704205F2E92C5801ECFA15C7C5767C63730C5F74D794E2D87DA8011E94636067B7D9BD8B90D834CF4B47C0F0534A37DF7FAE1516A9AC08C2726FC6DC639249469B4E2C2EA60E16D69B7E4055C2CAEA073EA1CBACCC93CD47BD4BB67D261AAC572516E284C1A11222ADA27C3807BCF0546BB084FD94C2C690B37EA1B0B05BF246AA17FF8B630AF0AF999D878EE9CCDD083154D34D15F3F54AF12E610CBE34B9B692A5140D91CE6C3A1B5DE21D7F28B4B3BCF4E34A06F0491E3525BE5FCC9177DF00BAB8B15F166164F482CD2B04098464EB42C1F5C15CFBE7119F4C2D02421E69F955F06C80452741E5BE98F36BDD51F4A1130A29F8DAF94E8A992F887F2C2486339D1FE807652ED1D010781C580F1C1FA527DF804AA8F5D09E1320E37FB93E8F87E4C9E1F1F80AEBDBFBCF6C0B4066429DA3C4B6ED03596C1096D2F56BEEFDFD65267B19E21AEA347871A5F4C749C4B3AC1E336A57C0AF37DB66A240CB32F44C42B9CAB5EF294832042339F703CEEE241DDB9002B198E210394DF7357290B049EBF46814411FDCA93A1F12D5234B32AFDFA7A1C5409EA7431D2082504C4B1', + 'dP' => '50EF253FB29B957F25875D04BA6C203D1A0B4FB5AD2E3C1764BA5B0EB675E1281BF14C2412BA23840ABB33856173BA9609D9069E0D0E8839B0BA5389B44AA782C351446BB4987415351B16A342D26FD77D9B17480E4F90ACE82F90D068FCCA4F107EF31FA35698BFAAF86C3819BDCE46968C0C3A7B91D2C4C749013D0349B5AA9EB44E20AC66746A427FB42501F968CD469D5D812F744DD05B7D6C28625B9642EB039C02568AC2A0E62266104F7DA1CC4EB0818B0126A3F211CDC50C30A7AF8779121AE1373A736EBB771BF83174F905EBCDAFB340786644A1BC1727368EB9BDF167E490D933610C0CF59B79D91C21B73991B591F47617E5CE20E63AAE050CD020C37FDB66B527EF5355F3866353BA612965978FC6ACA45342D53E714E59EE2811C9A99571E5AE3D30A7D10D97F8DA5D117CC813EB71FCC2F01A5AB80D2BA050F2A0208A61A47BEA69DD25683701C188539782BF1FDFB7B59AEBCB4B2BF7E90504F11EE022530A504567C54F797BC0E026B6B812DFACE2287AEB8F9CA3211118E333DCAFD3DA51B7B787E49A4FE272585D5EE46AADE1CC0B655DF0C469EE61DCDDB9435DB8FC3D7E1FC27E91F7454AE1706F6D6597303362CDA03BB8DE70CDA9FCBDCB8C875FF318CD2DD1D053F3D9D45BA9A956A26796AAB463DA2140815632127FADEF69AE08CCE9C5E8A8EC73ABC06A12B53B6BCC4D574F3A0AEEF45F0DF1', + 'dQ' => 'C4F6989E69D3BAB693DB0AA31BB98E26F4235B7AFB545829F52FF33D492969239D5A540FF899A0843C566A8F59B31F41487BDC55F550E58EFCB1382CFE423A8410D2CD19F4D26E9EE098AE87576505F344C85D332F2F6EF04C77B2D9D5C3A9B09D5E2C0B0DEFF9291A03B309ADD98A650C8C19C02A2E15928117068C286E7F3AFD369C107E1C492A30DD86861887EC31683C4A959216FA54B3F1F5A5BEAF84D748A37922A9963B224317FFB324C90ADFF6595CFE827CDDEACE7AF4924D8C10367F09388699420DEA07D3802C32073AE22F72C54011A6457D3A644870C3115DF1733C42CB7ECD50F2541E12A7744D28E8D69135211ECAA5EF9CB94DD30B8A179A977BB35B7AD9F4276DD0C444B294C01FB5F2AC860553C8D0D7384DBFAD210AA849310B8F509A4CFE83C9BCE184C5856F1705E1080543958260838F859AB8F49AA4A2CC53B1CFC191A5A5CA5B7A9DBF1F801378FDBFB8D4626F4EB6E9F6FC83EED33A192A23126CE85E3D69CD17BCFFF45E98F9E02E8A7448E9E3BF33C11C695B6E30F3566BAE13D3E18BE6AE52B261D2C7EA90DEEF63F34FF5114AD9B02890DA74C8902BE23F69F07D861A1ABE16E7BB484012715886738C8B4EE263372EAAB4C85641E766E89D72BEAC181CEF5FFB7E4DE11E1FCD3FCDEAEBB0EAA501C415159922145F3AEBA80FDFFEEF9D9E78E922EBD8DB53482F527AC582605DEFDF9945', + 'e' => '10001', + 'p' => 'D3FF688EABC3AC9E4177E6E99B68D78916B806E2C97BE65AF2E157E1BAB759A6AAC34E445641A11CAC0CEA460957BF993C70A2F6806510013CD16D7096D213DD3DA302B60E0A282AA88A9E35386A46403ACC46EB0FC0CC45D4A9B1D424F83774777CBE0D3EA43DF2346347FF1427DD02DF9257E58F15B7229AC3A33D11A067583E32CC9AF9F98AB5B4B6C46ACD0784A1BD11ED677952D988FF331D5288FBB57F41826CD8730EC96648F753508F8D40CEC4FDC05A651B6EB72AD964D2EA639E6BBA07D10CAB08170362BC42756F5585BD2C9B50598CF32D46AE707A29263EF2FDF1E61CFBECE3A9108E1DCCABF0FFFCEC82E51A1BB0075464167F2A2698D1D275C38BEFC81424545B2335E3B905382B6ED42776B3FAE36C2B74C5484DBA9ED808D6F7B9EC63F9F1B46FDD4FA8ABF5DFBA6196EA3164F235AA4428382D43B0BD366C240C62BD2778462068EE16792A3396F383F9312E31ED4F4D924BF34E146ECCB2817377F85691535DAED3FED7795F9AE7CCE90E5CE7031FDA397CDEFFEF8235A8A0C2D9FBEDE2A2936A7E7CDFC1D039C95046D1FAF887AFA22065323ECF9F3308350D895B005A4F49F63E026EFCB4F7A4D2ABDD2D48AC16C4129842BBCA974BB2F90120F9F299E4E8B2C28C9A6B9DB1E2980E14FE38D16845E394D2A37D6DC2C7A93D185908168A4752FC04A2DB0B75E3A0E0C0DC1A9D478BF1B29369B1DA45', + 'q' => 'CC8731273CD2D3FECF4DB70DB94110B5A9B3819E26AF7A5D7804DE8348FE93D6479DC7C83493367656EB54402FC6AA4A2BC1472A63DE15E0F67D2FBD0CC3028311E53EB1206609325AD1207A6CA6BB705F51D1604277B94A7B5DA28F2151DD49BBF09BBB32C8B09886D0CF68769DE8D551FC1F9B6BF9336611BB5BF69A067AFFA61EE7CAFC67C14D0A33428E927A695440DFB84B2C2B9D38C27F8EE956DA4FD03948F33C52AB587AF1E1A1594889BF6BC64B248EE3EA918F606F82792AF3E84E4C5428174610D04FB846ACEE773E09113C784B432FCFDFA11DD2C8E04E897822E363ECCE141908B0E76EE13B4F504E4B079F2F5B8F873DC3DB6AA912985D3DA738D10D7DE09E6A624A452695A95F89F7499C16D4C9DC631252738878A8E75DA07DE0BEEF89567F477E7631584C61FDAC9911BF04DD5688CED39ABDA202A59CD2E97D62B7D832BB8E99EA37D7D0A0DC41F369D7DB45114AC5FB913173BC51E613FE65C17EA1C9DD9B43B3909810D1445F8289DF6AC3EF1F1275E6926B563D69BB96054DBA0AE17BAB795954BB311E9D47CC4BFBF7521D13EB71D399AE8E25A7667032F7577F93CC1056155BC88F778A3FB0CDC651780F235A9D844CE5EDCFBB069EB31B76984B769AF09A194E8DFEE24E3BD7D3C6559392EE68170855D0A2CBAF889DBA60550FFD522CD524FDAB042C1937A99D8E62258C0A8FF5B46F17B6FE25', + 'qP' => 'BE0A7246BF680218C49D95ED8DB7099104F755E96CB3C11D440EC441C6E56A55D3931CCF2FB30C7219AFF0EA5ECCC63FBBD5F4AD8F9A997762876CD74B127A8E6090DB331367E63FE7B845577FE73D33B261BD1D8A902CAA329CC3851A69C51D3463FBF53C5430242B894C7F83F20793D25B47C6E8B06596F8D8A6D83A63F3F340682EA868B9B40C27C0B7247CECF04467A7ACD0A1E8F732D4DFABB8866A1D008DD79E6CA3ADE343BD02ECAC09AAD952529FA4CF60F1480E4170581D7D52E07250D0881C49A5D53D6C5CEA8BF51786DF70990AAB5A267D2D3C393564E7F2C886262B939B98E3A7DD8BE05756080F416539B6B9E7581FB369A49049C714D73033C92BF277216F8EE516CDB5BB88DF79A5953DF395FD99C0A4BC67312ED14FF433AE6B71207B4798022EDD8800A29C6E163D0F6130BA8DBBD653C0AAFABB8FCE2E2A1F198DB2B08F084CA116EDB74EF8E712F0BBE218B65508E7BBDD1FC4B81359C6F3AD841B71B9D657738803C5FC91264EDD10B64C7F3C2C44B1493B306F64C9B67B5B3BE42BF8F682ECCFDF0432EA2AD33B85961503595EFF6AF6A053D20BABB371B3A179BC1F73AD7FB6DB4A431EF321B7D0AC82AEC758393EB1AC137A3CE74E6DA90980D83244CDE608A763433BC299B6849CA252D059716EC1353063AD068AD25C4B2F5D6FC34AE45E4B2B275510CD911BBB639634A06030410E09E4F7E3', + }, + }; + my $kh = $K->key2hash; + $kh->{$_} =~ s/^0+// for (qw/N d dP dQ e p q qP/); #strip leading zeroes + is($kh->{e}, $R->{$name}{e}, "$name/$nick/e"); + is($kh->{N}, $R->{$name}{N}, "$name/$nick/N"); + if ($private) { + ok($K->is_private, "$name/$nick/is_private"); + is($kh->{d} , $R->{$name}{d} , "$name/$nick/d"); + is($kh->{p} , $R->{$name}{p} , "$name/$nick/p"); + is($kh->{q} , $R->{$name}{q} , "$name/$nick/q"); + is($kh->{qP}, $R->{$name}{qP}, "$name/$nick/qP"); + is($kh->{dP}, $R->{$name}{dP}, "$name/$nick/dP"); + is($kh->{dQ}, $R->{$name}{dQ}, "$name/$nick/dQ"); + } + else { + ok(!$K->is_private, "$name/$nick/is_not_private"); + } +}; + +for my $f (qw/ssh_rsa_1024 ssh_rsa_1536 ssh_rsa_2048 ssh_rsa_4096 ssh_rsa_768 ssh_rsa_8192/) { + $rsa->import_key("$dir/$f"); + ok($rsa->is_private, "RSA is_private $f"); + _check_rsa($rsa, $f, "private", 1); + $rsa->import_key("$dir/$f\_passwd", "secret"); + _check_rsa($rsa, $f, "private_pass", 1); + $rsa->import_key("$dir/$f.pub.pkcs8"); + _check_rsa($rsa, $f, "pub.pkcs8", 0); + $rsa->import_key("$dir/$f.pub"); + _check_rsa($rsa, $f, "pub", 0); + $rsa->import_key("$dir/$f.pub.pem"); + _check_rsa($rsa, $f, "pub.pem", 0); + $rsa->import_key("$dir/$f.pub.rfc4716"); + _check_rsa($rsa, $f, "pub.rfc4716", 0); +} + +sub _check_ecc { + my ($K, $name, $nick, $private) = @_; + my $E = { + ssh_ecdsa_256 => { + curve_A => 'FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC', + curve_B => '5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B', + curve_Gx => '6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296', + curve_Gy => '4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5', + curve_cofactor => 1, + curve_order => 'FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551', + curve_prime => 'FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF', + pub_x => '8E102175FA320D0D583E8EBD6A9BFCBF3CB13B39EA1AACE6C5E4021EAFAFD365', + pub_y => '7857336A28C25329FFF6A2F3FC27D6835A6A8F72A03A2159E01C93DF161F248B', + k => '6B0288C07B3793976145721D1E003EF42EA569B8931BF33E5DE8EBB0BE25AA23', + }, + ssh_ecdsa_384 => { + curve_A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC', + curve_B => 'B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF', + curve_Gx => 'AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7', + curve_Gy => '3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F', + curve_cofactor => 1, + curve_order => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973', + curve_prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF', + pub_x => '9642172A80894DA890979F39DCA786930621A91B5E4926CB06D4CE5E237C074251A420FA514356B3B919293836511177', + pub_y => 'C885A93FBEFDFBF276C09CDA0913AF61FB1C22D56E211ECCF8AA5C1AB475C93307298AD8B08733D06426DB8E9B886634', + k => 'F775C2D8302B016D6C4B6044326C62CB33A794B55DC0370932B3AA88C5DDFD64120939743A461E77C48BAED57F07165C', + }, + ssh_ecdsa_521 => { + curve_A => '1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC', + curve_B => '51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00', + curve_Gx => 'C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66', + curve_Gy => '11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650', + curve_cofactor => 1, + curve_order => '1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409', + curve_prime => '1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', + pub_x => '164DF9B2BB5E3FDB700B060ABD4F68BCC062EFB0DDEA51013EB15A3046F4099759E4C0B79D2A9F9461D15A449B5298DD3DD3BB71840DA4AF585C76CD48EE616D4D6', + pub_y => '159832886171C09618CFC3408DE7415CC8321F8256A652B91509B93F972F6A0948B42F6A90A8A851784273AED831806D8AF5E551ED0F808ABA91B1D3A9B5FAFB937', + k => 'DE25E7EFC05FCB26B854A24ED7BCA80859C6760685EAD9E6D72920C2E06C981252E18CBB73E1E231A7493248A0EABF0D11ADE94957B76A6E222DB9E0025C7E6E0E', + }, + }; + my $kh = $K->key2hash; + $kh->{$_} =~ s/^0+// for (qw/curve_A curve_B curve_Gx curve_Gy curve_order curve_prime pub_x pub_y k/); #strip leading zeroes + is($kh->{curve_A}, $E->{$name}{curve_A}, "$name/$nick/curve_A"); + is($kh->{curve_B}, $E->{$name}{curve_B}, "$name/$nick/curve_B"); + is($kh->{curve_Gx}, $E->{$name}{curve_Gx}, "$name/$nick/curve_Gx"); + is($kh->{curve_Gy}, $E->{$name}{curve_Gy}, "$name/$nick/curve_Gy"); + is($kh->{curve_cofactor}, $E->{$name}{curve_cofactor}, "$name/$nick/curve_cofactor"); + is($kh->{curve_order}, $E->{$name}{curve_order}, "$name/$nick/curve_order"); + is($kh->{curve_prime}, $E->{$name}{curve_prime}, "$name/$nick/curve_prime"); + is($kh->{pub_x}, $E->{$name}{pub_x}, "$name/$nick/pub_x"); + is($kh->{pub_y}, $E->{$name}{pub_y}, "$name/$nick/pub_y"); + if ($private) { + ok($K->is_private, "$name/$nick/is_private"); + is($kh->{k}, $E->{$name}{k}, "$name/$nick/k"); + } + else { + ok(!$K->is_private, "$name/$nick/is_not_private"); + } +} + +for my $f (qw/ssh_ecdsa_256 ssh_ecdsa_384 ssh_ecdsa_521/) { + $ec->import_key("$dir/$f"); + _check_ecc($ec, $f, "private", 1); + $ec->import_key("$dir/$f.pub.pkcs8"); + _check_ecc($ec, $f, "pub.pkcs8", 0); + $ec->import_key("$dir/$f.pub"); + _check_ecc($ec, $f, "pub", 0); + $ec->import_key("$dir/$f.pub.rfc4716"); + _check_ecc($ec, $f, "pub.rfc4716", 0); +} + +sub _check_dsa { + my ($K, $name, $nick, $private) = @_; + my $E = { + ssh_dsa_1024 => { + 'g' => '90F53CC0A24C241AD71C83FCD09639A8C2B9F4CE233280866EA5FA794154F88A23EDBAD97A58B75DBB29EE263CBF172418B3A138D240DD3CB87320FFC2FA5BF71D3B6699FA68640674B5C409BCDC3030A8BAC3ADA475C3FE10445C6BE556F2CBCAA77A3ACF8D32686C1375046B2FF38C079239A80A7EA91487E41987804E526', + 'q' => 'A1A6E6CB1D58B03C1FA34AF51BF1EE131D2ECF05', + 'p' => 'A53CFDABE69057869D2AB0606EDD6674251BED3540D6B1BB7179BF435C2FF491516EC876952AF2DD78B222B4980EB28E984B84E7F9B7C82E81311506594FF3A00D49B162807ED6377BFAC9D256AA6EB4A4D84D1CDFFFE7472736D22C5DBC5EAB756DB08EB8A641F5389A9E6431CB9AEEF79384F410A3B3B329527C5FF0B55049', + 'x' => '98C1BD9D96FD64B6AAC85814CEF879FE089E3044', + 'y' => '760F535CCC5414C35ABBBB48D0B81B653258659860B8CBCAD0551DF42605AE750A6AAB4ACDA409F18B180D729DF60436CC5C26AF67B17ADBE22D7B1F9047245907D20EC1503A5E05E2EBF20B0ADD681FA96C2D66C0E496D39BC3D721503FEC88AEAAFDD93F7D2201D87A348A77AFEE4EBC679664348E173B0B84B2C015866C0', + } + }; + my $kh = $K->key2hash; + $kh->{$_} =~ s/^0+// for (qw/g p q x y/); #strip leading zeroes + is($kh->{g}, $E->{$name}{g}, "$name/$nick/g"); + is($kh->{q}, $E->{$name}{q}, "$name/$nick/q"); + is($kh->{p}, $E->{$name}{p}, "$name/$nick/p"); + if ($private) { + ok($K->is_private, "$name/$nick/is_private"); + is($kh->{x}, $E->{$name}{x}, "$name/$nick/x"); + is($kh->{y}, $E->{$name}{y}, "$name/$nick/y"); + } + else { + ok(!$K->is_private, "$name/$nick/is_not_private"); + } +} + +{ + my $f = "ssh_dsa_1024"; + $dsa->import_key("$dir/$f"); + ok($dsa->is_private, "DSA is_private $f"); + _check_dsa($dsa, $f, "private", 1); + my $kh_priv = $dsa->key2hash; + $dsa->import_key("$dir/$f.pub.pkcs8"); + _check_dsa($dsa, $f, "pub.pkcs8", 0); + my $kh_pub = $dsa->key2hash; + $dsa->import_key("$dir/$f.pub"); + _check_dsa($dsa, $f, "pub", 0); + $dsa->import_key("$dir/$f.pub.rfc4716"); + _check_dsa($dsa, $f, "pub.rfc4716", 0); + $dsa->import_key($kh_priv); + _check_dsa($dsa, $f, "keyhash.priv", 1); + $dsa->import_key($kh_pub); + _check_dsa($dsa, $f, "keyhash.pub", 0); +} diff --git a/typemap b/typemap new file mode 100644 index 0000000..f68633a --- /dev/null +++ b/typemap @@ -0,0 +1,77 @@ +### see http://perldoc.perl.org/perlxstypemap.html + +########################### +TYPEMAP + +Crypt::Cipher T_PTROBJ +Crypt::Digest T_PTROBJ +Crypt::Digest::SHAKE T_PTROBJ + +Crypt::Checksum::Adler32 T_PTROBJ +Crypt::Checksum::CRC32 T_PTROBJ + +Crypt::AuthEnc::CCM T_PTROBJ +Crypt::AuthEnc::EAX T_PTROBJ +Crypt::AuthEnc::GCM T_PTROBJ +Crypt::AuthEnc::OCB T_PTROBJ +Crypt::AuthEnc::ChaCha20Poly1305 T_PTROBJ + +Crypt::Stream::ChaCha T_PTROBJ +Crypt::Stream::RC4 T_PTROBJ +Crypt::Stream::Sober128 T_PTROBJ + +Crypt::Mac::F9 T_PTROBJ +Crypt::Mac::HMAC T_PTROBJ +Crypt::Mac::OMAC T_PTROBJ +Crypt::Mac::Pelican T_PTROBJ +Crypt::Mac::PMAC T_PTROBJ +Crypt::Mac::XCBC T_PTROBJ +Crypt::Mac::Poly1305 T_PTROBJ +Crypt::Mac::BLAKE2s T_PTROBJ +Crypt::Mac::BLAKE2b T_PTROBJ + +Crypt::Mode::CBC T_PTROBJ +Crypt::Mode::CFB T_PTROBJ +Crypt::Mode::CTR T_PTROBJ +Crypt::Mode::ECB T_PTROBJ +Crypt::Mode::F8 T_PTROBJ +Crypt::Mode::LRW T_PTROBJ +Crypt::Mode::OFB T_PTROBJ +Crypt::Mode::XTS T_PTROBJ + +Crypt::PRNG T_PTROBJ + +Crypt::PK::RSA T_PTROBJ +Crypt::PK::DSA T_PTROBJ +Crypt::PK::ECC T_PTROBJ +Crypt::PK::DH T_PTROBJ + +Math::BigInt::LTM T_PTROBJ + +#pointer with automatic NULL<->undef conversion on input/output +unsigned char * T_PTR_OR_NULL +char * T_STR_OR_NULL +const char * T_STR_OR_NULL + +#perl 5.6.2 hack +STRLEN T_UV + +########################### +INPUT + +T_PTR_OR_NULL + $var = (SvIOK($arg)) ? INT2PTR($type,SvIVX($arg)) : NULL; + +T_STR_OR_NULL + $var = (SvOK($arg)) ? SvPV_nolen($arg) : NULL; + +########################### +OUTPUT + +T_PTR_OR_NULL + if ($var==NULL) XSRETURN_UNDEF; + else sv_setiv($arg, PTR2IV($var)); + +T_STR_OR_NULL + if ($var==NULL) XSRETURN_UNDEF; + else sv_setpv($arg, $var);