From 8a5223aec174a4e175351ab8fa221a791ffac010 Mon Sep 17 00:00:00 2001 From: Mario Fetka Date: Thu, 22 Mar 2018 15:51:09 +0100 Subject: [PATCH] Imported Upstream version 0.048 --- Changes | 249 + CryptX.xs | 580 ++ LICENSE | 1 + MANIFEST | 929 ++ META.json | 50 + META.yml | 26 + Makefile.PL | 87 + README | 68 + inc/CryptX_AuthEnc_CCM.xs.inc | 90 + inc/CryptX_AuthEnc_ChaCha20Poly1305.xs.inc | 185 + inc/CryptX_AuthEnc_EAX.xs.inc | 152 + inc/CryptX_AuthEnc_GCM.xs.inc | 184 + inc/CryptX_AuthEnc_OCB.xs.inc | 218 + inc/CryptX_BigInt_LTM.xs.inc | 658 ++ inc/CryptX_Checksum_Adler32.xs.inc | 70 + inc/CryptX_Checksum_CRC32.xs.inc | 70 + inc/CryptX_Cipher.xs.inc | 188 + inc/CryptX_Digest.xs.inc | 169 + inc/CryptX_Digest_SHAKE.xs.inc | 74 + inc/CryptX_KeyDerivation.xs.inc | 181 + inc/CryptX_Mac_BLAKE2b.xs.inc | 130 + inc/CryptX_Mac_BLAKE2s.xs.inc | 130 + inc/CryptX_Mac_F9.xs.inc | 134 + inc/CryptX_Mac_HMAC.xs.inc | 134 + inc/CryptX_Mac_OMAC.xs.inc | 134 + inc/CryptX_Mac_PMAC.xs.inc | 134 + inc/CryptX_Mac_Pelican.xs.inc | 130 + inc/CryptX_Mac_Poly1305.xs.inc | 130 + inc/CryptX_Mac_XCBC.xs.inc | 134 + inc/CryptX_Mode_CBC.xs.inc | 290 + inc/CryptX_Mode_CFB.xs.inc | 98 + inc/CryptX_Mode_CTR.xs.inc | 103 + inc/CryptX_Mode_ECB.xs.inc | 283 + inc/CryptX_Mode_OFB.xs.inc | 98 + inc/CryptX_PK_DH.xs.inc | 426 + inc/CryptX_PK_DSA.xs.inc | 275 + inc/CryptX_PK_ECC.xs.inc | 390 + inc/CryptX_PK_RSA.xs.inc | 419 + inc/CryptX_PRNG.xs.inc | 144 + inc/CryptX_Stream_ChaCha.xs.inc | 91 + inc/CryptX_Stream_RC4.xs.inc | 77 + inc/CryptX_Stream_Sober128.xs.inc | 82 + lib/Crypt/AuthEnc.pm | 17 + lib/Crypt/AuthEnc/CCM.pm | 100 + lib/Crypt/AuthEnc/ChaCha20Poly1305.pm | 164 + lib/Crypt/AuthEnc/EAX.pm | 179 + lib/Crypt/AuthEnc/GCM.pm | 179 + lib/Crypt/AuthEnc/OCB.pm | 174 + lib/Crypt/Checksum.pm | 197 + lib/Crypt/Checksum/Adler32.pm | 121 + lib/Crypt/Checksum/CRC32.pm | 121 + lib/Crypt/Cipher.pm | 217 + lib/Crypt/Cipher/AES.pm | 121 + lib/Crypt/Cipher/Anubis.pm | 121 + lib/Crypt/Cipher/Blowfish.pm | 121 + lib/Crypt/Cipher/CAST5.pm | 121 + lib/Crypt/Cipher/Camellia.pm | 121 + lib/Crypt/Cipher/DES.pm | 121 + lib/Crypt/Cipher/DES_EDE.pm | 121 + lib/Crypt/Cipher/KASUMI.pm | 121 + lib/Crypt/Cipher/Khazad.pm | 121 + lib/Crypt/Cipher/MULTI2.pm | 121 + lib/Crypt/Cipher/Noekeon.pm | 121 + lib/Crypt/Cipher/RC2.pm | 121 + lib/Crypt/Cipher/RC5.pm | 121 + lib/Crypt/Cipher/RC6.pm | 121 + lib/Crypt/Cipher/SAFERP.pm | 121 + lib/Crypt/Cipher/SAFER_K128.pm | 121 + lib/Crypt/Cipher/SAFER_K64.pm | 121 + lib/Crypt/Cipher/SAFER_SK128.pm | 121 + lib/Crypt/Cipher/SAFER_SK64.pm | 121 + lib/Crypt/Cipher/SEED.pm | 121 + lib/Crypt/Cipher/Skipjack.pm | 121 + lib/Crypt/Cipher/Twofish.pm | 121 + lib/Crypt/Cipher/XTEA.pm | 121 + lib/Crypt/Digest.pm | 382 + lib/Crypt/Digest/BLAKE2b_160.pm | 229 + lib/Crypt/Digest/BLAKE2b_256.pm | 229 + lib/Crypt/Digest/BLAKE2b_384.pm | 229 + lib/Crypt/Digest/BLAKE2b_512.pm | 229 + lib/Crypt/Digest/BLAKE2s_128.pm | 229 + lib/Crypt/Digest/BLAKE2s_160.pm | 229 + lib/Crypt/Digest/BLAKE2s_224.pm | 229 + lib/Crypt/Digest/BLAKE2s_256.pm | 229 + lib/Crypt/Digest/CHAES.pm | 227 + lib/Crypt/Digest/MD2.pm | 227 + lib/Crypt/Digest/MD4.pm | 227 + lib/Crypt/Digest/MD5.pm | 227 + lib/Crypt/Digest/RIPEMD128.pm | 227 + lib/Crypt/Digest/RIPEMD160.pm | 227 + lib/Crypt/Digest/RIPEMD256.pm | 227 + lib/Crypt/Digest/RIPEMD320.pm | 227 + lib/Crypt/Digest/SHA1.pm | 227 + lib/Crypt/Digest/SHA224.pm | 227 + lib/Crypt/Digest/SHA256.pm | 227 + lib/Crypt/Digest/SHA384.pm | 227 + lib/Crypt/Digest/SHA3_224.pm | 227 + lib/Crypt/Digest/SHA3_256.pm | 227 + lib/Crypt/Digest/SHA3_384.pm | 227 + lib/Crypt/Digest/SHA3_512.pm | 227 + lib/Crypt/Digest/SHA512.pm | 227 + lib/Crypt/Digest/SHA512_224.pm | 227 + lib/Crypt/Digest/SHA512_256.pm | 227 + lib/Crypt/Digest/SHAKE.pm | 106 + lib/Crypt/Digest/Tiger192.pm | 227 + lib/Crypt/Digest/Whirlpool.pm | 227 + lib/Crypt/KeyDerivation.pm | 167 + lib/Crypt/Mac.pm | 53 + lib/Crypt/Mac/BLAKE2b.pm | 156 + lib/Crypt/Mac/BLAKE2s.pm | 156 + lib/Crypt/Mac/F9.pm | 156 + lib/Crypt/Mac/HMAC.pm | 160 + lib/Crypt/Mac/OMAC.pm | 158 + lib/Crypt/Mac/PMAC.pm | 158 + lib/Crypt/Mac/Pelican.pm | 156 + lib/Crypt/Mac/Poly1305.pm | 156 + lib/Crypt/Mac/XCBC.pm | 158 + lib/Crypt/Misc.pm | 363 + lib/Crypt/Mode.pm | 72 + lib/Crypt/Mode/CBC.pm | 108 + lib/Crypt/Mode/CFB.pm | 99 + lib/Crypt/Mode/CTR.pm | 106 + lib/Crypt/Mode/ECB.pm | 109 + lib/Crypt/Mode/OFB.pm | 99 + lib/Crypt/PK.pm | 33 + lib/Crypt/PK/DH.pm | 643 ++ lib/Crypt/PK/DSA.pm | 617 ++ lib/Crypt/PK/ECC.pm | 1398 +++ lib/Crypt/PK/RSA.pm | 939 ++ lib/Crypt/PRNG.pm | 283 + lib/Crypt/PRNG/ChaCha20.pm | 159 + lib/Crypt/PRNG/Fortuna.pm | 160 + lib/Crypt/PRNG/RC4.pm | 159 + lib/Crypt/PRNG/Sober128.pm | 159 + lib/Crypt/PRNG/Yarrow.pm | 158 + lib/Crypt/Stream/ChaCha.pm | 76 + lib/Crypt/Stream/RC4.pm | 68 + lib/Crypt/Stream/Sober128.pm | 71 + lib/CryptX.pm | 114 + lib/Math/BigInt/LTM.pm | 463 + ppport.h | 7748 +++++++++++++++++ src/Makefile | 165 + src/Makefile.nmake | 167 + src/ltc/ciphers/aes/aes.c | 760 ++ src/ltc/ciphers/aes/aes_tab.c | 1032 +++ src/ltc/ciphers/anubis.c | 1559 ++++ src/ltc/ciphers/blowfish.c | 595 ++ src/ltc/ciphers/camellia.c | 742 ++ src/ltc/ciphers/cast5.c | 721 ++ src/ltc/ciphers/des.c | 2085 +++++ src/ltc/ciphers/kasumi.c | 319 + src/ltc/ciphers/khazad.c | 856 ++ src/ltc/ciphers/kseed.c | 392 + src/ltc/ciphers/multi2.c | 321 + src/ltc/ciphers/noekeon.c | 345 + src/ltc/ciphers/rc2.c | 419 + src/ltc/ciphers/rc5.c | 323 + src/ltc/ciphers/rc6.c | 349 + src/ltc/ciphers/safer/safer.c | 495 ++ src/ltc/ciphers/safer/safer_tab.c | 66 + src/ltc/ciphers/safer/saferp.c | 569 ++ src/ltc/ciphers/skipjack.c | 344 + src/ltc/ciphers/twofish/twofish.c | 715 ++ src/ltc/ciphers/twofish/twofish_tab.c | 498 ++ src/ltc/ciphers/xtea.c | 278 + src/ltc/encauth/ccm/ccm_add_aad.c | 61 + src/ltc/encauth/ccm/ccm_add_nonce.c | 111 + src/ltc/encauth/ccm/ccm_done.c | 63 + src/ltc/encauth/ccm/ccm_init.c | 79 + src/ltc/encauth/ccm/ccm_memory.c | 405 + src/ltc/encauth/ccm/ccm_process.c | 86 + src/ltc/encauth/ccm/ccm_reset.c | 33 + .../chachapoly/chacha20poly1305_add_aad.c | 34 + .../chachapoly/chacha20poly1305_decrypt.c | 45 + .../chachapoly/chacha20poly1305_done.c | 42 + .../chachapoly/chacha20poly1305_encrypt.c | 44 + .../chachapoly/chacha20poly1305_init.c | 26 + .../chachapoly/chacha20poly1305_memory.c | 70 + .../chachapoly/chacha20poly1305_setiv.c | 64 + .../chacha20poly1305_setiv_rfc7905.c | 36 + src/ltc/encauth/eax/eax_addheader.c | 38 + src/ltc/encauth/eax/eax_decrypt.c | 50 + .../encauth/eax/eax_decrypt_verify_memory.c | 108 + src/ltc/encauth/eax/eax_done.c | 94 + src/ltc/encauth/eax/eax_encrypt.c | 51 + .../eax/eax_encrypt_authenticate_memory.c | 82 + src/ltc/encauth/eax/eax_init.c | 144 + src/ltc/encauth/gcm/gcm_add_aad.c | 124 + src/ltc/encauth/gcm/gcm_add_iv.c | 94 + src/ltc/encauth/gcm/gcm_done.c | 83 + src/ltc/encauth/gcm/gcm_gf_mult.c | 221 + src/ltc/encauth/gcm/gcm_init.c | 107 + src/ltc/encauth/gcm/gcm_memory.c | 108 + src/ltc/encauth/gcm/gcm_mult_h.c | 59 + src/ltc/encauth/gcm/gcm_process.c | 157 + src/ltc/encauth/gcm/gcm_reset.c | 44 + src/ltc/encauth/ocb3/ocb3_add_aad.c | 81 + src/ltc/encauth/ocb3/ocb3_decrypt.c | 86 + src/ltc/encauth/ocb3/ocb3_decrypt_last.c | 105 + .../encauth/ocb3/ocb3_decrypt_verify_memory.c | 112 + src/ltc/encauth/ocb3/ocb3_done.c | 92 + src/ltc/encauth/ocb3/ocb3_encrypt.c | 86 + .../ocb3/ocb3_encrypt_authenticate_memory.c | 87 + src/ltc/encauth/ocb3/ocb3_encrypt_last.c | 107 + src/ltc/encauth/ocb3/ocb3_init.c | 138 + src/ltc/encauth/ocb3/ocb3_int_aad_add_block.c | 49 + .../encauth/ocb3/ocb3_int_calc_offset_zero.c | 72 + src/ltc/encauth/ocb3/ocb3_int_ntz.c | 41 + src/ltc/encauth/ocb3/ocb3_int_xor_blocks.c | 40 + src/ltc/hashes/blake2b.c | 580 ++ src/ltc/hashes/blake2s.c | 555 ++ src/ltc/hashes/chc/chc.c | 302 + src/ltc/hashes/helper/hash_file.c | 55 + src/ltc/hashes/helper/hash_filehandle.c | 75 + src/ltc/hashes/helper/hash_memory.c | 71 + src/ltc/hashes/helper/hash_memory_multi.c | 90 + src/ltc/hashes/md2.c | 251 + src/ltc/hashes/md4.c | 307 + src/ltc/hashes/md5.c | 368 + src/ltc/hashes/rmd128.c | 410 + src/ltc/hashes/rmd160.c | 469 + src/ltc/hashes/rmd256.c | 431 + src/ltc/hashes/rmd320.c | 496 ++ src/ltc/hashes/sha1.c | 288 + src/ltc/hashes/sha2/sha224.c | 131 + src/ltc/hashes/sha2/sha256.c | 336 + src/ltc/hashes/sha2/sha384.c | 136 + src/ltc/hashes/sha2/sha512.c | 315 + src/ltc/hashes/sha2/sha512_224.c | 132 + src/ltc/hashes/sha2/sha512_256.c | 132 + src/ltc/hashes/sha3.c | 296 + src/ltc/hashes/sha3_test.c | 420 + src/ltc/hashes/tiger.c | 814 ++ src/ltc/hashes/whirl/whirl.c | 315 + src/ltc/hashes/whirl/whirltab.c | 587 ++ src/ltc/headers/tomcrypt.h | 93 + src/ltc/headers/tomcrypt_argchk.h | 44 + src/ltc/headers/tomcrypt_cfg.h | 268 + src/ltc/headers/tomcrypt_cipher.h | 998 +++ src/ltc/headers/tomcrypt_custom.h | 616 ++ src/ltc/headers/tomcrypt_hash.h | 521 ++ src/ltc/headers/tomcrypt_mac.h | 557 ++ src/ltc/headers/tomcrypt_macros.h | 438 + src/ltc/headers/tomcrypt_math.h | 547 ++ src/ltc/headers/tomcrypt_misc.h | 113 + src/ltc/headers/tomcrypt_pk.h | 749 ++ src/ltc/headers/tomcrypt_pkcs.h | 98 + src/ltc/headers/tomcrypt_prng.h | 222 + src/ltc/mac/blake2/blake2bmac.c | 61 + src/ltc/mac/blake2/blake2bmac_file.c | 79 + src/ltc/mac/blake2/blake2bmac_memory.c | 44 + src/ltc/mac/blake2/blake2bmac_memory_multi.c | 58 + src/ltc/mac/blake2/blake2smac.c | 61 + src/ltc/mac/blake2/blake2smac_file.c | 79 + src/ltc/mac/blake2/blake2smac_memory.c | 44 + src/ltc/mac/blake2/blake2smac_memory_multi.c | 58 + src/ltc/mac/f9/f9_done.c | 77 + src/ltc/mac/f9/f9_file.c | 93 + src/ltc/mac/f9/f9_init.c | 70 + src/ltc/mac/f9/f9_memory.c | 71 + src/ltc/mac/f9/f9_memory_multi.c | 90 + src/ltc/mac/f9/f9_process.c | 78 + src/ltc/mac/hmac/hmac_done.c | 109 + src/ltc/mac/hmac/hmac_file.c | 96 + src/ltc/mac/hmac/hmac_init.c | 110 + src/ltc/mac/hmac/hmac_memory.c | 88 + src/ltc/mac/hmac/hmac_memory_multi.c | 92 + src/ltc/mac/hmac/hmac_process.c | 43 + src/ltc/mac/omac/omac_done.c | 86 + src/ltc/mac/omac/omac_file.c | 93 + src/ltc/mac/omac/omac_init.c | 101 + src/ltc/mac/omac/omac_memory.c | 85 + src/ltc/mac/omac/omac_memory_multi.c | 90 + src/ltc/mac/omac/omac_process.c | 92 + src/ltc/mac/pelican/pelican.c | 166 + src/ltc/mac/pelican/pelican_memory.c | 59 + src/ltc/mac/pmac/pmac_done.c | 74 + src/ltc/mac/pmac/pmac_file.c | 94 + src/ltc/mac/pmac/pmac_init.c | 150 + src/ltc/mac/pmac/pmac_memory.c | 74 + src/ltc/mac/pmac/pmac_memory_multi.c | 89 + src/ltc/mac/pmac/pmac_ntz.c | 39 + src/ltc/mac/pmac/pmac_process.c | 100 + src/ltc/mac/pmac/pmac_shift_xor.c | 44 + src/ltc/mac/poly1305/poly1305.c | 264 + src/ltc/mac/poly1305/poly1305_file.c | 84 + src/ltc/mac/poly1305/poly1305_memory.c | 49 + src/ltc/mac/poly1305/poly1305_memory_multi.c | 63 + src/ltc/mac/xcbc/xcbc_done.c | 77 + src/ltc/mac/xcbc/xcbc_file.c | 93 + src/ltc/mac/xcbc/xcbc_init.c | 108 + src/ltc/mac/xcbc/xcbc_memory.c | 71 + src/ltc/mac/xcbc/xcbc_memory_multi.c | 90 + src/ltc/mac/xcbc/xcbc_process.c | 75 + src/ltc/math/fp/ltc_ecc_fp_mulmod.c | 1590 ++++ src/ltc/math/ltm_desc.c | 525 ++ src/ltc/math/multi.c | 62 + src/ltc/math/rand_bn.c | 71 + src/ltc/math/rand_prime.c | 90 + src/ltc/math/tfm_desc.c | 811 ++ src/ltc/misc/adler32.c | 139 + src/ltc/misc/base64/base64_decode.c | 198 + src/ltc/misc/base64/base64_encode.c | 126 + src/ltc/misc/burn_stack.c | 34 + src/ltc/misc/crc32.c | 210 + src/ltc/misc/crypt/crypt.c | 486 ++ src/ltc/misc/crypt/crypt_argchk.c | 29 + src/ltc/misc/crypt/crypt_cipher_descriptor.c | 27 + src/ltc/misc/crypt/crypt_cipher_is_valid.c | 36 + src/ltc/misc/crypt/crypt_find_cipher.c | 41 + src/ltc/misc/crypt/crypt_find_cipher_any.c | 50 + src/ltc/misc/crypt/crypt_find_cipher_id.c | 40 + src/ltc/misc/crypt/crypt_find_hash.c | 40 + src/ltc/misc/crypt/crypt_find_hash_any.c | 49 + src/ltc/misc/crypt/crypt_find_hash_id.c | 40 + src/ltc/misc/crypt/crypt_find_hash_oid.c | 35 + src/ltc/misc/crypt/crypt_find_prng.c | 41 + src/ltc/misc/crypt/crypt_fsa.c | 58 + src/ltc/misc/crypt/crypt_hash_descriptor.c | 27 + src/ltc/misc/crypt/crypt_hash_is_valid.c | 36 + src/ltc/misc/crypt/crypt_inits.c | 44 + src/ltc/misc/crypt/crypt_ltc_mp_descriptor.c | 13 + src/ltc/misc/crypt/crypt_prng_descriptor.c | 26 + src/ltc/misc/crypt/crypt_prng_is_valid.c | 36 + src/ltc/misc/crypt/crypt_register_cipher.c | 54 + src/ltc/misc/crypt/crypt_register_hash.c | 54 + src/ltc/misc/crypt/crypt_register_prng.c | 54 + src/ltc/misc/crypt/crypt_unregister_cipher.c | 45 + src/ltc/misc/crypt/crypt_unregister_hash.c | 44 + src/ltc/misc/crypt/crypt_unregister_prng.c | 44 + src/ltc/misc/error_to_string.c | 80 + src/ltc/misc/hkdf/hkdf.c | 142 + src/ltc/misc/mem_neq.c | 60 + src/ltc/misc/pk_get_oid.c | 57 + src/ltc/misc/pkcs5/pkcs_5_1.c | 189 + src/ltc/misc/pkcs5/pkcs_5_2.c | 129 + src/ltc/misc/zeromem.c | 34 + src/ltc/modes/cbc/cbc_decrypt.c | 97 + src/ltc/modes/cbc/cbc_done.c | 42 + src/ltc/modes/cbc/cbc_encrypt.c | 98 + src/ltc/modes/cbc/cbc_getiv.c | 46 + src/ltc/modes/cbc/cbc_setiv.c | 44 + src/ltc/modes/cbc/cbc_start.c | 62 + src/ltc/modes/cfb/cfb_decrypt.c | 67 + src/ltc/modes/cfb/cfb_done.c | 42 + src/ltc/modes/cfb/cfb_encrypt.c | 65 + src/ltc/modes/cfb/cfb_getiv.c | 46 + src/ltc/modes/cfb/cfb_setiv.c | 52 + src/ltc/modes/cfb/cfb_start.c | 65 + src/ltc/modes/ctr/ctr_decrypt.c | 42 + src/ltc/modes/ctr/ctr_done.c | 42 + src/ltc/modes/ctr/ctr_encrypt.c | 112 + src/ltc/modes/ctr/ctr_getiv.c | 46 + src/ltc/modes/ctr/ctr_setiv.c | 56 + src/ltc/modes/ctr/ctr_start.c | 101 + src/ltc/modes/ecb/ecb_decrypt.c | 61 + src/ltc/modes/ecb/ecb_done.c | 42 + src/ltc/modes/ecb/ecb_encrypt.c | 61 + src/ltc/modes/ecb/ecb_start.c | 48 + src/ltc/modes/ofb/ofb_decrypt.c | 43 + src/ltc/modes/ofb/ofb_done.c | 42 + src/ltc/modes/ofb/ofb_encrypt.c | 60 + src/ltc/modes/ofb/ofb_getiv.c | 46 + src/ltc/modes/ofb/ofb_setiv.c | 52 + src/ltc/modes/ofb/ofb_start.c | 60 + .../pk/asn1/der/bit/der_decode_bit_string.c | 102 + .../asn1/der/bit/der_decode_raw_bit_string.c | 106 + .../pk/asn1/der/bit/der_encode_bit_string.c | 89 + .../asn1/der/bit/der_encode_raw_bit_string.c | 92 + .../pk/asn1/der/bit/der_length_bit_string.c | 54 + .../pk/asn1/der/boolean/der_decode_boolean.c | 47 + .../pk/asn1/der/boolean/der_encode_boolean.c | 51 + .../pk/asn1/der/boolean/der_length_boolean.c | 35 + .../pk/asn1/der/choice/der_decode_choice.c | 225 + .../der_decode_generalizedtime.c | 146 + .../der_encode_generalizedtime.c | 110 + .../der_length_generalizedtime.c | 60 + .../pk/asn1/der/ia5/der_decode_ia5_string.c | 96 + .../pk/asn1/der/ia5/der_encode_ia5_string.c | 85 + .../pk/asn1/der/ia5/der_length_ia5_string.c | 194 + .../pk/asn1/der/integer/der_decode_integer.c | 110 + .../pk/asn1/der/integer/der_encode_integer.c | 130 + .../pk/asn1/der/integer/der_length_integer.c | 81 + .../der_decode_object_identifier.c | 99 + .../der_encode_object_identifier.c | 111 + .../der_length_object_identifier.c | 89 + .../asn1/der/octet/der_decode_octet_string.c | 91 + .../asn1/der/octet/der_encode_octet_string.c | 86 + .../asn1/der/octet/der_length_octet_string.c | 53 + .../der_decode_printable_string.c | 96 + .../der_encode_printable_string.c | 85 + .../der_length_printable_string.c | 166 + .../der/sequence/der_decode_sequence_ex.c | 339 + .../der/sequence/der_decode_sequence_flexi.c | 475 + .../der/sequence/der_decode_sequence_multi.c | 147 + .../der_decode_subject_public_key_info.c | 120 + .../der/sequence/der_encode_sequence_ex.c | 244 + .../der/sequence/der_encode_sequence_multi.c | 151 + .../der_encode_subject_public_key_info.c | 69 + .../asn1/der/sequence/der_length_sequence.c | 214 + .../pk/asn1/der/sequence/der_sequence_free.c | 65 + src/ltc/pk/asn1/der/set/der_encode_set.c | 110 + src/ltc/pk/asn1/der/set/der_encode_setof.c | 163 + .../short_integer/der_decode_short_integer.c | 68 + .../short_integer/der_encode_short_integer.c | 97 + .../short_integer/der_length_short_integer.c | 70 + .../der_decode_teletex_string.c | 95 + .../der_length_teletex_string.c | 210 + .../pk/asn1/der/utctime/der_decode_utctime.c | 127 + .../pk/asn1/der/utctime/der_encode_utctime.c | 83 + .../pk/asn1/der/utctime/der_length_utctime.c | 46 + .../pk/asn1/der/utf8/der_decode_utf8_string.c | 111 + .../pk/asn1/der/utf8/der_encode_utf8_string.c | 106 + .../pk/asn1/der/utf8/der_length_utf8_string.c | 104 + src/ltc/pk/dh/dh.c | 505 ++ src/ltc/pk/dh/dh_static.c | 165 + src/ltc/pk/dh/dh_static.h | 129 + src/ltc/pk/dh/dh_sys.c | 487 ++ src/ltc/pk/dsa/dsa_decrypt_key.c | 140 + src/ltc/pk/dsa/dsa_encrypt_key.c | 132 + src/ltc/pk/dsa/dsa_export.c | 118 + src/ltc/pk/dsa/dsa_free.c | 34 + src/ltc/pk/dsa/dsa_import.c | 138 + src/ltc/pk/dsa/dsa_import_radix.c | 67 + src/ltc/pk/dsa/dsa_make_key.c | 268 + src/ltc/pk/dsa/dsa_shared_secret.c | 72 + src/ltc/pk/dsa/dsa_sign_hash.c | 154 + src/ltc/pk/dsa/dsa_verify_hash.c | 129 + src/ltc/pk/dsa/dsa_verify_key.c | 100 + src/ltc/pk/ecc/ecc.c | 426 + src/ltc/pk/ecc/ecc_ansi_x963_export.c | 76 + src/ltc/pk/ecc/ecc_ansi_x963_import.c | 106 + src/ltc/pk/ecc/ecc_decrypt_key.c | 148 + src/ltc/pk/ecc/ecc_dp_clear.c | 36 + src/ltc/pk/ecc/ecc_dp_fill_from_sets.c | 76 + src/ltc/pk/ecc/ecc_dp_from_oid.c | 86 + src/ltc/pk/ecc/ecc_dp_from_params.c | 86 + src/ltc/pk/ecc/ecc_dp_init.c | 36 + src/ltc/pk/ecc/ecc_dp_set.c | 100 + src/ltc/pk/ecc/ecc_encrypt_key.c | 134 + src/ltc/pk/ecc/ecc_export.c | 80 + src/ltc/pk/ecc/ecc_export_full.c | 182 + src/ltc/pk/ecc/ecc_export_raw.c | 63 + src/ltc/pk/ecc/ecc_free.c | 38 + src/ltc/pk/ecc/ecc_get_size.c | 42 + src/ltc/pk/ecc/ecc_import.c | 126 + src/ltc/pk/ecc/ecc_import_full.c | 154 + src/ltc/pk/ecc/ecc_import_pkcs8.c | 161 + src/ltc/pk/ecc/ecc_import_raw.c | 100 + src/ltc/pk/ecc/ecc_make_key.c | 141 + src/ltc/pk/ecc/ecc_shared_secret.c | 95 + src/ltc/pk/ecc/ecc_sign_hash.c | 165 + src/ltc/pk/ecc/ecc_sizes.c | 46 + src/ltc/pk/ecc/ecc_verify_hash.c | 207 + src/ltc/pk/ecc/ecc_verify_key.c | 77 + src/ltc/pk/ecc/ltc_ecc_export_point.c | 64 + src/ltc/pk/ecc/ltc_ecc_import_point.c | 72 + src/ltc/pk/ecc/ltc_ecc_is_point.c | 75 + src/ltc/pk/ecc/ltc_ecc_is_point_at_infinity.c | 50 + src/ltc/pk/ecc/ltc_ecc_is_valid_idx.c | 44 + src/ltc/pk/ecc/ltc_ecc_map.c | 81 + src/ltc/pk/ecc/ltc_ecc_mul2add.c | 211 + src/ltc/pk/ecc/ltc_ecc_mulmod.c | 234 + src/ltc/pk/ecc/ltc_ecc_mulmod_timing.c | 178 + src/ltc/pk/ecc/ltc_ecc_points.c | 58 + src/ltc/pk/ecc/ltc_ecc_projective_add_point.c | 217 + src/ltc/pk/ecc/ltc_ecc_projective_dbl_point.c | 200 + src/ltc/pk/pkcs1/pkcs_1_i2osp.c | 51 + src/ltc/pk/pkcs1/pkcs_1_mgf1.c | 108 + src/ltc/pk/pkcs1/pkcs_1_oaep_decode.c | 187 + src/ltc/pk/pkcs1/pkcs_1_oaep_encode.c | 173 + src/ltc/pk/pkcs1/pkcs_1_os2ip.c | 36 + src/ltc/pk/pkcs1/pkcs_1_pss_decode.c | 178 + src/ltc/pk/pkcs1/pkcs_1_pss_encode.c | 176 + src/ltc/pk/pkcs1/pkcs_1_v1_5_decode.c | 114 + src/ltc/pk/pkcs1/pkcs_1_v1_5_encode.c | 111 + src/ltc/pk/rsa/rsa_decrypt_key.c | 105 + src/ltc/pk/rsa/rsa_encrypt_key.c | 102 + src/ltc/pk/rsa/rsa_export.c | 99 + src/ltc/pk/rsa/rsa_exptmod.c | 183 + src/ltc/pk/rsa/rsa_free.c | 34 + src/ltc/pk/rsa/rsa_get_size.c | 42 + src/ltc/pk/rsa/rsa_import.c | 130 + src/ltc/pk/rsa/rsa_import_pkcs8.c | 151 + src/ltc/pk/rsa/rsa_import_radix.c | 64 + src/ltc/pk/rsa/rsa_import_x509.c | 120 + src/ltc/pk/rsa/rsa_make_key.c | 112 + src/ltc/pk/rsa/rsa_sign_hash.c | 134 + src/ltc/pk/rsa/rsa_sign_saltlen_get.c | 49 + src/ltc/pk/rsa/rsa_verify_hash.c | 180 + src/ltc/prngs/chacha20.c | 242 + src/ltc/prngs/fortuna.c | 449 + src/ltc/prngs/rc4.c | 244 + src/ltc/prngs/rng_get_bytes.c | 159 + src/ltc/prngs/rng_make_prng.c | 69 + src/ltc/prngs/sober128.c | 244 + src/ltc/prngs/sprng.c | 161 + src/ltc/prngs/yarrow.c | 351 + src/ltc/stream/chacha/chacha_crypt.c | 95 + src/ltc/stream/chacha/chacha_done.c | 26 + src/ltc/stream/chacha/chacha_ivctr32.c | 43 + src/ltc/stream/chacha/chacha_ivctr64.c | 43 + src/ltc/stream/chacha/chacha_keystream.c | 34 + src/ltc/stream/chacha/chacha_setup.c | 61 + src/ltc/stream/rc4/rc4.c | 107 + src/ltc/stream/sober128/sober128.c | 344 + src/ltc/stream/sober128/sober128tab.c | 167 + src/ltm/bn_error.c | 47 + src/ltm/bn_fast_mp_invmod.c | 148 + src/ltm/bn_fast_mp_montgomery_reduce.c | 172 + src/ltm/bn_fast_s_mp_mul_digs.c | 107 + src/ltm/bn_fast_s_mp_mul_high_digs.c | 98 + src/ltm/bn_fast_s_mp_sqr.c | 114 + src/ltm/bn_mp_2expt.c | 48 + src/ltm/bn_mp_abs.c | 43 + src/ltm/bn_mp_add.c | 53 + src/ltm/bn_mp_add_d.c | 112 + src/ltm/bn_mp_addmod.c | 41 + src/ltm/bn_mp_and.c | 57 + src/ltm/bn_mp_clamp.c | 44 + src/ltm/bn_mp_clear.c | 44 + src/ltm/bn_mp_clear_multi.c | 34 + src/ltm/bn_mp_cmp.c | 43 + src/ltm/bn_mp_cmp_d.c | 44 + src/ltm/bn_mp_cmp_mag.c | 55 + src/ltm/bn_mp_cnt_lsb.c | 53 + src/ltm/bn_mp_copy.c | 68 + src/ltm/bn_mp_count_bits.c | 45 + src/ltm/bn_mp_div.c | 295 + src/ltm/bn_mp_div_2.c | 68 + src/ltm/bn_mp_div_2d.c | 97 + src/ltm/bn_mp_div_3.c | 79 + src/ltm/bn_mp_div_d.c | 115 + src/ltm/bn_mp_dr_is_modulus.c | 43 + src/ltm/bn_mp_dr_reduce.c | 96 + src/ltm/bn_mp_dr_setup.c | 32 + src/ltm/bn_mp_exch.c | 34 + src/ltm/bn_mp_export.c | 88 + src/ltm/bn_mp_expt_d.c | 28 + src/ltm/bn_mp_expt_d_ex.c | 83 + src/ltm/bn_mp_exptmod.c | 112 + src/ltm/bn_mp_exptmod_fast.c | 321 + src/ltm/bn_mp_exteuclid.c | 82 + src/ltm/bn_mp_fread.c | 67 + src/ltm/bn_mp_fwrite.c | 52 + src/ltm/bn_mp_gcd.c | 105 + src/ltm/bn_mp_get_int.c | 45 + src/ltm/bn_mp_get_long.c | 41 + src/ltm/bn_mp_get_long_long.c | 41 + src/ltm/bn_mp_grow.c | 57 + src/ltm/bn_mp_import.c | 73 + src/ltm/bn_mp_init.c | 46 + src/ltm/bn_mp_init_copy.c | 32 + src/ltm/bn_mp_init_multi.c | 59 + src/ltm/bn_mp_init_set.c | 32 + src/ltm/bn_mp_init_set_int.c | 31 + src/ltm/bn_mp_init_size.c | 48 + src/ltm/bn_mp_invmod.c | 43 + src/ltm/bn_mp_invmod_slow.c | 175 + src/ltm/bn_mp_is_square.c | 109 + src/ltm/bn_mp_jacobi.c | 117 + src/ltm/bn_mp_karatsuba_mul.c | 167 + src/ltm/bn_mp_karatsuba_sqr.c | 121 + src/ltm/bn_mp_lcm.c | 60 + src/ltm/bn_mp_lshd.c | 67 + src/ltm/bn_mp_mod.c | 48 + src/ltm/bn_mp_mod_2d.c | 55 + src/ltm/bn_mp_mod_d.c | 27 + src/ltm/bn_mp_montgomery_calc_normalization.c | 59 + src/ltm/bn_mp_montgomery_reduce.c | 118 + src/ltm/bn_mp_montgomery_setup.c | 59 + src/ltm/bn_mp_mul.c | 67 + src/ltm/bn_mp_mul_2.c | 82 + src/ltm/bn_mp_mul_2d.c | 85 + src/ltm/bn_mp_mul_d.c | 79 + src/ltm/bn_mp_mulmod.c | 40 + src/ltm/bn_mp_n_root.c | 30 + src/ltm/bn_mp_n_root_ex.c | 132 + src/ltm/bn_mp_neg.c | 40 + src/ltm/bn_mp_or.c | 50 + src/ltm/bn_mp_prime_fermat.c | 62 + src/ltm/bn_mp_prime_is_divisible.c | 50 + src/ltm/bn_mp_prime_is_prime.c | 83 + src/ltm/bn_mp_prime_miller_rabin.c | 103 + src/ltm/bn_mp_prime_next_prime.c | 170 + src/ltm/bn_mp_prime_rabin_miller_trials.c | 52 + src/ltm/bn_mp_prime_random_ex.c | 124 + src/ltm/bn_mp_radix_size.c | 78 + src/ltm/bn_mp_radix_smap.c | 24 + src/ltm/bn_mp_rand.c | 55 + src/ltm/bn_mp_read_radix.c | 85 + src/ltm/bn_mp_read_signed_bin.c | 41 + src/ltm/bn_mp_read_unsigned_bin.c | 55 + src/ltm/bn_mp_reduce.c | 100 + src/ltm/bn_mp_reduce_2k.c | 63 + src/ltm/bn_mp_reduce_2k_l.c | 64 + src/ltm/bn_mp_reduce_2k_setup.c | 47 + src/ltm/bn_mp_reduce_2k_setup_l.c | 44 + src/ltm/bn_mp_reduce_is_2k.c | 52 + src/ltm/bn_mp_reduce_is_2k_l.c | 44 + src/ltm/bn_mp_reduce_setup.c | 34 + src/ltm/bn_mp_rshd.c | 72 + src/ltm/bn_mp_set.c | 29 + src/ltm/bn_mp_set_int.c | 48 + src/ltm/bn_mp_set_long.c | 24 + src/ltm/bn_mp_set_long_long.c | 24 + src/ltm/bn_mp_shrink.c | 41 + src/ltm/bn_mp_signed_bin_size.c | 27 + src/ltm/bn_mp_sqr.c | 60 + src/ltm/bn_mp_sqrmod.c | 41 + src/ltm/bn_mp_sqrt.c | 81 + src/ltm/bn_mp_sqrtmod_prime.c | 124 + src/ltm/bn_mp_sub.c | 59 + src/ltm/bn_mp_sub_d.c | 93 + src/ltm/bn_mp_submod.c | 42 + src/ltm/bn_mp_to_signed_bin.c | 33 + src/ltm/bn_mp_to_signed_bin_n.c | 31 + src/ltm/bn_mp_to_unsigned_bin.c | 48 + src/ltm/bn_mp_to_unsigned_bin_n.c | 31 + src/ltm/bn_mp_toom_mul.c | 286 + src/ltm/bn_mp_toom_sqr.c | 228 + src/ltm/bn_mp_toradix.c | 75 + src/ltm/bn_mp_toradix_n.c | 88 + src/ltm/bn_mp_unsigned_bin_size.c | 28 + src/ltm/bn_mp_xor.c | 51 + src/ltm/bn_mp_zero.c | 36 + src/ltm/bn_prime_tab.c | 61 + src/ltm/bn_reverse.c | 39 + src/ltm/bn_s_mp_add.c | 109 + src/ltm/bn_s_mp_exptmod.c | 252 + src/ltm/bn_s_mp_mul_digs.c | 90 + src/ltm/bn_s_mp_mul_high_digs.c | 81 + src/ltm/bn_s_mp_sqr.c | 84 + src/ltm/bn_s_mp_sub.c | 89 + src/ltm/bncore.c | 36 + src/ltm/tommath.h | 578 ++ src/ltm/tommath_class.h | 1057 +++ src/ltm/tommath_private.h | 123 + src/ltm/tommath_superclass.h | 76 + t/001_compile.t | 73 + t/002_all_pm.t | 19 + t/003_all_pm_pod.t | 15 + t/auth_enc_ccm.t | 25 + t/auth_enc_ccm_test_vector_ltc.t | 65 + t/auth_enc_chacha20poly1305.t | 55 + t/auth_enc_eax.t | 60 + t/auth_enc_eax_test_vector_ltc.t | 125 + t/auth_enc_gcm.t | 58 + t/auth_enc_gcm_test_vector_ltc.t | 118 + t/auth_enc_ocb.t | 46 + t/auth_enc_ocb_test_vectors_ietf.t | 144 + t/checksum.t | 47 + t/cipher_aes.t | 65 + t/cipher_aes_test_vectors_bc.t | 50 + t/cipher_anubis.t | 65 + t/cipher_blowfish.t | 65 + t/cipher_camellia.t | 65 + t/cipher_cast5.t | 65 + t/cipher_des.t | 65 + t/cipher_des_ede.t | 65 + t/cipher_kasumi.t | 65 + t/cipher_khazad.t | 65 + t/cipher_multi2.t | 75 + t/cipher_multi2_rounds.t | 572 ++ t/cipher_noekeon.t | 65 + t/cipher_rc2.t | 65 + t/cipher_rc5.t | 75 + t/cipher_rc6.t | 65 + t/cipher_safer_k128.t | 75 + t/cipher_safer_k64.t | 75 + t/cipher_safer_sk128.t | 75 + t/cipher_safer_sk64.t | 75 + t/cipher_saferp.t | 65 + t/cipher_seed.t | 65 + t/cipher_seed_test_vectors_bc.t | 29 + t/cipher_skipjack.t | 65 + t/cipher_stream.t | 42 + t/cipher_test_vectors_ltc.t | 2190 +++++ t/cipher_test_vectors_openssl.t | 389 + t/cipher_twofish.t | 65 + t/cipher_twofish_test_vectors_bc.t | 27 + t/cipher_xtea.t | 65 + t/cipher_xtea_test_vectors_bc.t | 28 + t/crypt-misc.t | 56 + t/data/binary-test.file | Bin 0 -> 5000 bytes t/data/cryptx_priv_dh1.bin | Bin 0 -> 529 bytes t/data/cryptx_priv_dh2.bin | Bin 0 -> 529 bytes t/data/cryptx_priv_dh_pg1.bin | Bin 0 -> 791 bytes t/data/cryptx_priv_dh_pg2.bin | Bin 0 -> 791 bytes t/data/cryptx_priv_dsa1.der | Bin 0 -> 855 bytes t/data/cryptx_priv_dsa1.pem | 18 + t/data/cryptx_priv_dsa2.der | Bin 0 -> 853 bytes t/data/cryptx_priv_dsa2.pem | 18 + t/data/cryptx_priv_ecc1.der | Bin 0 -> 279 bytes t/data/cryptx_priv_ecc1.pem | 8 + t/data/cryptx_priv_ecc1_OLD.der | Bin 0 -> 113 bytes t/data/cryptx_priv_ecc1_OLD.pem | 5 + t/data/cryptx_priv_ecc2.der | Bin 0 -> 279 bytes t/data/cryptx_priv_ecc2.pem | 8 + t/data/cryptx_priv_ecc2_OLD.der | Bin 0 -> 113 bytes t/data/cryptx_priv_ecc2_OLD.pem | 5 + t/data/cryptx_priv_rsa1.der | Bin 0 -> 1190 bytes t/data/cryptx_priv_rsa1.pem | 24 + t/data/cryptx_priv_rsa2.der | Bin 0 -> 1190 bytes t/data/cryptx_priv_rsa2.pem | 24 + t/data/cryptx_pub_dh1.bin | Bin 0 -> 269 bytes t/data/cryptx_pub_dh2.bin | Bin 0 -> 269 bytes t/data/cryptx_pub_dh_pg1.bin | Bin 0 -> 531 bytes t/data/cryptx_pub_dh_pg2.bin | Bin 0 -> 531 bytes t/data/cryptx_pub_dsa1.der | Bin 0 -> 842 bytes t/data/cryptx_pub_dsa1.pem | 18 + t/data/cryptx_pub_dsa2.der | Bin 0 -> 840 bytes t/data/cryptx_pub_dsa2.pem | 18 + t/data/cryptx_pub_ecc1.der | Bin 0 -> 248 bytes t/data/cryptx_pub_ecc1.pem | 8 + t/data/cryptx_pub_ecc1_OLD.der | Bin 0 -> 78 bytes t/data/cryptx_pub_ecc1_OLD.pem | 5 + t/data/cryptx_pub_ecc2.der | Bin 0 -> 248 bytes t/data/cryptx_pub_ecc2.pem | 8 + t/data/cryptx_pub_ecc2_OLD.der | Bin 0 -> 78 bytes t/data/cryptx_pub_ecc2_OLD.pem | 5 + t/data/cryptx_pub_rsa1.der | Bin 0 -> 294 bytes t/data/cryptx_pub_rsa1.pem | 9 + t/data/cryptx_pub_rsa2.der | Bin 0 -> 294 bytes t/data/cryptx_pub_rsa2.pem | 9 + t/data/dsa-aes128.pem | 15 + t/data/dsa-aes192.pem | 15 + t/data/dsa-aes256.pem | 15 + t/data/dsa-camellia128.pem | 15 + t/data/dsa-camellia192.pem | 15 + t/data/dsa-camellia256.pem | 15 + t/data/dsa-des.pem | 15 + t/data/dsa-des3.pem | 15 + t/data/dsa-param.pem | 9 + t/data/dsa-seed.pem | 15 + t/data/ec-aes128.pem | 11 + t/data/ec-aes192.pem | 10 + t/data/ec-aes256.pem | 11 + t/data/ec-camellia128.pem | 12 + t/data/ec-camellia192.pem | 11 + t/data/ec-camellia256.pem | 16 + t/data/ec-des.pem | 10 + t/data/ec-des3.pem | 10 + t/data/ec-seed.pem | 11 + t/data/jwk_ec-priv1.json | 7 + t/data/jwk_ec-pub.json | 6 + t/data/jwk_ec-pub1.json | 6 + t/data/jwk_rsa-priv.json | 13 + t/data/jwk_rsa-priv1.json | 11 + t/data/jwk_rsa-pub1.json | 5 + t/data/openssl_dsa1.der | Bin 0 -> 857 bytes t/data/openssl_dsa1.pem | 20 + t/data/openssl_dsa2.der | Bin 0 -> 858 bytes t/data/openssl_dsa2.pem | 20 + t/data/openssl_ec-short.der | Bin 0 -> 121 bytes t/data/openssl_ec-short.pem | 5 + t/data/openssl_ec-short.pub.der | Bin 0 -> 91 bytes t/data/openssl_ec-short.pub.pem | 4 + t/data/openssl_ec1.key.pem | 23 + t/data/openssl_ec1.pri.der | Bin 0 -> 510 bytes t/data/openssl_ec1.pri.pem | 13 + t/data/openssl_ec1.pric.der | Bin 0 -> 414 bytes t/data/openssl_ec1.pric.pem | 11 + t/data/openssl_ec1.pub.der | Bin 0 -> 464 bytes t/data/openssl_ec1.pub.pem | 12 + t/data/openssl_ec1.pubc.der | Bin 0 -> 368 bytes t/data/openssl_ec1.pubc.pem | 10 + t/data/openssl_rsa1.der | Bin 0 -> 609 bytes t/data/openssl_rsa1.pem | 15 + t/data/openssl_rsa1.pubonly.der | Bin 0 -> 162 bytes t/data/openssl_rsa1.pubonly.pem | 6 + t/data/openssl_rsa2.der | Bin 0 -> 610 bytes t/data/openssl_rsa2.pem | 15 + t/data/openssl_rsa2.pubonly.der | Bin 0 -> 162 bytes t/data/openssl_rsa2.pubonly.pem | 6 + t/data/pkcs8.ec-priv-nopass.der | Bin 0 -> 308 bytes t/data/pkcs8.ec-priv-nopass.pem | 9 + t/data/pkcs8.ec-priv-pass.der | Bin 0 -> 350 bytes t/data/pkcs8.ec-priv-pass.pem | 10 + t/data/pkcs8.ec-short-priv-nopass.der | Bin 0 -> 113 bytes t/data/pkcs8.ec-short-priv-nopass.pem | 5 + t/data/pkcs8.ec-short-priv-pass.der | Bin 0 -> 155 bytes t/data/pkcs8.ec-short-priv-pass.pem | 6 + t/data/pkcs8.rsa-priv-nopass.der | Bin 0 -> 634 bytes t/data/pkcs8.rsa-priv-nopass.pem | 16 + t/data/pkcs8.rsa-priv-pass.der | Bin 0 -> 678 bytes t/data/pkcs8.rsa-priv-pass.pem | 17 + t/data/rsa-aes128.pem | 18 + t/data/rsa-aes192.pem | 18 + t/data/rsa-aes256.pem | 18 + t/data/rsa-camellia128.pem | 18 + t/data/rsa-camellia192.pem | 18 + t/data/rsa-camellia256.pem | 18 + t/data/rsa-des.pem | 18 + t/data/rsa-des3.pem | 18 + t/data/rsa-seed.pem | 18 + t/data/ssh/ssh_dsa_1024 | 12 + t/data/ssh/ssh_dsa_1024.pub | 1 + t/data/ssh/ssh_dsa_1024.pub.pkcs8 | 12 + t/data/ssh/ssh_dsa_1024.pub.rfc4716 | 12 + t/data/ssh/ssh_ecdsa_256 | 5 + t/data/ssh/ssh_ecdsa_256.pub | 1 + t/data/ssh/ssh_ecdsa_256.pub.pkcs8 | 9 + t/data/ssh/ssh_ecdsa_256.pub.rfc4716 | 6 + t/data/ssh/ssh_ecdsa_384 | 6 + t/data/ssh/ssh_ecdsa_384.pub | 1 + t/data/ssh/ssh_ecdsa_384.pub.pkcs8 | 12 + t/data/ssh/ssh_ecdsa_384.pub.rfc4716 | 6 + t/data/ssh/ssh_ecdsa_521 | 7 + t/data/ssh/ssh_ecdsa_521.pub | 1 + t/data/ssh/ssh_ecdsa_521.pub.pkcs8 | 15 + t/data/ssh/ssh_ecdsa_521.pub.rfc4716 | 7 + t/data/ssh/ssh_rsa_1024 | 15 + t/data/ssh/ssh_rsa_1024.pub | 1 + t/data/ssh/ssh_rsa_1024.pub.pem | 5 + t/data/ssh/ssh_rsa_1024.pub.pkcs8 | 6 + t/data/ssh/ssh_rsa_1024.pub.rfc4716 | 6 + t/data/ssh/ssh_rsa_1024_passwd | 18 + t/data/ssh/ssh_rsa_1536 | 21 + t/data/ssh/ssh_rsa_1536.pub | 1 + t/data/ssh/ssh_rsa_1536.pub.pem | 7 + t/data/ssh/ssh_rsa_1536.pub.pkcs8 | 7 + t/data/ssh/ssh_rsa_1536.pub.rfc4716 | 8 + t/data/ssh/ssh_rsa_1536_passwd | 24 + t/data/ssh/ssh_rsa_2048 | 27 + t/data/ssh/ssh_rsa_2048.pub | 1 + t/data/ssh/ssh_rsa_2048.pub.pem | 8 + t/data/ssh/ssh_rsa_2048.pub.pkcs8 | 9 + t/data/ssh/ssh_rsa_2048.pub.rfc4716 | 9 + t/data/ssh/ssh_rsa_2048_passwd | 30 + t/data/ssh/ssh_rsa_4096 | 51 + t/data/ssh/ssh_rsa_4096.pub | 1 + t/data/ssh/ssh_rsa_4096.pub.pem | 13 + t/data/ssh/ssh_rsa_4096.pub.pkcs8 | 14 + t/data/ssh/ssh_rsa_4096.pub.rfc4716 | 14 + t/data/ssh/ssh_rsa_4096_passwd | 54 + t/data/ssh/ssh_rsa_768 | 12 + t/data/ssh/ssh_rsa_768.pub | 1 + t/data/ssh/ssh_rsa_768.pub.pem | 5 + t/data/ssh/ssh_rsa_768.pub.pkcs8 | 5 + t/data/ssh/ssh_rsa_768.pub.rfc4716 | 6 + t/data/ssh/ssh_rsa_768_passwd | 15 + t/data/ssh/ssh_rsa_8192 | 99 + t/data/ssh/ssh_rsa_8192.pub | 1 + t/data/ssh/ssh_rsa_8192.pub.pem | 24 + t/data/ssh/ssh_rsa_8192.pub.pkcs8 | 25 + t/data/ssh/ssh_rsa_8192.pub.rfc4716 | 23 + t/data/ssh/ssh_rsa_8192_passwd | 102 + t/data/text-CR.file | 1 + t/data/text-CRLF.file | 19 + t/data/text-LF.file | 19 + t/digest_blake2b_160.t | 105 + t/digest_blake2b_256.t | 105 + t/digest_blake2b_384.t | 105 + t/digest_blake2b_512.t | 105 + t/digest_blake2s_128.t | 105 + t/digest_blake2s_160.t | 105 + t/digest_blake2s_224.t | 105 + t/digest_blake2s_256.t | 105 + t/digest_chaes.t | 105 + t/digest_md2.t | 105 + t/digest_md4.t | 105 + t/digest_md5.t | 105 + t/digest_ripemd128.t | 105 + t/digest_ripemd160.t | 105 + t/digest_ripemd256.t | 105 + t/digest_ripemd320.t | 105 + t/digest_sha1.t | 105 + t/digest_sha224.t | 105 + t/digest_sha256.t | 105 + t/digest_sha384.t | 105 + t/digest_sha3_224.t | 105 + t/digest_sha3_256.t | 105 + t/digest_sha3_384.t | 105 + t/digest_sha3_512.t | 105 + t/digest_sha512.t | 105 + t/digest_sha512_224.t | 105 + t/digest_sha512_256.t | 105 + t/digest_shake.t | 53 + t/digest_test_vectors_ltc.t | 1815 ++++ t/digest_tiger192.t | 105 + t/digest_whirlpool.t | 105 + t/jwk.t | 249 + t/key_derivation.t | 138 + t/mac_blake2b.t | 45 + t/mac_blake2s.t | 45 + t/mac_f9.t | 81 + t/mac_hmac.t | 81 + t/mac_hmac_test_vectors_ltc.t | 1826 ++++ t/mac_omac.t | 81 + t/mac_omac_test_vectors_ltc.t | 562 ++ t/mac_pelican.t | 81 + t/mac_pmac.t | 81 + t/mac_pmac_test_vectors_ltc.t | 562 ++ t/mac_poly1305.t | 45 + t/mac_xcbc.t | 81 + t/mbi_ltm/bigfltpm.inc | 2087 +++++ t/mbi_ltm/bigintpm.inc | 3085 +++++++ t/mbi_ltm_01load.t | 13 + t/mbi_ltm_bigfltpm.t | 41 + t/mbi_ltm_bigintg.t | 565 ++ t/mbi_ltm_bigintpm.t | 52 + t/mbi_ltm_biglog.t | 194 + t/mbi_ltm_bigroot.t | 50 + t/mbi_ltm_bugs.t | 52 + t/mbi_ltm_mbi-from-big-scalar.t | 53 + t/mbi_ltm_storable.t | 19 + t/mode_cbc.t | 98 + t/mode_cfb.t | 27 + t/mode_ctr.t | 49 + t/mode_ecb.t | 85 + t/mode_ofb.t | 28 + t/pk_dh.t | 209 + t/pk_dsa.t | 114 + t/pk_dsa_test_vectors_openssl.t | 42 + t/pk_ecc.t | 206 + t/pk_ecc_test_vectors_openssl.t | 90 + t/pk_enc_pem.t | 22 + t/pk_rsa.t | 106 + t/pk_rsa_test_vectors_openssl.t | 65 + t/pkcs8.t | 54 + t/prng.t | 66 + t/prng_chacha20.t | 66 + t/prng_fortuna.t | 66 + t/prng_rc4.t | 66 + t/prng_sober128.t | 66 + t/prng_yarrow.t | 66 + t/sshkey.t | 231 + typemap | 77 + 929 files changed, 132874 insertions(+) create mode 100644 Changes create mode 100644 CryptX.xs create mode 100644 LICENSE create mode 100644 MANIFEST create mode 100644 META.json create mode 100644 META.yml create mode 100644 Makefile.PL create mode 100644 README create mode 100644 inc/CryptX_AuthEnc_CCM.xs.inc create mode 100644 inc/CryptX_AuthEnc_ChaCha20Poly1305.xs.inc create mode 100644 inc/CryptX_AuthEnc_EAX.xs.inc create mode 100644 inc/CryptX_AuthEnc_GCM.xs.inc create mode 100644 inc/CryptX_AuthEnc_OCB.xs.inc create mode 100644 inc/CryptX_BigInt_LTM.xs.inc create mode 100644 inc/CryptX_Checksum_Adler32.xs.inc create mode 100644 inc/CryptX_Checksum_CRC32.xs.inc create mode 100644 inc/CryptX_Cipher.xs.inc create mode 100644 inc/CryptX_Digest.xs.inc create mode 100644 inc/CryptX_Digest_SHAKE.xs.inc create mode 100644 inc/CryptX_KeyDerivation.xs.inc create mode 100644 inc/CryptX_Mac_BLAKE2b.xs.inc create mode 100644 inc/CryptX_Mac_BLAKE2s.xs.inc create mode 100644 inc/CryptX_Mac_F9.xs.inc create mode 100644 inc/CryptX_Mac_HMAC.xs.inc create mode 100644 inc/CryptX_Mac_OMAC.xs.inc create mode 100644 inc/CryptX_Mac_PMAC.xs.inc create mode 100644 inc/CryptX_Mac_Pelican.xs.inc create mode 100644 inc/CryptX_Mac_Poly1305.xs.inc create mode 100644 inc/CryptX_Mac_XCBC.xs.inc create mode 100644 inc/CryptX_Mode_CBC.xs.inc create mode 100644 inc/CryptX_Mode_CFB.xs.inc create mode 100644 inc/CryptX_Mode_CTR.xs.inc create mode 100644 inc/CryptX_Mode_ECB.xs.inc create mode 100644 inc/CryptX_Mode_OFB.xs.inc create mode 100644 inc/CryptX_PK_DH.xs.inc create mode 100644 inc/CryptX_PK_DSA.xs.inc create mode 100644 inc/CryptX_PK_ECC.xs.inc create mode 100644 inc/CryptX_PK_RSA.xs.inc create mode 100644 inc/CryptX_PRNG.xs.inc create mode 100644 inc/CryptX_Stream_ChaCha.xs.inc create mode 100644 inc/CryptX_Stream_RC4.xs.inc create mode 100644 inc/CryptX_Stream_Sober128.xs.inc create mode 100644 lib/Crypt/AuthEnc.pm create mode 100644 lib/Crypt/AuthEnc/CCM.pm create mode 100644 lib/Crypt/AuthEnc/ChaCha20Poly1305.pm create mode 100644 lib/Crypt/AuthEnc/EAX.pm create mode 100644 lib/Crypt/AuthEnc/GCM.pm create mode 100644 lib/Crypt/AuthEnc/OCB.pm create mode 100644 lib/Crypt/Checksum.pm create mode 100644 lib/Crypt/Checksum/Adler32.pm create mode 100644 lib/Crypt/Checksum/CRC32.pm create mode 100644 lib/Crypt/Cipher.pm create mode 100644 lib/Crypt/Cipher/AES.pm create mode 100644 lib/Crypt/Cipher/Anubis.pm create mode 100644 lib/Crypt/Cipher/Blowfish.pm create mode 100644 lib/Crypt/Cipher/CAST5.pm create mode 100644 lib/Crypt/Cipher/Camellia.pm create mode 100644 lib/Crypt/Cipher/DES.pm create mode 100644 lib/Crypt/Cipher/DES_EDE.pm create mode 100644 lib/Crypt/Cipher/KASUMI.pm create mode 100644 lib/Crypt/Cipher/Khazad.pm create mode 100644 lib/Crypt/Cipher/MULTI2.pm create mode 100644 lib/Crypt/Cipher/Noekeon.pm create mode 100644 lib/Crypt/Cipher/RC2.pm create mode 100644 lib/Crypt/Cipher/RC5.pm create mode 100644 lib/Crypt/Cipher/RC6.pm create mode 100644 lib/Crypt/Cipher/SAFERP.pm create mode 100644 lib/Crypt/Cipher/SAFER_K128.pm create mode 100644 lib/Crypt/Cipher/SAFER_K64.pm create mode 100644 lib/Crypt/Cipher/SAFER_SK128.pm create mode 100644 lib/Crypt/Cipher/SAFER_SK64.pm create mode 100644 lib/Crypt/Cipher/SEED.pm create mode 100644 lib/Crypt/Cipher/Skipjack.pm create mode 100644 lib/Crypt/Cipher/Twofish.pm create mode 100644 lib/Crypt/Cipher/XTEA.pm create mode 100644 lib/Crypt/Digest.pm create mode 100644 lib/Crypt/Digest/BLAKE2b_160.pm create mode 100644 lib/Crypt/Digest/BLAKE2b_256.pm create mode 100644 lib/Crypt/Digest/BLAKE2b_384.pm create mode 100644 lib/Crypt/Digest/BLAKE2b_512.pm create mode 100644 lib/Crypt/Digest/BLAKE2s_128.pm create mode 100644 lib/Crypt/Digest/BLAKE2s_160.pm create mode 100644 lib/Crypt/Digest/BLAKE2s_224.pm create mode 100644 lib/Crypt/Digest/BLAKE2s_256.pm create mode 100644 lib/Crypt/Digest/CHAES.pm create mode 100644 lib/Crypt/Digest/MD2.pm create mode 100644 lib/Crypt/Digest/MD4.pm create mode 100644 lib/Crypt/Digest/MD5.pm create mode 100644 lib/Crypt/Digest/RIPEMD128.pm create mode 100644 lib/Crypt/Digest/RIPEMD160.pm create mode 100644 lib/Crypt/Digest/RIPEMD256.pm create mode 100644 lib/Crypt/Digest/RIPEMD320.pm create mode 100644 lib/Crypt/Digest/SHA1.pm create mode 100644 lib/Crypt/Digest/SHA224.pm create mode 100644 lib/Crypt/Digest/SHA256.pm create mode 100644 lib/Crypt/Digest/SHA384.pm create mode 100644 lib/Crypt/Digest/SHA3_224.pm create mode 100644 lib/Crypt/Digest/SHA3_256.pm create mode 100644 lib/Crypt/Digest/SHA3_384.pm create mode 100644 lib/Crypt/Digest/SHA3_512.pm create mode 100644 lib/Crypt/Digest/SHA512.pm create mode 100644 lib/Crypt/Digest/SHA512_224.pm create mode 100644 lib/Crypt/Digest/SHA512_256.pm create mode 100644 lib/Crypt/Digest/SHAKE.pm create mode 100644 lib/Crypt/Digest/Tiger192.pm create mode 100644 lib/Crypt/Digest/Whirlpool.pm create mode 100644 lib/Crypt/KeyDerivation.pm create mode 100644 lib/Crypt/Mac.pm create mode 100644 lib/Crypt/Mac/BLAKE2b.pm create mode 100644 lib/Crypt/Mac/BLAKE2s.pm create mode 100644 lib/Crypt/Mac/F9.pm create mode 100644 lib/Crypt/Mac/HMAC.pm create mode 100644 lib/Crypt/Mac/OMAC.pm create mode 100644 lib/Crypt/Mac/PMAC.pm create mode 100644 lib/Crypt/Mac/Pelican.pm create mode 100644 lib/Crypt/Mac/Poly1305.pm create mode 100644 lib/Crypt/Mac/XCBC.pm create mode 100644 lib/Crypt/Misc.pm create mode 100644 lib/Crypt/Mode.pm create mode 100644 lib/Crypt/Mode/CBC.pm create mode 100644 lib/Crypt/Mode/CFB.pm create mode 100644 lib/Crypt/Mode/CTR.pm create mode 100644 lib/Crypt/Mode/ECB.pm create mode 100644 lib/Crypt/Mode/OFB.pm create mode 100644 lib/Crypt/PK.pm create mode 100644 lib/Crypt/PK/DH.pm create mode 100644 lib/Crypt/PK/DSA.pm create mode 100644 lib/Crypt/PK/ECC.pm create mode 100644 lib/Crypt/PK/RSA.pm create mode 100644 lib/Crypt/PRNG.pm create mode 100644 lib/Crypt/PRNG/ChaCha20.pm create mode 100644 lib/Crypt/PRNG/Fortuna.pm create mode 100644 lib/Crypt/PRNG/RC4.pm create mode 100644 lib/Crypt/PRNG/Sober128.pm create mode 100644 lib/Crypt/PRNG/Yarrow.pm create mode 100644 lib/Crypt/Stream/ChaCha.pm create mode 100644 lib/Crypt/Stream/RC4.pm create mode 100644 lib/Crypt/Stream/Sober128.pm create mode 100644 lib/CryptX.pm create mode 100644 lib/Math/BigInt/LTM.pm create mode 100644 ppport.h create mode 100644 src/Makefile create mode 100644 src/Makefile.nmake create mode 100644 src/ltc/ciphers/aes/aes.c create mode 100644 src/ltc/ciphers/aes/aes_tab.c create mode 100644 src/ltc/ciphers/anubis.c create mode 100644 src/ltc/ciphers/blowfish.c create mode 100644 src/ltc/ciphers/camellia.c create mode 100644 src/ltc/ciphers/cast5.c create mode 100644 src/ltc/ciphers/des.c create mode 100644 src/ltc/ciphers/kasumi.c create mode 100644 src/ltc/ciphers/khazad.c create mode 100644 src/ltc/ciphers/kseed.c create mode 100644 src/ltc/ciphers/multi2.c create mode 100644 src/ltc/ciphers/noekeon.c create mode 100644 src/ltc/ciphers/rc2.c create mode 100644 src/ltc/ciphers/rc5.c create mode 100644 src/ltc/ciphers/rc6.c create mode 100644 src/ltc/ciphers/safer/safer.c create mode 100644 src/ltc/ciphers/safer/safer_tab.c create mode 100644 src/ltc/ciphers/safer/saferp.c create mode 100644 src/ltc/ciphers/skipjack.c create mode 100644 src/ltc/ciphers/twofish/twofish.c create mode 100644 src/ltc/ciphers/twofish/twofish_tab.c create mode 100644 src/ltc/ciphers/xtea.c create mode 100644 src/ltc/encauth/ccm/ccm_add_aad.c create mode 100644 src/ltc/encauth/ccm/ccm_add_nonce.c create mode 100644 src/ltc/encauth/ccm/ccm_done.c create mode 100644 src/ltc/encauth/ccm/ccm_init.c create mode 100644 src/ltc/encauth/ccm/ccm_memory.c create mode 100644 src/ltc/encauth/ccm/ccm_process.c create mode 100644 src/ltc/encauth/ccm/ccm_reset.c create mode 100644 src/ltc/encauth/chachapoly/chacha20poly1305_add_aad.c create mode 100644 src/ltc/encauth/chachapoly/chacha20poly1305_decrypt.c create mode 100644 src/ltc/encauth/chachapoly/chacha20poly1305_done.c create mode 100644 src/ltc/encauth/chachapoly/chacha20poly1305_encrypt.c create mode 100644 src/ltc/encauth/chachapoly/chacha20poly1305_init.c create mode 100644 src/ltc/encauth/chachapoly/chacha20poly1305_memory.c create mode 100644 src/ltc/encauth/chachapoly/chacha20poly1305_setiv.c create mode 100644 src/ltc/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.c create mode 100644 src/ltc/encauth/eax/eax_addheader.c create mode 100644 src/ltc/encauth/eax/eax_decrypt.c create mode 100644 src/ltc/encauth/eax/eax_decrypt_verify_memory.c create mode 100644 src/ltc/encauth/eax/eax_done.c create mode 100644 src/ltc/encauth/eax/eax_encrypt.c create mode 100644 src/ltc/encauth/eax/eax_encrypt_authenticate_memory.c create mode 100644 src/ltc/encauth/eax/eax_init.c create mode 100644 src/ltc/encauth/gcm/gcm_add_aad.c create mode 100644 src/ltc/encauth/gcm/gcm_add_iv.c create mode 100644 src/ltc/encauth/gcm/gcm_done.c create mode 100644 src/ltc/encauth/gcm/gcm_gf_mult.c create mode 100644 src/ltc/encauth/gcm/gcm_init.c create mode 100644 src/ltc/encauth/gcm/gcm_memory.c create mode 100644 src/ltc/encauth/gcm/gcm_mult_h.c create mode 100644 src/ltc/encauth/gcm/gcm_process.c create mode 100644 src/ltc/encauth/gcm/gcm_reset.c create mode 100644 src/ltc/encauth/ocb3/ocb3_add_aad.c create mode 100644 src/ltc/encauth/ocb3/ocb3_decrypt.c create mode 100644 src/ltc/encauth/ocb3/ocb3_decrypt_last.c create mode 100644 src/ltc/encauth/ocb3/ocb3_decrypt_verify_memory.c create mode 100644 src/ltc/encauth/ocb3/ocb3_done.c create mode 100644 src/ltc/encauth/ocb3/ocb3_encrypt.c create mode 100644 src/ltc/encauth/ocb3/ocb3_encrypt_authenticate_memory.c create mode 100644 src/ltc/encauth/ocb3/ocb3_encrypt_last.c create mode 100644 src/ltc/encauth/ocb3/ocb3_init.c create mode 100644 src/ltc/encauth/ocb3/ocb3_int_aad_add_block.c create mode 100644 src/ltc/encauth/ocb3/ocb3_int_calc_offset_zero.c create mode 100644 src/ltc/encauth/ocb3/ocb3_int_ntz.c create mode 100644 src/ltc/encauth/ocb3/ocb3_int_xor_blocks.c create mode 100644 src/ltc/hashes/blake2b.c create mode 100644 src/ltc/hashes/blake2s.c create mode 100644 src/ltc/hashes/chc/chc.c create mode 100644 src/ltc/hashes/helper/hash_file.c create mode 100644 src/ltc/hashes/helper/hash_filehandle.c create mode 100644 src/ltc/hashes/helper/hash_memory.c create mode 100644 src/ltc/hashes/helper/hash_memory_multi.c create mode 100644 src/ltc/hashes/md2.c create mode 100644 src/ltc/hashes/md4.c create mode 100644 src/ltc/hashes/md5.c create mode 100644 src/ltc/hashes/rmd128.c create mode 100644 src/ltc/hashes/rmd160.c create mode 100644 src/ltc/hashes/rmd256.c create mode 100644 src/ltc/hashes/rmd320.c create mode 100644 src/ltc/hashes/sha1.c create mode 100644 src/ltc/hashes/sha2/sha224.c create mode 100644 src/ltc/hashes/sha2/sha256.c create mode 100644 src/ltc/hashes/sha2/sha384.c create mode 100644 src/ltc/hashes/sha2/sha512.c create mode 100644 src/ltc/hashes/sha2/sha512_224.c create mode 100644 src/ltc/hashes/sha2/sha512_256.c create mode 100644 src/ltc/hashes/sha3.c create mode 100644 src/ltc/hashes/sha3_test.c create mode 100644 src/ltc/hashes/tiger.c create mode 100644 src/ltc/hashes/whirl/whirl.c create mode 100644 src/ltc/hashes/whirl/whirltab.c create mode 100644 src/ltc/headers/tomcrypt.h create mode 100644 src/ltc/headers/tomcrypt_argchk.h create mode 100644 src/ltc/headers/tomcrypt_cfg.h create mode 100644 src/ltc/headers/tomcrypt_cipher.h create mode 100644 src/ltc/headers/tomcrypt_custom.h create mode 100644 src/ltc/headers/tomcrypt_hash.h create mode 100644 src/ltc/headers/tomcrypt_mac.h create mode 100644 src/ltc/headers/tomcrypt_macros.h create mode 100644 src/ltc/headers/tomcrypt_math.h create mode 100644 src/ltc/headers/tomcrypt_misc.h create mode 100644 src/ltc/headers/tomcrypt_pk.h create mode 100644 src/ltc/headers/tomcrypt_pkcs.h create mode 100644 src/ltc/headers/tomcrypt_prng.h create mode 100644 src/ltc/mac/blake2/blake2bmac.c create mode 100644 src/ltc/mac/blake2/blake2bmac_file.c create mode 100644 src/ltc/mac/blake2/blake2bmac_memory.c create mode 100644 src/ltc/mac/blake2/blake2bmac_memory_multi.c create mode 100644 src/ltc/mac/blake2/blake2smac.c create mode 100644 src/ltc/mac/blake2/blake2smac_file.c create mode 100644 src/ltc/mac/blake2/blake2smac_memory.c create mode 100644 src/ltc/mac/blake2/blake2smac_memory_multi.c create mode 100644 src/ltc/mac/f9/f9_done.c create mode 100644 src/ltc/mac/f9/f9_file.c create mode 100644 src/ltc/mac/f9/f9_init.c create mode 100644 src/ltc/mac/f9/f9_memory.c create mode 100644 src/ltc/mac/f9/f9_memory_multi.c create mode 100644 src/ltc/mac/f9/f9_process.c create mode 100644 src/ltc/mac/hmac/hmac_done.c create mode 100644 src/ltc/mac/hmac/hmac_file.c create mode 100644 src/ltc/mac/hmac/hmac_init.c create mode 100644 src/ltc/mac/hmac/hmac_memory.c create mode 100644 src/ltc/mac/hmac/hmac_memory_multi.c create mode 100644 src/ltc/mac/hmac/hmac_process.c create mode 100644 src/ltc/mac/omac/omac_done.c create mode 100644 src/ltc/mac/omac/omac_file.c create mode 100644 src/ltc/mac/omac/omac_init.c create mode 100644 src/ltc/mac/omac/omac_memory.c create mode 100644 src/ltc/mac/omac/omac_memory_multi.c create mode 100644 src/ltc/mac/omac/omac_process.c create mode 100644 src/ltc/mac/pelican/pelican.c create mode 100644 src/ltc/mac/pelican/pelican_memory.c create mode 100644 src/ltc/mac/pmac/pmac_done.c create mode 100644 src/ltc/mac/pmac/pmac_file.c create mode 100644 src/ltc/mac/pmac/pmac_init.c create mode 100644 src/ltc/mac/pmac/pmac_memory.c create mode 100644 src/ltc/mac/pmac/pmac_memory_multi.c create mode 100644 src/ltc/mac/pmac/pmac_ntz.c create mode 100644 src/ltc/mac/pmac/pmac_process.c create mode 100644 src/ltc/mac/pmac/pmac_shift_xor.c create mode 100644 src/ltc/mac/poly1305/poly1305.c create mode 100644 src/ltc/mac/poly1305/poly1305_file.c create mode 100644 src/ltc/mac/poly1305/poly1305_memory.c create mode 100644 src/ltc/mac/poly1305/poly1305_memory_multi.c create mode 100644 src/ltc/mac/xcbc/xcbc_done.c create mode 100644 src/ltc/mac/xcbc/xcbc_file.c create mode 100644 src/ltc/mac/xcbc/xcbc_init.c create mode 100644 src/ltc/mac/xcbc/xcbc_memory.c create mode 100644 src/ltc/mac/xcbc/xcbc_memory_multi.c create mode 100644 src/ltc/mac/xcbc/xcbc_process.c create mode 100644 src/ltc/math/fp/ltc_ecc_fp_mulmod.c create mode 100644 src/ltc/math/ltm_desc.c create mode 100644 src/ltc/math/multi.c create mode 100644 src/ltc/math/rand_bn.c create mode 100644 src/ltc/math/rand_prime.c create mode 100644 src/ltc/math/tfm_desc.c create mode 100644 src/ltc/misc/adler32.c create mode 100644 src/ltc/misc/base64/base64_decode.c create mode 100644 src/ltc/misc/base64/base64_encode.c create mode 100644 src/ltc/misc/burn_stack.c create mode 100644 src/ltc/misc/crc32.c create mode 100644 src/ltc/misc/crypt/crypt.c create mode 100644 src/ltc/misc/crypt/crypt_argchk.c create mode 100644 src/ltc/misc/crypt/crypt_cipher_descriptor.c create mode 100644 src/ltc/misc/crypt/crypt_cipher_is_valid.c create mode 100644 src/ltc/misc/crypt/crypt_find_cipher.c create mode 100644 src/ltc/misc/crypt/crypt_find_cipher_any.c create mode 100644 src/ltc/misc/crypt/crypt_find_cipher_id.c create mode 100644 src/ltc/misc/crypt/crypt_find_hash.c create mode 100644 src/ltc/misc/crypt/crypt_find_hash_any.c create mode 100644 src/ltc/misc/crypt/crypt_find_hash_id.c create mode 100644 src/ltc/misc/crypt/crypt_find_hash_oid.c create mode 100644 src/ltc/misc/crypt/crypt_find_prng.c create mode 100644 src/ltc/misc/crypt/crypt_fsa.c create mode 100644 src/ltc/misc/crypt/crypt_hash_descriptor.c create mode 100644 src/ltc/misc/crypt/crypt_hash_is_valid.c create mode 100644 src/ltc/misc/crypt/crypt_inits.c create mode 100644 src/ltc/misc/crypt/crypt_ltc_mp_descriptor.c create mode 100644 src/ltc/misc/crypt/crypt_prng_descriptor.c create mode 100644 src/ltc/misc/crypt/crypt_prng_is_valid.c create mode 100644 src/ltc/misc/crypt/crypt_register_cipher.c create mode 100644 src/ltc/misc/crypt/crypt_register_hash.c create mode 100644 src/ltc/misc/crypt/crypt_register_prng.c create mode 100644 src/ltc/misc/crypt/crypt_unregister_cipher.c create mode 100644 src/ltc/misc/crypt/crypt_unregister_hash.c create mode 100644 src/ltc/misc/crypt/crypt_unregister_prng.c create mode 100644 src/ltc/misc/error_to_string.c create mode 100644 src/ltc/misc/hkdf/hkdf.c create mode 100644 src/ltc/misc/mem_neq.c create mode 100644 src/ltc/misc/pk_get_oid.c create mode 100644 src/ltc/misc/pkcs5/pkcs_5_1.c create mode 100644 src/ltc/misc/pkcs5/pkcs_5_2.c create mode 100644 src/ltc/misc/zeromem.c create mode 100644 src/ltc/modes/cbc/cbc_decrypt.c create mode 100644 src/ltc/modes/cbc/cbc_done.c create mode 100644 src/ltc/modes/cbc/cbc_encrypt.c create mode 100644 src/ltc/modes/cbc/cbc_getiv.c create mode 100644 src/ltc/modes/cbc/cbc_setiv.c create mode 100644 src/ltc/modes/cbc/cbc_start.c create mode 100644 src/ltc/modes/cfb/cfb_decrypt.c create mode 100644 src/ltc/modes/cfb/cfb_done.c create mode 100644 src/ltc/modes/cfb/cfb_encrypt.c create mode 100644 src/ltc/modes/cfb/cfb_getiv.c create mode 100644 src/ltc/modes/cfb/cfb_setiv.c create mode 100644 src/ltc/modes/cfb/cfb_start.c create mode 100644 src/ltc/modes/ctr/ctr_decrypt.c create mode 100644 src/ltc/modes/ctr/ctr_done.c create mode 100644 src/ltc/modes/ctr/ctr_encrypt.c create mode 100644 src/ltc/modes/ctr/ctr_getiv.c create mode 100644 src/ltc/modes/ctr/ctr_setiv.c create mode 100644 src/ltc/modes/ctr/ctr_start.c create mode 100644 src/ltc/modes/ecb/ecb_decrypt.c create mode 100644 src/ltc/modes/ecb/ecb_done.c create mode 100644 src/ltc/modes/ecb/ecb_encrypt.c create mode 100644 src/ltc/modes/ecb/ecb_start.c create mode 100644 src/ltc/modes/ofb/ofb_decrypt.c create mode 100644 src/ltc/modes/ofb/ofb_done.c create mode 100644 src/ltc/modes/ofb/ofb_encrypt.c create mode 100644 src/ltc/modes/ofb/ofb_getiv.c create mode 100644 src/ltc/modes/ofb/ofb_setiv.c create mode 100644 src/ltc/modes/ofb/ofb_start.c create mode 100644 src/ltc/pk/asn1/der/bit/der_decode_bit_string.c create mode 100644 src/ltc/pk/asn1/der/bit/der_decode_raw_bit_string.c create mode 100644 src/ltc/pk/asn1/der/bit/der_encode_bit_string.c create mode 100644 src/ltc/pk/asn1/der/bit/der_encode_raw_bit_string.c create mode 100644 src/ltc/pk/asn1/der/bit/der_length_bit_string.c create mode 100644 src/ltc/pk/asn1/der/boolean/der_decode_boolean.c create mode 100644 src/ltc/pk/asn1/der/boolean/der_encode_boolean.c create mode 100644 src/ltc/pk/asn1/der/boolean/der_length_boolean.c create mode 100644 src/ltc/pk/asn1/der/choice/der_decode_choice.c create mode 100644 src/ltc/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c create mode 100644 src/ltc/pk/asn1/der/generalizedtime/der_encode_generalizedtime.c create mode 100644 src/ltc/pk/asn1/der/generalizedtime/der_length_generalizedtime.c create mode 100644 src/ltc/pk/asn1/der/ia5/der_decode_ia5_string.c create mode 100644 src/ltc/pk/asn1/der/ia5/der_encode_ia5_string.c create mode 100644 src/ltc/pk/asn1/der/ia5/der_length_ia5_string.c create mode 100644 src/ltc/pk/asn1/der/integer/der_decode_integer.c create mode 100644 src/ltc/pk/asn1/der/integer/der_encode_integer.c create mode 100644 src/ltc/pk/asn1/der/integer/der_length_integer.c create mode 100644 src/ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.c create mode 100644 src/ltc/pk/asn1/der/object_identifier/der_encode_object_identifier.c create mode 100644 src/ltc/pk/asn1/der/object_identifier/der_length_object_identifier.c create mode 100644 src/ltc/pk/asn1/der/octet/der_decode_octet_string.c create mode 100644 src/ltc/pk/asn1/der/octet/der_encode_octet_string.c create mode 100644 src/ltc/pk/asn1/der/octet/der_length_octet_string.c create mode 100644 src/ltc/pk/asn1/der/printable_string/der_decode_printable_string.c create mode 100644 src/ltc/pk/asn1/der/printable_string/der_encode_printable_string.c create mode 100644 src/ltc/pk/asn1/der/printable_string/der_length_printable_string.c create mode 100644 src/ltc/pk/asn1/der/sequence/der_decode_sequence_ex.c create mode 100644 src/ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.c create mode 100644 src/ltc/pk/asn1/der/sequence/der_decode_sequence_multi.c create mode 100644 src/ltc/pk/asn1/der/sequence/der_decode_subject_public_key_info.c create mode 100644 src/ltc/pk/asn1/der/sequence/der_encode_sequence_ex.c create mode 100644 src/ltc/pk/asn1/der/sequence/der_encode_sequence_multi.c create mode 100644 src/ltc/pk/asn1/der/sequence/der_encode_subject_public_key_info.c create mode 100644 src/ltc/pk/asn1/der/sequence/der_length_sequence.c create mode 100644 src/ltc/pk/asn1/der/sequence/der_sequence_free.c create mode 100644 src/ltc/pk/asn1/der/set/der_encode_set.c create mode 100644 src/ltc/pk/asn1/der/set/der_encode_setof.c create mode 100644 src/ltc/pk/asn1/der/short_integer/der_decode_short_integer.c create mode 100644 src/ltc/pk/asn1/der/short_integer/der_encode_short_integer.c create mode 100644 src/ltc/pk/asn1/der/short_integer/der_length_short_integer.c create mode 100644 src/ltc/pk/asn1/der/teletex_string/der_decode_teletex_string.c create mode 100644 src/ltc/pk/asn1/der/teletex_string/der_length_teletex_string.c create mode 100644 src/ltc/pk/asn1/der/utctime/der_decode_utctime.c create mode 100644 src/ltc/pk/asn1/der/utctime/der_encode_utctime.c create mode 100644 src/ltc/pk/asn1/der/utctime/der_length_utctime.c create mode 100644 src/ltc/pk/asn1/der/utf8/der_decode_utf8_string.c create mode 100644 src/ltc/pk/asn1/der/utf8/der_encode_utf8_string.c create mode 100644 src/ltc/pk/asn1/der/utf8/der_length_utf8_string.c create mode 100644 src/ltc/pk/dh/dh.c create mode 100644 src/ltc/pk/dh/dh_static.c create mode 100644 src/ltc/pk/dh/dh_static.h create mode 100644 src/ltc/pk/dh/dh_sys.c create mode 100644 src/ltc/pk/dsa/dsa_decrypt_key.c create mode 100644 src/ltc/pk/dsa/dsa_encrypt_key.c create mode 100644 src/ltc/pk/dsa/dsa_export.c create mode 100644 src/ltc/pk/dsa/dsa_free.c create mode 100644 src/ltc/pk/dsa/dsa_import.c create mode 100644 src/ltc/pk/dsa/dsa_import_radix.c create mode 100644 src/ltc/pk/dsa/dsa_make_key.c create mode 100644 src/ltc/pk/dsa/dsa_shared_secret.c create mode 100644 src/ltc/pk/dsa/dsa_sign_hash.c create mode 100644 src/ltc/pk/dsa/dsa_verify_hash.c create mode 100644 src/ltc/pk/dsa/dsa_verify_key.c create mode 100644 src/ltc/pk/ecc/ecc.c create mode 100644 src/ltc/pk/ecc/ecc_ansi_x963_export.c create mode 100644 src/ltc/pk/ecc/ecc_ansi_x963_import.c create mode 100644 src/ltc/pk/ecc/ecc_decrypt_key.c create mode 100644 src/ltc/pk/ecc/ecc_dp_clear.c create mode 100644 src/ltc/pk/ecc/ecc_dp_fill_from_sets.c create mode 100644 src/ltc/pk/ecc/ecc_dp_from_oid.c create mode 100644 src/ltc/pk/ecc/ecc_dp_from_params.c create mode 100644 src/ltc/pk/ecc/ecc_dp_init.c create mode 100644 src/ltc/pk/ecc/ecc_dp_set.c create mode 100644 src/ltc/pk/ecc/ecc_encrypt_key.c create mode 100644 src/ltc/pk/ecc/ecc_export.c create mode 100644 src/ltc/pk/ecc/ecc_export_full.c create mode 100644 src/ltc/pk/ecc/ecc_export_raw.c create mode 100644 src/ltc/pk/ecc/ecc_free.c create mode 100644 src/ltc/pk/ecc/ecc_get_size.c create mode 100644 src/ltc/pk/ecc/ecc_import.c create mode 100644 src/ltc/pk/ecc/ecc_import_full.c create mode 100644 src/ltc/pk/ecc/ecc_import_pkcs8.c create mode 100644 src/ltc/pk/ecc/ecc_import_raw.c create mode 100644 src/ltc/pk/ecc/ecc_make_key.c create mode 100644 src/ltc/pk/ecc/ecc_shared_secret.c create mode 100644 src/ltc/pk/ecc/ecc_sign_hash.c create mode 100644 src/ltc/pk/ecc/ecc_sizes.c create mode 100644 src/ltc/pk/ecc/ecc_verify_hash.c create mode 100644 src/ltc/pk/ecc/ecc_verify_key.c create mode 100644 src/ltc/pk/ecc/ltc_ecc_export_point.c create mode 100644 src/ltc/pk/ecc/ltc_ecc_import_point.c create mode 100644 src/ltc/pk/ecc/ltc_ecc_is_point.c create mode 100644 src/ltc/pk/ecc/ltc_ecc_is_point_at_infinity.c create mode 100644 src/ltc/pk/ecc/ltc_ecc_is_valid_idx.c create mode 100644 src/ltc/pk/ecc/ltc_ecc_map.c create mode 100644 src/ltc/pk/ecc/ltc_ecc_mul2add.c create mode 100644 src/ltc/pk/ecc/ltc_ecc_mulmod.c create mode 100644 src/ltc/pk/ecc/ltc_ecc_mulmod_timing.c create mode 100644 src/ltc/pk/ecc/ltc_ecc_points.c create mode 100644 src/ltc/pk/ecc/ltc_ecc_projective_add_point.c create mode 100644 src/ltc/pk/ecc/ltc_ecc_projective_dbl_point.c create mode 100644 src/ltc/pk/pkcs1/pkcs_1_i2osp.c create mode 100644 src/ltc/pk/pkcs1/pkcs_1_mgf1.c create mode 100644 src/ltc/pk/pkcs1/pkcs_1_oaep_decode.c create mode 100644 src/ltc/pk/pkcs1/pkcs_1_oaep_encode.c create mode 100644 src/ltc/pk/pkcs1/pkcs_1_os2ip.c create mode 100644 src/ltc/pk/pkcs1/pkcs_1_pss_decode.c create mode 100644 src/ltc/pk/pkcs1/pkcs_1_pss_encode.c create mode 100644 src/ltc/pk/pkcs1/pkcs_1_v1_5_decode.c create mode 100644 src/ltc/pk/pkcs1/pkcs_1_v1_5_encode.c create mode 100644 src/ltc/pk/rsa/rsa_decrypt_key.c create mode 100644 src/ltc/pk/rsa/rsa_encrypt_key.c create mode 100644 src/ltc/pk/rsa/rsa_export.c create mode 100644 src/ltc/pk/rsa/rsa_exptmod.c create mode 100644 src/ltc/pk/rsa/rsa_free.c create mode 100644 src/ltc/pk/rsa/rsa_get_size.c create mode 100644 src/ltc/pk/rsa/rsa_import.c create mode 100644 src/ltc/pk/rsa/rsa_import_pkcs8.c create mode 100644 src/ltc/pk/rsa/rsa_import_radix.c create mode 100644 src/ltc/pk/rsa/rsa_import_x509.c create mode 100644 src/ltc/pk/rsa/rsa_make_key.c create mode 100644 src/ltc/pk/rsa/rsa_sign_hash.c create mode 100644 src/ltc/pk/rsa/rsa_sign_saltlen_get.c create mode 100644 src/ltc/pk/rsa/rsa_verify_hash.c create mode 100644 src/ltc/prngs/chacha20.c create mode 100644 src/ltc/prngs/fortuna.c create mode 100644 src/ltc/prngs/rc4.c create mode 100644 src/ltc/prngs/rng_get_bytes.c create mode 100644 src/ltc/prngs/rng_make_prng.c create mode 100644 src/ltc/prngs/sober128.c create mode 100644 src/ltc/prngs/sprng.c create mode 100644 src/ltc/prngs/yarrow.c create mode 100644 src/ltc/stream/chacha/chacha_crypt.c create mode 100644 src/ltc/stream/chacha/chacha_done.c create mode 100644 src/ltc/stream/chacha/chacha_ivctr32.c create mode 100644 src/ltc/stream/chacha/chacha_ivctr64.c create mode 100644 src/ltc/stream/chacha/chacha_keystream.c create mode 100644 src/ltc/stream/chacha/chacha_setup.c create mode 100644 src/ltc/stream/rc4/rc4.c create mode 100644 src/ltc/stream/sober128/sober128.c create mode 100644 src/ltc/stream/sober128/sober128tab.c create mode 100644 src/ltm/bn_error.c create mode 100644 src/ltm/bn_fast_mp_invmod.c create mode 100644 src/ltm/bn_fast_mp_montgomery_reduce.c create mode 100644 src/ltm/bn_fast_s_mp_mul_digs.c create mode 100644 src/ltm/bn_fast_s_mp_mul_high_digs.c create mode 100644 src/ltm/bn_fast_s_mp_sqr.c create mode 100644 src/ltm/bn_mp_2expt.c create mode 100644 src/ltm/bn_mp_abs.c create mode 100644 src/ltm/bn_mp_add.c create mode 100644 src/ltm/bn_mp_add_d.c create mode 100644 src/ltm/bn_mp_addmod.c create mode 100644 src/ltm/bn_mp_and.c create mode 100644 src/ltm/bn_mp_clamp.c create mode 100644 src/ltm/bn_mp_clear.c create mode 100644 src/ltm/bn_mp_clear_multi.c create mode 100644 src/ltm/bn_mp_cmp.c create mode 100644 src/ltm/bn_mp_cmp_d.c create mode 100644 src/ltm/bn_mp_cmp_mag.c create mode 100644 src/ltm/bn_mp_cnt_lsb.c create mode 100644 src/ltm/bn_mp_copy.c create mode 100644 src/ltm/bn_mp_count_bits.c create mode 100644 src/ltm/bn_mp_div.c create mode 100644 src/ltm/bn_mp_div_2.c create mode 100644 src/ltm/bn_mp_div_2d.c create mode 100644 src/ltm/bn_mp_div_3.c create mode 100644 src/ltm/bn_mp_div_d.c create mode 100644 src/ltm/bn_mp_dr_is_modulus.c create mode 100644 src/ltm/bn_mp_dr_reduce.c create mode 100644 src/ltm/bn_mp_dr_setup.c create mode 100644 src/ltm/bn_mp_exch.c create mode 100644 src/ltm/bn_mp_export.c create mode 100644 src/ltm/bn_mp_expt_d.c create mode 100644 src/ltm/bn_mp_expt_d_ex.c create mode 100644 src/ltm/bn_mp_exptmod.c create mode 100644 src/ltm/bn_mp_exptmod_fast.c create mode 100644 src/ltm/bn_mp_exteuclid.c create mode 100644 src/ltm/bn_mp_fread.c create mode 100644 src/ltm/bn_mp_fwrite.c create mode 100644 src/ltm/bn_mp_gcd.c create mode 100644 src/ltm/bn_mp_get_int.c create mode 100644 src/ltm/bn_mp_get_long.c create mode 100644 src/ltm/bn_mp_get_long_long.c create mode 100644 src/ltm/bn_mp_grow.c create mode 100644 src/ltm/bn_mp_import.c create mode 100644 src/ltm/bn_mp_init.c create mode 100644 src/ltm/bn_mp_init_copy.c create mode 100644 src/ltm/bn_mp_init_multi.c create mode 100644 src/ltm/bn_mp_init_set.c create mode 100644 src/ltm/bn_mp_init_set_int.c create mode 100644 src/ltm/bn_mp_init_size.c create mode 100644 src/ltm/bn_mp_invmod.c create mode 100644 src/ltm/bn_mp_invmod_slow.c create mode 100644 src/ltm/bn_mp_is_square.c create mode 100644 src/ltm/bn_mp_jacobi.c create mode 100644 src/ltm/bn_mp_karatsuba_mul.c create mode 100644 src/ltm/bn_mp_karatsuba_sqr.c create mode 100644 src/ltm/bn_mp_lcm.c create mode 100644 src/ltm/bn_mp_lshd.c create mode 100644 src/ltm/bn_mp_mod.c create mode 100644 src/ltm/bn_mp_mod_2d.c create mode 100644 src/ltm/bn_mp_mod_d.c create mode 100644 src/ltm/bn_mp_montgomery_calc_normalization.c create mode 100644 src/ltm/bn_mp_montgomery_reduce.c create mode 100644 src/ltm/bn_mp_montgomery_setup.c create mode 100644 src/ltm/bn_mp_mul.c create mode 100644 src/ltm/bn_mp_mul_2.c create mode 100644 src/ltm/bn_mp_mul_2d.c create mode 100644 src/ltm/bn_mp_mul_d.c create mode 100644 src/ltm/bn_mp_mulmod.c create mode 100644 src/ltm/bn_mp_n_root.c create mode 100644 src/ltm/bn_mp_n_root_ex.c create mode 100644 src/ltm/bn_mp_neg.c create mode 100644 src/ltm/bn_mp_or.c create mode 100644 src/ltm/bn_mp_prime_fermat.c create mode 100644 src/ltm/bn_mp_prime_is_divisible.c create mode 100644 src/ltm/bn_mp_prime_is_prime.c create mode 100644 src/ltm/bn_mp_prime_miller_rabin.c create mode 100644 src/ltm/bn_mp_prime_next_prime.c create mode 100644 src/ltm/bn_mp_prime_rabin_miller_trials.c create mode 100644 src/ltm/bn_mp_prime_random_ex.c create mode 100644 src/ltm/bn_mp_radix_size.c create mode 100644 src/ltm/bn_mp_radix_smap.c create mode 100644 src/ltm/bn_mp_rand.c create mode 100644 src/ltm/bn_mp_read_radix.c create mode 100644 src/ltm/bn_mp_read_signed_bin.c create mode 100644 src/ltm/bn_mp_read_unsigned_bin.c create mode 100644 src/ltm/bn_mp_reduce.c create mode 100644 src/ltm/bn_mp_reduce_2k.c create mode 100644 src/ltm/bn_mp_reduce_2k_l.c create mode 100644 src/ltm/bn_mp_reduce_2k_setup.c create mode 100644 src/ltm/bn_mp_reduce_2k_setup_l.c create mode 100644 src/ltm/bn_mp_reduce_is_2k.c create mode 100644 src/ltm/bn_mp_reduce_is_2k_l.c create mode 100644 src/ltm/bn_mp_reduce_setup.c create mode 100644 src/ltm/bn_mp_rshd.c create mode 100644 src/ltm/bn_mp_set.c create mode 100644 src/ltm/bn_mp_set_int.c create mode 100644 src/ltm/bn_mp_set_long.c create mode 100644 src/ltm/bn_mp_set_long_long.c create mode 100644 src/ltm/bn_mp_shrink.c create mode 100644 src/ltm/bn_mp_signed_bin_size.c create mode 100644 src/ltm/bn_mp_sqr.c create mode 100644 src/ltm/bn_mp_sqrmod.c create mode 100644 src/ltm/bn_mp_sqrt.c create mode 100644 src/ltm/bn_mp_sqrtmod_prime.c create mode 100644 src/ltm/bn_mp_sub.c create mode 100644 src/ltm/bn_mp_sub_d.c create mode 100644 src/ltm/bn_mp_submod.c create mode 100644 src/ltm/bn_mp_to_signed_bin.c create mode 100644 src/ltm/bn_mp_to_signed_bin_n.c create mode 100644 src/ltm/bn_mp_to_unsigned_bin.c create mode 100644 src/ltm/bn_mp_to_unsigned_bin_n.c create mode 100644 src/ltm/bn_mp_toom_mul.c create mode 100644 src/ltm/bn_mp_toom_sqr.c create mode 100644 src/ltm/bn_mp_toradix.c create mode 100644 src/ltm/bn_mp_toradix_n.c create mode 100644 src/ltm/bn_mp_unsigned_bin_size.c create mode 100644 src/ltm/bn_mp_xor.c create mode 100644 src/ltm/bn_mp_zero.c create mode 100644 src/ltm/bn_prime_tab.c create mode 100644 src/ltm/bn_reverse.c create mode 100644 src/ltm/bn_s_mp_add.c create mode 100644 src/ltm/bn_s_mp_exptmod.c create mode 100644 src/ltm/bn_s_mp_mul_digs.c create mode 100644 src/ltm/bn_s_mp_mul_high_digs.c create mode 100644 src/ltm/bn_s_mp_sqr.c create mode 100644 src/ltm/bn_s_mp_sub.c create mode 100644 src/ltm/bncore.c create mode 100644 src/ltm/tommath.h create mode 100644 src/ltm/tommath_class.h create mode 100644 src/ltm/tommath_private.h create mode 100644 src/ltm/tommath_superclass.h create mode 100644 t/001_compile.t create mode 100644 t/002_all_pm.t create mode 100644 t/003_all_pm_pod.t create mode 100644 t/auth_enc_ccm.t create mode 100644 t/auth_enc_ccm_test_vector_ltc.t create mode 100644 t/auth_enc_chacha20poly1305.t create mode 100644 t/auth_enc_eax.t create mode 100644 t/auth_enc_eax_test_vector_ltc.t create mode 100644 t/auth_enc_gcm.t create mode 100644 t/auth_enc_gcm_test_vector_ltc.t create mode 100644 t/auth_enc_ocb.t create mode 100644 t/auth_enc_ocb_test_vectors_ietf.t create mode 100644 t/checksum.t create mode 100644 t/cipher_aes.t create mode 100644 t/cipher_aes_test_vectors_bc.t create mode 100644 t/cipher_anubis.t create mode 100644 t/cipher_blowfish.t create mode 100644 t/cipher_camellia.t create mode 100644 t/cipher_cast5.t create mode 100644 t/cipher_des.t create mode 100644 t/cipher_des_ede.t create mode 100644 t/cipher_kasumi.t create mode 100644 t/cipher_khazad.t create mode 100644 t/cipher_multi2.t create mode 100644 t/cipher_multi2_rounds.t create mode 100644 t/cipher_noekeon.t create mode 100644 t/cipher_rc2.t create mode 100644 t/cipher_rc5.t create mode 100644 t/cipher_rc6.t create mode 100644 t/cipher_safer_k128.t create mode 100644 t/cipher_safer_k64.t create mode 100644 t/cipher_safer_sk128.t create mode 100644 t/cipher_safer_sk64.t create mode 100644 t/cipher_saferp.t create mode 100644 t/cipher_seed.t create mode 100644 t/cipher_seed_test_vectors_bc.t create mode 100644 t/cipher_skipjack.t create mode 100644 t/cipher_stream.t create mode 100644 t/cipher_test_vectors_ltc.t create mode 100644 t/cipher_test_vectors_openssl.t create mode 100644 t/cipher_twofish.t create mode 100644 t/cipher_twofish_test_vectors_bc.t create mode 100644 t/cipher_xtea.t create mode 100644 t/cipher_xtea_test_vectors_bc.t create mode 100644 t/crypt-misc.t create mode 100644 t/data/binary-test.file create mode 100644 t/data/cryptx_priv_dh1.bin create mode 100644 t/data/cryptx_priv_dh2.bin create mode 100644 t/data/cryptx_priv_dh_pg1.bin create mode 100644 t/data/cryptx_priv_dh_pg2.bin create mode 100644 t/data/cryptx_priv_dsa1.der create mode 100644 t/data/cryptx_priv_dsa1.pem create mode 100644 t/data/cryptx_priv_dsa2.der create mode 100644 t/data/cryptx_priv_dsa2.pem create mode 100644 t/data/cryptx_priv_ecc1.der create mode 100644 t/data/cryptx_priv_ecc1.pem create mode 100644 t/data/cryptx_priv_ecc1_OLD.der create mode 100644 t/data/cryptx_priv_ecc1_OLD.pem create mode 100644 t/data/cryptx_priv_ecc2.der create mode 100644 t/data/cryptx_priv_ecc2.pem create mode 100644 t/data/cryptx_priv_ecc2_OLD.der create mode 100644 t/data/cryptx_priv_ecc2_OLD.pem create mode 100644 t/data/cryptx_priv_rsa1.der create mode 100644 t/data/cryptx_priv_rsa1.pem create mode 100644 t/data/cryptx_priv_rsa2.der create mode 100644 t/data/cryptx_priv_rsa2.pem create mode 100644 t/data/cryptx_pub_dh1.bin create mode 100644 t/data/cryptx_pub_dh2.bin create mode 100644 t/data/cryptx_pub_dh_pg1.bin create mode 100644 t/data/cryptx_pub_dh_pg2.bin create mode 100644 t/data/cryptx_pub_dsa1.der create mode 100644 t/data/cryptx_pub_dsa1.pem create mode 100644 t/data/cryptx_pub_dsa2.der create mode 100644 t/data/cryptx_pub_dsa2.pem create mode 100644 t/data/cryptx_pub_ecc1.der create mode 100644 t/data/cryptx_pub_ecc1.pem create mode 100644 t/data/cryptx_pub_ecc1_OLD.der create mode 100644 t/data/cryptx_pub_ecc1_OLD.pem create mode 100644 t/data/cryptx_pub_ecc2.der create mode 100644 t/data/cryptx_pub_ecc2.pem create mode 100644 t/data/cryptx_pub_ecc2_OLD.der create mode 100644 t/data/cryptx_pub_ecc2_OLD.pem create mode 100644 t/data/cryptx_pub_rsa1.der create mode 100644 t/data/cryptx_pub_rsa1.pem create mode 100644 t/data/cryptx_pub_rsa2.der create mode 100644 t/data/cryptx_pub_rsa2.pem create mode 100644 t/data/dsa-aes128.pem create mode 100644 t/data/dsa-aes192.pem create mode 100644 t/data/dsa-aes256.pem create mode 100644 t/data/dsa-camellia128.pem create mode 100644 t/data/dsa-camellia192.pem create mode 100644 t/data/dsa-camellia256.pem create mode 100644 t/data/dsa-des.pem create mode 100644 t/data/dsa-des3.pem create mode 100644 t/data/dsa-param.pem create mode 100644 t/data/dsa-seed.pem create mode 100644 t/data/ec-aes128.pem create mode 100644 t/data/ec-aes192.pem create mode 100644 t/data/ec-aes256.pem create mode 100644 t/data/ec-camellia128.pem create mode 100644 t/data/ec-camellia192.pem create mode 100644 t/data/ec-camellia256.pem create mode 100644 t/data/ec-des.pem create mode 100644 t/data/ec-des3.pem create mode 100644 t/data/ec-seed.pem create mode 100644 t/data/jwk_ec-priv1.json create mode 100644 t/data/jwk_ec-pub.json create mode 100644 t/data/jwk_ec-pub1.json create mode 100644 t/data/jwk_rsa-priv.json create mode 100644 t/data/jwk_rsa-priv1.json create mode 100644 t/data/jwk_rsa-pub1.json create mode 100644 t/data/openssl_dsa1.der create mode 100644 t/data/openssl_dsa1.pem create mode 100644 t/data/openssl_dsa2.der create mode 100644 t/data/openssl_dsa2.pem create mode 100644 t/data/openssl_ec-short.der create mode 100644 t/data/openssl_ec-short.pem create mode 100644 t/data/openssl_ec-short.pub.der create mode 100644 t/data/openssl_ec-short.pub.pem create mode 100644 t/data/openssl_ec1.key.pem create mode 100644 t/data/openssl_ec1.pri.der create mode 100644 t/data/openssl_ec1.pri.pem create mode 100644 t/data/openssl_ec1.pric.der create mode 100644 t/data/openssl_ec1.pric.pem create mode 100644 t/data/openssl_ec1.pub.der create mode 100644 t/data/openssl_ec1.pub.pem create mode 100644 t/data/openssl_ec1.pubc.der create mode 100644 t/data/openssl_ec1.pubc.pem create mode 100644 t/data/openssl_rsa1.der create mode 100644 t/data/openssl_rsa1.pem create mode 100644 t/data/openssl_rsa1.pubonly.der create mode 100644 t/data/openssl_rsa1.pubonly.pem create mode 100644 t/data/openssl_rsa2.der create mode 100644 t/data/openssl_rsa2.pem create mode 100644 t/data/openssl_rsa2.pubonly.der create mode 100644 t/data/openssl_rsa2.pubonly.pem create mode 100644 t/data/pkcs8.ec-priv-nopass.der create mode 100644 t/data/pkcs8.ec-priv-nopass.pem create mode 100644 t/data/pkcs8.ec-priv-pass.der create mode 100644 t/data/pkcs8.ec-priv-pass.pem create mode 100644 t/data/pkcs8.ec-short-priv-nopass.der create mode 100644 t/data/pkcs8.ec-short-priv-nopass.pem create mode 100644 t/data/pkcs8.ec-short-priv-pass.der create mode 100644 t/data/pkcs8.ec-short-priv-pass.pem create mode 100644 t/data/pkcs8.rsa-priv-nopass.der create mode 100644 t/data/pkcs8.rsa-priv-nopass.pem create mode 100644 t/data/pkcs8.rsa-priv-pass.der create mode 100644 t/data/pkcs8.rsa-priv-pass.pem create mode 100644 t/data/rsa-aes128.pem create mode 100644 t/data/rsa-aes192.pem create mode 100644 t/data/rsa-aes256.pem create mode 100644 t/data/rsa-camellia128.pem create mode 100644 t/data/rsa-camellia192.pem create mode 100644 t/data/rsa-camellia256.pem create mode 100644 t/data/rsa-des.pem create mode 100644 t/data/rsa-des3.pem create mode 100644 t/data/rsa-seed.pem create mode 100644 t/data/ssh/ssh_dsa_1024 create mode 100644 t/data/ssh/ssh_dsa_1024.pub create mode 100644 t/data/ssh/ssh_dsa_1024.pub.pkcs8 create mode 100644 t/data/ssh/ssh_dsa_1024.pub.rfc4716 create mode 100644 t/data/ssh/ssh_ecdsa_256 create mode 100644 t/data/ssh/ssh_ecdsa_256.pub create mode 100644 t/data/ssh/ssh_ecdsa_256.pub.pkcs8 create mode 100644 t/data/ssh/ssh_ecdsa_256.pub.rfc4716 create mode 100644 t/data/ssh/ssh_ecdsa_384 create mode 100644 t/data/ssh/ssh_ecdsa_384.pub create mode 100644 t/data/ssh/ssh_ecdsa_384.pub.pkcs8 create mode 100644 t/data/ssh/ssh_ecdsa_384.pub.rfc4716 create mode 100644 t/data/ssh/ssh_ecdsa_521 create mode 100644 t/data/ssh/ssh_ecdsa_521.pub create mode 100644 t/data/ssh/ssh_ecdsa_521.pub.pkcs8 create mode 100644 t/data/ssh/ssh_ecdsa_521.pub.rfc4716 create mode 100644 t/data/ssh/ssh_rsa_1024 create mode 100644 t/data/ssh/ssh_rsa_1024.pub create mode 100644 t/data/ssh/ssh_rsa_1024.pub.pem create mode 100644 t/data/ssh/ssh_rsa_1024.pub.pkcs8 create mode 100644 t/data/ssh/ssh_rsa_1024.pub.rfc4716 create mode 100644 t/data/ssh/ssh_rsa_1024_passwd create mode 100644 t/data/ssh/ssh_rsa_1536 create mode 100644 t/data/ssh/ssh_rsa_1536.pub create mode 100644 t/data/ssh/ssh_rsa_1536.pub.pem create mode 100644 t/data/ssh/ssh_rsa_1536.pub.pkcs8 create mode 100644 t/data/ssh/ssh_rsa_1536.pub.rfc4716 create mode 100644 t/data/ssh/ssh_rsa_1536_passwd create mode 100644 t/data/ssh/ssh_rsa_2048 create mode 100644 t/data/ssh/ssh_rsa_2048.pub create mode 100644 t/data/ssh/ssh_rsa_2048.pub.pem create mode 100644 t/data/ssh/ssh_rsa_2048.pub.pkcs8 create mode 100644 t/data/ssh/ssh_rsa_2048.pub.rfc4716 create mode 100644 t/data/ssh/ssh_rsa_2048_passwd create mode 100644 t/data/ssh/ssh_rsa_4096 create mode 100644 t/data/ssh/ssh_rsa_4096.pub create mode 100644 t/data/ssh/ssh_rsa_4096.pub.pem create mode 100644 t/data/ssh/ssh_rsa_4096.pub.pkcs8 create mode 100644 t/data/ssh/ssh_rsa_4096.pub.rfc4716 create mode 100644 t/data/ssh/ssh_rsa_4096_passwd create mode 100644 t/data/ssh/ssh_rsa_768 create mode 100644 t/data/ssh/ssh_rsa_768.pub create mode 100644 t/data/ssh/ssh_rsa_768.pub.pem create mode 100644 t/data/ssh/ssh_rsa_768.pub.pkcs8 create mode 100644 t/data/ssh/ssh_rsa_768.pub.rfc4716 create mode 100644 t/data/ssh/ssh_rsa_768_passwd create mode 100644 t/data/ssh/ssh_rsa_8192 create mode 100644 t/data/ssh/ssh_rsa_8192.pub create mode 100644 t/data/ssh/ssh_rsa_8192.pub.pem create mode 100644 t/data/ssh/ssh_rsa_8192.pub.pkcs8 create mode 100644 t/data/ssh/ssh_rsa_8192.pub.rfc4716 create mode 100644 t/data/ssh/ssh_rsa_8192_passwd create mode 100644 t/data/text-CR.file create mode 100644 t/data/text-CRLF.file create mode 100644 t/data/text-LF.file create mode 100644 t/digest_blake2b_160.t create mode 100644 t/digest_blake2b_256.t create mode 100644 t/digest_blake2b_384.t create mode 100644 t/digest_blake2b_512.t create mode 100644 t/digest_blake2s_128.t create mode 100644 t/digest_blake2s_160.t create mode 100644 t/digest_blake2s_224.t create mode 100644 t/digest_blake2s_256.t create mode 100644 t/digest_chaes.t create mode 100644 t/digest_md2.t create mode 100644 t/digest_md4.t create mode 100644 t/digest_md5.t create mode 100644 t/digest_ripemd128.t create mode 100644 t/digest_ripemd160.t create mode 100644 t/digest_ripemd256.t create mode 100644 t/digest_ripemd320.t create mode 100644 t/digest_sha1.t create mode 100644 t/digest_sha224.t create mode 100644 t/digest_sha256.t create mode 100644 t/digest_sha384.t create mode 100644 t/digest_sha3_224.t create mode 100644 t/digest_sha3_256.t create mode 100644 t/digest_sha3_384.t create mode 100644 t/digest_sha3_512.t create mode 100644 t/digest_sha512.t create mode 100644 t/digest_sha512_224.t create mode 100644 t/digest_sha512_256.t create mode 100644 t/digest_shake.t create mode 100644 t/digest_test_vectors_ltc.t create mode 100644 t/digest_tiger192.t create mode 100644 t/digest_whirlpool.t create mode 100644 t/jwk.t create mode 100644 t/key_derivation.t create mode 100644 t/mac_blake2b.t create mode 100644 t/mac_blake2s.t create mode 100644 t/mac_f9.t create mode 100644 t/mac_hmac.t create mode 100644 t/mac_hmac_test_vectors_ltc.t create mode 100644 t/mac_omac.t create mode 100644 t/mac_omac_test_vectors_ltc.t create mode 100644 t/mac_pelican.t create mode 100644 t/mac_pmac.t create mode 100644 t/mac_pmac_test_vectors_ltc.t create mode 100644 t/mac_poly1305.t create mode 100644 t/mac_xcbc.t create mode 100644 t/mbi_ltm/bigfltpm.inc create mode 100644 t/mbi_ltm/bigintpm.inc create mode 100644 t/mbi_ltm_01load.t create mode 100644 t/mbi_ltm_bigfltpm.t create mode 100644 t/mbi_ltm_bigintg.t create mode 100644 t/mbi_ltm_bigintpm.t create mode 100644 t/mbi_ltm_biglog.t create mode 100644 t/mbi_ltm_bigroot.t create mode 100755 t/mbi_ltm_bugs.t create mode 100644 t/mbi_ltm_mbi-from-big-scalar.t create mode 100644 t/mbi_ltm_storable.t create mode 100644 t/mode_cbc.t create mode 100644 t/mode_cfb.t create mode 100644 t/mode_ctr.t create mode 100644 t/mode_ecb.t create mode 100644 t/mode_ofb.t create mode 100644 t/pk_dh.t create mode 100644 t/pk_dsa.t create mode 100644 t/pk_dsa_test_vectors_openssl.t create mode 100644 t/pk_ecc.t create mode 100644 t/pk_ecc_test_vectors_openssl.t create mode 100644 t/pk_enc_pem.t create mode 100644 t/pk_rsa.t create mode 100644 t/pk_rsa_test_vectors_openssl.t create mode 100644 t/pkcs8.t create mode 100644 t/prng.t create mode 100644 t/prng_chacha20.t create mode 100644 t/prng_fortuna.t create mode 100644 t/prng_rc4.t create mode 100644 t/prng_sober128.t create mode 100644 t/prng_yarrow.t create mode 100644 t/sshkey.t create mode 100644 typemap 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 0000000000000000000000000000000000000000..380ee630f97cfad35426c9775708d474768b6447 GIT binary patch literal 5000 zcmV;36L;)lzdVHFl2v;NWRG#2)0sdYPEq2}GjZ(-kKJJ`Trn7J zD!iNRJKDGmg~@6$(^@=AQ*>|b} zR7$@ukuR!ap8=Wl$b-t_=jf&_#eQ4S{=*c)P_b2&ak4((5AIBJ)50|@=RStC-( z`m!aO$O`4Yz9UB(&c$Xk@heNnzgn7AT=xXk+D&$4j-?7vv%nc@rT-L;DKs*7x_vq~ zfJ~+h>KvYmlKe|0?Xn{TI|awm@IwhMk{Q+`GUU@`cg$cd6IJLV1bEwB=d}&_;q~cE zl)tK#pn;^_mWfOq!3shyw>_86lxEqPPUlw=K8g2iPL=+7D0n$3&#TbE-6vF@CX8ly z_JbVf?WuLz<$qnzp4F3kpTKQl{;>+6x;F8CW#A zH7~JzB-71=qa3kl4ITMh)X?Nf+5`yHF`SM785raQsk+p~+M7cLzbRfT5JDJ~2h?P; zBJv_Eu#*=;2m^aSL6hLY>xi_%gpYW6S?OUgEC(8JdFNRWtpI3`%LTzMwwzxCf2^2O z(uk=pouocY`IHx&Bj09IfbAQIiV>5}JYahcLU%GJ&{zb->41wmZ~hoCFf6vQ_iZI36iL6aj6+$X$?+LdjYKbwYd=QZ2HE=9tJX1KB^8x16U>gk>)Tv} zRX#dM%@Yhfzr3z47cPLGgW!m}zdMwF4lS6k`CXzg-RBJnw)_j*k*?3FKHihB)^ z?vx<~HtfBIu#N_HA9+l~_m3Phv~B$`gV({IMUFOR{qbs09xgbW4vV1&!9HReXoz_ zkhY?BDmZL@AemJ9$Pw-k9_kOR$~uatoj2BIdg@dnfedMU?u1e{U_A_IAPNqXjsbEx zk?jLQv79tn$X$c6Q|Si|!*((J4&^9er8uWN{9c)}zI^pN1AHdovvBF^N_r-@g@wB_ zB(#OLx%87>=Bb43mesZQ0wd*J7Timw-8mvSuq%+IH{)p$tv6YNInSuwAC_(*Yg<6R zhCTlKWalPbuAW862dQMyUFQ7F9#e+GF z-h$fi|6?;pC(%B6%Vx7JB|K0?D`s%FaAme*xkxPyKS&*P zeC;h*{}rBp8Hqat`1^fC_W!iwB(bV+{}2EVN}^-eMK^dDZRs9#5?H+s!RLM|6U6GE&_$~E)iXIFbMTJR%G!HXg|)?2d&DhoIu;9N5(LL+Lqt#g^Kl;`@gg<~2$ zjIUHd9o1@5v`@p=+Lm34|HMP6Z;eY|H;4=r&zL+Oc|0b|?h%fT(1)jdP}(pUXc6*H zgptdfHgq)_84Or|(ml;KRG@XWrO$+a$c)+JNM%d{+)*dOm@8mIht)1Xn>5y1E@`f| z_DTlg3tQ*_DAxMmSb+iktS$cPqI9q~DZxl88)D${#OB-#w8B>w?ZZyu4~|K|94GZ-cL5|qhp*6p?$UQ=)~!84}4rSo*m8vj~v#d(e@f0l$`Jn%TX)a27O&u{UYlJ3fWxQs0=I$O37T+jA z2!gFvP>xDn!@Ww3rR5^n+PYjc_Xq_yJh>=J)1JIN22Eu zt7ir%%C-mCqVG?l%~N#^3JDna^XrPAO7S#<%79JKkmww5i(ffECj3drMwfj?D#?wa zBQu2M>+9NiMr&7|O2s7SP6ev@Uh19Iw>5^8?{ix&`I+OeAVzV!1Eu{6>(Y?27SCyw zV3nU|f@XN(8*e+Io}60FI#50En6(&UQv|f40EF^P#U^wg9H0)qvG2!t%ql!UyXf2a zGlNt-@|=qzn>hkQw+xdv910EfNog6wP4Hw`ttb3!It}WFt-DJmOyN8?@ZVvcobx}c z``z^pbFNN#rM6M?tZdZRojn*6TJ}bw8boGkQ8%=m-h5O@lHE^tQ}Mt~Wd3x{=rN9h z>m9o?I(j1ecMpIp>b~Qpq8VIc{hSAVA94KA%$sT$YT`k42Xt0+Bn^^$Agt1xK4 z^Z_GJL9op!aB^>~U{qdE6?!{fan`#jHfHkp7{jCpkASxSws+N_FvF&@7B_*U*ut^J zCxjn39BSCd?LY^QmiW0_h9&&G$^#q*RhhWgMI?F+n`rD;DN1Y^3)`T=%MWFkl=o4FDwqDL(jHY5V}wyB>_=z~dFt-hzJA!M8+DEe zRVVOd?divnZxU`ViRAhCd+*4&!GCze`+-8c{;7jmL3Jl&m91f);)iO0u z{f`X$q4^FH^{) z1*e2`zwX9(ra!d&$?}vL(-TA6fqBcb;T0I>jm}6WFGk_v9al35<&G)Fi73!Kj*^9a zpA?sO^jzZ$03WjQFR?EBz#i@C8!#CG4_KP#5S&Jyc8ojVei*6YW%o zS(QSjK_FrVMqq=Y@JjcZJ~4>w1Q;;9yuflL`{(Kzs42?*WYZ6hCk-%eRKHDX7UCWv zAUrKQ^qx`#=ix2j8)8z9_Lt(b^17dAMf+KUB|oz4HoA{ED(41o2H=~N-rOQ0ImnuK zCdv_YT+A7a{~Y$B{7>Z^tDd9<6NdP_^_sNVP!#}KcbSi=%!|8Br852{4%Mj4DFaJ$ z{`!TqtyWNtMv4O1(zS4Sde&TpvMa4~eiM%IM;|<20Kg9@t2r5hat6@CcP(ohhgO0* zO2>~xKqn^=2cGwr9Yz_Fx)(jx`SxoAI(@K)&24W+2FbM)OH2M(3dkI=k2|-u0AzD z_fDL3<1xUQQfs@}r>rCNhP0p`2o3A^Mx7@(_!dQSvT#m`XV%S0Nh4Kcybyi7Ci-Nw= zsV`n{q`h8NS zu&eR}REfINSysV|^x&dk`QF8o0trR~^q)f`PakNYW%q zBoMJ;R4PFNAAhuJkZx(^<2++@18gY=jowop_6*~ATv2mJ{9EX>;h4lkA|EFB z*yvQI&{}8Owv(XdqksB^wB#{g-jg!7K<+A^V#faMBsk0{88d;1dQWcpik5juT72uq zNwO?m8K%S}y94?2!P(H@XRa0huH)i;-nvog$8sRlzKZVe*bJ(zL5hznQbqWuv?84;R>BnnSqw;2d!% zqqV*BzINr^`o}%qgC;nv<+rzCjTvRYIXyiA8w+LOMAT6Rpd9x=YMF_U)X(_JjImiX z&QO?vUlwM1$!76);|@H?k_=oMR8)MJJI)c*g`2z^4I^dZa_Wn`DYGXsbkMm_G4F4bBZStSrdFc3>M66`30eTa z9RGL5lElf2r{tOMJ5bEKaO+~w)~txU}Ilz=J*>9H#OLt&7F$g+b$h*2ak~lzd57#-e^zvpx%7 z3nGBUmv!>sTczZrtwSToD$y_fi1DSBn;u%vRSk|MqQUl!mY0tcL=x( z1o)o#5W0N}I{!ww-}_nxLlglWhGG~LR4cs83%hAS4Rz}gRA?0}ZxY32*Te7y@Vy2w zAJJKB4y01cANS)pQ_AO})Gp7Rvt`0zVtr5?JdoaK2?}FDM=GNW{a&Kdd5DZHo&m+4 z&aRv&Mog3cp&dweVu9@4SLA^r+*1a+C^vk03KPBBXH|rZ0WE|H<}<(5 z!!dH)n@v(>vW28NhUyP{AyO%5<8tU(oG~hK!DZ6SAWjhdJ}pj#6fD%QyH&7bI7-V_ z?j|sOT!9t&-=YQmsVDy&t2CC;`OlPswhW-5^KIprZAJ+%P*X~h5Z^`+Dg_tlc&@TQ zn$xe3zx912AMVMiuuvG*dq@w9hmke((l^&Eh6%k3F6Z=PB_dvEjHn+#PjS3a%Bidw z()hegJ3V0_$}uU7W9tLs61D>pC{H3h>ls@K4pFx55DDsS4xMy00UWM;a4AIqE#N2wgFE=1n^q3xiUC}+Rp{O4t$l?vyjk2QJho_>lQ zwyp4N2q)}jyz&k>1b;L9dDxi9qu;FlsDWDwbj;BzZh-VGWQ$21!U5(mE&IggteFte Sk=yc&QN-g4?jrd|I)?!BU$%+> literal 0 HcmV?d00001 diff --git a/t/data/cryptx_priv_dh1.bin b/t/data/cryptx_priv_dh1.bin new file mode 100644 index 0000000000000000000000000000000000000000..1b73aebc8b9e4743c36c0b7a1f55a7478b83040c GIT binary patch literal 529 zcmV+s0`C160RaF3AOisa0IQm+KzB_%)ONKmg6Hlnij6?ch`&R5g?yA$W~zaiKW48h zE2wF9V3#bm3C@g%*tqO!X<6-M7h?r@Qmo2Avk{$h&Ro0Gr)Zb!yGiX>8dfp&6aR;> zvN&@$N8OJ^msmEKT<*)VI9lI=#XN!0@xK-Mg3%T_`FmuM`>0B7qhS*;qTXleEHdK*{NKthjah!BPM!AMW7!=+9+a6IOD280(TmQmd_IPJf9 zC!mxW_=+-XcJBn(5k=U2eJ#%$B#Kcf50GGK;g_`8>ZQbjh(-4FJ zNEP{gPj7U`kb;8JPn1r24Hf_ynTzA)n-rYUQ6$_vjr zsbYhg!oaNnG>7XO^EcW-qms|2Y5h6NEK)o$ni)90tSE(vtL!1i2Br%mt(v}s1D29f zMwQ{?0#b4Nqgj#u`sj>f^hGPWdF@-rV2SQ@GQfDs6In@X0~1fjBkeB%KGRKJH)m=u zQE1WU(P^HVdz`W+KZjT%883h_x?(w6Vx%}-9#di{+fx<#V@jb{GnVFc&X6NK1rz#^}M@T&7 zZRwqf34P)|rKlhDPvr9=Pf=YB4z?)Y8b8z5=M=JA^eliX@4aMGn3ly{9w&o-()UCx z)h%(I)@r@2&&?$mMTKxhJiys;zH({7R;+7$YPhoRUR9N8zZ!QH^G~W5}+h}n#^&(^3qH&($ESveB8I@IML^S(; TWwD!~Qtcq0+kKDpp(4VB6XFD@ literal 0 HcmV?d00001 diff --git a/t/data/cryptx_priv_dh_pg1.bin b/t/data/cryptx_priv_dh_pg1.bin new file mode 100644 index 0000000000000000000000000000000000000000..5e9bd0e1238c5bcd751151e1ca18566a25ef9b82 GIT binary patch literal 791 zcmV+y1L*u00RaF3{{R6103uz_Xu}0diN$122)1Yv?3!W1PijMc%slpXYdvlUaJ`m= z*?BCb;17xJ%-BHdg8w1sJgCtD-~I9@UE1E}kLLSgsxAqJ-(aps(a8)v5ihbJTv|pU zFjeCxJ(&T`-3h57LVN#?IxUmpQHC5W=dxA+{kG-gj|tNrB8d6;>?QMXWdV3$EUc}t z(t8bEcn2QM&o^`hpPR8%^Gz5g!qW=0&Ea8&65nJgk75ja(^q>P$*V;&_m*YiKEP00U9 z=!}M5QF~|F)U*v`y=Tk*QuS}VXJpV~o?icBH5&1s^O!eV+~P02^Poi9vbO4~MA4^@ zPxnBG7hY>$7(ycP7WBp#g-7`d3f!Y5UZ)g{wSHcOE_w7g`IXPZta+dvEHa!2P}N`B z+{XI$)`bX??!a^Xcg%m7*wYu(0^+EiL16$LuJk>u4>)c}hYdx4u`I>64sTZ(V3sk< zi$k5Z((p|9r*vnJXaN8K00IC300960|NsC0|NqGk+M*$7!ZgIjVvB&>9MLHPP6&!; z%ya?^zNR}9n<7z42zib)1l{kI8MDngLmMzF3T^UV6gN-dHEnHC!bRkTwRU1&e#Z1n zLg}VA?Q0AFT(pQWy!BoTZ|ALdCYW>M_qTRp-6e7K=wzXh1uNH!c* z)0$}(KdAjA&tHROT_fD1t(F{O^Hv~*QoEkjDF<+tmThMYHBL&rm;~{3YzWF2A$&5B zUPdl9&O76tcPtnVh69@?gQDyQqK~!3UGQ&AQpw&c%l4I67Z^E}Nqp*+YULHuCK#Cd V1rQZ-j#`SWs%ZcJ|NsC0|NmB3g6seQ literal 0 HcmV?d00001 diff --git a/t/data/cryptx_priv_dh_pg2.bin b/t/data/cryptx_priv_dh_pg2.bin new file mode 100644 index 0000000000000000000000000000000000000000..9344acb867099ddd623bb1e111f84f46fea10bd0 GIT binary patch literal 791 zcmV+y1L*u00RaF3{{R610A3!7XMce^T}`w#x{?Q~Ic>?eNgPilp5R1#&RG8r8dIdr zo(D*^dZzv>^l5fLKeMiBQ-O%vHv!g(sy0kNRjMvIO?AQU1_i{WO{0Me2BdrH&v;vD z#J5Qr!(3c?hFeXLA>ZXSwYk?S4ZXI{zs5 zas2rVL<=$GtC%Z_mfjmP^T1gmXQ)}4t8aNq;a9d_ySbn6S`yt-Dv>EgD2yHClS~JW z_lX1Ph&j*CWDX~lQ2+q|03m8frZaH4C{pjN89HfGMISS?TK-{J6<$a~;M+{F9Hjo+ zVxBC*yZmP(@BK2P_aPG%j&r1z5NYbLW5^YWD?Cut9A)`Fk3^GhAgs1m&UCetfUDKL zB`gA{oP+WkqB0RSM81wafWpuM|AbnJq{VQc6g;oZDKX--=dwk5nVOWR^vLuOSzRfb z1^Y>52QNnBTnTjsm?d)4XbtEj8q--Y@K)@)(PgcDX7>?YFb6Zg#33tF@WOACI$`mr zTA9NB{i7nF=U%CEuQ8MRBALTf##my9R3Gh55gHt3X_s$lffc~e&%K_t&_Md_rksY6 znUsC$$h`uv;?-Q8PXPb`00IC300960|NsC0|NqGk+M*$7!ZgIjVvB&>9MLHPP6&!; z%ya?^zNR}9n<7z42zib)1l{kI8MDngLmMzF3T^UV6gN-dHEnHC!bRkTwRU1&e#Z1n zLg}VA?Q0AFT(pQWy!BoTZ|ALdCYW>M_qTRp-6e7K=wzXh1uNH!c* z)0$}(KdAjA&tHROT_fD1t(F{O^Hv~*QoEkjDF<+tmThMYHBL&rm;~{3YzWF2A$&5B zUPdl9&O76tcPtnVh69@?gQDyQqK~!3UGQ&AQpw&c%l4I67Z^E}Nqp*+YULHuCK#Cd V1rQZ-j#`SWs%ZcJ|NsC0|Nn&Wc-jB} literal 0 HcmV?d00001 diff --git a/t/data/cryptx_priv_dsa1.der b/t/data/cryptx_priv_dsa1.der new file mode 100644 index 0000000000000000000000000000000000000000..31d68ae059074a2cf08c3980535ffb68f36f37ef GIT binary patch literal 855 zcmV-d1E~Bkf&)_m0RRGm0RaH2_&KL!;7x#nOL_Vq1eU;)PlbRFVL177h;fMZ@fHTe z3fw?_sQjXw40BJ*kkT##$d=G{l$m5E@UA8Ne8y(M_V55(VYHD{FSM38--|Z$HR|pE1`&G=lfGFOAICA z$%`)HiL6jnUHFPbQA7eanv(CN7D|+T!2An;FpXL|Uk^+z_HWwG@@ftG1sLj%MK4o9 znyCzANa*hFj1>?-lcYe+z;M0)hbn z0EB*smeDMm@sHwzu6osu*YkH4-X{%@)?{Qj<|aJGtMGsNtx6HRvMajDVbP{6I#`M7 z+L$Ol9|!2$ZGtK2dPFJNlEyB{cH=_^I<9bj<|K9h+tU$7vh8WQN%Rcd6p8<~zi;D0 zCE?Bua8^`%xH**v14)HUwp*oG{(-VtGf%FVTG@FZkzp284|seZ-lY&o|1okCl7S;Q z$q=qVpGHEKqs-c$i~1K~2GDSm;4lQ0%ZA<^x z?+Y~Thc_86vh00CCwWdtCM0MXtHP+McSi9Yv*=Gx%jGQWz`{H6bThS~K#i{Bp8|pb z0RWG71lND2EOj|nBv__Ab`iHYx6~MKxi-XNxGKU=9ytDDeV$iVLDw!kcf0j__9$H9G(oxC=9D+mjvFv4(M%g*FrUJ z=Pa})tSF-`EZ}p@{H*bt+opP3Xu`HQRdPazW6((Z82jHKZtQVS`U0`0J1~a4YZY07 z<~(%G6BE8XZ-n$%gg0$m=~$rv1b&LssbUcmT=|mT`nMh0F*8Cho)J3`VR~Ckj}`(R hY=9X7taResaZPop_Lh``&jLBoLaTm1GM?Dfo(DIqn&kih literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..f125f2d88826f6910890af94a9ea5d0c74bcce9e GIT binary patch literal 853 zcmV-b1FHNmf&)q)XHDC(gFhFS?CbJ5e_xNf~n&x z^&#j|O^OBWN))^rmw0V8W+Vd)#uAXmCk9eNx&$j;7Kzxb3_#&kvG$X(b>Kisa{Whc zTW6UQj7(4kiaPq6LIh$qpRLx}h{W2?2XLb98P;5~lF@~R2)kpQM9F-HQO6M0)Ynjv z_Ltct{|r@>4-FSY1Bbr?HXkhmH$1{-rCdWpcWIwJrISprn7T=BK3GFi)xZ7yftay= z>cNvs0Ph|r{Lr@3hdn1fqZT+=fMtD#5Xmcvf4(>6k9*5wnJn3^tLQWAmyNMb^N5N* zMF&(Dvxi9??8rc$YCMwy9{}ZnNA%*BfKkHo-tSAy`P`3b#^ip0Fzs5|J^FsX0)hbm zNMme4IjiuTkH$a<1*rpXg7Yag;HZ~Ot%dCBd(jYR-ZVNLCtYt(Uv~E-3lbNwx2WPq z0Jn>UOk()_tN;iHo4LbDbTuue}%;fU2A z`Uo;CeqX~mkB_Ez64z4QquI*?|Hy1pDaf6=>KX6lU1t#Er^-;n)k08>KCI-wlX880 z7?mLG2t*U)WaRcg6Bh!IrP7cj2~57MoKKR(w1K0sXrw2OA&J9KEnD~Joh0)hbm zS4>V`xYEo?{m99LXNCs!>!E(4s;WN!n7=O**nY^=`n@*p;$FGA-|8DvY-Gz~XMHgi z!rt8I%g@+Zl5LGR4sw`7w5Z5ryh*8dh9b-KPp6>CJ37-T183k#@}vNldyM!rdUhRW zhx1Ja3i%z5{qP|jv zm$+$8$*u@=Cmkx1+C@?;j)8@M{nBl>H|aM(4`77ud`0|Yc>GO$)lZZQ(qC}^XvMdo zJ5}sU{ZAzjZwKW2|E{WCfI;@3$zlA1TxY@22KuuE@e?1r^_-u~d^h8uZWDjb0v=os fDM7N&)6cS^P<-qR@#i=6L#w>K^@X53N>VV(8~U8q literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..e5048b16167c64ff90c62e4b0f00ba144983caca GIT binary patch literal 279 zcmXqLViaa#WMolzpF1Ib=~W*o@#(6Ew(?}UUEzAanuYn*`M3Xr#Ls+c_Fd4p)Sz(@ zP^p0q8@pDU$2nU@MkYmu|G2@w|NsB!8?do3GO#eRvpBL;?n|rtd1v>U&;?0T&$V;2 zGtK^UTlbvC&B#xU(PBTuXLwlMDpy;4BsF%)?>~Hk94r2cZ}C{x8X`Hz{X+k5fh#*O zZTq)t-JNIaJr-E+zZBPV!OYPS=)8q4%uWm}2Qs#Yv{!j;)>xXk>)4f)71H8Q)h}HO v3fI~#xOZ{5ZovMY=gF=UE={sx7Svg`?y+C+iNb7W7ds&nCO7AN>z*zEY*vnJ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..d1e45528954377d74020c1c12642711591340529 GIT binary patch literal 113 zcmV-%0FM7KZvz4cfC2#^0wDmaQ|(AAP+r5kPNJo9gshqZm~kx(^@ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..3371ebbeda46d95bd5a75d7b1242198fd51883ed GIT binary patch literal 279 zcmXqLViaa#WMom`Yhg_9zqZHw*QL6r&dGdV6qe1-Z@y|E>hhXNIx(1G?t;dp291k= zN)2?_*tOa`&e<|DGAT0r#|{4d|NlqdfQ^NbfrXKs#gV0QUs~PIJG<9}E=ZbsuAQ5m zY4)Gny5}@*Mt*9H7W*MS!^7%Ux!U3*sj*9b|KStlSn*eUi^sCo5Xm|27y5q-T-kwX z+rM4w?mS!XvA}x&rMR98W{!?P=Ph($c4A;@c`W|(ly=2~WtNSuMbnu6-J2-uwfJ-N vlR$sjisP3Kyk4sJ%3aVwpUHjyo~2UdOBz2-x%cNzHFM6iA1_(EOOp5i+zOEw literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..99c62e7f029acd535e7b38af2c9a17c05bbae4c8 GIT binary patch literal 113 zcmV-%0FM7KZvz4cfC2#^0wDmxSVLh7)U2Ev1Af9=2|8lF5>QEO*_mUwtqZN~X6F|I zAWXcKAq;Rb4vXWBMRC362)fjAS~e}8x+<3t$TSe_!U7=x?K{5|Dsf3U0a;+@Zy^ZK T%HL~2UK|8SV)t0dreTrhA+{{M literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..a01cd4f4516ca267b53476bcca067b649f15a05e GIT binary patch literal 1190 zcmV;X1X=qqf&`)h0RRGm0RaHerOe9UJ^8}*#K^$TgbiZN;(3`3#&U69_yc1fuW#bF z&^Up042vr>B*WR2$P>seunuw@KsTItHPTx!L)j z$M_JBfNDw-xRO8zDciE1=tjqtQ)riNWu0D`-j-yU;4k$gmJ)nFFnY%8fDG;JBFyHE zwD?{wolhF7dAvP`fWZ4NrCFcj>}P~evPX4oRcz9+Km=9Z zK~sbdbezd+c)t$xd27&ETWYOs7B~%foN+*O8tE1CI6;zF5Jq-*@O<$8(tWxa?}v@L z*o>xVs!-^f8`~aKZbn1_=l?$hHxDOZ7#ls5WGp#|K--EKHDuc7t6Fh~2PQkUJR=3$ zdd*iJJ%uL5{C(3k5CEv?=3>e3pl`72WTMu3dmtBOA+(*HHUitZDnx)&A`=$IM^;EE zY=DOAG!9~7(~fwaGOJ$b0x1NgNQ1z}DtDc>S#?n!`Cc59Jqmf=IwbB!`PLme<9X!1 zm2G7`WDHL?T1`^b(l5FAUQ8hU0)c@5)9(N%|Eo}rCv(PG^+(so7cGa`ohJy|+6i1Q2EqtXGs9R<2V$CK0)c@5 z{0HP~7CftJgSg~p(P>jlAa~r}?5>Z`z{9OBx-3fq(l;Y%nG9m7BhoGqah&ZL9wQt` zGW$rD?A$INIcSX{Y@5~dz^-KS3j2tR z6zczsj)Fy&K=d%|=iql`tH-H{`C*ISgDP95n{> z8i0^o4s03->?<_;y4u3~2X`VsM%#gm-^ zfq+GqC`&15w=6;u+kTHEHVc@0fKg4UC9H?tfCN_q!}61P1|Bk0X(_7eZY{hqNQRdC zy5n@PP3qp9EnpGJ{H}DR)qN883}QHN{>vt6u61BQMZLK(g&OYpy_G~EZua7RMFLP} z1Kuhqc}J#GvsN+Q>yDh#8;XE-=mnoI_hABofC!9jKyQOR_dJVpMM&T{Qemx8^cZ~p z75DwRLvh{9>x;p&gUsV Ee0e}JrvLx| literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..ee817e6a93ab4f3a8fb5e9675a00a1f9d9c6b03f GIT binary patch literal 1190 zcmV;X1X=qqf&`)h0RRGm0RaHJr?2IVJRd-On#;#|dNg;KHQixp=oZ%{Wx+NSyO^gS z^W?xbZz)EQ9K{Sgk6bZ^x19W*iM47*ovk>YZCUKepMlgjpXx@qPW?(kY`8q6Hq%P{ z&z1_`Q+aZ5_yb!fH_4Q|g8WS~ErN6cz&W^9Y7P`&Jys^6C4lk{Slz29nTQ6Me2zuW z2GDYI0D?C(b2G|c_K?Ut@c&N(n`aP6>>@ z$9C;%{jNesWz}~GR9d|P0|5X50)hbm0sujlXx@^R5}p%B-xTNr{B*DDBrA60I2E(n zkMXm9E)qszR{iWB>s2M*!LvG0M&eIcyh0091oOYoN0l;{$My0|OWBNt(A@gNbjaTT z58sQ*KEC1YG{D42m`QZLUqLU3?NV2i57EDA-J7J$mXl7JAg}BdYqNUT1ebdL^94qo zwx;R5wn>GN(>+5oR(Fxoi*~oa`@2l%S#&p4Xx1(I5!ucBZ$%kvH zBYx0COq`u#2Ip2ZLW!RoJ#|^qAqGtm>xt2E z>11pI80(HLKpNO9^Fm#byS~yw(@~35bdvKt`cURSVZ2A%9D7CP*mqv{g6g;tcNv4~(@hiA3(b z7lPfcW<5PLleQsmV}0)c>WyfNa3PiKQ`H8tmgX5%jE8`kkOh7_n% zHm(N8K3#L`OG+>DUSl~8(1} zpzsXU@OXlRE?%8%nG`roqz>@{mj3CYtYbu>kWQ^LBUs!QsL8Y(U3vXwBi7`xX_%uW~rI%Oor2 zk+BUgPnb7*owc+2t$E~hYVAd8vpCT`Sa|}0fP68vyr|u6v9nIhRU^`O5oWR{7aIG} z{mAnkFf0?swK8F!o(a<&xjs_M+UTB#JN<0DM8YSw_=DH$$84b_54cC=*_w+vU%xl^ zI^9=O5IQ^(o)#^SbIq(t>@RFEw~ZUMVlFq2Gt8I$`(EP|?~Ddn2w50o2dHo=bNxIP EM-hQWvj6}9 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..4b2d81805de47e39156dfa7e4f74f3c31f1e96d6 GIT binary patch literal 269 zcmV+o0rLJA0RaF2AOisa0IQm+KzB_%)ONKmg6Hlnij6?ch`&R5g?yA$W~zaiKW48h zE2wF9V3#bm3C@g%*tqO!X<6-M7h?r@Qmo2Avk{$h&Ro0Gr)Zb!yGiX>8dfp&6aR;> zvN&@$N8OJ^msmEKT<*)VI9lI=#XN!0@xK-Mg3%T_`Fmub;8JPn1r24Hf_ynTzA)n-rYUQ6$_vjr zsbYhg!oaNnG>7XO^EcW-qms|2Y5h6NEK)o$ni)90tSE(vtL!1i2Br%mt(v}s1D29f zMwQ{?0#b4Nqgj#u`sj>f^hGPWdF@-rV2SQ@GQfDs6In@X0~1fjBkeB%KGRKJH)m=u zQE1WU(P^HVdz`W+KZjT%883?QMXWdV3$EUc}t z(t8bEcn2QM&o^`hpPR8%9MLHPP6&!; z%ya?^zNR}9n<7z42zib)1l{kI8MDngLmMzF3T^UV6gN-dHEnHC!bRkTwRU1&e#Z1n zLg}VA?Q0AFT(pQWy!BoTZ|ALdCYW>M_qTRp-6e7K=wzXh1uNH!c* z)0$}(KdAjA&tHROT_fD1t(F{O^Hv~*QoEkjDF<+tmThMYHBL&rm;~{3YzWF2A$&5B zUPdl9&O76tcPtnVh69@?gQDyQqK~!3UGQ&AQpw&c%l4I67Z^E}Nqp*+YULHuCK#Cd V1rQZ-j#`SWs%ZcJ|NsC0|Nq6i0OtSz literal 0 HcmV?d00001 diff --git a/t/data/cryptx_pub_dh_pg2.bin b/t/data/cryptx_pub_dh_pg2.bin new file mode 100644 index 0000000000000000000000000000000000000000..cd650251c34c8b2b831f5e46f11a1da6c0fd8f52 GIT binary patch literal 531 zcmV+u0_^=40RaF2{{R610A3!7XMce^T}`w#x{?Q~Ic>?eNgPilp5R1#&RG8r8dIdr zo(D*^dZzv>^l5fLKeMiBQ-O%vHv!g(sy0kNRjMvIO?AQU1_i{WO{0Me2BdrH&v;vD z#J5Qr!(3c?hFeXLA>ZXSwYk?S4ZXI{zs5 zas2rVL<=$GtC%Z_mfjmP^T1gmXQ)}4t8aNq;a9d_ySbn6S`yt-Dv>EgD2yHClS~JW z_lX1Ph&j*CWDX~lQ2_t|00IC300960|NsC0|NqGk+M*$7!ZgIjVvB&>9MLHPP6&!; z%ya?^zNR}9n<7z42zib)1l{kI8MDngLmMzF3T^UV6gN-dHEnHC!bRkTwRU1&e#Z1n zLg}VA?Q0AFT(pQWy!BoTZ|ALdCYW>M_qTRp-6e7K=wzXh1uNH!c* z)0$}(KdAjA&tHROT_fD1t(F{O^Hv~*QoEkjDF<+tmThMYHBL&rm;~{3YzWF2A$&5B zUPdl9&O76tcPtnVh69@?gQDyQqK~!3UGQ&AQpw&c%l4I67Z^E}Nqp*+YULHuCK#Cd V1rQZ-j#`SWs%ZcJ|NsC0|Nqeh`E39I literal 0 HcmV?d00001 diff --git a/t/data/cryptx_pub_dsa1.der b/t/data/cryptx_pub_dsa1.der new file mode 100644 index 0000000000000000000000000000000000000000..ad4e7a12d698df5c337a512632b2956b9da2ff6e GIT binary patch literal 842 zcmV-Q1GW4xf&)e{f&w@O2P%e0&Nu`CFoFUr0)hbn0IK*or)1zwfPzbT`X2`mf zfDd6f`E!VIi1qOn2E+>7Kz*qEqMQtKPs@rUe5(Tq^b53Gb~Bfi|zVSh)1MY2fUr zW9ro{!(_r7efm)yvN%Tqc(@*xUT@7>Q>TR5$}^-(O`!M(x^IEZ%VE}4EC3sYXm7{E zk8LZVh-K&dQ!PsjCF048F5-!-P*q*{ibPRF0ymnH@1zz=lzqVb3x6<;S~_13OfB|r z+RpN74f+Kb>W)P(Q$d=k5Nz$2ye&YLUeAm>Jpvy9&|FNkUn$d5L@yugL#Dnf=*Naz z&_nMP^L~E|f(ZhG0RaGneu$RQESvF<;)AYw)sENmcNX3!4Ug7jWH{y~JjSc=fBLOT z5xlZ1y2)YDrYt&GiR#*zC_Wzt=-X|ADd>7cDcO?7F3EP|Lk2poaDL__b^qJb5k|7@ zX}U@D4BQln|F*wx<3c6j&JA!@RC~BNl?MY!g-o_vrC9!fvRN}vu9#Zcc_5Kt7E}*- zd>`JW5J>+qaubq)BRI(ru0fwhLYAY<+MkR17hwj_aFgIL1m3;mt^0=!fvygI*&?c^ zbuCyza8k{O_DXF_|JUyeH0_5s87{KyeMBdDPDmysXc?=*sHt~G@g1}1PfyF`EbPF- zJMnZgwV^x{u*DgGFyY+kaC~u_(J!-{|*xeAa{jNU*kB3Zr?x&`A3j z``;jL>~T-}0b zW1U3Fe1=iS5Z2V!P?7eR*(CoARg@167eoVxzXCQNEdw_^!e*shLqm6IpFO3MOs|-_ zNp3z^LsHeh{r!QMv3}~olS=^a9w+?Jw$q0_Cq1JUI9PyXeTERpD~W%;H|39e%VU`= z*{-YTGwhd*u}<@diatdLR2Q>{NgeFSK%Z(nlL8+A<$*`^;+B9>!t&nlOU(J)k7>r_ zet7Ne!l{O0RTv2Y(Y7z@SKmvKnMk?18;)!DK+4zmrSjN?CN{b5NO^sIvpon zZ%w;)xgrw0UTQ^N8b@>oJ4zG+YSz z$v8r@77?&cPe|d2)gSr@GAw>y!#R(Srgsw8Qr)B3%LD(&Y*Q)7ox187@8w-*5aXxH zP{Y+iP>nvU|AnXW46Xay%_CMr%c8Q1)RMi(SuLuv)t%N^5*8x62T?Dj? zcHld7Xu~Ur3&8_|0R;d8f&lKjvRWXob_eK8io-rVTR&)8X#ZH+h%a+pK3sK{izNvU^+BFpqor=ZC@ zI@2iwXW&WlqyU$DjQBKqb{%Jj^GyZ{`5lh^@E$4&a~VL4%7=duDi_>X+9CTtqMQ(3 z5brbJ4VT0KpophA{(y3rAj%7uxM@zwt_XA|9V(LAMN%t{frWtm(rvdl={GxF z#kY7YYYmZ{<9?z4x4@Mhn6~}fweHTd^&ShX_g{+ZxnSn#2y`B^69dbEjO`)qRbHDl zmS*lcb|qznwD?o?OV@(JwRQ{cT^z0(u)pVdvg?FPldPBpb(XDr>=%5ZFx%P1PRNAG K%{kw?rwagdMSq|G literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..269aea4cf85a38044a05de3094b2124d1241b832 GIT binary patch literal 78 zcmV-U0I~ltOalT300IFZ0wDmaQ|(xF z#kY7YYYmZ{<9?z4x4@Mhn6~}fweHTd^&ShX_g{+ZxnSn#2y`B^69Y@jWAUG-v@0Gg zvut!Nn#T0+-b7ii#h;^}1p3QX9KUqn^-{f8?t%{bOz!*lER`x>()el0y+3!VnRBN7 Lc*)vblEeo9%gBUJ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..c8150b36bc89d3c4572cb2bd41c3f0c0aca95c45 GIT binary patch literal 78 zcmV-U0I~ltOalT300IFZ0wDmxSVLh7)U2Ev1Af9=2|8lF5>QEO*_mUwtqZN~X6F|I kAWXcKAq;Rb4vXWBMRC362)fjAS~e}8x+<3t$TSe_!tHk*!T0ondAf&n5h4F(A+hDe6@4FLfG1potr0S^E$f&mHwf&l>l(51}E;63@m^~A`) z&V&tO&Ek2P4aRbDUibrJAFprXx6n9&bqtK=F6RkH5TL{C!gEs#9t{MQ_>yfYr=88R zp@?xmjx$9OJ!2XP^SwN#<(y|Yq#8Dx#- z>g!oyim+u2X_kh$6UpU3zRkAP}Q61b8;2PxaKp6Eu$l~ZV!Ze^WbnckLU zncy$=B$g6wpaH?IO(PjkNe)E}c&rs(HLUhk(HQFQr+Z0ondAf&n5h4F(A+hDe6@4FLfG1potr0S^E$f&mHwf&l>lyQi<^j65Gee45M0 zd3rQ=m^IyDY3LT$C1t@j6uX$GAoJwFHg73LkQ~JfJda#4hPRyjo{6<;MxCuVo^4s| z$)ADLH=pW8xK8~_LTtD^q&Cw^{LhvO-&1*VaQFjTCpXEIyn_5qGA)910>C-AR%#9u zU_DkQp(TLw4p`l*Cz*%_n0$^!&j!$Pa{z)%XKVV5*m~&KcLY}D=_;n`!g-%I)mO<@ zR{(f>5Z5DbzZI`r&pRNL*F)#(ndI&&fIt=)SuyOe$#XNxU*vNL8kcxZotyfK_?SJ4 s^&h}J=A@E;>R)4fu1X0-i%toQzQ=a$YW=Q4M`hJ_2vl0V0s{d60TJAUNdN!< literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..ed275559873453421809ed41996ff5a75bd4990c GIT binary patch literal 857 zcmV-f1E%~if&*0o0RRGm0RaHZ)XQ%TBO76J5s6`4BWi#kuEVg==H-yOvzzHq&o@H@ z7=Hg;B!_-hAulsM zNuty34Njxb%;WN(t=KWu9Z`~Pt4LKSxV3>N8FnaXdn}?!ADl>cv40_x=O$WKiumn} z9TH!fn+oq4-dcP3Xzod^L8^Ob8Vt$O&^A$xDu8<{dI8|DPyQ6w-ULRDP9v#`&F7qR zUDG>`nz7IYG?V1+*6%yKn;L=UeJuZu2!7@&OPc2Ka!Q~*!+_AO>O%k)} zBm5=Sz`~9$<}2e%C>@D=B6T#eC@wXagsI=z)c0NjrsKt9!(PnbIT{W{!j18<2cyS} z4w)We!|JqBAm;u1|e(Bkd-NLB1{R!>y3BL)e{wf|tF51**e%w|?! zktAYY!vm2-Ip|pRjIvxTk3$RFhp*wW6iD3i(FBCMq%45Pi{dsK)W)fn;8wKDJ$3>d z@ROiNN2S8mQGtOfK~(g@iL_H=4U?Eq`G!-}^^}qC)cHvGQpIFF6R-IPGekoA>RtkZ z0RS1GzI=vd)_AdOZtxAim0292p8T(~&~czqOEx5oa&4p1vLq;}jDXMr4;uxqp#82@+h#y>!q#H)au>0$-iy-RzM1Knb)Cx literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..643db3e1bc288850dd66eb163ba931afe7d27bb9 GIT binary patch literal 858 zcmV-g1Eu^hf&*3p0RRGm0RaHZ)XQ%TBO76J5s6`4BWi#kuEVg==H-yOvzzHq&o@H@ z7=Hg;B!_-hAulsM zNuty34Njxb%;WN(t=KWu9Z`~Pt4LKSxV3>N8FnaXdn}?!ADl>cv40_x=O$WKiumn} z9TH!fn+oq4-dcP3Xzod^L8^Ob8Vt$O&^A$xDu8<{dI8|DPyQ6w-ULRDP9v#`&F7qR zUDG>`nz7IYG?V1+*6%yKn;L=UeJuZu2!7@&OPc2Ka!Q~*!+_AO>O%k)} zBm5=Sz`~9$<}2e%C>@D=B6T#eC@wXagsI=z)c0NjrsKt9!(PnbIT{W{!j18<2cyS} z4w)We!|JqBAm;u1|e(Bkd-NLB1{R!>y3BL)e{wf|tF51**e%w|?! zktAYY!vm2-Ip|pRjIvxTk3$RFhp*wW6iD3i(FBCMq%45Pi{dsK)W)fn;8wKDJ$3>d z@ROiNN2S8mQGtOfK~(g@iL_H=4U?Eq`G!-}^^}qC)cHvGQpIFF6R-IPGekoA>RtkZ z0RVT13I1n#BC(597G;0Y!;3SppHwSDm^H^av@Xuo93_M(!ReUJod#ql zpvO|W6Y&zpWShtDXCTSQ=spl_RRBwsb`yK0D`}fCUE6zag8BNOzrPY=#sOnTBclx4 z^M`N1oQ5RVxsQBvQ+X~<0^78I{j~~mM&!^FgO|`05=>n&=R03`Y+U(3;=sURbhv!c zFOuDomy}|=Y{pyIog~q?H9>d9mc~GvzRg#BWK5;lmGw# literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..442d3e885c6373233f88436cecec7259ee7fe4be GIT binary patch literal 121 zcmV-<0EYiCcLD(c1RxQ$bA0*PKNrBu8iZwCIhCL&Bnf{1rR~`6CO96o*2AC*1_&yK zNX|V20SBQ(13~}ok_-eCLh@64r#lQ0#S(+IR4Z%#H&IE*I|zVtH1nG}qa b6g^M$Y%I4vK59YN?(#eYexV*eI*+6v0WsWU! u`F>`87Cq{M`@R?*ohi~YMa0(sOODQVJG(5$>+e3Kk&1eyQXCJK7o@yFYDg!xe|Tg z(mIy8Tb0k5{Mx#pi80!si7_0g*}#U4U8~LGoGl|GlOe-@{NNu*ngI$xY=deR0}zb| zpzHa=VzAjzfB7T3=TBzzv1UL1p(`mNJ16g7qoWYB2uFW_aC_9TFw5R9y^C|TT2H*a z{6_0Nvna!2(@9y2B^Oo6GIVC87cXh5I=iNrC6Q%S`zfV;-K^$)8;{Fu?mT^C@SOHZYF-uYnqx)e(by%`zKAhqxs{D>|Tvo zA~i2>847Rxu;Tz%!p3v5b&YeYoMme!yyA<;6C}rzeH*`+>)wx$;@#x2VR_Y?H#}G65;>= literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..3d0bcb8d7b0dff32d7eff3b3dfbb6e21113e85c1 GIT binary patch literal 414 zcmXqLVw}aq$jD;Av5=vFZ;sNvCdohDT6xv_s@L`>Kk&1eyQXCJK7o@yFYDg!xe|Tg z(mIy8Tb0k5{Mx#piBa32iBTP>*}#U4U8~LGoGl|GlOe-@{NNu*ngI$xY=deR0}zb| zpzHa=VzAjzfB7T3=TBzzv1UL1p(`mNJ16g7qoWYB2uFW_aC_9TFw5R9y^C|TT2H*a z{6_0Nvna!2(@9y2B^Oo6GIVC87cXh5I=iNr#gKVb`zfV;-K^$)8;{Fu?mT^C@SOHj>n6~lYJY%nCsq;kmB9sv0-`Dn>UhK zXO3zX1H)*c39}Icb45?^~BrD zZ?xVsi!v-Wos_j$a#58mLuXcc@sg&hvulc35?NNYpHkY_&1&Aa@wnV)g|#Jlverr6 z%V*Ds{O z8NZhPvY2RGnC{G=D}88Y#P4ghJtgI*f{PaYbYHNJW9!u=A@6zR&j;zM6oox*{ctb$ Lj^c^McMk#pngsfS literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..e2c77437d4385a1392d6f17b797f3e2174087eb6 GIT binary patch literal 368 zcmXqLV$3mUVl-i6*J|@PXUoJ0p682me6Q3{U`K8&tCxfM`4b zUC$pDgUyEe%OBZ2e=?(wHT&@oT}cVqIeGsY9fg=hIQj#G+oO(!S@w46U7V}cdgATn zH(KwRMHv>GPRd#=xu{B(p))JJcu7;$*)_#1hRmzlPbux|W;O5IcwFwY!rGENS?i?k z<+Eo*es_G(6ryDj%JeCAf2d}TRY;sgQ5n~EJYGDW?A!RoT=#y26z?XF4a=+Eypha0 zb5ye!7)H!S49pcd?KV5xi_V;PzRaQ6`FY-)M~=JSsa+H5(ORpJ<6LhcqkG(Zj=JR* NnT%gce_2d41^_e~$lL$` literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..335572250b13a51ee509313bea296c9b554db6e6 GIT binary patch literal 609 zcmV-n0-pUaf&yIv0RRGlfdJL@t?Os(lN0A3E4vURocBw4(pKgu?{{OOyRvX26QhrHa;t2*jS_QO^A3GPpqC=#-emjXcm=RnF`4a*m`|E_saferw03# z0zm+~mW4A%gwfPx4~KgcxtLQvi;#&LNQUaX#r^PgCZSnYXl#j(pEkZr=DN`W1ELx*26?MkBnj0@cq6prfeavc~T0%++>OY`YHYc_g@ zn8dz50{0`or$yO-<&+v`s>aS>GLVdWCwJshnMXH8ZR{I$#(nkkGJOIA0RRC4fq?+w zHIGI_M4BsD?M| zjneUj)=KsI8(gQEV)zKLxis;;;Hl*TK>+-_*@w^l9!@oJ&=x(;z4(Y6vj|HjT9!gx zmYCVVb0ulBz{nHd-(qn~zc!gbnV&uQkjM4(@cYXyB%uk>BQpX)0OxViGxjSUtGBZ1 znAn{xJLu8ot6`5tjsrtEd(UDuA7uQq>cmE!zZFp2sS&bg)xzMlsy$t8E5nE(=9O(z zj{-pe!=V7P;OaCGBg}GN6#lpi?g$YH1!}Fz3!3-bUkO>*2IlSkv23I?Mlf{MWpNz1 zr?!O?Q!ayU)Cy*<1hh{B0zgyFXi`3UV6n$z_XPj4@)(15wlgZRiF+aaPOM>U>s5j1 z>v2FoUD29zTw|~=%-^4&WXI1=tUzO)K)_KgbV~w30Nj~=$=g(vHj941w*dR|*GRkC1HA8kvv$pt|$>h6gV0QDegn5n-Xe6&j>o&YD?*IS* literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..8b3116f714dfb031bbbd69203293925686727d40 GIT binary patch literal 162 zcmV;T0A2qufuAr91_>&LNQU@=}b%W={;*UdWM+9zCHr?BfqCb*?{Gg8fL1-&R{Z-jC&_{QbLDW?^l%sNYt z#gL^|v%HbvSd{F-3UjfD-gDaBUhn#p`X#1WtmIcpE;cvz_Pnz#EBD0D>0PJFJXShy zKyzAE(gnj4_D)m2IlK`D`hg|XAQ(hRbS(-wrgY?ig?8%8Td|AIa_@WAazx?iNxOw6 z%tj0>E(aG(zZhn!JI6b^aQCyD^S5`^?h-dq-~Z1ft)J)a<@H;pPqeQq>YerbP`{dp H(REJ%nlPKX literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..174875cfc5afd26f45e05f55d659ab5a17e2e976 GIT binary patch literal 350 zcmV-k0ipgdf&p4E90m$1hDe6@4FL=R127H*2=VhC;)Paca{>Yg00e>oI7r05n3m_v zGfrZ0hyQswONU?mF+sfQYBE`X2K+jnIpKnyB^inh+YZLksz`n-0m|w!3#B_eR!?2z z8xz3R`Y2s2$&K{YyN#Eopv~~ybWx%hFIK=l}US^&cv6)V?Q%PIl zm@N$4Z}D*#fpu;WSv?RS4xPv15aZ9WUpmUjMCeMeUCAKTUr1`+w?ZFyC4YXQ({mhX z247ehcET)6G*8{a-Q`cBB!a_xQws-?x)u=Am&(n>8Sp|GgaJCt=qP?d5AWh&9b0X9 z8DF-zcl|HC85XKqzEdl9gCAGbCYb5)xH9ew@oM3e)n-TQSI!u$O`O2IAWl*Ly;!~- wZX{MO>BayFfryU1M&)3x9#|l(GS!C`c88KYZ?dn zaz1R=iv4$gp$W4Q1Iwl6RgV5!{9eVs{JCh(nrOCNH$qDPa7OBd-nlp@>~8cF#|ufO Ro3hi?Wf#Btr_7qY0RVBLEmHsh literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..6b127f82fabaa0b43358888c91b617f6df6ed570 GIT binary patch literal 155 zcmV;M0A&9#ftWBH1_~;MNQU&LNQUpU@(FLTmk_A0)c@5)6LhsR^Uko z;?8lPnfvke0s{d60Rn-60Hyo4Xlii7>cZT0Azx3NlO*zSa@|+b+r}qw zsToxfy*>{o*EZ)PdRlg~E<_(K=WEf4qWV0VWs=4akr=6BMnpPZ3dAv&LP@2F*aow> za0Zn^Q4~dFz1dpa3xNWDveAb_r~Tw^4KivOipW0(tG+XxMjH&h(d3&^*av?qRRTc( z??^%dOm@!v5qpJMr70E}NYTm=`tR|7&X$@|*MhG>931#2dHPs^`_ zOH#YzRM&M#V~t090zm-cnjP~_1joxQwbi1eb02#s{vor#la=QM&vlJHz+i`q@y8>z z`F-~oOt4{E#<+LD5BNx7FT*vYZx<>b!MRTYKq%3^(EXBE1rbJV9XZ>ib#ubDA?IxW zS-Lo0<2v|+MJqCu@|t94wfKCbY=_q!$m$|$5* zC`KIuKpjS|?lKJHkt;h-dY|4Ehu&%Lpbf<8=vvIqw|`U0@=nS^AE5jNY69y8Wql?( UEZgw;;GsT$Dl+2T@*O|FpIP51aR2}S literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..a61a42378672fcf5a5338914f236119da30cf981 GIT binary patch literal 678 zcmV;X0$Keqf&!v290m$1hDe6@4FL=R127H*2r@iDbJa4@5&{AU00e>pfW15de6_4J z1|QaFpbU%=Rb8m)ryIOOXlsZO^qMHF55L`f#0)>goX;|MpU0IscW zB-1Ey*e}FSMzqfGWZ#;n0>Oh6hDG#^qA!G262Y<;I_YJdU{Wj(>UOc`?hcI7bk}y2 zeJ>G4y*f9H&Rs8y3Nob=l3%CICup}VEb^?uI!=}??ACfT-8Jq5S%kI$0+G>L=k1;E zoq(kL@-YDV`#7vImWZ1yb5(teuibZy+KFB%mfsp=B=#X|h?LK_I&p@;xvI29zYo10 zAaJQt%lrE{)x+#965IR_2^`o?acnM;J0bFH7(7bTB*XV|XaI>UQQ z6e0OFx*w<1ggnOtpwRT^V&u37=zqDwad4%_RH{hVZ>8q9#9%Y9-ZniFZx;=Unflyv z5y#Iw0kfL5lXIxl!hb6nyet*WWS~XY)w~^{>XxgO0(|831s*u8fjd2M_nAYC!C>_w z=6LiM1A9OAHU-6a^fWCmcmzZx9vmeO7b5wZGGusJ+iTQ~K#NC%``WF&W$!o`kU!cG z3l6`~T-XVM8w9}@D2bq0?_ki9-);ZT7xRr6SB@0?KgBQ5KeS9OIIX~Ny}Y}Zg@Oe_j9bt)wio0|yci*kH4iPWth8SL MstSbL?mxI5;`Hi9zyJUM literal 0 HcmV?d00001 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);